Python GAE extend db.Property and add a method [duplicate] - python

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Google App Engine - how to extend db.IntegerProperty
This is most likely a more general Python query.
I was attempting to inherit and extend one of the db.Property classes in GAE by adding a method that will return an integer representation of a special String value for example:
class DbHHMM(db.StringProperty):
def to_mins(self):
'''Convert the string to minutes'''
arr = re.split(":",self)
ret = 0.0
if (len(arr)==2):
ret = (int(arr[0])*60)+(int(arr[1]))
return ret;
In my model I have a method that sums up a series of these values eg:
class WorkSchedule(db.Model):
'''todo - core hours for the days
TODO is there any way to attach a widgeted form to these via newform = WorkScheduleForm() '''
time1 = DbHHMM()
time2 = DbHHMM()
total = db.IntegerProperty
def sum_times:
self.total = time1.to_mins + time2.to_mins
However when sum_times is called I seem to get the error:
AttributeError: 'unicode' object has no attribute 'to_mins'
Is it possible to add extra methods to the GAE Property classes what are the Python techniques that have been used to prevent this? Am I doing something totally wrong?

Would you mind posting your actual code? your "def sum_times:" is not even valid Python.
My guess is that you want this, and it'll work fine:
class WorkSchedule(db.Model):
time1 = DbHHMM()
time2 = DbHHMM()
total = db.IntegerProperty() # ADDED ()
def sum_times(self): # ADDED (self)
self.total = self.time1.to_mins() + self.time2.to_mins() # ADDED self...() twice

Related

Function not working properly inside a class instance [duplicate]

This question already has answers here:
How to change a module variable from another module?
(3 answers)
Closed last year.
I have this module which stores a class, an instance of that class, a counter, and a dictionary:
#test_module.py:
class TestClass:
def __init__(self, name='name', attr='attr'):
self.name = name
self.attr = attr
def func(self, test_list):
test_dict[count] = test_list[-1].name + '_' + test_list[-1].attr
test_inst = TestClass()
count = 0
test_dict = {}
What I want is for the dictionary to store each consecutive value of the counter (1,2,3...) as a key and the name and attribute of the last class instance in a test_list. (All the code here is simplified for the sake of reproducing the problem, the actual number of classes and instances is greater).
In a notebook, I have the following code:
from test_module import *
test_list = []
test_list.append(test_inst)
count += 1
test_list_item = test_list[-1]
test_dict[count] = test_list_item.name + '_' + test_list_item.attr
test_list.append(test_inst)
count += 1
test_list_item = test_list[-1]
test_list_item.func(test_list)
What now is in the dictionary is:
{1: 'name_attr', 0: 'name_attr'}
Why am I getting zero as the second key?
I've tried specifying the count and the test_dict as global variables in the TestClass definition, but to no avail.
All works OK if I copy the contents of the test_module into the notebook, but this is not what I'm after. My goal is to have as much code as possible in the test_module. What am I doing wrong? How can I make it work properly?
I just copied your code and the output is
{1: 'name_attr', 2: 'name_attr'}

Python 3 - Does the direct manipulation of a class' attribute override the same attribute for its objects making the attribue purely static?

While learning about how classes work in Python I came across a class definition example which behaved kind of strangely in my eyes.
The purpose of the example was to demonstrate how the behaviour of a static variable can be achieved in Python. The example was written as follows:
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
after setting up the class and creating the objects, I printed the values of the 'members' attribute. These were the results:
MemberCounter.members = 2
m1.members = 2
m2.members = 2
And that's when I got confused. While I was expecting for 'MemberCounter.members = 2' the two other results made no sense to me - why would both of 'm1' and 'm2' objects' 'members' value be equal to 2? I thought that both of the values should have been 0 - if the only attribute that was chaged is the 'members' attribute which was attached to the MemberCounter class why would it cause any change to the own unique 'members' value of each of the class' objects. It looks like the fact that the 'members' attribute is addresed like 'MemberCounter.members += 1' in the init() function of each object, completely overrides the unique values which m1.members and m2.members refer to and redirects their pointers to the MemberCounter.members value making all the three pointers point at the same value
==> m1.members = m2.members = MemberCounter.members.
Moreover, I have tried defining the class in an opossite way (Increasing self.members instead of MemberCounter.members):
class MemberCounter:
members = 0
def init(self):
self.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
This definition yielded logical results (which got me curious about the above mentioned strange behaviour even more):
MemberCounter.members = 0
m1.members = 1
m2.members = 1
In short, I was curious about why the first class definition behaves in such a strange way? Why the mere 'MemberCounter.members += 1' statement completely erased 'm1.members' and 'm2.members' own unique value and made it equal to the MemberCounter.members value.
I hope I was able to clearly present my problem and I will be extremly happy to get an insight about this strange behaviour :)
That you can read a static attribute with instance.attribute notation as alternative to the more natural class.attribute notation, is an intended feature in Python.
From the documentation:
Both static data and static methods (in the sense of C++ or Java) are supported in Python.
For static data, simply define a class attribute. To assign a new
value to the attribute, you have to explicitly use the class name in
the assignment:
class C:
count = 0 # number of times C.__init__ called
def __init__(self):
C.count = C.count + 1
def getcount(self):
return C.count # or return self.count
c.count also refers to C.count for any c such that
isinstance(c, C) holds, unless overridden by c itself or by some
class on the base-class search path from c.__class__ back to C.
Caution: within a method of C, an assignment like self.count = 42
creates a new and unrelated instance named “count” in self’s own dict.
Rebinding of a class-static data name must always specify the class
whether inside a method or not:
C.count = 314
The paragraph just below the first code block explains your doubts. The "Caution" paragraph explains what you found logical.

Should a class to have several attributes or one attribute as dictionary with many keys, Python3

I have class for calculating temperatures of an object at different positions, based on ambient temperature. I have two ways of implementation. In BodyA, the temperature of each position is an attribute of the class; while in BodyB, there is an attribute pos_t, which is a dict, and the temperature of each position is just a key-value pair in the dict.
class BodyA:
def __init__(self, ambient_temperature)
self.amb_t = ambient_temperature
self.pos1_t = self.amb_t + 1
self.pos2_t = self.amb_t * 2
self.pos3_t = self.pos1_t + self.pos2_t - 5
class BodyB:
def __init__(self, ambient_temperature)
self.amb_t = ambient_temperature
self.pos_t = dict()
self.pos_t['pos1'] = self.amb_t + 1
self.pos_t['pos2'] = self.amb_t * 2
self.pos_t['pos3'] = self.pos_t['pos1'] + self.pos_t['pos2'] - 5
In practical case, there are up-to 10 positions, and I want to build child-class from it. And some child-classes do not have certain positions. For example, pos2 can be missing in some child.
Could you please let me know, which design is better in terms of OOP and efficiency. Thanks.
A data structure to store some custom identifiers that may or may exist calls clearly for a dict. As class attributes are also stored in an internal dict, the first approach can be used too, but to have pratical manipulation without explicit hand writing the members will require different code. I suspect performance will not matter. If you find it matters, maybe a redesign of the data structure that does not use classes at all will do, as object creation processing time may be relevant then.

Python: Object does not support indexing

Yes, this question has been asked before. No, none of the answers I read could fix the problem I have.
I'm trying to create a little Bounce game. I've created the bricks like this:
def __init__(self,canvas):
self.canvas = canvas
self.brick1 = canvas.create_rectangle(0,0,50,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick2 = canvas.create_rectangle(50,0,100,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick3 = canvas.create_rectangle(100,0,150,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick4 = canvas.create_rectangle(150,0,200,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick5 = canvas.create_rectangle(200,0,250,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick6 = canvas.create_rectangle(250,0,300,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick7 = canvas.create_rectangle(300,0,350,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick8 = canvas.create_rectangle(350,0,400,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick9 = canvas.create_rectangle(400,0,450,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick10 = canvas.create_rectangle(450,0,500,20,fill=random_fill_colour(),outline=random_fill_colour())
self.bricksId = [self.brick1,self.brick2,self.brick3,self.brick4,self.brick5,self.brick6,self.brick7,self.brick8,self.brick9,self.brick10]
And I'm trying to reference the ID of bricksId[0] over here:
self.hit_brick(pos,self.bricks.bricksId[0])
Earlier, in the __init__, I define bricks as bricks, which is defined as Brick(canvas). However, the error states:
TypeError: 'Brick' object does not support indexing
In the answers to the other questions of this subject, I cannot find any that help me access bricks.bricksId[0].
In order for the Brick object to be indexable, you must implement the methods:
__getitem__
__setitem__
__delitem__
You don't need all of them, only the ones you use.
However, this seems like a case of self.bricks being a brick instead of a list of bricks. A list of bricks is indexable; however, a brick itself is not unless you implement the methods above.
Check this for reference.
In order to be able to call self.bricks.bricksId[number] when I needed:
def __getitem__(self,index):
return self.bricks.bricksId[index]
def __setitem__(self,index,value):
self.bricks.bricksId[index] = value

Python - Class and function

Doing a class and finished with the rest less this one. Any guidance is appreciated. I have derived part of the question where I am stuck with to keep it short. I have also attached my working. Question as follows:
Create a class with 1 variable in it holding its own properties.
Provide the following 3 methods:
getvariable1() - use return key tp return value of property 1
setvariable1() - This should allow new value to be specified for property 1 - additional parameter needed to accept input.
printerfun() - to print values of the variables for the object.
Create your own object of the class and call get & set methods for the object created. Use printerfun() method to check if the codes works.
My working:
class animal:
horns = 2
def printerfun(self):
print getHorns()
def getHorns(self): #don't get where I should call this
return self.horns
def setHorns(horns):
self.horns = horns
animal_1 = animal()
F1 = raw_input('Please enter number of horns: ')
setHorns(F1)
Not sure what the question is, but anyway...
You should write a __init__ member function to create the initial member variables:
class animal:
def __init__(self):
self.horns = 2
Your code creates a class variable, not a normal member variable.
Then change the horns with:
animal_1.setHorns(F1)
Your code doesn't say which animal you want to change the variable to.

Categories

Resources