Benutzung einer Klasse anstatt eines Dicts

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.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

Hey Leute,

ich habe folgenden Code:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import re

companies = {}
for line in open('/home/ibrahim/Desktop/Test.list'):
    company, founding_year, number_of_employee = line.split(',')
    number, name = company.split(")")
    companies[name] = [name, founding_year, number_of_employee]
    print "Company: %s" % company

CompanyIndex = raw_input('\n<Choose a company you want to know more about.>\n\n<Insert a companyspecific-number and press "Enter" .>\n')

if CompanyIndex in companies:
    name, founding_year, number_of_employee = companies[CompanyIndex]
    print 'The companys name is: ',name,'\nThe founding year is: ', founding_year,'\nThe amount of employees is: ', number_of_employee
else:
    print"Your input is wrong."
ich habe eine text Datei die folgendermaßen aussieht:

(1)Chef,1965,10
(2)Fisher,1932,20
(3)Gardener,1998,5

mein Programm erfüllt auch seinen Zweck und es funktioniert so weit. Doch nun wurde mir gesagt, dass ich anstatt eines Dictionairys eine Klasse benutzen soll :shock: ich habe mir nun etliche Tutorials über Klassen reingezogen und habe echt keinen blassen Schimmer was nun die Klasse für einen Vorteil gegenüber eines Dicts haben sollen :K Die zweite und wichtigste Sache ist, dass ich überhaupt keine Ahnung habe wie ich aus meinem alten Programm ein neues ohne Dict und mit einer Klasse machen soll :K :K :K ich bin echt gerade ratlos und wenn diese Frage vielleicht ein bisschen dumm erscheint tut es mir Leid aber ich bin erst seit ca 2 Wochen mit python in Beschäftigung
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@ZedsWhatSheSaid: Bei diesem Grad der Entwicklung braucht es IMHO noch keine eigene Klasse zur Abfrage der Firmeneinträge. Das kann man machen, wenn dein Programm mehr Funktionalität erhält und man irgendeine Art von Verwaltung für die Einträge (mit dauerhafter Speicherung, Hinzufügen-Funktion, etc) haben möchte. Im Moment würde ich bloß die Einträge an sich als eigene Klassen (z.B. via `collectins.namedtuple`) erzeugen, weil dies die Arbeit damit etwas erleichtern wird.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

so etwas in der Art soll auch später gemacht werden, ich soll auch eine Funktion einbauen in der ich die Informationen der Firmen updaten kann (außerdem soll ich später noch diese Information in Json konvertieren, falls diese Information von Nöten ist)
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Naja, gut. Du kannst natürlich schon jetzt einen `CompanyManager` als Klasse definieren, der sich um das Einlesen der Einträge aus einer Textdatei kümmert (als eigene Methode der Klasse) und der sich um die Abfrage eines bestimmten Eintrags kümmert (wieder eigene Methode). Das Abfragen könnte man noch gliedern in eine interne Methode, die eine Abfrage aus Programmierer-Sicht abwickelt, sowie einer Methode auf Benutzerebene, die mit netten Zwischenmeldungen zur Eingabe auffordert (`raw_input()` verwendest du ja bereits richtigerweise), sowie mögliche Fehler auf Shell-Ebene ausgibt ("Your input is wrong.") - wobei deren Funktionalität dann auf der "internen" Methode basieren würde. Bevor du das alles wirklich verstehst, musst du dich aber wahrscheinlich noch etwas näher mit Python, unter anderem mit Exception-Handling (hier wohl vor allem: `KeyError`) auseinandersetzen.
BlackJack

@ZedsWhatSheSaid: Bei dem Beispielprogramm sehe ich auch keinen Sinn für eine Klasse. Insbesondere nicht für eine die ausgerechnet das Wörterbuch ersetzt. Bei den Werten im Wörtberbuch könnte man noch argumentieren, dass die einzelnen Komponenten dann Namen haben statt eines nichtssagenden Index. Klassen fangen erst an wirklich Sinn zu machen wenn man Operationen auf diesen neuen Datentypen in Form von Methoden oder Operatorüberladung definiert, die von vorhandenen Datentypen nicht zur Verfügung gestellt werden.

Wenn das geplant ist, dann könntest Du natürlich eine Klasse dafür schreiben. Und naja, für das holen und setzen von Firmen-Objekten kann man natürlich auch jeweils eine eigene Methode zur Verfügung stellen.

@snafu: Bitte nicht `Company*Manager*`. Das sind so typische Namen von Java-Programmierern wenn ihnen nichts gescheites einfällt. `Companies` würde so einen Container doch auch ausreichend beschreiben.
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@BlackJack: Magst du spätere Unterklassen a la `JsonFileCompanyManager` und `TxtFileCompanyManager` (wobei beide natürlich von der Schnittstelle `FileBasedCompanyManager` erben) etwa nicht...? *schnüff* ;)
BlackJack

@snafu: Die werden dann sicher von einer `CompanyManagerFactory` erstellt, wobei die von einem `CompanyManagerFactoryManager` verwaltet wird der sie mit Hilfe eines `CompanyManagerBuilder` erstellt. :-D
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nicht zu vergessen der `AbstractFileBasedCompanyManager`, der ein praktisches Grundgerüst für die Gemeinsamkeiten aller `FileBasedCompanyManager`s bereitstellt, um dem Programmierer das Leben zu erleichtern... :cool:
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Jungs, nicht heute so einen Mist. :twisted: Ich fühle mich irgendwie an Arabica-Kaffee erinnert.
BlackJack

@ZedsWhatSheSaid: Hast Du die Aufgabe eigentlich bisher schon richtig umgesetzt? Du machst mit der Zahl in den Eingabedaten überhaupt nichts, der Ausgabetext vom Prompt für die Benutzereingabe deutet aber darauf hin, dass gar nicht der Firmennamen eingegeben werden soll.

Edit: Und sind die Daten so vorgegeben? Die Unregelmässigkeit mit der Nummer in Klammern ist ja irgendwie doof. Und sollte vielleicht mit regulären Ausdrücken gearbeitet werden? Das `re`-Modul wird ja — unnötigerweise — schon importiert.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

ups ja das war mein Fehler :S ich habe das Programm vorher so gestaltet dass ich eine Zahl eingeben musste damit man die Informationen über die firma bekommt ^^ fand da sirgendwie schöner und sinniger mit einem index, sollte es aber dann ändern :P habe vergessen die alte aufforderung, dass eine Zahl vom Benutzer eingegeben werden soll zu ersetzen gegen die neue :X also der benutzer soll in diesem Beispiel den namen der firma eingeben um die 2 weiteren infos ( gründungsjahr und mitarbeiteranzahl) zu bekommen

btw wie könnte man denn eine klasse erstellen die einen update manager darstellt Oo ?
BlackJack

@ZedsWhatSheSaid: Vergiss das Wort „manager” bitte. Du möchtest eine Klasse die Firmen enthält und die über den Firmennamen auf die Firmenobjekte zugreifen kann. Also sollten die Exemplare dieser Klasse die Firmen intern in einem Wörterbuch speichern. Dann musst Du halt die entsprechenden Methoden bereitstellen die dazu nötigt sind. Also mindestens eintragen und abfragen einer Firma.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

@BlackJack also wenn ich das jetzt richtig verstanden habe soll ich die methoden die ich bei meinem geposteten beispiel hatte nun in die klasse einbauen oder wie ? wenn diese annahme richtig ist, welchen konstruktor soll ich benutzen und wie soll das alles aufgebaut sein Oo ich habe mir tuts über klassen angeschaut werde aber nicht schlauer wie man das genau schreiben soll :K es tut mir leid aber ich hänge gerade irgendwie

Edit: was ich irgendwie besser finden würde ist folgendes: ich erzähle dir wie ich denke, wie klassen funktionieren und wie sie aufgebaut sind und sage dir einfach wie ich denke wie man an mein problem rangehen sollte und du sagst mir wo der fehler in meinem mindset ist :D das würde ich cooler finden als wenn mir jemand einen fertigen code schicken würde :/ ich will das ja auch verstehen :S
BlackJack

@ZedsWhatSheSaid: In Deinem Beispiel sind doch gar keine Methoden definiert. Dazu bräuchte man ja eine Klasse. In Deinem Beispiel sind nicht einmal Funktionen definiert.

Du musst Dir überlegen wie die Schnittstelle zu Deinem Datentyp der Firmen enthält aussehen soll und welche Daten dafür intern in welcher Datenstruktur gespeichert werden müssen. Die Datenstruktur ist ja im Grunde festgelegt: Es funktioniert bisher mit einem Wörterbuch ja ganz gut. Das kann man in der `__init__()` erstellen. Die ist übrigens technisch gesehen kein Konstruktur sondern eine Initialisierungsmethode. Da es mit `__new__()` auch einen tatsächlichen Konstruktor gibt, sollte man die Begrifflichkeiten sauber trennen.

Dann musst Du festlegen welche Methoden Du benötigst. Was soll man mit dem Datentyp machen können? Welche Operationen müssen durchgeführt werden? Welche Informationen brauchen die, ausser den im Datentyp gekapselten, also die Abbildung von Name zu Firmendaten.

Tutorials nur anzuschauen bringt nicht viel, man muss sie durcharbeiten. Code schreiben, verändern, verstehen.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

klar sind in meinem beispiel keine methoden definiert ! ^^ und natürlich habe ich auch keine klasse :P ich glaube ich habe in meinem post den begriff methode missbraucht und ihn für etwas anderes benutzt :P mit dem begriff methode meinte ich nicht den programmierspezifischen begriff sondern den begriff im normalen sinne, ich meinte mit der methode jetzt das auslesen der informationen der text datei und dann das speichern in das dict - habe mich vielleicht ein bisschen blöd ausgedrückt und btw was meinst du jetzt explizit mit datentyp ?
BlackJack

@ZedsWhatSheSaid: Mit Datentyp meint man etwas was aus Daten und Operationen auf diesen Daten besteht. Datentypen beschreibt man in Python mit Klassen. Man kann den Begriff also synonym zu Klasse verwenden. Du sollst mit der Klasse ja einen eigenen Datentyp beschreiben. Statt eines Wörterbuchs mit den Operation die einem Namen die Daten einer Firma zuordnen und über einen Namen die Daten einer Firma zugänlich zu machen, sollst Du einen eigenen Datentyp schreiben, der… ja welche Operationen brauchst Du denn und welche Daten benötigen die jeweils? Gib doch mal etwas mehr von Dir als „verstehe ich nicht”. *Was* verstehst Du nicht? Wie soll man denn auf Dein Problem eingehen wenn Du nicht sagst wo die Probleme genau liegen?
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

also ich denke dass eine klasse dafür da ist um attribute und methoden zu speichern, ich hoffe dass diese annahme überhaupt richtig ist, ich denke mal dass man in der klasse die man beispielsweise "Firmentinformation" nennt dann die 3 attribute firmenname, gründungsjahr un mitarbeiteranzahl speichert - und dass man in der klasse eine methode erstellen müsste die die daten aus der text datei ausliest diese dann speichert und sie dann gegebenenfalls auf anforderung ausgibt - falls ich das überhaupt so richtig gedacht habe liegt mein problem bei der genauen umsetzung meiner gedanken
BlackJack

@ZedsWhatSheSaid: Das ist für `Firmeninformation` soweit richtig. Ich würde auch die Firma mit einer Klasse repäsentieren, aber die eigentliche Aufgabe ist ja das Wörterbuch durch eine Klasse zu ersetzen. Also den Containertyp in dem mehrere Firmen gespeichert werden.

Statt `Firmeninformation` würde ich die Klasse übrigens einfach `Firma` nennen. Das solche Objekte Informationen speichern ist selbstverständlich, damit muss man den Namen nicht unnötig aufblähen. Den Typ der das Wörterbuch ersetzen soll kann man dann `Firmen` nennen, denn er enthält die Firmen in Form von `Firma`-Objekten. Allerdings würde ich englische Bezeichner vorziehen, also `Company` und `Companies` für die beiden Datentypen.

Für das Einlesen der Daten würde man eine statische Methode (siehe `staticmethod()`) beziehungsweise eine Klassenmethode (siehe `classmethod()`) verwenden. Wenn Dir das für den Anfang noch zu hoch ist, tut es auch eine Funktion. Das ist vielleicht sowieso ein erster Schritt, den Du tun könntest: Dein bisheriges Programm so umschreiben, dass für die einzelnen Operationen Funktionen verwendet werden.

Bei den Klassen könntest Du dann mit der `Company`-Klasse anfangen. Als Tipp sei hier die `__str__()`-Methode erwähnt, die man für eine Zeichenkettendarstellung überschreiben kann. Wenn man ein Objekt mit ``print`` ausgibt, wird diese Methode aufgerufen um das Objekt als Zeichenkette darzustellen.
ZedsWhatSheSaid
User
Beiträge: 8
Registriert: Donnerstag 12. September 2013, 11:00

ok das hört sich schon mal ganz gut an :D es tut mir leid falls ich fragen schlecht stelle oder mich falsch ausdrücke oder so, ich habe noch nicht wirklich das richtige mindset für klassen wie sie funktionieren und was man damit machen kann :/ ich beschäftige mich nicht so lange mit python ^^ ich weiß nur auch momentan nicht ob es an meiner eigenen inkompetenz liegt oder ob es schon ein bisschen zeit braucht damit man dieses ganze zeug versteht

Edit: danke dass du so viel geduld hast
BlackJack

@ZedsWhatSheSaid: Ich finde den Sprung von so einem Miniprogramm das komplett auf Modulebene linear runtergeschrieben ist, zu Klassen ziemlich weit. Bevor man zu Klassen kommt, sollte man sich eigentlich erst einmal mit Funktionen beschäftigen. Dann fällt auch der Schritt Funktionen und Daten mittels Klassen zu Objekten zusammenzufassen leichter.
Antworten