@Blackjack: Danke für den Hinweis auf Graphen. Mit der Graphentheorie hatte ich mich noch nicht groß beschäftigt, scheint aber interessant und passend. Daher habe ich mich da etwas eingelesen und das unten genannte Programm nach Anleitung (inf-schule.de) gebastelt, um anschließend zeichnen zu können. Mit String-Knoten wie "A" funktioniert das bereits halbwegs gut, so dass ich demnächst die Strings durch Knoten-Objekte ersetzen möchte, die dann auch einen zweiten String, sowie ggf. Synonyme usw. beinhalten. Wobei das nicht ganz zum original Konzept passt, da die Synonyme ja eigentlich gleichwertig sind, und nicht eins als "Hauptbegriff" und die anderen als ihm zugeordnet gelten. Aber ich fürchte, ich verzettele mich da vielleicht auch schon etwas an einem Nebenschauplatz. Mir ging es auch darum, später beim *Speichern* der Daten nicht zu oft den *selben* Text zu speichern, nur weil er bei verschiedenen Synonymen vorkommt.
@nezzcarth: Ja, es geht hier eher um den Hausgebrauch, aber danke für die Anregungen und Fachbegriffe, die ich für weitere Inspiration benutze. Tatsächlich scheint das auch ein interessantes Forschungsfeld zu sein. Zum Ratschlag, das "konzeptuell anständig umzusetzen" fand ich leider wenige Suchtreffer - und genau damit tue ich mich derzeit extrem schwer! Wo finde ich Anleitungen dazu, welche konzetionellen Arbeiten sinnvoll wären? Diese Frage stellt sich mir in vielen Projekten...! :K
Hier dachte ich ja spontan, weil ich ja schon weiß, welche Daten ich bearbeiten möchte, dann wäre die Wahl einer passenden Datenstruktur doch ein wertvoller nächster Schritt. Nicht wegen Effizienz, sondern um die Entwicklung voranzutreiben. Aber du hast Recht, sie könnte sich in Zukunft auch ändern, und über das Speichern in einer Datenbank habe ich auch bereits nachgedacht. Damit kenne ich mich auch noch nicht gut genug aus.
Nachfolgend der aktuelle Code in einer Umbauphase, gerade wurde er umgestellt. Vorher war Graph.knotenliste = ["A", "B", "C", "D"] und damit funktionieren auch die assert, jetzt mit dem neuen Knoten-Objekt aber nicht mehr, weshalb ich einige Hürden überspringen muss, die den Code unübersichtlich machen.
Kann ich die Knoten-Klasse so gestalten, dass sie nach außen hin weiter wie ein String verhält? Z.B. bei """if "A" in ["A", "B", "C", "D"]""" kam vorher True, jetzt natürlich erstmal ValueError, weil mein Klassenobjekt nicht "A" ist...
Code: Alles auswählen
# Angelehnt an http://www.inf-schule.de/algorithmen/graphen/implementierung/
class Knoten(object):
def __init__(self, name, beschreibung = None):
self.name = name
self.beschreibung = beschreibung
self.synonyme = []
def __str__(self):
return self.name
def __repr__(self):
return "'%s'" % self.name
def hat_synonyme(self):
return len(self.synonyme) > 0
def add_synonym(self, name):
if name not in self.synonyme:
self.synonyme.append(name)
else:
raise ValueError("Synonym bereits bekannt.")
class Graph(object):
def __init__(self, knotenliste = None, adjazenzmatrix = None):
if knotenliste:
self.knotenliste = knotenliste
else:
self.knotenliste = [
Knoten("A", "Der erste Buchstabe des Alphabets."),
Knoten("B", "Der zweite Buchstabe des Alphabets."),
Knoten("C", "Der dritte Buchstabe des Alphabets."),
Knoten("D", "Der vierte Buchstabe des Alphabets.")
]
if adjazenzmatrix:
self.adjazenzmatrix = adjazenzmatrix
else:
self.adjazenzmatrix = [
[0, 1, 0, 0],
[0, 1, 1, 1],
[1, 1, 0, 0],
[0, 0, 0, 0]
]
# Alternative Implementierung, noch nicht weiter betrachtet:
#self.adjazenzliste = [
# ["A", ["B"]],
# ["B", ["A", "B", "C"]],
# ["C", ["A", "B"]],
# ["D", []]
#]
def alle_knoten(self):
return self.knotenliste
def existiert_knoten(self, knoten):
for k in self.knotenliste:
if knoten == k.name:
return True
return False
def add_knoten(self, knoten):
if not self.existiert_knoten(knoten):
self.adjazenzmatrix.append([0] * len(self.knotenliste))
for zeile in self.adjazenzmatrix:
zeile.append(0)
self.knotenliste.append(knoten)
else:
raise ValueError("Der Knoten '%s' existiert bereits." % knoten)
def del_knoten(self, knoten):
if self.existiert_knoten(knoten):
position = self.knotenliste.index(knoten)
self.adjazenzmatrix.pop(position)
for zeile in self.adjazenzmatrix:
zeile.pop(position)
self.knotenliste.remove(knoten)
else:
raise IndexError("Der Knoten '%s' existiert nicht." % knoten)
def existiert_kante(self, startknoten, endknoten):
for k in (startknoten, endknoten):
if not self.existiert_knoten(k):
return False
x = self.knotenliste.index(startknoten)
y = self.knotenliste.index(endknoten)
return self.adjazenzmatrix[x][y] > 0
def add_kante(self, startknoten, endknoten):
if not self.existiert_kante(startknoten, endknoten):
start_position = self.knotenliste.index(startknoten)
end_position = self.knotenliste.index(endknoten)
self.adjazenzmatrix[start_position][end_position] = 1
else:
raise ValueError("Die Kante von '%s' nach '%s' existiert bereits." %
(startknoten, endknoten))
def del_kante(self, startknoten, endknoten):
if self.existiert_kante(startknoten, endknoten):
start_position = self.knotenliste.index(startknoten)
end_position = self.knotenliste.index(endknoten)
self.adjazenzmatrix[start_position][end_position] = 0
else:
raise IndexError("Die Kante von '%s' nach '%s' existiert nicht." %
(startknoten, endknoten))
def alle_nachbarn(self, knoten):
nachbarn = [k for k in self.knotenliste if
self.existiert_kante(knoten, k)]
return nachbarn
def test():
Mein_Graph = Graph()
assert Mein_Graph.existiert_knoten("D") == True
assert Mein_Graph.existiert_knoten("G") == False
assert Mein_Graph.existiert_kante("A", "D") == False
assert Mein_Graph.existiert_kante("B", "D") == True
assert Mein_Graph.existiert_kante("X", "Y") == False
assert Mein_Graph.alle_nachbarn("B") == ['B', 'C', 'D']
knotenliste_vorher = Mein_Graph.knotenliste[:]
adjazenzmatrix_vorher = Mein_Graph.adjazenzmatrix[:]
Mein_Graph.add_knoten("X")
Mein_Graph.add_kante("X", "D")
Mein_Graph.del_kante("X", "D")
Mein_Graph.del_knoten("X")
assert Mein_Graph.knotenliste == knotenliste_vorher
assert Mein_Graph.adjazenzmatrix == adjazenzmatrix_vorher
def test2():
print "\nAdding Knoten 'X'"
Mein_Graph.add_knoten("X")
print "Knotenliste: {}".format(Mein_Graph.knotenliste)
print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)
print "\nAdding Kante ('B', 'X')"
Mein_Graph.add_kante("B", "X")
print "Knotenliste: {}".format(Mein_Graph.knotenliste)
print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)
print "\nDeleting Kante ('X', 'D')"
Mein_Graph.del_kante("X", "D")
print "Knotenliste: {}".format(Mein_Graph.knotenliste)
print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)
print "\nDeleting Knoten 'C'"
Mein_Graph.del_knoten("C")
print "Knotenliste: {}".format(Mein_Graph.knotenliste)
print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)
if __name__ == '__main__':
test()