simple Frage zu einer graph klasse

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
muskel
User
Beiträge: 6
Registriert: Sonntag 9. November 2008, 19:12

Hallo liebe Freunde des Mondes!
Ich quäle mich und quäle mich. Bei mir ist es so, dass ich einen code und dessen Aufgabe am ehesten dann verstehe, wenn ich etwa eingebe und schaue, was das Programm macht und auswirft. Aber nun bin ich tatsächlich (durch mehrmaliges Fehlen in der Vorlesung :oops: )
an meine Grenzen gestoßen. Mir liegt folgende Klasse vor:

Code: Alles auswählen

import copy
from operator import itemgetter
class Graph:
    def __init__(self):
        self.knotenListe = []
        self.kantenListe = []
    def addvertex(self, v1):
         if v1 not in self.knotenListe:
             self.knotenListe.append(v1)
    def addedge(self, v1, v2, c):
         if not v1 == v2:
              self.addvertex(v1)
              self.addvertex(v2)
              for i in self.kantenListe:
                   a1 = i[0][0]
                   a2 = i[0][1]
                   if a1 == v1 and a2 == v2:
                        self.kantenListe.remove(i)
              self.kantenListe.append(((v1,v2),c))
    def getvertices(self):
         return copy.copy(self.knotenListe)
    def getedges(self):
         kanten = copy.copy(self.kantenListe)
         return sorted(kanten, key=itemgetter(1))
    def cost(self, v1, v2):
         ret = None
         for i in self.kantenListe:
              a1 = i[0][0]
              a2 = i[0][1]
              if a1 == v1 and a2 == v2:
                   ret = i[1]
         return ret
Sexy, nicht wahr? :roll:
Jedenfalls weiß ich nicht genau, in welcher Form ich im init-bereich (Zeile 5,6) eine Eingabe machen muss (ich hoffe, dass ich wenigstens mit meiner Idee, dort eine Eingabe unternehmen zu wollen, richtig liege) und wie ich eine Ausgabe erwirke... wenn es doch nur ein einfacher Print-befehl wäre!!! :cry:

Weiß jemand weiter?
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Würd's als Argument für die __init__ Methode machen.. oder es ganz lassen und immer per addedge und addnode und sowas verwalten oO!

Das ganze errinert mich übrigens an: http://www.python.org/doc/essays/graphs.html
DeJe
User
Beiträge: 39
Registriert: Sonntag 23. November 2008, 19:38

Vielleicht bin ich zu vermessen...aber wo ist eigentlich die Frage bzw. Aufgabe? :roll:
Ich frage mich manchmal ob ich zu rückständig bin bei einer "Anfrage" auch eine eindeutige und halbwegs verständliche "Frage" voraussetze. ;)
muskel hat geschrieben:Weiß jemand weiter?
Aber klar doch. Du könntest die Klasse einfach nutzen, ein paar Graphen einfügen und sie dann ausgeben. :D
muskel
User
Beiträge: 6
Registriert: Sonntag 9. November 2008, 19:12

Nein nein, die Frage lautet:

in welcher form muss etwas wo eingegeben werden und mit welchem befehl halte ich eine ausgabe?

Danach könnte ich etwas rumspielen, editieren, hinzufügen und das ganze auch verstehen.
:wink:

sorry, wenn das nicht so klar rüber kam!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

muskel hat geschrieben: in welcher form muss etwas wo eingegeben werden und mit welchem befehl halte ich eine ausgabe?
Das ist doch keine präzise Frage! Darauf könnte man antworten:

In dieser Form muss das dort eingegeben werden ;-)

Beim zweiten Teil einfach: print

Also Du musst das schon präzisieren, ansonsten kann man kaum brauchbare Tipps geben! Es muss dazu doch eine sinnvolle Aufgabenstellung, Kontext oder sogar präzise Frage geben!

(Mal abgesehen davon, dass man über den Code arg streiten könnte! Stichwort "properties" und ziemlich sinnfreie getter-Methoden!)
muskel
User
Beiträge: 6
Registriert: Sonntag 9. November 2008, 19:12

Okay, also anders:
Ich muss eine Aufgabe bearbeiten. Wie die Aufgabe lautet will ich gar nicht erläutern, denn ich will dafür keine kompakten/sinnvollen/effizienten codes von Forenmitglieder verfasst und geschildert bekommen. Ich muss bei meiner Aufgabe jedoch die genannte Klasse "Graph" (die genau so aussieht, wie ich sie als code gepostet habe) verwenden. Über die Richtigkeit und Funktionalität des Codes kann man diskutieren/streiten/etc. sobald er jedoch in manchen Fällen verwendbar ist, sollte ich ihn wohl in meiner Aufgabe nutzen.
Mir ist halbwegs klar, was der code macht, allerdings fehlen mir zwei wichtige Dinge (die man bei Testen von Algorithmen meist brauch, oder nicht?!) nämlich einmal einen input und dann einen Befehl, der den bearbeiteten Input auch auswirft.

Und nun nehme ich mal deine Antwort für bare Münze:

In dieser Form muss das dort eingegeben werden

Beim zweiten Teil einfach: print

Heißt für mich, ich setze ein Wort namens "dieser" (ohne "") an eine Stelle, die in meinem code "dort" heißt. leider kann ich kein "dort" finden. Also setze ich es einfach mal in eine leere eckige Klammer am Anfang.
"print" (ohne "") beim "zweiten teil" (also vielleicht im zweiten "def" block?) einzusetzen mache ich dann auch mal..

kommt das bei raus:

Code: Alles auswählen

import copy
from operator import itemgetter
class Graph:
    def __init__(self):
        self.knotenListe = [dieser]
        self.kantenListe = [dieser]
    def addvertex(self, v1):
         if v1 not in self.knotenListe:
             self.knotenListe.append(v1)
             print
    def addedge(self, v1, v2, c):
         if not v1 == v2:
              self.addvertex(v1)
              self.addvertex(v2)
              for i in self.kantenListe:
                   a1 = i[0][0]
                   a2 = i[0][1]
                   if a1 == v1 and a2 == v2:
                        self.kantenListe.remove(i)
              self.kantenListe.append(((v1,v2),c))
    def getvertices(self):
         return copy.copy(self.knotenListe)
    def getedges(self):
         kanten = copy.copy(self.kantenListe)
         return sorted(kanten, key=itemgetter(1))
    def cost(self, v1, v2):
         ret = None
         for i in self.kantenListe:
              a1 = i[0][0]
              a2 = i[0][1]
              if a1 == v1 and a2 == v2:
                   ret = i[1]
         return ret
Ausgabe: nichts! (also nicht in worten sondern kein inhalt)
Ich könnte auch so etwas machen:

Code: Alles auswählen

import copy
from operator import itemgetter
class Graph:
    def __init__(self):
        self.knotenListe = []
        self.kantenListe = []
    def addvertex(self, v1):
         if v1 not in self.knotenListe:
             self.knotenListe.append(v1)
             print
    def addedge(self, v1, v2, c):
         if not v1 == v2:
              self.addvertex(v1)
              self.addvertex(v2)
              for i in self.kantenListe:
                   a1 = i[0][0]
                   a2 = i[0][1]
                   if a1 == v1 and a2 == v2:
                        self.kantenListe.remove(i)
              self.kantenListe.append(((v1,v2),c))
    def getvertices(self):
         return copy.copy(self.knotenListe)
    def getedges(self):
         kanten = copy.copy(self.kantenListe)
         return sorted(kanten, key=itemgetter(1))
    def cost(self, v1, v2):
         ret = None
         for i in self.kantenListe:
              a1 = i[0][0]
              a2 = i[0][1]
              if a1 == v1 and a2 == v2:
                   ret = i[1]
         return ret

print "juhu, ich bin eine Ausgabe, aber leider beziehe ich mich nicht auf den vorherigen code!" 
Ausgabe: juhu, ich bin eine Ausgabe, aber leider beziehe ich mich nicht auf den vorherigen code!


Immerhin habe ich dadurch eine Ausgabe. Das ist etwas, womit ich arbeiten kann, was ich verstehen kann. Aber leider wird keiner der vorherigen Definitionen für die Ausgabe verwendet.

Und ich greife nochmal Dejes Worte auf:
Aber klar doch. Du könntest die Klasse einfach nutzen, ein paar Graphen einfügen und sie dann ausgeben.
Wo wird der Graph eingefügt und in welcher Form und wie werden sie dann ausgegeben?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Was definierst du denn als Output? Werte zu bekommen oder einen tatsächlichen Graphen?

Wenn du den Code so verwenden sollst, wird er sowohl Input als auch Output nicht leisten können.

Für einen Input kannst du `__init__' anpassen

Code: Alles auswählen

def __init__(self, knoten_liste, kanten_liste):
    self.knoten_liste = knoten_liste
    self.kanten_liste = kanten_liste
Für den Output kannst du __repr__, __str__ überladen und wenns grafisch werden soll, dann musst du das deiner Klasse noch beibringen ;) Aber besser wäre es eine Funktion zu schreiben, die aus einer Graph instanz eine Grafik bastelt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hast Du einmal das Tutorial durchgearbeitet?

Ok, also mal ein kleines Beispiel:

Code: Alles auswählen

zahlen = [13, 677, 99]
for i in zahlen:
    print "Die aktuelle Zahl heißt: %d" % zahlen
Und dann mal mit Strings:

Code: Alles auswählen

words = ["Hallo", "Welt"]
for i in words:
    print "Das aktuelle Wort heißt: %s" % words
Wichtig sind hier die "%d" und "%s", die quasi Platzhalter für einen Wert sind, den ich nach dem String per Tupel angeben muss. Für weitere Infos solltest Du da mal in die Doku gucken.

Zum ersten Teil der Frage: Was genau meinst Du mit Input? Ich meine was ist denn Dein Input? Vermutlich hast Du doch einen Graphen gegeben, also eine Menge aus Ecken und Kanten. Da es in der Klasse zwei add-Methoden gibt, nutze die doch einfach! Ich kapiere da wirklich nicht, wo Dein Problem liegt ...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

cofi hat geschrieben:Aber besser wäre es eine Funktion zu schreiben, die aus einer Graph instanz eine Grafik bastelt.
Was z.B. per Graphviz super einfach zu realisieren wäre :-) Das dot-Format ist da eigentlich recht simpel, auch für Anfänger.
BlackJack

@muskel: Wie man einen Graphen angibt und wie er ausgegeben werden soll musst *Du* definieren. Da gibt's ja schliesslich mehrere Möglichkeiten und Du musst doch wissen wie die Ein- und Ausgabedaten aussehen sollen.

Wieso musst Du mit *der* Klasse eigentlich arbeiten? Die ist nämlich nicht besonders (intellig|effizi)ent implementiert.

Man sollte den Namen der Datenstuktur in der Regel nicht im Attributnamen haben. So kann man die Implementierung nicht ändern, ohne auch überall den Namen ändern zu müssen. Für die Knoten böte sich nämlich ein `set` eher an als eine Liste. Und für die Kanten ein Dictionary, so ist die `cost()`-Methode nämlich ziemlich gruselig umständlich und langsam.

Ausserdem ist mischen von englischen und deutschen Bezeichnern doof.

@cofi: Man sollte natürlich an der Stelle nicht nur zuweisen, sondern auch Testen, ob die beiden Listen konsistent sind.

@Hyperion: Kanten reichen, weil die `addegde()`-Methode die Knoten selbst hinzufügt. Es sei denn man hat auch freie Knoten im Graphen.
DeJe
User
Beiträge: 39
Registriert: Sonntag 23. November 2008, 19:38

@Muskel, wie ich schon schrub. Du sollst um diese Klasse 'Graph' eine Ausgabe programmieren, die GUI sozusagen. Also definiere eine 'main()'-Funktion, lege ein oder mehrere Objekte der Klasse 'Graph' an, füge Kanten/Knoten (mit den 'add*'-Funktionen) hinzu und gebe diese dann (z.B. mit Hilfe von 'print' und den 'get*'-Funktionen) aus.
Du sollst, so wie ich das verstehe, die Klasse nicht *ändern*. Du sollst sie nur *nutzen*. ;)

Alternativ könnte man natürlich eine zusätzliche source-Datei anlegen und 'Graph' importieren.
Antworten