Acessing content of Instance variable in Post method - google-app-engine

Below is a fragement of my code
def LoadCategory(self, filter_string):
time.sleep(1)
self.heading = ""
self.Question_title = list()
self.Question_tag = list()
self.Question_body = list()
self.Question_who_ask = list()
self.Question_who_email = list()
self.Question_key = list()
self.Question_Date = list()
# list is then populated
def post(self):
self.response.write(self.Question_body)
# want to print out self.Question_body in post method.
But the list is empty. what is the right way to access the content of the variable ?

Quick solution assuming you are inside a request class. Although using self to assign variables to the class is not a good approach as said before.
def LoadCategory(self, filter_string):
time.sleep(1)
self.heading = ""
self.Question_title = list()
self.Question_tag = list()
self.Question_body = list()
self.Question_who_ask = list()
self.Question_who_email = list()
self.Question_key = list()
self.Question_Date = list()
# list is then populated
def post(self):
self.LoadCategory(filter_string)
self.response.write(self.Question_body)
Also it would be better if you name LoadCategory to load_category or loadcategory. Try following the PEP8 which states that the function names should be lowercase

Related

Shoveling objects into an array

I'm working on scraping.
class MMA::School
attr_accessor :name, :location_info, :url
def self.today
self.schools
end
def self.schools
schools = []
schools << self.scrape_cbs
schools
end
def self.scrape_cbs
doc = Nokogiri::HTML(open("http://newyork.cbslocal.com/top-lists/5-best-mma-and-martial-arts-studios-in-new-york/"))
schools_1 = self.new
schools_1.name = doc.search("//div/p/strong/span").text.strip
schools_1.location_info = doc.search("//div/p")[4].text.strip
schools_1.url = doc.search("//div/p/a")[0].text.strip
schools_1
schools_2 = self.new
schools_2.name = doc.search("//div/p/span")[0].text.strip
schools_2.location_info = doc.search("//div/p")[7].text.strip
schools_2.url = doc.search("//div/p/a")[2].text.strip
schools_2
schools_3 = self.new
schools_3.name = doc.search("//div/p/span")[1].text.strip
schools_3.location_info = doc.search("//div/p")[9].text.strip
schools_3.url = doc.search("//div/p/a")[3].text.strip
schools_3
schools_4 = self.new
schools_4.name = doc.search("//div/p/span")[2].text.strip
schools_4.location_info = doc.search("//div/p")[12].text.strip
schools_4.url = doc.search("//div/p/a")[5].text.strip
schools_4
schools_5 = self.new
schools_5.name = doc.search("//div/p/span")[3].text.strip
schools_5.location_info = doc.search("//div/p")[14].text.strip
schools_5.url = doc.search("//div/p/a")[6].text.strip
schools_5
end
end
I have some trouble placing my scraped data into an empty array. It only pushes one of the schools_1 etc. to the schools array.
Does anyone have any suggestions on how to fix this?
Without any explanation, it is absolutely not clear what you are trying to do, but it is clear that in your self.scrape_cbs definition, the lines:
schools_1
...
schools_2
...
...
schools_4
are meaningless. Perhaps, you intended to return an array like this from this method:
[schools_1, schools_2, ..., schools_5]
If so, put the line above as the last line of your method definition of self.scrape_cbs.

Returning a dictionary from a file

I have have written this code defining a class
class OrderRecord:
"""Defines an OrderRecord class, suitable for use in keeping track of order records"""
import tools2
def __init__(self, string):
"""Creates a new OrderRecord object"""
string = string.split(',')
self.date = string[0]
self.location = string[1]
self.name = string[2]
self.colour = string[3]
self.order_num = string[4]
self.cost = 0
def cost_of_order(self):
"""Creates a list of the name and adds up the cost of each letter"""
letter = list(self.name)
for let in letter:
self.cost = self.cost + self.tools2.letter_price(let, self.colour)
return self.cost
def __str__(self):
"""Calls the cost_of_order function and returns the split string in the required format"""
self.cost = self.cost_of_order()
return("Date: {0}\nLocation: {1}\nName: {2}\nColour: \
{3}\nOrder Num: {4}\nCost: {5:.2f}".format(self.date, self.location, \
self.name, self.colour, self.order_num, self.cost))
Now I need to write a function that reads a file containing the following:
20130902,Te Rakipaewhenua,Vinas,parauri,8638
20130909,Te Papaioea,McClary,kikorangi,11643
20131215,Kapiti,Labrie,kikorangi,65291
20141106,Waihopai,Labrie,ma,57910
and returns a dictionary that has the location as the key and lists of OrderRecords as the values.
I know this isn't too hard of a task but I have been stuck on this for awhile because I can't get my head around what to do for it.
Any help would be appreciated.
Maybe something like this. It is not the solution but it has what you need with some modifications.
import collections
dct_result = collections.defaultdict(list)
for line in open('file_path'):
fields = line.split(',')
# index 1 being the second column
dct_result[field(1)].append(OrderRecord( some args ))

Shortest way to get File object from resource in Groovy

Right now I'm using Java API to create file object from resource:
new File(getClass().getResource('/resource.xml').toURI())
Is there any more idiomatic/shorter way to do that in Groovy using GDK?
Depending on what you want to do with the File, there might be a shorter way. Note that URL has GDK methods getText(), eachLine{}, and so on.
Illustration 1:
def file = new File(getClass().getResource('/resource.xml').toURI())
def list1 = []
file.eachLine { list1 << it }
// Groovier:
def list2 = []
getClass().getResource('/resource.xml').eachLine {
list2 << it
}
assert list1 == list2
Illustration 2:
import groovy.xml.*
def xmlSlurper = new XmlSlurper()
def url = getClass().getResource('/resource.xml')
// OP style
def file = new File(url.toURI())
def root1 = xmlSlurper.parseText(file.text)
// Groovier:
def root2 = xmlSlurper.parseText(url.text)
assert root1.text() == root2.text()

Passing values between forms with npyscreen

I am trying to create a simple npyscreen curses application in python that requests user input on one screen, and then verifies it for the user on another screen.
Mostly, this is an effort to understand how values are stored and retrieved from within npyscreen. I am sure I am missing something simple, but I have been unable to find (or understand?) the answer within the documentation.
Sample code below which will not pass the value properly:
#!/usr/bin/env python3.5
import npyscreen as np
class EmployeeForm(np.Form):
def afterEditing(self):
self.parentApp.switchForm('CONFIRMFM')
def create(self):
self.myName = self.add(np.TitleText, name='Name')
self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
self.myDate = self.add(np.TitleDateCombo, name='Date Employed')
class EmployeeConfirmForm(np.Form):
def afterEditing(self):
self.parentApp.setNextForm(None)
def create(self):
self.value = None
self.wgName = self.add(np.TitleText, name = "Name:",)
self.wgDept = self.add(np.TitleText, name = "Dept:")
self.wgEmp = self.add(np.TitleText, name = "Employed:")
def beforeEditing(self):
if self.value:
self.name = "Is this correct?"
self.wgName.value = self.myName.value
self.wgDept.value = self.myDepartment.value
self.wgEmp.value = self.myDate.value
def on_cancel(self):
self.parentApp.switchFormPrevious()
class myApp(np.NPSAppManaged):
def onStart(self):
self.addForm('MAIN', EmployeeForm, name='Employee Entry')
self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
if __name__ == '__main__':
TestApp = myApp().run()
I haven't found a straightforward way to directly pass variables between forms. However, you can work around this by using variables that have a global scope among forms.
The NPSAppManaged app class runs completely encapsulated, so if you try to declare global variables at the top of the Python file, the forms within will not have access to them. Instead, declare the variables inside the NPSAppManaged app class before the onStart method as shown below.
class myApp(np.NPSAppManaged):
# declare variables here that have global scope to all your forms
myName, myDepartment, myDate = None, None, None
def onStart(self):
self.addForm('MAIN', EmployeeForm, name='Employee Entry')
self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
if __name__ == '__main__':
TestApp = myApp().run()
You can then access these variables using self.parentApp.[variable name] as follows:
class EmployeeConfirmForm(np.Form):
def afterEditing(self):
self.parentApp.setNextForm(None)
def create(self):
self.add(np.FixedText, value = "Is this correct?")
self.wgName = self.add(np.TitleText, name = "Name:", value = self.parentApp.myName)
self.wgDept = self.add(np.TitleText, name = "Dept:", value = self.parentApp.myDepartment)
self.wgEmp = self.add(np.TitleText, name = "Employed:", value = self.parentApp.myDate)
def on_cancel(self):
self.parentApp.switchFormPrevious()
Note: you don't need to have a separate beforeEditing method since the values will be loaded directly into EmployeeConfirmForm during the create method from the app class global variables.
One way to do this is to use getForm before switchForm to pass the values. The following works for me using python2 to pass the name. Passing other values should be similar. I'm very much learning this myself but please comment if you have further questions.
import npyscreen as np
class EmployeeForm(np.ActionForm):
def create(self):
self.myName = self.add(np.TitleText, name='Name')
self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
self.myDate = self.add(np.TitleDateCombo, name='Date Employed')
def afterEditing(self):
self.parentApp.getForm('CONFIRMFM').wgName.value = self.myName.value
self.parentApp.switchForm('CONFIRMFM')
class EmployeeConfirmForm(np.Form):
def afterEditing(self):
self.parentApp.setNextForm(None)
def create(self):
self.value = None
self.wgName = self.add(np.TitleFixedText, name = "Name:",)
self.wgDept = self.add(np.TitleText, name = "Dept:")
self.wgEmp = self.add(np.TitleText, name = "Employed:")
def on_cancel(self):
self.parentApp.switchFormPrevious()
class myApp(np.NPSAppManaged):
def onStart(self):
self.addForm('MAIN', EmployeeForm, name='Employee Entry')
self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
if __name__ == '__main__':
TestApp = myApp().run()
Assign values (including the value returned by addForm) to self.whatever.
So if you do
self.myAppValue = 2
self.mainForm = self.addForm('MAIN', MainForm, ...)
self.form2 = self.addForm('FORM2', Form2, ...)
you can use these in any form
self.parentApp.myAppValue
self.parentApp.mainForm.main_form_widget.main_form_value
And in myApp() you can do
self.mainForm.main_form_widget.main_form_value
I had the same problems during development as the documentation is not very detailed about passing values between forms.
I have added a few modification, the first one was changing Form to ActionForm in the confirmation form to have access to ok and cancel buttons. Secondly, the values on the confirmation form should not be editable as this is a confirmation. You can press cancel to edit on the previous form. The last one was passing the first element of the department list rather than the value - it would be just a list index. I hope it helps a little.
#!/usr/bin/env python3.5
import npyscreen as np
class EmployeeForm(np.Form):
def create(self):
self.myName = self.add(np.TitleText, name='Name')
self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
self.myDate = self.add(np.TitleDateCombo, name='Date Employed')
def afterEditing(self):
self.parentApp.switchForm('CONFIRMFM')
self.parentApp.getForm('CONFIRMFM').wgName.value = self.myName.value
self.parentApp.getForm('CONFIRMFM').wgDept.value = self.myDepartment.values[0]
self.parentApp.getForm('CONFIRMFM').wgEmp.value = self.myDate.value
class EmployeeConfirmForm(np.ActionForm):
def create(self):
self.add(np.FixedText, value="Is this correct?", editable=False)
self.wgName = self.add(np.TitleText, name = "Name:", editable=False)
self.wgDept = self.add(np.TitleText, name = "Dept:", editable=False)
self.wgEmp = self.add(np.TitleText, name = "Employed:", editable=False)
def on_ok(self):
self.parentApp.setNextForm(None)
def on_cancel(self):
self.parentApp.switchFormPrevious()
class myApp(np.NPSAppManaged):
def onStart(self):
self.addForm('MAIN', EmployeeForm, name='Employee Entry')
self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
if __name__ == '__main__':
TestApp = myApp().run()

How to create a nested dictionary from a datastore model?

I am working on this problem a couple of days, my idea is from this model:
class oceni(db.Model):
user = db.UserProperty()
weight = db.FloatProperty()
item = db.StringProperty()
..to create a dictionary in this format:
collection = dict()
collection = {
'user1':{'item1':weight1,'item2':weight2..},
'user2':{'item3':weight3,'item4':weight4..},
..}
..and as far as I reached is this:
kontenier = db.GqlQuery('SELECT * FROM oceni')
kolekcija = dict()
tmp = dict()
lista = []
for it in kontenier:
lista.append(it.user)
set = []
for e in lista:
if e not in set:
set.append(e)
for i in set:
kontenier = db.GqlQuery('SELECT * FROM oceni WHERE user=:1',i)
for it in kontenier:
tmp[it.item]=it.weight
kolekcija[i]=tmp
..but this creates a dictionary where all the users have the same dictionary with items and their weight. I know this isn't the most pythonic way, but I'm new to this so I will be eager to learn something more about this problem.
I've used your variable names your notation in this snippet.
kontenier = db.GqlQuery('SELECT * FROM oceni')
kolekcija = {}
for it in kontenier:
if it.user not in kolekcija:
kolekcija[it.user] = {}
kolekcija[it.user][it.item] = it.weight

Resources