Iterating a GTK3 Treestore with child nodes in python - python

im trying to search a GTK 3 treestore for a string. The treestore has 4 columns,and is for a treeview widget that has callapsible nodes. im creating the nodes with this function:
def AddItem(self,ParentIter,txt,datapath='',projName=Project):
self.store = self.builder.get_object('theTreeStore')
NodeId = secrets.token_hex(8)
if ParentIter == None:
ParentNodeId = ''
else:
ParentNodeId = self.store.get_value(ParentIter, 2)
treeEntry = ['%s' %ParentNodeId,'%s' %txt,'%s' %NodeId,'%s' %datapath]
node = self.store.append(ParentIter, treeEntry) <<<<<<<<<<<<<
self.view = self.builder.get_object('Tree')
self.view.set_model(self.store)
# table nodes(tParentNodeID ,tNodeTxt ,tNodeID ,tDataPath );
sql = "INSERT INTO %s (tParentNodeID ,tNodeTxt ,tNodeID ,tDataPath ) VALUES ('%s','%s','%s','%s')" %(projName,ParentNodeId,txt,NodeId,datapath)
self.cursor.execute(sql)
self.mariadb_connection.commit()
for x in self.cursor:
print(x)
return(node)
as you can see the data in the tree is nested in its parent.
now i need to somehow search the treestore for a row that contains a certain NodeId string. Ive read the gtk docs over and over but i cant quite figure out what to do. im guessing i need to use following methods:
store.get_iter()
store.iter_children()
but idk everything i try only returns the root nodes no children.
i basically want a search function that will recursively search each node and its children,and their children for a string. something like this:
def GetRowbyNodeID(nodeid):
for row in treestore:
if row[1]==nodeid:
return(row)
for children in row:
if children[1] == nodeid
return(children)
The code is in multiple files, i can post any functions relevant if needed.

GtkTreeStore implements GtkTreeModel interface. Thus you can use the following methods:
iter = store.get_iter() to obtain an iterator
chld_iter = iter.get_children()to obtain an iterator over children elements (please note, it's an iter's method!)
I'd also recommend reading this tutorial. "The Model" section contains all you need on iterating over the model (spoiler: search for print_tree_store)

Got it all working. thanks again. im posting the relevant code just in case anyone else could use it.
def SearchTreeRows(self,store, treeiter, searchstr):
print("\nsearch>%s"%searchstr)
while treeiter != None:
if store[treeiter][2] ==searchstr:
print("found in:%s"%str(store[treeiter][:]))
return(treeiter)
break
print("searched:%s"%str(store[treeiter][:]))
if store.iter_has_child(treeiter):
childiter = store.iter_children(treeiter)
ret = self.SearchTreeRows(store, childiter, searchstr)
if ret is not None:
return ret
treeiter = store.iter_next(treeiter)
def NodeId2Tree(self,nodeid):
self.store = self.builder.get_object('theTreeStore')
rootiter = self.store.get_iter_first()
row = self.SearchTreeRows(self.store, rootiter,nodeid)
return(row)
def LoadProject(self):
global Project
global ProjSel
sql = "SHOW TABLES"
self.cursor.execute(sql)
tbls = []
for x in self.cursor:
tbls.append(x)
diag = self.builder.get_object('ProjectChooser')
self.combo = Gtk.ComboBox()
ls =Gtk.ListStore(str)
for tble in tbls:
strg ="%s" %tble
ls.append(tble)
self.combo.set_model(ls)
cellr = Gtk.CellRendererText()
self.combo.pack_start(cellr,True)
self.combo.add_attribute(cellr, 'text', 0)
diag.vbox.pack_start(self.combo, True, True, 5)
diag.show_all()
response = diag.run()
self.combo.destroy()
print(ProjSel)
Project = ProjSel
ProjSel = ''
view = self.builder.get_object('Tree')
self.store.clear()
view.set_model(self.store)
sql = "SELECT tParentNodeId,tNodeTxt,tNodeId FROM %s"%(Project)
self.cursor.execute(sql)
for x in self.cursor:
parid = x[0]
nodtxt = x[1]
nodid =x[2]
if parid == '':
treeEntry = ['%s' %parid, '%s' %nodtxt, '%s' %nodid, '']
node = self.store.append(None, treeEntry) #root nodes
else:
treeEntry = ['%s' %parid, '%s' %nodtxt, '%s' %nodid, '']
n2id = self.NodeId2Tree(parid)
node = self.store.append(n2id, treeEntry)
print("got return:%s For:%s"%(n2id,treeEntry[0]))
view.set_model(self.store)
#select * where parentid == none >> get root nodes ???? or parse line by line

Related

Removing a word from a list

So I got a list with names and I'm trying to delete the names out of the list. but somehow it doesn't work the way I want it to. Any help would be much appreciated. I think the problem is something with the replace function but I'm not sure.
Funtion:
#pyqtSlot(str, str)
def rapportmail (self, email, wachtwoord):
credentials = Credentials(email, wachtwoord)
acc = Account(email, credentials=credentials, autodiscover=True)
cursor.execute("SELECT DISTINCT Naam FROM Klant")
updatedklant = str(cursor.fetchall())
test = updatedklant
for item in acc.inbox.all().order_by('-datetime_received')[:500]:
inboxmail = str(item.sender).split("'")
currentinboxmail = inboxmail[3]
cursor.execute("SELECT DISTINCT Klant FROM Mail WHERE Mail=?", currentinboxmail)
currentklant = str(cursor.fetchall())
remove_characters = ["(",")",",","]","["]
for characters in remove_characters:
currentklant = currentklant.replace(characters, "")
if currentklant not in updatedklant:
for idx, elem in enumerate(test):
if elem[0] == currentklant:
test.pop(idx)
It is prints this now:
currentklant == 'alerttestting'
test == [('alerttestting', ), ('emretestingsystems', ), ('jarnodebaas', ),('yikes', )]
Result should be:
currentklant == 'alerttestting'
test ==[('emretestingsystems', ), ('jarnodebaas', ),('yikes', )]
Never, ever convert the result of cursor.fetchall() to a str and then strip out the characters you don't like. This is going to be a huge source of trouble. What if the name itself contains one of those characters, like "Bond, James" or "O'Brien"?
Keep it as a Python object (probably a list or tuple) and process it in that form.
In this case you probably wanted something like this:
...
updatedklant = cursor.fetchall() # No more str()
...
currentklant = cursor.fetchall()) # No more str()
...
test = [klant for klant in updatedklant if klant != currentklant]
should work perfectly
[('alerttestting',), ('emretestingsystems',), ('jarnodebaas',), ('yikes',)]
if __name__ == "__main__":
currentklant = 'alerttestting'
test = [('alerttestting',), ('emretestingsystems',), ('jarnodebaas',), ('yikes',)]
for idx, elem in enumerate(test):
if elem[0] == currentklant:
test.pop(idx)
[('emretestingsystems',), ('jarnodebaas',), ('yikes',)]

Displaying tags correctly using TextBuffer pyGtk

I was playing around with pygtk to build my little project, that uses gtk, basically there is a window, in this window I have a treeview, inside the treeview a gtk.liststore.
Here is a image with the window and its values
Everything was cool until I realized that I was needing some tags, saw a lot of examples using pango, and it's work, at least until the row selected is changed.
I got around the problem with something not much elegant, and
here a link to the complete code:
def on_toolbar_button_clicked(self, widget, tag):
bounds_front = self.text_buffer_front.get_selection_bounds()
bounds_back = self.text_buffer_back.get_selection_bounds()
if len(bounds_front) != 0:
(start, end) = bounds_front
selection_front = self.text_buffer_front.get_text(start, end, True)
get_insert_front = self.text_buffer_front.get_insert()
self.text_buffer_front.delete(start, end)
iter_front = self.text_buffer_front.get_iter_at_mark(get_insert_front)
self.text_buffer_front.insert(iter_front, tag[0] + selection_front + tag[1])
Basically this method will put <u></u> around a word when I click at the toolbar underline button, and it's value will be placed at liststore, and also display that value with textview. This would be perfect if at least set_text detected these syntaxes.
So, what I'm trying to achieve is something that display the word tagged at textview and when I change the row and get back at the previous tagged row that it still display words tagged, like, if I underline a word, that it still underline when I get back, and in case the solution involves using pango, how can I get the values from it to use later.
What I tried so far was messing around textbuffer.serialize and textbuffer.deserialized, but it didn't worked as I want.
Edit
Like here I had applied underline tag to 'paper', serialized the textbuffer, put it inside a variable, but how can I pass it back to the buffer?
exported = self.text_buffer_front.serialize( self.text_buffer_front, format, start_iter_front, end_iter_front )
Printing the variable 'exported' I get a byte value:
b'GTKTEXTBUFFERCONTENTS-0001\x00\x00\x00w <text_view_markup>\n <tags>\n </tags>\n<text>A
At the first comes rock! Rock, <apply_tag name="underline">paper</apply_tag>, scissors!
Edit 2
This was probably obvious but not for me, if I have a serialized something all that I'll need to do next is just 'deserialize' it, and for that there is gtk.TextBuffer.deserialize.
The syntaxes should be something like this:
self.dict_any_tags = {str(key): value[1] for key, value in enumerate(self.sub_list_store)}
def item_selected(self, *args):
try:
iter_start_front = self.text_buffer_front.get_start_iter()
iter_end_front = self.text_buffer_front.get_end_iter()
path = self.selected_row.get_selected_rows()[1][0]
try:
self.text_buffer_front.deserialize(self.text_buffer_front, self.text_buffer_front.register_deserialize_tagset(), self.text_buffer_front.get_start_iter(), self.dict_any_tags[str(path)])
except:
self.text_buffer_front.set_text(self.sub_list_store[path][1])
except IndexError:
pass
def on_toolbar_button_clicked(self, widget, tag):
bounds_front = self.text_buffer_front.get_selection_bounds()
bounds_back = self.text_buffer_back.get_selection_bounds()
path = self.selected_row.get_selected_rows()[1][0]
if len(bounds_front) != 0:
(start, end) = bounds_front
selection_front = self.text_buffer_front.get_text(start, end, True)
get_insert_front = self.text_buffer_front.get_insert()
self.text_buffer_front.apply_tag(tag, start, end)
start_iter_front = self.text_buffer_front.get_start_iter()
end_iter_front = self.text_buffer_front.get_end_iter()
format = self.text_buffer_front.register_serialize_tagset()
exported = self.text_buffer_front.serialize( self.text_buffer_front,
format,
start_iter_front,
end_iter_front)
self.dict_any_tags[str(path)] = exported
The thing is that when I tried it before I was probably putting the deserialize at wrong place and with that it did nothing. Now I can track more easily where are the tags, etc. I just need run some more tests.
The key was create another iterator (I used a dictionary) to track the serialized text, then when I click in a row it tries to use deserialize function if the value is byte, caso is not it will simply set a text normally with set_text.
Also is important set the text to nothing set_text('') before deserialize, otherwise the previous value of the buffer will be placed in front of the current value at the buffer.
As for the changes on text, I used the method connect to connect the 'changed' signal and serialized the changes and passed the serialized value to the dictionary. And this is what I got:
# dictionary to track the tags
self.dict_any_change_front = {str(key): value[1] for key, value in enumerate(self.sub_list_store)}
self.dict_any_change_back = {str(key): value[1] for key, value in enumerate(self.sub_list_store_back)}
def deserialize(self, text_buffer, exported):
text_buffer.set_text('')
text_buffer.deserialize( text_buffer,
text_buffer.register_deserialize_tagset(),
text_buffer.get_start_iter(),
exported )
def item_selected(self, *args):
# Need this try/except to silent a indexerror that will occur case the second window close and if opened again,
# merely cosmetic as it will always occur, just select any row and all good.
# The get_selected_rows()[1] will return a empty list at first try when reopening the second window, I just don't know why
try:
path = self.selected_row.get_selected_rows()[1][0]
exported_front = self.dict_any_change_front[str(path)]
exported_back = self.dict_any_change_back[str(path)]
try:
if isinstance(exported_front, bytes):
self.deserialize(self.text_buffer_front, exported_front)
else:
self.text_buffer_front.set_text(self.sub_list_store[path][1])
if isinstance(exported_back, bytes):
self.deserialize(self.text_buffer_back, exported_back)
else:
self.text_buffer_back.set_text(self.sub_list_store_back[path][1])
except:
self.text_buffer_front.set_text(self.sub_list_store[path][1])
self.text_buffer_back.set_text(self.sub_list_store_back[path][1])
self.text_buffer_front.connect('changed', self.editingCard)
self.text_buffer_back.connect('changed', self.editingCardBack)
except IndexError:
pass
def editingCard(self, text_buffer):
path = self.selected_row.get_selected_rows()[1][0]
start_iter_front = text_buffer.get_start_iter()
end_iter_front = text_buffer.get_end_iter()
self.sub_list_store[path][1] = text_buffer.get_text(start_iter_front, end_iter_front, True)
format = text_buffer.register_serialize_tagset()
exported = text_buffer.serialize( text_buffer,
format,
start_iter_front,
end_iter_front )
self.dict_any_change_front[str(path)] = exported
def editingCardBack(self, text_buffer):
path = self.selected_row.get_selected_rows()[1][0]
start_iter_back = text_buffer.get_start_iter()
end_iter_back = text_buffer.get_end_iter()
self.sub_list_store_back[path][1] = text_buffer.get_text(start_iter_back, end_iter_back, True)
format = text_buffer.register_serialize_tagset()
exported = text_buffer.serialize( text_buffer,
format,
start_iter_back,
end_iter_back )
self.dict_any_change_back[str(path)] = exported
def on_toolbar_button_clicked(self, widget, tag_front, tag_back):
bounds_front = self.text_buffer_front.get_selection_bounds()
bounds_back = self.text_buffer_back.get_selection_bounds()
path = self.selected_row.get_selected_rows()[1][0]
##### FRONT
if len(bounds_front) != 0:
(start, end) = bounds_front
selection_front = self.text_buffer_front.get_text(start, end, True)
get_insert_front = self.text_buffer_front.get_insert()
self.text_buffer_front.apply_tag(tag_front, start, end)
start_iter_front = self.text_buffer_front.get_start_iter()
end_iter_front = self.text_buffer_front.get_end_iter()
format = self.text_buffer_front.register_serialize_tagset()
exported = self.text_buffer_front.serialize( self.text_buffer_front,
format,
start_iter_front,
end_iter_front )
self.dict_any_change_front[str(path)] = exported
###### BACK
if len(bounds_back) != 0:
(start, end) = bounds_back
selection_back = self.text_buffer_back.get_text(start, end, True)
get_insert_back = self.text_buffer_back.get_insert()
self.text_buffer_back.apply_tag(tag_back, start, end)
start_iter_back = self.text_buffer_back.get_start_iter()
end_iter_back = self.text_buffer_back.get_end_iter()
format = self.text_buffer_back.register_serialize_tagset()
exported = self.text_buffer_back.serialize( self.text_buffer_back,
format,
start_iter_back,
end_iter_back )
self.dict_any_change_back[str(path)] = exported
Working as I wanted :).
Edit
I adjusted my code to serialize everything at start and putting at the dictionary, instead of putting strings in the dictionary and as was editing the texts serializing the text and putting it the dictionary, with this was possible remove some if/else's and try/except's.
Also I created functions to serialize and deserialize thing, and put these functions in another file, I think this way is better.
myhandlerfile.py:
...
from myfuncfile import serializeIt, deserializeIt
...
# dictionary to track the tags
self.dict_any_change_front = {str(key): serializeIt(text_buffer=self.text_buffer_front, tmp_string=value[1]) \
for key, value in enumerate(self.sub_list_store)}
self.dict_any_change_back = {str(key): serializeIt(text_buffer=self.text_buffer_back, tmp_string=value[1]) \
for key, value in enumerate(self.sub_list_store_back)}
def item_selected(self, *args):
# Silencing a indexerror that will occur in case the window was hided and rised again
# it is not important, can be ignored
try:
path = self.selected_row.get_selected_rows()[1][0]
exported_front = self.dict_any_change_front[str(path)]
exported_back = self.dict_any_change_back[str(path)]
deserializeIt(self.text_buffer_front, exported_front)
deserializeIt(self.text_buffer_back, exported_back)
self.text_buffer_front.connect('changed', self.editingCard)
self.text_buffer_back.connect('changed', self.editingCardBack)
except IndexError:
pass
def editingCard(self, text_buffer_front):
# Silencing a indexerror that will occur in case the window was hided and rised again
# it is not important, can be ignored
try:
path = self.selected_row.get_selected_rows()[1][0]
start_iter_front = text_buffer_front.get_start_iter()
end_iter_front = text_buffer_front.get_end_iter()
self.sub_list_store[path][1] = text_buffer_front.get_text(start_iter_front, end_iter_front, True)
exported = serializeIt(text_buffer=text_buffer_front)
self.dict_any_change_front[str(path)] = exported
except IndexError:
pass
def editingCardBack(self, text_buffer_back):
# Silencing a indexerror that will occur in case the window was hided and rised again
# it is not important, can be ignored
try:
path = self.selected_row.get_selected_rows()[1][0]
start_iter_back = text_buffer_back.get_start_iter()
end_iter_back = text_buffer_back.get_end_iter()
self.sub_list_store_back[path][1] = text_buffer_back.get_text(start_iter_back, end_iter_back, True)
exported = serializeIt(text_buffer=text_buffer_back)
self.dict_any_change_back[str(path)] = exported
except IndexError:
pass
def on_toolbar_button_clicked(self, widget, tag_front, tag_back):
bounds_front = self.text_buffer_front.get_selection_bounds()
bounds_back = self.text_buffer_back.get_selection_bounds()
path = self.selected_row.get_selected_rows()[1][0]
##### FRONT
if len(bounds_front) != 0:
(start, end) = bounds_front
selection_front = self.text_buffer_front.get_text(start, end, True)
get_insert_front = self.text_buffer_front.get_insert()
self.text_buffer_front.apply_tag(tag_front, start, end)
exported = serializeIt(text_buffer=self.text_buffer_front)
self.dict_any_change_front[str(path)] = exported
###### BACK
if len(bounds_back) != 0:
(start, end) = bounds_back
selection_back = self.text_buffer_back.get_text(start, end, True)
get_insert_back = self.text_buffer_back.get_insert()
self.text_buffer_back.apply_tag(tag_back, start, end)
exported = serializeIt(text_buffer=self.text_buffer_back)
self.dict_any_change_back[str(path)] = exported
...
myfuncfile.py:
...
def serializeIt(text_buffer, tmp_string=None):
if tmp_string:
text_buffer.set_text(tmp_string)
tmp_start_iter = text_buffer.get_start_iter()
tmp_end_iter = text_buffer.get_end_iter()
tmp_format = text_buffer.register_serialize_tagset()
tmp_exported = text_buffer.serialize( text_buffer,
tmp_format,
tmp_start_iter,
tmp_end_iter )
return tmp_exported
else:
start_iter = text_buffer.get_start_iter()
end_iter = text_buffer.get_end_iter()
format = text_buffer.register_serialize_tagset()
exported = text_buffer.serialize( text_buffer,
format,
start_iter,
end_iter )
return exported
def deserializeIt(text_buffer, exported):
text_buffer.set_text('')
text_buffer.deserialize(text_buffer,
text_buffer.register_deserialize_tagset(),
text_buffer.get_start_iter(),
exported )
...

Python sql returning list

got some functions with sqlstatements. My first func is fine because i get only 1 result.
My second function returns a large list of errorcodes and i dont know how to get them back for response.
TypeError: <sqlalchemy.engine.result.ResultProxy object at 0x7f98b85ef910> is not JSON serializable
Tried everything need help.
My Code:
def topalarms():
customer_name = request.args.get('customer_name')
machine_serial = request.args.get('machine_serial')
#ts = request.args.get('ts')
#ts_start = request.args.get('ts')
if (customer_name is None) or (machine_serial is None):
return missing_param()
# def form_response(response, session):
# response['customer'] = customer_name
# response['serial'] = machine_serial
# return do_response(customer_name, form_response)
def form_response(response, session):
result_machine_id = machine_id(session, machine_serial)
if not result_machine_id:
response['Error'] = 'Seriennummer nicht vorhanden/gefunden'
return
#response[''] = result_machine_id[0]["id"]
machineid = result_machine_id[0]["id"]
result_errorcodes = error_codes(session, machineid)
response['ErrorCodes'] = result_errorcodes
return do_response(customer_name, form_response)
def machine_id(session, machine_serial):
stmt_raw = '''
SELECT
id
FROM
machine
WHERE
machine.serial = :machine_serial_arg
'''
utc_now = datetime.datetime.utcnow()
utc_now_iso = pytz.utc.localize(utc_now).isoformat()
utc_start = datetime.datetime.utcnow() - datetime.timedelta(days = 30)
utc_start_iso = pytz.utc.localize(utc_start).isoformat()
stmt_args = {
'machine_serial_arg': machine_serial,
}
stmt = text(stmt_raw).columns(
#ts_insert = ISODateTime
)
result = session.execute(stmt, stmt_args)
ts = utc_now_iso
ts_start = utc_start_iso
ID = []
for row in result:
ID.append({
'id': row[0],
'ts': ts,
'ts_start': ts_start,
})
return ID
def error_codes(session, machineid):
stmt_raw = '''
SELECT
name
FROM
identifier
WHERE
identifier.machine_id = :machineid_arg
'''
stmt_args = {
'machineid_arg': machineid,
}
stmt = text(stmt_raw).columns(
#ts_insert = ISODateTime
)
result = session.execute(stmt, stmt_args)
errors = []
for row in result:
errors.append(result)
#({'result': [dict(row) for row in result]})
#errors = {i: result[i] for i in range(0, len(result))}
#errors = dict(result)
return errors
My problem is func error_codes somethiing is wrong with my result.
my Output should be like this:
ABCNormal
ABCSafety
Alarm_G01N01
Alarm_G01N02
Alarm_G01N03
Alarm_G01N04
Alarm_G01N05
I think you need to take a closer look at what you are doing correctly with your working function and compare that to your non-working function.
Firstly, what do you think this code does?
for row in result:
errors.append(result)
This adds to errors one copy of the result object for each row in result. So if you have six rows in result, errors contains six copies of result. I suspect this isn't what you are looking for. You want to be doing something with the row variable.
Taking a closer look at your working function, you are taking the first value out of the row, using row[0]. So, you probably want to do the same in your non-working function:
for row in result:
errors.append(row[0])
I don't have SQLAlchemy set up so I haven't tested this: I have provided this answer based solely on the differences between your working function and your non-working function.
You need a json serializer. I suggest using Marshmallow: https://marshmallow.readthedocs.io/en/stable/
There are some great tutorials online on how to do this.

Exporting data from python to text file using petl package in python

I am trying to extract raw data from a text file and after processing the raw data, I want to export it to another text file. Below is the python code I have written for this process. I am using the "petl" package in python 3 for this purpose. 'locations.txt' is the raw data file.
import glob, os
from petl import *
class ETL():
def __init__(self, input):
self.list = input
def parse_P(self):
personids = None
for term in self.list:
if term.startswith('P'):
personids = term[1:]
personid = personids.split(',')
return personid
def return_location(self):
location = None
for term in self.list:
if term.startswith('L'):
location = term[1:]
return location
def return_location_id(self, location):
location = self.return_location()
locationid = None
def return_country_id(self):
countryid = None
for term in self.list:
if term.startswith('C'):
countryid = term[1:]
return countryid
def return_region_id(self):
regionid = None
for term in self.list:
if term.startswith('R'):
regionid = term[1:]
return regionid
def return_city_id(self):
cityid = None
for term in self.list:
if term.startswith('I'):
cityid = term[1:]
return cityid
print (os.getcwd())
os.chdir("D:\ETL-IntroductionProject")
print (os.getcwd())
final_location = [['L','P', 'C', 'R', 'I']]
new_location = fromtext('locations.txt', encoding= 'Latin-1')
stored_list = []
for identifier in new_location:
if identifier[0].startswith('L'):
identifier = identifier[0]
info_list = identifier.split('_')
stored_list.append(info_list)
for lst in stored_list:
tabling = ETL(lst)
location = tabling.return_location()
country = tabling.return_country_id()
city = tabling.return_city_id()
region = tabling.return_region_id()
person_list = tabling.parse_P()
for person in person_list:
table_new = [location, person, country, region, city]
final_location.append(table_new)
totext(final_location, 'l1.txt')
However when I use "totext" function of petl, it throws me an "Assertion Error".
AssertionError: template is required
I am unable to understand what the fault is. Can some one please explain the problem I am facing and what I should be doing ?
The template parameter to the toext function is not optional there is no default format for how the rows are written in this case, you must provide a template. Check the doc for toext here for an example: https://petl.readthedocs.io/en/latest/io.html#text-files
The template describes the format of each row that it writes out using the field headers to describe things, you can optionally pass in a prologue to write the header too. A basic template in your case would be:
table_new_template = "{L} {P} {C} {R} {I}"
totext(final_location, 'l1.txt', template=table_new_template)

Networkx: find way according to .dot file attribute

I'm working with digraph defined in dot language using networkx. I need to achieve something like this:
X = networkx.read_dot('_t.dot') #loads dotfile
def navigate_through_model(model, type): #model is model, type -> string of desired 'comment'
.....
return path
if \__target\__== '\__main\__':
print navigate_through_model(X, 'regression') # I need to return path, that is going through all nodes with comment == 'regression' (it can be other attribute, comment is only for question)
And I'm kind a lost in this :(
Any help will be appreciated.
Ok finally I found (after good sleep) that I can use weight of edges to achieve the same result. So solution is easy.. set lowest weight to 'regression' path and than just generate shortest path.
networkx(X, 'start', 'end', weight='weight')
In order to do this you have to edit networkx/algorithms/shortest_paths/weighted.py
There is some kind of bug on the row 342.
vw_dist = dist[v] + edgedata.get(weight, 1)
You have to change it to:
vw_dist = dist[v] + float(edgedata.get(weight, 1)) #if you want to use floating number or just int to use integers
Ok I finally gets to this:
import networkx
X = networkx.read_dot('_t.dot')
def navigate_through_model(model, start_node, end_node, typex):
path = []
actual_node = start_node
visited_nodes = []
status = True
while actual_node != end_node:
u = networkx.all_neighbors(model, actual_node)
for line in u:
target_node = line
print target_node
try:
comm = model[actual_node][target_node][0]['comment']
if (comm == typex and target_node not in visited_nodes):
path.append((actual_node, target_node))
actual_node = target_node
visited_nodes.append(target_node)
print path
print '\n'
print visited_nodes
status = True
else:
status = False
except Exception as err:
pass
if not status:
return "not found"
return path
print navigate_through_model(X, 'start', 'end', 'regression')
Maybe it is not the best solution but it works!

Categories