Appending Items to a SimpleFocusListWalker in Urwid - python

Rather than do this as in the urwid example:
simple_walker = urwid.SimpleFocusListWalker([
urwid.AttrMap(urwid.Text([u'\n ',caption]), 'heading'),
urwid.AttrMap(line, 'line'),
urwid.Divider()] + choices + [urwid.Divider()])
self.listbox=urwid.ListBox(simple_walker)
I'd like to do this:
simple_walker = urwid.SimpleFocusListWalker([])
simple_walker.append(urwid.AttrMap(urwid.Text([u'\n ',caption]), 'heading'))
simple_walker.append(urwid.AttrMap(line, 'line'))
simple_walker.append(urwid.Divider())
simple_walker.append(choices)
simple_walker.append(urwid.Divider())
self.listbox=urwid.ListBox(simple_walker)
However, when I do this I get a long exception dump ending in:
File ".../listbox.py", line 717, in _set_focus_complete
(maxcol,maxrow), focus)
File ".../listbox.py", line 687, in _set_focus_first_selectable
(maxcol, maxrow), focus=focus)
File ".../listbox.py", line 419, in calculate_visible
n_rows = next.rows( (maxcol,) )
AttributeError: 'list' object has no attribute 'rows'
What is the correct way to append items to a SimpleFocusListWalker.
I'm trying to build a menu from the top down without specifying the whole thing in the constructor.

The problem above was that "choices" is a list. Needs to be the following:
for ii in choices:
simple_walker.append(ii)

Related

Neo.ClientError.Statement.ParameterMissing} {message: Expected parameter(s): username_} with Python

I have the following function and the following call (with the connection setup before it)
from neo4j import GraphDatabase
from pypher import Pypher
# from WebScraper import *
py = Pypher()
# server connection link
uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "cs411fpl"))
session = driver.session()
username = 'a'
varray = []
# adds a user node
def add_user(username_):
q1 = "CREATE (u:User) SET u.name= $username_"
nodes = session.run(q1)
add_user(username)
This leads to the error:
File "UserHandler.py", line 37, in <module>
add_user(username)
File "UserHandler.py", line 14, in add_user
nodes = session.run(q1)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/neo4j/work/simple.py", line 217, in run
self._autoResult._run(query, parameters, self._config.database, self._config.default_access_mode, self._bookmarks, **kwparameters)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/neo4j/work/result.py", line 101, in _run
self._attach()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/neo4j/work/result.py", line 202, in _attach
self._connection.fetch_message()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/neo4j/io/_bolt4.py", line 363, in fetch_message
response.on_failure(summary_metadata or {})
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/neo4j/io/_common.py", line 179, in on_failure
raise Neo4jError.hydrate(**metadata)
neo4j.exceptions.ClientError: {code: Neo.ClientError.Statement.ParameterMissing} {message: Expected parameter(s): username_}
Any suggestions would be great. Thanks!
You are missing the connectiong between Cypher and Python (a second argument to run). It is not enough to have spelled username_ the same way both places.
def add_user(username_):
q1 = "CREATE (u:User) SET u.name= $username_"
nodes = session.run(q1, username_=username_)
I think the following would work as well, notice how the second argument for run must describe the coupling between the Cypher and Python:
def add_user(username_):
q1 = "CREATE (u:User) SET u.name= $login"
nodes = session.run(q1, login=username_)
You might be able to find more here:
https://neo4j.com/developer/python/

Creating nested dictionary from 3 different CSV files

My aim is to take the data from 3 different CSV file and create a nested dictionary, I realize my error, but I fail to fix it.
Shall I create 3 different methods for each file to iterate the data and then create the nested dictionary, or it is something else that I have to do?
Code:
class STproject:
def __init__(self,app): #1
self.mlb=LabelFrame(app, text='Movie Recommendation Engine')
self.mlb.grid()
self.lframe3=LabelFrame(self.mlb,text="Movies/Users",background='purple')
self.lframe3.grid(row=0,column=1)
self.framebutton=Frame(self.mlb,background='pink',height=50,width=50)
self.framebutton.grid(row=0,column=0)
self.buttonsnlabels()
def buttonsnlabels(self):
self.ratingbutton=Button(self.framebutton,text='Upload movies',command=lambda :self.file1())
self.ratingbutton.grid()
self.ratingbutton=Button(self.framebutton,text='Upload ratings',command=lambda :self.file2())
self.ratingbutton.grid()
self.ratingbutton=Button(self.framebutton,text='Upload links',command=lambda :self.file3())
self.ratingbutton.grid()
def file1(self):
umovies=tkFileDialog.askopenfilename()
f=open(umovies)
self.csv_file1 = csv.reader(f)
self.dictionary()
def file2(self):
uratings=tkFileDialog.askopenfilename()
f=open(uratings)
self.csv_file2 = csv.reader(f)
self.dictionary()
def file3(self):
links=tkFileDialog.askopenfilename()
f=open(links)
self.csv_file3 = csv.reader(f)
self.dictionary()
def dictionary(self):
for line1,line2,line3 in zip(self.csv_file1,self.csv_file2,self.csv_file3):
dict={}
dict[line1]={[line2]:[line3]}
root=Tk()
root.title()
application=STproject(root)
root.mainloop()
and this is the error given:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\Lib\lib-tk\Tkinter.py", line 1547, in __call__
return self.func(*args)
File "C:/Users/Umer Selmani/Desktop/voluntarily/Voluntiraly.py", line 825, in <lambda>
self.ratingbutton=Button(self.framebutton,text='Upload movies',command=lambda :self.file1())
File "C:/Users/Umer Selmani/Desktop/voluntarily/Voluntiraly.py", line 836, in file1
self.dictionary()
File "C:/Users/Umer Selmani/Desktop/voluntarily/Voluntiraly.py", line 858, in dictionary
for line1,line2,line3 in zip(self.csv_file1,self.csv_file2,self.csv_file3):
AttributeError: STproject instance has no attribute 'csv_file2'
I would suggest to first store the selected results at a place, and process them later by another button. In the below sample i'm using StringVar to store the file paths.
class STproject:
def __init__(self, app):
self.mlb=LabelFrame(app, text='Movie Recommendation Engine')
self.mlb.grid()
self.lframe3=LabelFrame(self.mlb,text="Movies/Users",background='purple')
self.lframe3.grid(row=0,column=1)
self.framebutton=Frame(self.mlb,background='pink',height=50,width=50)
self.framebutton.grid(row=0,column=0)
self.buttonsnlabels()
self.all_vars = [StringVar() for _ in range(3)]
def buttonsnlabels(self):
self.ratingbutton=Button(self.framebutton,text='Upload movies',command=lambda:self.file(self.all_vars[0]))
self.ratingbutton.grid(row=0,column=0)
self.ratingbutton=Button(self.framebutton,text='Upload ratings',command=lambda:self.file(self.all_vars[1]))
self.ratingbutton.grid(row=1,column=0)
self.ratingbutton=Button(self.framebutton,text='Upload links',command=lambda:self.file(self.all_vars[2]))
self.ratingbutton.grid(row=2,column=0)
self.process = Button(self.framebutton,text='Process',command=self.dictionary)
self.process.grid(row=1,column=1)
def file(self, v):
result = tkFileDialog.askopenfilename()
if result:
v.set(result)
def dictionary(self):
if all(i.get() for i in self.all_vars): #process only if all 3 files are selected
with open(self.all_vars[0].get(),"r") as a, open(self.all_vars[1].get(),"r") as b, open(self.all_vars[2].get(),"r") as c:
d = {}
for line1,line2,line3 in zip(csv.reader(a),csv.reader(b),csv.reader(c)):
d[line1]={line2:line3}
root=Tk()
root.title()
application=STproject(root)
root.mainloop()
Note that I also moved the location and the name of the dict in your original code. In your code, not other it shadows the built in method dict, it also overwrites itself during each iteration of the for loop, which i think would not be what you looking for.

TypeError: 'xml.etree.ElementTree.Element' object is not callable

I am converting to Python an application I had earlier written in C#. It's a GUI application to manage unknown words while learning a new language. When the application starts, I have to load the words from the XML file which has a pretty simple structure:
<Words>
<Word>
<Word>test</Word>
<Explanation>test</Explanation>
<Translation>test</Translation>
<Examples>test</Examples>
</Word>
</Words>
Nevertheless, I am getting:
/usr/bin/python3.5 /home/cali/PycharmProjects/Vocabulary/Vocabulary.py
Traceback (most recent call last): File
"/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 203, in
main() File "/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 198, in
main
gui = Vocabulary(root) File "/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 28, in
init
self.load_words() File "/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 168, in
load_words
w = Word(node('Word').text, node('Explanation').text, node('Translation').text, node('Example').text) TypeError:
'xml.etree.ElementTree.Element' object is not callable
This is the original LoadWords() method:
void LoadWords()
{
words.Clear();
listView1.Items.Clear();
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string vocabulary_path = path + "\\Vocabulary\\Words.xml";
if (!Directory.Exists(path + "\\Vocabulary"))
Directory.CreateDirectory(path + "\\Vocabulary");
if (!File.Exists(vocabulary_path))
{
XmlTextWriter xW = new XmlTextWriter(vocabulary_path, Encoding.UTF8);
xW.WriteStartElement("Words");
xW.WriteEndElement();
xW.Close();
}
XmlDocument xDoc = new XmlDocument();
xDoc.Load(vocabulary_path);
foreach (XmlNode xNode in xDoc.SelectNodes("Words/Word"))
{
Word w = new Word();
w.WordOrPhrase = xNode.SelectSingleNode("Word").InnerText;
w.Explanation = xNode.SelectSingleNode("Explanation").InnerText;
w.Translation = xNode.SelectSingleNode("Translation").InnerText;
w.Examples = xNode.SelectSingleNode("Examples").InnerText;
words.Add(w);
listView1.Items.Add(w.WordOrPhrase);
WordCount();
}
}
I don't know how to access each node's inner text.
Here is my load_words function:
def load_words(self):
self.listBox.delete(0, END)
self.words.clear()
path = os.path.expanduser('~/Desktop')
vocabulary = os.path.join(path, 'Vocabulary', 'Words.xml')
if not os.path.exists(vocabulary):
if not os.path.exists(os.path.dirname(vocabulary)):
os.mkdir(os.path.dirname(vocabulary))
doc = ET.Element('Words')
tree = ET.ElementTree(doc)
tree.write(vocabulary)
else:
tree = ET.ElementTree(file=vocabulary)
for node in tree.findall('Word'):
w = Word(node('Word').text, node('Explanation').text, node('Translation').text, node('Example').text)
self.words.append(w)
self.listBox.insert(w.wordorphrase)
TypeError: 'xml.etree.ElementTree.Element' object is not callable
As the error message mentioned, node is an Element, not a method which you can call/invoke like method_name(parameters) as you did in this part :
w = Word(node('Word').text, node('Explanation').text, node('Translation').text, node('Example').text)
Method that is closer to SelectSingleNode() in your C# would be Element.find(), for example, to get the first child element named Word from node and then extract the inner text :
inner_text = node.find('Word').text
And the implementation in your context code would be as follows :
w = Word(node.find('Word').text, node.find('Explanation').text, node.find('Translation').text, node.find('Example').text)

AttributeError: 'NoneType' object has no attribute 'grid_remove'

I have only done a little work with Tkinter and I enjoy using it but as with any type programing it takes time to learn. I am trying to create a simple To do list that will eventually be saved on a file. But i can't get the button in line 17 to be removed and the on the next line be replace in a different position.
from tkinter import *
import time
root = Tk()
root.geometry("300x300")
root.title("Programs")
global TDrow
TDrow = 2
def tdTaskAdd():
global TDrow
global tdEnter
TDrow = int(TDrow+1)
s = tdEntry.get()
label = Label(ToDoFrame,text=s).grid(row=TDrow,column=1)
tdEntry.grid(row=TDrow+1,column=1)
tdEnter.grid_remove()
tdEnter = Button(ToDoFrame,text="AddTask",command=tdTaskAdd).grid(row=TDrow+2,column=1)
ToDoFrame = Frame()
ToDoFrame.place(x=0,y=10)
tdTitle = Label(ToDoFrame,text="To Do List:").grid(row=TDrow-1,column=1)
tdEntry= Entry(ToDoFrame)
tdEntry.grid(row=TDrow+1,column=1)
tdEntry.insert(0, "Enter a new task")
global tdEnter
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd).grid(row=TDrow+2,column=1)
mainloop()
I keep getting an error when running this saying that:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Eddy\Desktop\pythonStartup.py", line 17, in tdTaskAdd
tdEnter.grid_remove()
AttributeError: 'NoneType' object has no attribute 'grid_remove'
The problem is this line:
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd).grid(row=TDrow+2,column=1)
This way, tdEnter is not the Button, but the return value of grid, i.e. None.
Try this instead:
tdEnter = Button(ToDoFrame,text="Add Task",command=tdTaskAdd)
tdEnter.grid(row=TDrow+2,column=1)
Same for label and when you create a new button in your tdAddTask function.
BTW, no need to add a new button each time, just call it's grid method to repositon it.

ETE2: adding image to nodes

I have been trying to add different images to nodes in a phylogenetic tree using the ete2 software in Python, but have no success.
from ete2 import Tree, TreeStyle, NodeStyle, TextFace, faces, add_face_to_node, AttrFace
ts.show_leaf_name = True
ts.show_branch_support = True
nw = """
(((Dre:0.008339,Dme:0.300613)1.000000:0.596401,
(Cfa:0.640858,Hsa:0.753230)1.000000:0.182035)1.000000:0.106234,
((Dre:0.271621,Cfa:0.046042)1.000000:0.953250,
(Hsa:0.061813,Mms:0.110769)1.000000:0.204419)1.000000:0.973467);
"""
t = Tree(nw)
img_path = "/home/leonard/Desktop/img_faces/"
humanFace = faces.ImgFace(img_path+"human.png")
mouseFace = faces.ImgFace(img_path+"mouse.png")
def my_layout(node):
if name.startswith("Dre"):
faces.add_face_to_node(humanface, node, column=1)
t.show(my_layout)
ts = TreeStyle()
t.render("img_faces.png", w=600, tree_style = ts)
These are error messages that I have been getting:
File "abc1.py", line 34, in <module>
t.show(my_layout)
File "/usr/local/lib/python2.7/dist-packages/ete2-2.1rev544-py2.7.egg/ete2/coretype/tree.py", line 1283, in show
drawer.show_tree(self, layout=layout, tree_style=tree_style)
File "/usr/local/lib/python2.7/dist-packages/ete2-2.1rev544-py2.7.egg/ete2/treeview/drawer.py", line 84, in show_tree
tree_item, n2i, n2f = render(t, img)
File "/usr/local/lib/python2.7/dist-packages/ete2-2.1rev544-py2.7.egg/ete2/treeview/qt4_render.py", line 258, in render
set_style(n, layout_fn)
File "/usr/local/lib/python2.7/dist-packages/ete2-2.1rev544-py2.7.egg/ete2/treeview/qt4_render.py", line 746, in set_style
layout_func(n)
File "abc1.py", line 29, in my_layout
if name.startswith("Dre"):
NameError: global name 'name' is not defined
Any help is much appreciated!
This is the solution from Jaime Huerta Cepas in google group, and I quote:
"There is a general Python programming error in your script ("name" variable does not exist). I guess that what you meant is "node.name.startswith()" instead of "name.startswith()""
It worked.
According to the documentation (ete2) you need to create a faces ready to read the name attribute of nodes.
Try to add the following to your code:
#nameFace = faces.TextFace(open("text").readline().strip(), fsize=20, fgcolor="#009000")
nameFace = faces.AttrFace("name", fsize=20, fgcolor="#009000")

Categories