1. Kontonummer-Attribut
Ich sehe da ja auch einen Zusammenhang, allerdings nur einen mittelbaren (durch die Zuordnung). Zudem möchte ich Redundanzen als Fehlerquellen vermeiden. Wenn die Kontonummer in das Kontoobjekt aufgenommen würde, dürfte sie nicht erneut (redundant) als Schlüssel des dictionaries verwendet werden. Die Frage ist doch, ob das Kontoobjekt die ihm Container übergeordnete Zuordnung (hier dict) kennen muss. Das sehe ich im Moment nicht.
Alternativ böte sich ein set an. Wobei man hier die Kontoklasse (nun mit Kontonummer) und entsprechende Funktionen set-tauglich gestalten müsste.
2. authenticate()-API
Der Gedanke war, dass die API durch ein BankOMat-Objekt, welches die Benutzerschnittstelle definiert, verwendet wird. Dieses Objekt verwendet die Kontonummer als inneren Zustand. Kontonummer vorhanden -> angemeldet, Kontonummer nicht vorhanden (=None) -> nicht angemeldet.
Zugegeben, so sollte man produktiv nicht mit Sicherheit umgehen
Gebt mir Tipps
@bwbg: Ad 1.) Eine Kontonummer gehört zu einem Konto-Objekt, das ist eine Eigenschaft des Kontos, dadurch kann man ein Konto innerhalb einer Bank von anderen Konten unterscheiden. Wenn ich ein Konto-Objekt habe und von dem nicht seine Kontonummer abfragen kann, dann fehlt da etwas. Das hat überhaupt nichts damit zu tun wie ein `Konten`- oder `Bank`-Objekt die `Konto`-Objekte am Ende verwaltet. Wie Du schon sagst, davon sollte ein Konto-Objekt nichts wissen müssen und man sollte nicht wegen Implementierungsdetails wichtige Attribute die zur Problemdomäne gehören einfach weglassen.
Ad 2.) Warum der unnötige Umweg? Warum nicht `Konto`-Objekt vorhanden = angemeldet, `None` = nicht angemeldet? Und selbst Dein Ansatz erklärt immer noch nich die API, denn das liesse sich auch mit einem Wahrheitswert als Rückgabwert der `authenticate()`-Funktion realisieren. Wenn da `True` zurück kommt setzt man die Kontonummer als inneren Zustand, falls `False` zurück kommt eben `None`. Die Kontonummer hat der Aufrufer ja, weshalb ich die API ja schräg finde das die Kontonummer die man sowieso schon hat, als Rückgabwert kommt oder halt `None` was letztlich auf zwei Mögliche Rückgabewert hinaus läuft, also eigentlich ein Wahrheitswert.
Ad 2.) Warum der unnötige Umweg? Warum nicht `Konto`-Objekt vorhanden = angemeldet, `None` = nicht angemeldet? Und selbst Dein Ansatz erklärt immer noch nich die API, denn das liesse sich auch mit einem Wahrheitswert als Rückgabwert der `authenticate()`-Funktion realisieren. Wenn da `True` zurück kommt setzt man die Kontonummer als inneren Zustand, falls `False` zurück kommt eben `None`. Die Kontonummer hat der Aufrufer ja, weshalb ich die API ja schräg finde das die Kontonummer die man sowieso schon hat, als Rückgabwert kommt oder halt `None` was letztlich auf zwei Mögliche Rückgabewert hinaus läuft, also eigentlich ein Wahrheitswert.
@BlackJack:
Zu 1) gebe ich Dir recht. Wenn man intensiver darüber nachdenkt, ist es sinnfrei, die Kontonummer getrennt vom Kontoobject zu halten.
Zu 2) bin ich noch nicht ganz überzeugt. None eignet sich doch hervorrangend als (mögliches) Ergebnis für eine Operation, welche fehlschlagen kann. Zumal sich das Ergebnis (durch None) als Wahrheitswert verwenden ließe.
Code sagt mehr als tausend Worte: http://www.python-forum.de/pastebin.php?mode=view&s=429
Anmerkung: Account verfügt (noch) nicht über ein account_id-Attribut.
Hier verwendet die BankOMat.login das von mir vorgeschlagene API-Konstrukt. Die Rückgabe als Wahrheitswert oder gar eine Exception würde das ganze m. E. nach nicht übersichtlicher machen.
Zu 1) gebe ich Dir recht. Wenn man intensiver darüber nachdenkt, ist es sinnfrei, die Kontonummer getrennt vom Kontoobject zu halten.
Zu 2) bin ich noch nicht ganz überzeugt. None eignet sich doch hervorrangend als (mögliches) Ergebnis für eine Operation, welche fehlschlagen kann. Zumal sich das Ergebnis (durch None) als Wahrheitswert verwenden ließe.
Code sagt mehr als tausend Worte: http://www.python-forum.de/pastebin.php?mode=view&s=429
Anmerkung: Account verfügt (noch) nicht über ein account_id-Attribut.
Hier verwendet die BankOMat.login das von mir vorgeschlagene API-Konstrukt. Die Rückgabe als Wahrheitswert oder gar eine Exception würde das ganze m. E. nach nicht übersichtlicher machen.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
@bwbg: ein
würde den Code um einiges klarer machen. In Deiner Schreibweise würde sich jeder Leser wundern, wie das Argument account_id mit dem Rückgabewert zusammenhängt. Mit if ist klar, dass es keine zwei verschiedenen account_ids gibt.
Code: Alles auswählen
if self.bank.authenticate(account_id, password):
self.account_id = account_id
@bwbg: Hm, der Entwurf wird IMHO nicht besser. Transaktionen gehören IMHO zum Beispiel zum Konto und nicht zur Bank. Dein Konto-Objekt enthält ja so gut wie gar nichts, dabei wäre das aus Sicht eines Kunden ein zentrales Objekt auf dem so gut wie alles relevante erreichbar ist. Der Titel ist eigentlich eine Verquickung von Kontotyp und Benutzer. Wenn man schon Benutzer und Pins hat, dann würde ich auch eher sagen das Name und Pin in einer `User`-Objekt gehören. Wenn man es einfach halten möchte dann wäre der Kontotyp eine beschreibende Zeichenkette, oder man würde das wenn man die Typen tatsächlich unterscheiden muss über verschiedene Klassen regeln oder das Strategie-Entwurfsmuster anwenden. Der regelmässige Abschluss zum Beispiel sieht ja bei Girokonten anders aus als bei Sparkonten oder internen Konten.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Nicht unbedingt! Im Grunde genommen sind dafür Exceptions oftmals die wesentlich bessere Wahl - denn damit kann ich die Fehlerbehandlung flexibel im Call-Stack behandeln, muss es also nicht unmittelbar an der aufrufenden Stelle tun. Bei einem möglichen ``None`` muss ich eigentlich immer *sofort* prüfen, ob ich etwas bekommen habe, da ich ansonsten *irgend einen* Fehler wie z.B. einen ``AttributeError`` bekomme.bwbg hat geschrieben: Zu 2) bin ich noch nicht ganz überzeugt. None eignet sich doch hervorrangend als (mögliches) Ergebnis für eine Operation, welche fehlschlagen kann.
Mal als Beispiel:
Code: Alles auswählen
In [3]: def get_configuration():
...: return None
...:
In [4]: config = get_configuration()
In [5]: config.some_property
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-c6a6cf6a3f6f> in <module>()
----> 1 config.some_property
AttributeError: 'NoneType' object has no attribute 'some_property'
Werfe ich hingegen eine *spezielle* Exception, wenn ich die Konfiguration nicht erstellen kann, so kann ich das zielgerichtet abfangen und zwar dort, wo es sinnvoll erscheint.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Nach einer Nacht drüber schlafen ziehe ich meine Punkte 1 und 2 zurück und behaupte das Gegenteil. Das ganze werde ich nochmal in meine gedankliche Entwurfsabteilung geben.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Sorry, ich komme überhaupt nicht mit. Vielleicht habt ihr ein paar Vorschläge zum lernen für mich. Habe eine Menge
Ideen aber überhaupt keine Ahnung wie ich das mit der Umsetzung mache.. Da währe z.B ein Bot und zum
Code der hier Präsentiert wird - Sowas hab ich noch nie gesehen -
Ideen aber überhaupt keine Ahnung wie ich das mit der Umsetzung mache.. Da währe z.B ein Bot und zum
Code der hier Präsentiert wird - Sowas hab ich noch nie gesehen -
@Mr.White: Es gibt im Netz ein paar Seiten wo man Probleme/Aufgaben findet, die man mit Hilfe von Programmen lösen kann. Mal als Beispiele: Project Euler, Sphere Online Judge (SPOJ), HP CodeWars, und Reddit: Dailyprogrammer.
@Mr.White, du benutzt Klassen, davon würde ich erstmal abraten.
Lerne erstmal Funktionen sinnvoll einzusetzen.
Dein Code ist momentan ein einziges Spaghetti-Wirrwarr aus If/Else/usw. bis in die zehnte Stufe.
Da kann niemand sinnvoll drüberschauen.
Versuch mal die Sachen in einzelne Funktionen aufzuteilen, die alle nicht tiefer als maximal 2-3 If-Stufen gehen dürfen.
Auch Listen/Dicts würde ich empfehlen zum rumspielen, bevor du wieder Klassen versuchst.
Nicht zu viel gleichzeitig oder zu schnell lernen, das verwirrt eher.
Lerne erstmal Funktionen sinnvoll einzusetzen.
Dein Code ist momentan ein einziges Spaghetti-Wirrwarr aus If/Else/usw. bis in die zehnte Stufe.
Da kann niemand sinnvoll drüberschauen.
Versuch mal die Sachen in einzelne Funktionen aufzuteilen, die alle nicht tiefer als maximal 2-3 If-Stufen gehen dürfen.
Auch Listen/Dicts würde ich empfehlen zum rumspielen, bevor du wieder Klassen versuchst.
Nicht zu viel gleichzeitig oder zu schnell lernen, das verwirrt eher.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.