Was geht noch einfacher?

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.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

schlangenbeschwörer hat geschrieben:
rolgal_reloaded hat geschrieben: Meinst du mich :?:
:arrow: ja

Zu deiner letzten Frage: Es geht ja grade darum, das die Klasse nicth für den "Endverbraucher" sein soll, sondern für Leute wie mich grade, die die Klasse dann dem "Endverbraucher", der nix von Pyhton versteht bzw. verstehen muss, nutzbar machen. Du kannst auch eine Konsolenanwendung schreiben. Das machst du dann in einer neuen Klasse oder Funktion, wo du mit einer Instanz deiner Grundklasse arbeitest und die Eingaben in Methodenaufrufe umwandelst und umgekehrt die zurückgegebenen Werte entsprechend dem Benutzer ausgibst.
Ich versteh schon was du meinst, ob meine Frage damit beantwortet ist weiss ich dennoch nicht:-)

Der Code ist im ganzen vielleicht etwas lang, wie und wo kann ich das jetzt außerhalb des Forums posten?

@edit:

Ich habs wieder denke ich:

http://paste.pocoo.org/show/1527/

LG

r_r
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

schlangenbeschwörer hat geschrieben:@Leonidas: Ehmm...wie schreibt man Unittests?
Dazu gibts ein ganzes Kapitel in "Dive into Python", danach komt gleich das Kapitel zu Test-First-Programming. Inzwischen müsste man aber überlegen, ob man das Modul ``unittest`` noch verwenden will oder sollte oder ob man nicht besser ``doctest``, ``py.test`` oder zumindest ``nose`` verwendet.
schlangenbeschwörer hat geschrieben:Und wie trennt man dann Daten und Darstellung, wenn man nicht nur auf die Klasse zugreift, sondern diese auch selbstständig bei bestimmten Gegebenheiten etwas darstellen will?
Die Klasse will aber nie bei bestimmten Gegebenheiten etwas darstellen. Daten sind passiv, auf sie wird zugegriffen. Wenn etwas dargestellt werden soll, muss man das auf höherer Ebene, in einer UI machen, die die Klasse anspricht. Nicht andersrum, sonst wird die Datenlogik mit der Darstellungslogik vermischt.
schlangenbeschwörer hat geschrieben:Der __init__ entsprechende Methoden übergeben, die bestimmte Vorraussetzungen erfüllen? Also so, wie man stdout eine Instanz einer Klasse mit einer write-Methode übergibt?
Würde zwar gehen, stellt dann aber unfassbar komplizierte Anforderungen an die GUI (zumindest wenn sie *etwas* größer sein soll), so dass du jedes Toolkit erstmal dazu bringen müsstest, die von deiner Klasse benötigte API zu haben.
schlangenbeschwörer hat geschrieben:Oder alles mit return regeln, sodass man überprüfen muss, was zurückgegeben wird? Das denke ich, ist wohl besser, aber oft schwer zu machen...
Warum sollte sowas schwer zu machen sein? Und Rückgabewerte überprüfen muss man nicht, wir sind nicht bei C - dafür gibt es Exceptions. Mit einer geeigneten Strukturierung von Exceptions lassen sich Fehler sehr gut behandeln.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

So, hier:
http://paste.pocoo.org/show/1528/
Hab mal so das geändert, was ich noch komisch fand. Ist jetzt leider ungetestet da untestbar, aber morgen liefer ich dazu ne GUI.
An einigen Stellen hab ich meine Änderungen kommentiert, aber halt nicht an allen...musste dir mal ansehen.

Ach, wozu sollte eigentlich

Code: Alles auswählen

def eingabe_eintragsnummer(nummer):
    try:
        return int(nummer)
    except ValueError:
        return None
gut sein? Das geht doch auch einfacher, oder? Und dann global über der klasse...naja.

edit @ Leonidas: Ich seh grad deinen Beitrag...hab grad nicht mehr so viel Zeit, kannst dir ja mal meine Version ansehen und es "testen".

Mit "selbstständig bei bestimmten Gegebenheiten etwas darstellen" meinte ich auch nicht direkt dieses Programm. ZB bei Spielen, für die man ein GUI schreibt, da kommt sowas häufiger vor. Klingt komisch, GUI für Spiele...

Gruß, jj
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

schlangenbeschwörer hat geschrieben:So, hier:
http://paste.pocoo.org/show/1528/
Hab mal so das geändert, was ich noch komisch fand. Ist jetzt leider ungetestet da untestbar, aber morgen liefer ich dazu ne GUI.
An einigen Stellen hab ich meine Änderungen kommentiert, aber halt nicht an allen...musste dir mal ansehen.

Ach, wozu sollte eigentlich

Code: Alles auswählen

def eingabe_eintragsnummer(nummer):
    try:
        return int(nummer)
    except ValueError:
        return None
gut sein? Das geht doch auch einfacher, oder? Und dann global über der klasse...naja.

edit @ Leonidas: Ich seh grad deinen Beitrag...hab grad nicht mehr so viel Zeit, kannst dir ja mal meine Version ansehen und es "testen".

Mit "selbstständig bei bestimmten Gegebenheiten etwas darstellen" meinte ich auch nicht direkt dieses Programm. ZB bei Spielen, für die man ein GUI schreibt, da kommt sowas häufiger vor. Klingt komisch, GUI für Spiele...

Gruß, jj
Kann man eigentlich seinen Code editieren, seh ich es wieder mal nicht oder gehts nicht???

Zur Funktion: die überprüft, ob eine Zahl eingegeben wurde - Auswahl löschen, bearbeiten - diese Funktion ist doch keine sinnvolle Methode der Klasse, denke ich, deshalb steht sie ausserhalb.
Ist doch nichts besonderes, oder?

Die Keys könnte man natürlich schon holen, das probiere ich mal...
aber jetzt weiss ich wieder warum ich es nicht getan habe:

Wenn du die keys mit irgendwas.keys() ausliest bekommst du sie ja nicht in der Ordnung zurück wie du sie in der Anwendung brauchst.

Deine anderen Änderungen muss ich mir erst näher ansehen.

LG

r_r
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

So hier mal eine allgemeinere Fassung. Kurz auch drei Beispiele zur Verwendung dieser Klasse. Hauptprogramm fehlt natürlich.

Übrigens gefällt es mir einfach besser, wenn das konkrete Objekt mit dem Konstruktor geladen bzw. gespeichert wird. Diese Klasse ist in ihrer Art sehr nahe an einer fertigen Anwendung und daher empfinde ich es als Vorteil, wenn man sich nach der Instanzierung z. Bsp. nicht mehr um die Abspeicherung kümmern muss.
Laden sollte daher auch keine Methode sein. Geladen wird bei der Instanzierung und solange das Objekt existiert gibts wohl keinen Grund eine Methode laden() darauf anzuwenden.

Gerne diskutier ich über alle meine kühnen Aussagen:-)

Hier der Code:


http://paste.pocoo.org/show/1531/




Zu den vier Fassungen, unflexibel - alles global, alles mit Funktionen, Lösung mit Klasse, Klasse mit abstrahierter Namensgebung werde ich mir jetzt ein ordentliches didaktisches Konzept bauen.
Ich glaube, dass man damit viele Themen rund ums Programmieren effizient besprechen kann.
Bevor ich die ersten beiden Version poste, werde ich nochmal gründlich drüber gehen.

LG

rolgal_reloaded
Zuletzt geändert von rolgal_reloaded am Sonntag 27. Mai 2007, 23:54, insgesamt 1-mal geändert.
BlackJack

Bei meinem Beispiel war das Laden eine statische Methode, also nichts was man auf einem fertigen Exemplar sondern nur auf der Klasse aufruft. Wenn das Laden aus einer Datei in der `__init__()` steckt, schränkt man sich IMHO unnötig ein. Zum Beispiel bei (automatischen) Tests, die dann nicht ohne Datei oder Zugriff auf ein Dateisystem funktionieren, oder dass man andere Möglichkeiten wie laden aus einer CSV-Datei, Mail-Programm-Adressbuch oder ähnliches als Alternative ausschliesst.

Ausserdem kann man in der `__init__()` nicht das gesamte Objekt laden sondern nur Teile/Attribute davon, weil das Objekt selbst zu dem Zeitpunkt schon besteht. Das man so ein Objekt nicht konstruieren kann ohne die Schlüssel zu kennen, ist eine unglückliche Trennung. Diese Information gehört IMHO mit in die Datei.

Das aktuelle Arbeitsverzeichnis zu dem Zeitpunkt als das Modul geladen wurde, als Ausgangspunkt für alle Lade- und Speichervorgänge zu benutzen ist sehr willkürlich und nicht das was man erwarten würde. Was ist denn der Sinn von dieser Aktion und auch der Fallunterscheidung zwischen 'Linux1' und 'win32' wenn eh in beiden Fällen das gleiche gemacht wird? Bei mir kommt bei `sys.platform` 'linux2' heraus, dass heisst das würde bei mir ziemlich auf die Nase fallen, weil der Dateiname nicht angehängt wird, und versucht wird das aktuelle Arbeitsverzeichnis als Datei zu öffnen.

`self.min_entries` kann man mit 0 initialisieren, dann braucht man einen Test weniger.

``del`` ist keine Funktion.

Irgendwie gefällt es mir nicht so gut, weil es als OOP-Beispiel furchtbar ist. Das würde man nie ernsthaft so entwerfen.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

BlackJack hat geschrieben:Bei meinem Beispiel war das Laden eine statische Methode, also nichts was man auf einem fertigen Exemplar sondern nur auf der Klasse aufruft. Wenn das Laden aus einer Datei in der `__init__()` steckt, schränkt man sich IMHO unnötig ein. Zum Beispiel bei (automatischen) Tests, die dann nicht ohne Datei oder Zugriff auf ein Dateisystem funktionieren, oder dass man andere Möglichkeiten wie laden aus einer CSV-Datei, Mail-Programm-Adressbuch oder ähnliches als Alternative ausschliesst.

Ausserdem kann man in der `__init__()` nicht das gesamte Objekt laden sondern nur Teile/Attribute davon, weil das Objekt selbst zu dem Zeitpunkt schon besteht. Das man so ein Objekt nicht konstruieren kann ohne die Schlüssel zu kennen, ist eine unglückliche Trennung. Diese Information gehört IMHO mit in die Datei.

Das aktuelle Arbeitsverzeichnis zu dem Zeitpunkt als das Modul geladen wurde, als Ausgangspunkt für alle Lade- und Speichervorgänge zu benutzen ist sehr willkürlich und nicht das was man erwarten würde. Was ist denn der Sinn von dieser Aktion und auch der Fallunterscheidung zwischen 'Linux1' und 'win32' wenn eh in beiden Fällen das gleiche gemacht wird? Bei mir kommt bei `sys.platform` 'linux2' heraus, dass heisst das würde bei mir ziemlich auf die Nase fallen, weil der Dateiname nicht angehängt wird, und versucht wird das aktuelle Arbeitsverzeichnis als Datei zu öffnen.

`self.min_entries` kann man mit 0 initialisieren, dann braucht man einen Test weniger.

``del`` ist keine Funktion.

Irgendwie gefällt es mir nicht so gut, weil es als OOP-Beispiel furchtbar ist. Das würde man nie ernsthaft so entwerfen.

Zunächst mal zu "Linux 1" usw. Das hat nur was mit unserer Schule zu tun.

@edit
Aber es dämmert mir grad was....das ist gar nicht mehr nötig. Zu 99,9% hast du Recht ich brauch die Fallunterscheidung hier nicht......den Werdegang dieses Denkfehlers von mir erspar ich dir, ggg

Alles zum Thema laden() (automatische Tests usw.) war hier nicht vorgesehen. Nochmal: Beschränkung bedeutet oft leichteres Verständnis. Beim Programmieren der 4 Ansätze und ersten Tests habe ich gesehen, dass der 4. Ansatz oder vielleicht noch ein höher entwickelter wie deiner (Implementierung von __len__ usw.) zum Anfangen mit SchülerInnen zum Scheitern verurteilt ist. Warum denkst du sind in fast allen Schulen - ich rede nicht von HTLs udgl. - der Einsatz von Java im Unterricht zu einer Katastrophe geführt hat?

Ich finde es als OOPbeispiel gar nicht furchtbar, muss ich dir glatt widersprechen.
Es hat alle Aspekte, das ein OOPP haben sollten, dass man vieles besser machen kann ist ja eh klar.
Es ist dennoch vielseitig einsetzbar, nicht abstrakt und nicht falsch.

Die Sache mit dem Verzeichnis, dass man das nur so festlegen sollten, wenn kein Pfad angegeben wird, habe ich mir auch schon mal gedacht.

Die Idee mit min_entries klingt auch gut, sehe ich mir an.

Warum ist del keine Funktion, anders gefragt, wie sollte ich es ändern in meinem furchtbaren Code:-)

LG

rolgal_reloaded
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@rolgal_reloaded:
Lass doch bitte die full-quotes, die tragen nicht unbeding zur Übersicht bei
rolgal_reloaded hat geschrieben:Es hat alle Aspekte, das ein OOPP haben sollten, dass man vieles besser machen kann ist ja eh klar.
Wie sieht das mit Polymorphie aus? Daran kann ich mich nämlich in dem Beispiel nicht erinnern, nachschauen konnte ich leider nicht, da der Server nicht erreichbar war.
rolgal_reloaded hat geschrieben:Warum ist del keine Funktion, anders gefragt, wie sollte ich es ändern in meinem furchtbaren Code:-)
"del" ist ein Statement.
BlackJack

@rolgal_reloaded: Ich bin davon ausgegangen, dass die OOP-Variante nicht der Anfang ist, sondern das was am Ende präsentiert/gelernt wird, d.h. die meisten Methoden dürften zu dem Zeitpunkt schon als Funktionen in sehr ähnlicher Form aus früheren Versionen bekannt sein. Da kann man dann IMHO schon so etwas wie `__len__()` neu einführen. Der Übergang könnte so aussehen: Vorher hatten wir eine Liste, da konnte man mit `len()` Abfragen wieviele Datensätze vorhanden sind, jetzt haben wir eine eigene Klasse und so (`__len__()`) kann man dafür sorgen, dass man immer noch mit `len()` an diese Anzahl kommt.

Zum Thema `laden()`: Der Lehrer darf IMHO schon weiterdenken und sollte Beispiele geben, die erweiterbar sind, auch wenn das im Unterricht nicht getan wird. Und gerade beim Lernen ist der interaktive Interpreter eine sehr nützliche Sache, deshalb sollte man auf "Testbarkeit" Wert legen, auch wenn man keine automatischen Tests durchführt. Wenn man die meisten Funktionen/Methoden "live" aufrufen und die Auswirkungen inspizieren kann, bekommt man ein besseres Gefühl für die Wirkungsweisen und Zusammenhänge, als wenn man nur den Quelltext und einen kompletten, grossen Programmablauf "von aussen" beobachten kann.

Und gerade bei Python sind automatische Tests zum Beispiel als "doctests" sehr einfach. Das kann man den Schülern zumindest mal zeigen. Oder zu Aufgaben einen passenden Doctest mitgeben, den der selbstgeschriebene Code bestehen muss.

Bei uns im Informatik-Unterricht und in der Uni wurde immer Wert darauf gelegt, dass zu den Hausaufgaben nicht nur eine Funktion oder ein Progrämmchen geschrieben wurde, sondern auch ein dokumentierter, teilweise interaktiver Testlauf, abgeliefert wurde. Nur so lernt man zu testen und Fehler selber zu finden und bekommt ein "Gefühl" für den Code.

Wir scheinen und einig zu sein, dass wir uns uneinig sind was das OOP-Beispiel angeht. ;-)

Es geht nicht darum dass hier Klassen und Methoden angewendet werden, sondern dass der Entwurf IMHO schlecht ist. Schon ganz grundsätzlich. Ich habe sogar die Befürchtung, dass das nicht einmal etwas mit OOP zu tun hat und in den anderen 3 Varianten genauso ist. Das könnte teilweise daran liegen, dass es kein klares Ziel gab (gibt?) ─ die Anforderungen scheinen sich jedenfalls im Laufe der Zeit und während des Programmierens geändert zu haben. Wie hast Du denn vor dieses Programm zu motivieren und wie gehst Du beim Entwurf vor?
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Grundsätzlich hast du mit vielem recht. Auch an deinen Ideen was man im Unterricht machen könnte - könnte!, gibts eigentlich nichts zu rütteln.

Aber zu der Sache mit OOP. Das war sogar deine Idee, als ich zum Spaß auch mal ein Adressbuch gebastelt habe, dabei mich ganz auf das Wesentlichste reduziert habe, um Dinge wie Zugriff auf ein Dict., Listen usw. zu zeigen.

Schließlich, auch durch dich, entstand die Idee, das Programm auch an sich zu verbessern. So ging es dann Schritt für Schritt weiter.

Der Entwurf ist schlecht. Was ist denn genau schlecht?
Eine Klasse, die es mir ermöglicht viele ähnliche Anwendungen zu machen, es ist kompakt übersichtlich, funktioniert, was soll daran schlecht, schlecht im engeren Sinne, nicht vor dem Hintergrund deines Genies sein ???
Und natürlich hat es was mit OOP zu tun.
Es wurde ein Datentyp definiert, die aufgenommen Daten der davon abgeleiteten einzelnen Objekte können manipuliert werden usw.

Jetzt sind die vier Versionen mal lauffähig, die will ich wo es geht selbst noch etwas tunen. Dann werden wir diskutieren ab welcher Klasse das machbar wäre und wie man das am besten aufbauen zu hat.
Grundsätzlich versucht man Motivation zu schaffen, in dem besprochene Themen unmittelbar erfahrbar werden. Häufig ist das im Unterricht nicht der Fall, ein ganz großes Problem auch des Instrumentalunterrichts übrigens. Gruhn - Der Musikverstand, ein super Buch zu diesem Thema.

Zum Entwurf kann ich daher mal zunächst nur sagen, dass ich versuchen werde, mit den SchülerInnen, nach Etstellung der anderen Versionen, ein Adressbuch abstrakter zu sehen, zu beschreiben, usw. Dadurch Parallelen zu anderen Objekten wie Telefonbuch usw. zu erkennen.

Eine Klasse von der man Objekte ableiten kann, die schon eine Anwendung ansich definieren legt nahe, dass man Mechanismen beim Instanzieren integriert, die man bei der Programmierung dieser einzelnen Anwendungen sowieso braucht und einbauen würde.
Stichwort laden() und speichern().

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

EyDu hat geschrieben:@rolgal_reloaded:
Lass doch bitte die full-quotes, die tragen nicht unbeding zur Übersicht bei
Dein Wunsch ist mir Befehl:-) Aber wohl eine Geschmacksache. Wird aber erst nächstes mal umgesetzt:-))
rolgal_reloaded hat geschrieben:Es hat alle Aspekte, das ein OOPP haben sollten, dass man vieles besser machen kann ist ja eh klar.
Wie sieht das mit Polymorphie aus? Daran kann ich mich nämlich in dem Beispiel nicht erinnern, nachschauen konnte ich leider nicht, da der Server nicht erreichbar war.
Darüber ist zu hirnen, vielleicht hat es nicht alles, aber wenn wir jetzt anfangen jede Klasse, die mal geschrieben wurde darauf zu prüfen, ob sie tatsächlich alle Kriterien von OOP erfüllt, dann bleibt wohl ausser den Klassen in der Standardbibliothek nicht allzuviel übrig.
rolgal_reloaded hat geschrieben:Warum ist del keine Funktion, anders gefragt, wie sollte ich es ändern in meinem furchtbaren Code:-)
"del" ist ein Statement.
Und warum darf ich das nicht über eine Funktion aufrufen?
Das habe ich schon öfters gesehen.

LG

rolgal_reloaded
Zuletzt geändert von rolgal_reloaded am Montag 28. Mai 2007, 11:23, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

rolgal_reloaded hat geschrieben:
EyDu hat geschrieben:@rolgal_reloaded:
Lass doch bitte die full-quotes, die tragen nicht unbeding zur Übersicht bei
Dein Wunsch ist mir Befehl:-) Aber wohl eine Geschmacksache.
Nein - Fullquotes sind so ziemlich von allen die sich etwas mit dem Usenet oder ernsthaft mit Mails beschäftigen ungerne gesehen. Ich antworte quasi immer indem ich nur das zitiere auf das ich antworte - so sieht man auf was genau ich antworte und muss es sich nicht aus dem Fullquote fischen - hilft mir, weil ich dann nicht vergesse auf etwas zu antworten und hilft dem leser, weil er dann sieht auf was ich mich beziehe.
Lerne bitte aber richtig zu zitieren, denn in deinen Zitaten sind deine Aussagen mit denen von Y0Gi vermischt, was das ganze nur schwer nachvollziehbar macht - es sieht aus, als würdest du dialektische Selbstgespräche führen ;)
rolgal_reloaded hat geschrieben:Darüber ist zu hirnen, vielleicht hat es nicht alles, aber wenn wir jetzt anfangen jede Klasse, die mal geschrieben wurde darauf zu prüfen, ob sie tatsächlich alle Kriterien von OOP erfüllt, dann bleibt wohl ausser den Klassen in der Standardbibliothek nicht allzuviel übrig.
Nein, aber die Klassen sind dann auch nicht zu Lehrzwecken da. Deine ist es und sollte also mit gutem Beispiel vorran gehen.
rolgal_reloaded hat geschrieben:
Y0Gi hat geschrieben:"del" ist ein Statement.
Und warum darf ich das nicht über eine Funktion aufrufen?
Das habe ich schon öfters gesehen.
Das macht es nicht richtiger. Es ist zwar gültige Syntax, aber meist nur damit die Quellcodes von Leuten die aus Java und C kommen, nicht sofort auf die Nase fliegen: ``if(...)``, ``for(...)`` etc. In Python geht das ohne und es sollte auch ohne sein. So sieht man, was ein Statement ist und was eine Funktion.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@Leonidas

Also meistens setze ich genau an der letzten Zeile eines Zitats fort. Möglich, dass mir ein paar ausgekommen sind, die nicht optimal waren.

Nur die Sache mit Yogi bleibt mir ein Rätsel?

Und zu del:
Jetzt hats gerasselt! Es ging nur um die () ! Ich dachte es ging um was ganz anderes.

Diese Klassen, die ich meine sind sogar ganz oft Lehr- bzw. Lernbeispiele.

LG

rolgal_reloaded
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

rolgal_reloaded hat geschrieben:Diese Klassen, die ich meine sind sogar ganz oft Lehr- bzw. Lernbeispiele.
Und dadurch ist es ok Fehler anderer zu wiederholen?

Eine wirklich wichtige Sache bei OOP ist eben nicht nur die Fähigkeit Klassen zu nutzen sondern, sie auch sinnvoll zu nutzen. Denn OOP ist eben letztendlich nur eine Art zu Denen und zu Programmieren, die bestimmte Abstraktionen bietet und es ermöglicht einfacher zu denken. OOP soll das Programmieren vereinfachen und kein Selbstzweck sein. Dazu zählt eben die Entscheidung: bringt mir OOP in diesem Fall etwas oder müsste ich mein Problem in OOP reinzwingen? Das ist etwas was Java fehlt: wenn das Problem nicht OOP-fähig ist, dann wird es eben dazu gezwungen. Bei OOP ist eben der Entwurf wichtig: wenn der Entwurf stimmt, können sich Klassen intuitiv verwenden lassen ohne erst überlegen zu müssen, was der Autor der Klasse sich denn bei dieser oder jener Klasse denn bitte gedacht hat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Leonidas hat geschrieben:
rolgal_reloaded hat geschrieben:Diese Klassen, die ich meine sind sogar ganz oft Lehr- bzw. Lernbeispiele.
Und dadurch ist es ok Fehler anderer zu wiederholen?
Ich bin jetzt arrogant und sage, dass das Beispiel dann doch viel besser ist, als vieles was mir in Büchern usw. unterkommt.
Eine wirklich wichtige Sache bei OOP ist eben nicht nur die Fähigkeit Klassen zu nutzen sondern, sie auch sinnvoll zu nutzen.
Warum kann sie nicht sinnvoll genutzt werden???
Denn OOP ist eben letztendlich nur eine Art zu Denen und zu Programmieren, die bestimmte Abstraktionen bietet und es ermöglicht einfacher zu denken. OOP soll das Programmieren vereinfachen und kein Selbstzweck sein.
Nicht der Fall??? Ich kann mit einer kleinen Klasse viele verschiedene Anwendungen realisieren.
Dazu zählt eben die Entscheidung: bringt mir OOP in diesem Fall etwas oder müsste ich mein Problem in OOP reinzwingen?

Da ist nichts reingezwungen, wenn ja, dann bitte ganz detailliert.
Das ist etwas was Java fehlt: wenn das Problem nicht OOP-fähig ist, dann wird es eben dazu gezwungen. Bei OOP ist eben der Entwurf wichtig: wenn der Entwurf stimmt, können sich Klassen intuitiv verwenden lassen ohne erst überlegen zu müssen, was der Autor der Klasse sich denn bei dieser oder jener Klasse denn bitte gedacht hat.
Da bleibt ja nicht mal viel in der Standardbibliothek übrig.
Bei der Verwendung von Klassen muss man sich wohl immer mit diesen - in irgendeiner Art, freilich mehr oder weniger - beschäftigen. Und grade bei Dict muss man zähneknirschend feststellen, dass es seine Richtigkeit hat, dass Keys usw. nicht in einer bestimmten Ordnung zurückgegeben werden.

LG

rolgal_reloaded
BlackJack

@rolgal_reloaded: Diese Schrittweise Umwandlung mit einem "beweglichen Ziel" ist wahrscheinlich keine gute Idee gewesen.

Ein Entwurf der funktioniert ist dadurch nicht automatisch gut. paste.pocoo.org hat gerade mal wieder einen "Internal Server Error"[*], darum habe ich jetzt keinen Zugriff auf die letzte Version. Entwurf ist ein Prozess und das Endergebnis sieht für mich nicht so aus, als wenn der nicht besonders geradlinig verlaufen ist. Was wie gesagt, höchstwahrscheinlich damit zu tun hat, dass es mehr gewachsen als geplant ist. Die Methoden beschränken sich nicht nur auf eine Aufgabe, wie `__init__()`, das auch das Laden übernimmt, oder `__str__()`, das ein in der Dokumentation nicht vorgesehenes Argument bekommt und dafür explizit aufgerufen werden muss. Dann ist in der Klasse "GUI" und Datenhaltung vermischt. Es ist aber auch nicht die ganze "GUI" in der Klasse enthalten, also kann man es auch nicht als Anwendungsobjekt sehen. Das sind alles schlechte Beispiele und die sollte man als Lehrer möglichst nicht bringen. Schüler werden das als Muster für künftige Programme benutzen. So etwas wie Sternchen-Import, ``global``, ``input`` und ``eval`` sollte man gar nicht erst einführen und Punktabzug geben, wenn es jemand benutzt, ohne genau erklären zu können warum das im Allgemeinen schlecht ist und genau bei *dem* Einsatz eine Ausnahme von der Regel gerechtfertigt ist. IMHO.

Das es nicht nur etwas mit OOP zu tun hat, vermute ich, da ich nicht sehe das hier eine klare Anforderung in eine Datenstruktur umgesetzt wurde, sondern es mit der Zeit gewachsen ist. Ich denke das wird in der imperativen Variante ähnlich aussehen.

Ich habe ja offensichtlich keine grosse Erfahrung mit Lehre, aber ich würde folgenden Ablauf für ganz gut halten: Klare Anforderung worauf man hinauswill, Datenstrukuren auswählen und begründen, die benötigten Operationen herausarbeiten, und diese dann als einzelne Funktionen implementieren. Dabei immer darauf achten, das sie von den Schülern einzeln ausprobiert und "erfahren" werden können. Dabei sollte dann ein Ansatz herauskommen, der sich sehr einfach in OOP umsetzen lässt, weil ein guter imperativer Entwurf gar nicht soweit von OOP entfernt sein muss. Im Grunde müssen dabei nur zusammengehörige Datenstrukturen und Funktionen zu Attributen und Methoden zusammengefasst werden.

[*] @pocoo-Menschen: Ich weiss, es ist ein kostenloser Service und man kann leicht meckern bei Sachen, für die man nicht verantwortlich ist, aber der Service ist in letzter Zeit verdammt unzuverlässig. Woran liegt das? Ist der paste-Service selber nicht stabil oder liegt's daran, dass der auf einem Server läuft, auf dem auch andere Komponenten aktiv in der Entwicklung und damit nicht immer so ganz stabil sind?
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

BlackJack hat geschrieben: Die Methoden beschränken sich nicht nur auf eine Aufgabe, wie `__init__()`, das auch das Laden übernimmt,
Es gehört eben wie schon begründet bei der Instanzierung dieser Objekte dazu
....oder `__str__()`, das ein in der Dokumentation nicht vorgesehenes Argument bekommt und dafür explizit aufgerufen werden muss.

Das sehe ich jetzt mal etwas locker, wenn es eine ganz einfache andere Lösung - integrierbar in meinen Code, gibt, dann gern
Dann ist in der Klasse "GUI" und Datenhaltung vermischt. Es ist aber auch nicht die ganze "GUI" in der Klasse enthalten, also kann man es auch nicht als Anwendungsobjekt sehen.
Du hast auch ein raw_input in deinem Beispiel, erwischt, ggg.
Aber darüber habe ich natürlich auch schon nachgedacht, aber halt noch keine Lösung dafür.
Das sind alles schlechte Beispiele und die sollte man als Lehrer möglichst nicht bringen........
Wenn das immer möglich wäre ohne schlechte Beispiele auszukommen, ich meine auch mein Hauptfach, dann würde ich doppelt so gern unterrichten.
Das es nicht nur etwas mit OOP zu tun hat, vermute ich, da ich nicht sehe das hier eine klare Anforderung in eine Datenstruktur umgesetzt wurde, sondern es mit der Zeit gewachsen ist. Ich denke das wird in der imperativen Variante ähnlich aussehen.
Das stimmt. Allerdings habe ich auf diesem Weg erkannt was eine wesentlich bessere Datenstruktur ist. Erinnerst dich vielleicht noch an die alte?
Ich habe ja offensichtlich keine grosse Erfahrung mit Lehre, aber ich würde folgenden Ablauf für ganz gut halten: Klare Anforderung worauf man hinauswill, Datenstrukuren auswählen und begründen, die benötigten Operationen herausarbeiten, und diese dann als einzelne Funktionen implementieren. Dabei immer darauf achten, das sie von den Schülern einzeln ausprobiert und "erfahren" werden können. Dabei sollte dann ein Ansatz herauskommen, der sich sehr einfach in OOP umsetzen lässt, weil ein guter imperativer Entwurf gar nicht soweit von OOP entfernt sein muss. Im Grunde müssen dabei nur zusammengehörige Datenstrukturen und Funktionen zu Attributen und Methoden zusammengefasst werden.
Auf die Gefahr hin, dass ich gleich wieder durch den Fleichwolf gedreht werde, poste ich mal die Variante mit Funktionen. Ich finde, dass der letzte Satz deines Absatzes ziemlich genau zutrifft.
Aber gucken wir mal....

http://www.ubuntuusers.de/paste/11148/
BlackJack

Man könnte zum Beispiel eine Methode `_entries2str()` einführen und die von `__str__()` und der Suche aus benutzen. Ansonsten verhindert das Laden in der `__init__()` eine mögliche Lösung, nämlich dass die Suche ein `DataBook`-Objekt liefert, dass man einfach ausgeben kann.

Du hast zwar Deine imperative Lösung relativ direkt in Klassen und Methoden umgesetzt, aber ich finde die imperative Lösung auch nicht gut. Kein Wunder dass die OOP-Lösung nicht besser wird. ;-)

Dein einer Datentyp vermischt Datensätze, die Datenbank und die Anwendung. Ein sauberer Entwurf hätte ein Datenbank-Objekt, das Datensatz-Objekte enthält und die Anwendung wäre entweder auch ein Objekt oder als Funktionen auf Modulebene implementiert.

Zur Modellierung: Ein Datensatz braucht Schlüssel und Werte, in der Datenbank selbst allerdings reicht es die Schlüssel nur einmal zu speichern und von den Objekten nur die Werte. Und was Datensätze im Grunde auch brauchen ist eine eindeutige ID. Solange man mit dem Programm nicht folgenden Arbeitsablauf bewerkstelligen kann: Eine Suche starten und einfach einen Datensatz im Suchergebnis bearbeiten, ist das genauso sinnlos wie Fahrzeuge als Klassen. Und das wolltest Du ja nicht. :-)
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@BlackJack

Du müsstest wissen, dass wenn es mir um eine prof., soll heissen richtige Anwendung ginge, ich es sowieso anders gelöst hätte.

Inzwischen denke ich ist es sinnlos zu versuchen zu erklären, was der Unterschied ist zwischen Programmen, die ansehnlich, funktional, lehrreich sind - weil vieles rund ums Programmieren demonstriert werden kann, und solchen die echte Programme sind.

Es ist jetzt auch der Punkt erreicht wo ich darüber nicht mehr diskutieren mag.
Irgendwas wird nicht gelesen, verstanden oder gehört, sonst würdest du mir gar nicht erklären, dass der imperative Ansatz auch nicht gut ist.

Ich werde weiterhin als schlechter Programmierer schlechte Programme schreiben, hoffe bei Problemen weiterhin sinnvolle Hilfe zu bekommen und bin froh, dass die Bestätigung für meine trotzdem produktive Arbeit nicht allein von den Leuten in diesem Forum mit ihren für meinen Anwendungszweck inkompatiblen Kriterien abhängig ist.

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Du hast zwar Deine imperative Lösung relativ direkt in Klassen und Methoden umgesetzt, aber ich finde die imperative Lösung auch nicht gut. Kein Wunder dass die OOP-Lösung nicht besser wird. ;-)

Dein einer Datentyp vermischt Datensätze, die Datenbank und die Anwendung. Ein sauberer Entwurf hätte ein Datenbank-Objekt, das Datensatz-Objekte enthält und die Anwendung wäre entweder auch ein Objekt oder als Funktionen auf Modulebene implementiert.

usw., usw.
Da muss man sich auch fragen, warum du dann überhaupt auf Seite 1 deine Vorschläge zur Verbesserung gemacht hast, wenn diese den Ausführungen oben entsprechend, ja gar keine sein können.
:?:

Du hattest da sogar noch viel mehr in den Funktionen drin was nicht reingehört, wie du dich vielleicht noch erinnern kannst.

Dennoch war es ein guter Anstoß in die richtige Richtung weiterzudenken.

LG

rolgal_reloaded
Antworten