class main_window:
def __init__(self, question):
self.question = question
def question_func(self):
return '{}'.format(self.question)
q1 = main_window('In general, my problem is related to:')
main_window.question_func(q1)
How do i assign main_window.question_func(q1) to a variable which i can call ?
Perhaps you're looking for something like this:
class main_window:
def __init__(self, question):
self.question = question
def question_func(self):
return '{}'.format(self.question)
q1 = main_window('In general, my problem is related to:')
variable = q1.question_func()
print(variable)
Output:
In general, my problem is related to:
I don't get what you're doing "main_window.question_func(q1)". Perhaps you want to create a static/class method??
I think you may be triying to do something like this:
class main_window:
def __init__(self, question):
self.question = question
def question_func(self):
def function_toBe_called():
return '{}'.format(self.question)
# question_func returns a function that
# returns a string, not a string
return function_toBe_called
And then you cand do:
q1 = main_window('In general, my problem is related to:')
variable_youCan_Call = main_window.question_func()
variable_youCan_Call()
Related
First time poster and python newbie here, this question is probably asked before, but I am not able to find any answer.
I have a Class that reads robot status data, this works fine and I am able to dive my data into methods that are working fine when i call them. But I would like to divide my class even more, so the data is structured better. for example
I have some methods the reads and return target_data
def target_joint_positions(self):
t_j_p = self.read_data()[1:7]
return t_j_p
def target_joint_velocities(self):
t_j_v = self.read_data()[7:13]
return t_j_v
def target_joint_currents(self):
t_j_c = self.read_data()[19:25]
return t_j_c
And similar methods returning actual_data:
def actual_joint_positions(self):
a_j_p = self.read_data()[31:37]
return a_j_p
def actual_joint_velocities(self):
a_j_v = self.read_data()[37:43]
return a_j_v
def actual_joint_currents(self):
a_j_c = self.read_data()[43:49]
return a_j_c
So what I would like to accomplish is that when i make a instance of my class, instead of getting all the methods i would like something like this:
inst = Class_Name()
inst.target. (list of target methods)
inst.actual. (list of actual methods)
I have looked into nested classes and inheritance but I have not been successful in achieving my goal. Thanks for any pointers.
Welcome!
You can do the following:
class TargetMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[1:7]
...
class ActualMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[31:37]
...
class RobotMetrics:
def __init__(self):
data = read_data()
self.actual = ActualMetrics(data)
self.target = TargetMetrics(data)
...
I'm currently learning how to write object oriented programming in python and I have this code I wrote (well part of it, some of it is part of the class I'm following)
class Toolbox:
def __init__(self, tool):
pass
class Hammer:
def __init__(self, color):
pass
class Screwdriver:
def __init__(self, size):
pass
class Screw:
MAX_TIGHTNESS = 5
def __init__(self):
self.tightness = 0
def loosen(self):
if (self.tightness > 0):
self.tightness -= 1
def tighten(self):
if (self.tightness < self.MAX_TIGHTNESS):
self.tightness += 1
def __str__(self):
return "Screw with tightness {}".format(self.tightness)
class Nail:
def __init__(self):
self.in_wall = False
def nail_in(self):
if (not self.in_wall):
self.in_wall = True
def remove(self):
if (self.in_wall):
self.in_wall = False
def __str__(self):
return "Nail {}in wall.".format("" if self.in_wall else "not ")
hammer = Hammer("blue")
sdriver = Screwdriver("300")
#tbox = Toolbox()
tool1 = Toolbox(hammer)
tool2 = Toolbox(sdriver)
screw1 = Screw()
print(screw1)
screw1.tighten()
print(screw1)
nail1 = Nail()
print(nail1)
nail1.nail_in
print(nail1)
The output of print(screw1) works but print(nail1) gives me the same output (Nail in wall.) twice instead Nail in wall. I guess there's a problem in my logic and I can't seem to figure it out. Can someone help me?
Thanks!
Marc
You need to call nail_in - just as you are already doing with screw1.tighten. So do this (note the brackets here):
nail1.nail_in()
With this fix, your code works:
Screw with tightness 0
Screw with tightness 1
Nail not in wall.
Nail in wall.
By referring to the function but without the brackets, it is a syntactically valid line of code, but it is just an expression for the function object itself, and as you are not doing anything with it (such as assigning it to a variable), it is then simply discarded.
I have a class called Question as per below
class Question:
q_count = 0
def __init__(self, s_id, q_id, question):
print("q count is ", Question.q_count)
self._s_id = s_id
self._question_text = question
self._answers = []
self._q_id = Question.q_count
def get_answers(self):
return self._answers
def set_answers(self,answers):
self._answers = answers
def add_answer(self, Answer()):
self._answers.append(Answer())
and I want it to have a list called _answers which is a list of Answer objects. where Answer is another type of class i have created.
class Answer:
def __init__(self, q_id, a_id):
self._q_id = q_id
self._a_id = a_id
# Subclass for multiple choice
class MC_Answer(Answer):
def __init__(self, q_id, a_id, answer_text):
Answer.__init__(self, q_id, a_id)
self._answer_text = answer_text
def get_answer_text(self):
return self._answer_text
def set_answer_text(self, a_id):
self._a_id = a_id;
In another part of my code, I am creating an instance of an MC_Answer object. I also have an instance of a question object. How do I append this onto its answers list??
answer1 = MC_Answer(idQ, 1, answer_text)
new_q.add_answer(answer1)
write_to_file(alist1, "answers.csv")
this is wrong but if i don't have answer1 as a parameter, how does Python know to add that particular instance of an answer?
Your add answer class never uses the parameter, instead you make a new instance of the Answer class and append that to the list, instead you need to modify it to give it a parameter and then use it correctly
def add_answer(self, Answer()):
self._answers.append(Answer())
should be
def add_answer(self, answer):
self._answers.append(answer)
Objective:
Given something like:
stackoverflow.users['55562'].questions.unanswered()
I want it converted into the following:
http://api.stackoverflow.com/1.1/users/55562/questions/unanswered
I have been able to achieve that, using the following class:
class SO(object):
def __init__(self,**kwargs):
self.base_url = kwargs.pop('base_url',[]) or 'http://api.stackoverflow.com/1.1'
self.uriparts = kwargs.pop('uriparts',[])
for k,v in kwargs.items():
setattr(self,k,v)
def __getattr__(self,key):
self.uriparts.append(key)
return self.__class__(**self.__dict__)
def __getitem__(self,key):
return self.__getattr__(key)
def __call__(self,**kwargs):
return "%s/%s"%(self.base_url,"/".join(self.uriparts))
if __name__ == '__main__':
print SO().abc.mno.ghi.jkl()
print SO().abc.mno['ghi'].jkl()
#prints the following
http://api.stackoverflow.com/1.1/abc/mno/ghi/jkl
http://api.stackoverflow.com/1.1/abc/mno/ghi/jkl
Now my problem is I can't do something like:
stackoverflow = SO()
user1 = stackoverflow.users['55562']
user2 = stackoverflow.users['55462']
print user1.questions.unanswered
print user2.questions.unanswered
#prints the following
http://api.stackoverflow.com/1.1/users/55562/users/55462/questions/unanswered
http://api.stackoverflow.com/1.1/users/55562/users/55462/questions/unanswered/questions/unanswered
Essentially, the user1 and user2 refer to the same SO object, so it can't represent different users.
I have been thinking any pointers to do that would be helpful, because this additional level of functionality would make the API far more interesting.
IMHO, when you recreate a new stackoverflow object, you need to separate the arguments from old instance attributes with a deep copy
import copy
........
def __getattr__(self,key):
dict = copy.deepcopy(self.__dict__)
dict['uriparts'].append(key)
return self.__class__(**dict)
....
If you want more flexibility on the URI parts, an abstraction is needed for a cleaner design. For example:
class SOURIParts(object):
def __init__(self, so, uriparts, **kwargs):
self.so = so
self.uriparts = uriparts
for k,v in kwargs.items():
setattr(self,k,v)
def __getattr__(self,key):
return SOURIParts(self.so, self.uriparts+[key])
def __getitem__(self,key):
return self.__getattr__(key)
def __call__(self,**kwargs):
return "%s/%s"%(self.so.base_url,"/".join(self.uriparts))
class SO(object):
def __init__(self, base_url='http://api.stackoverflow.com/1.1'):
self.base_url = base_url
def __getattr__(self,key):
return SOURIParts(self, [])
def __getitem__(self,key):
return self.__getattr__(key)
I hope this helps.
You could override __getslice__(Python 2.7), or getitem()(Python3.x) and use a memorizing decorator so that if the slice you request (the userid) has already been looked up it would use cached results -- otherwise it could retrieve the results and populate the existing SO instance object.
However, I think a more OO way to solve the problem is make SO a pure lookup module that returns stack overflow user objects which would then have the deeper-digging lookups for profile details. But thats just me.
Apologies if this question has already been asked but I do not think I know the correct terminology to search for an appropriate solution through google.
I would like to select an object from a list of objects by the value of it's attribute, for example:
class Example():
def __init__(self):
self.pList = []
def addPerson(self,name,number):
self.pList.append(Person(self,name,number))
class Person():
def __init__(self,name,number):
self.nom = name
self.num = number
a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)
a.pList #.... somehow select dave by giving the value 123
in my case the number will always be unique
Thanks for the help
One option is to use the next() built-in:
dave = next(person for person in a.pList if person.num == 123)
This will throw StopIteration if nothing is found. You can use the two-argument form of next() to provide a default value for that case:
dave = next(
(person for person in a.pList if person.num == 123),
None,
)
A slightly more verbose alternative is a for loop:
for person in a.pList:
if person.num == 123:
break
else:
print "Not found."
person = None
dave = person
If those nom's are unique keys, and all you are ever going to do is access your persons using this unique key you should indeed rather use a dictionary.
However if you want to add more attributes over time and if you like to be able to retrieve one or more person by any of those attributes, you might want to go with a more complex solution:
class Example():
def __init__(self):
self.__pList = []
def addPerson(self,name,number):
self.__pList.append(Person(name,number))
def findPerson(self, **kwargs):
return next(self.__iterPerson(**kwargs))
def allPersons(self, **kwargs):
return list(self.__iterPerson(**kwargs))
def __iterPerson(self, **kwargs):
return (person for person in self.__pList if person.match(**kwargs))
class Person():
def __init__(self,name,number):
self.nom = name
self.num = number
def __repr__(self):
return "Person('%s', %d)" % (self.nom, self.num)
def match(self, **kwargs):
return all(getattr(self, key) == val for (key, val) in kwargs.items())
So let's assume we got one Mike and two Dave's
a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)
a.addPerson('dave',678)
Now you can find persons by number:
>>> a.findPerson(num=345)
Person('mike', 345)
Or by name:
>>> a.allPersons(nom='dave')
[Person('dave', 123), Person('dave', 678)]
Or both:
>>> a.findPerson(nom='dave', num=123)
Person('dave', 123)
The terminology you need is 'map' or 'dictionnary' : this will lead you to the right page in the python doc.
Extremely basic example:
>>> a = {123:'dave', 345:'mike'}
>>> a[123]
'dave'
The missing underscore makes plist a public property. I don't think that's what you want, since it does not encapsulate the functionality and you could call a.plist.append instead of a.addPerson.
class Example():
...
def filter(self, criteria):
for p in self.plist:
if criteria(p):
yield p
def getByNum(self, num):
return self.filter(lambda p: p.num == num)
dave = next(a.getByNum(123))
If the numbers are unique, you may also consider using a dictionary that maps from number to name or person instead of a list. But that's up to your implementation.