Update an attribute each time the class constructor is invoked - python

I have this class in Python. (Removed the unecessary parts)
class Spillebrett:
def __init__(self, rader, kolonner):
self._rader = rader
self._kolonner = kolonner
self._generasjonsnummer = 0
I need to add 1 to _generasjonsnummer everytime i run the class. If i try _generasjonsnummer += 1 i get an error. I tried to make a def addGenerasjonsnummer() and call it in the init like so:
class Spillebrett:
def __init__(self, rader, kolonner):
self._rader = rader
self._kolonner = kolonner
self._generasjonsnummer = 0
addGenerasjonsnummer()
def addGenerasjonsnummer():
self._generasjonsnummer += 1
But i cant call on functions in the init. What i need is for this number to update to +=1 each time i start the init, how do i do this?

If your class has an attribute that is going to be incremented each time the constructor is called, then you should disassociate it with any instance to begin with. In other words, declare it as a class attribute, outside __init__.
I'd recommend something along these lines:
In [625]: class Spillebrett:
...: ctr = 0
...: def __init__(self):
...: print(Spillebrett.ctr)
...: Spillebrett.ctr += 1
...:
In [626]: Spillebrett()
0
Out[626]: <__main__.Spillebrett at 0x10b918da0>
In [627]: Spillebrett()
1
Out[627]: <__main__.Spillebrett at 0x109f1af98>
In [628]: Spillebrett()
2
Out[628]: <__main__.Spillebrett at 0x10b918470>

Related

Timer Threading - AttributeError '...' has no attribute '...'

As I'm new in python maybe I'm missing the obvious.
I've wrote the updateRates method for the class which counts fps in this RDP program.
When I try to access some attributes from inside the call from the timer method there is this weird Error:
"AttributeError: type object 'RDCToGUI' has no attribute '_cnt_framerate'"
it is really obvious this class inherits this attribute, but in the Timer thread it doesn't seem to be there anymore
So the problem is: I can call the inherited methods of the super (e.g. self.rates) but inside some attributes aren't present in the method
class RDCToGUI(clientProtocol.rdc):
def __init__(self):
clientProtocol.rdc.__init__(self)
self.num = 0
self.count = 0
self.framerate_before = 0
def updateRates(self, framerate_label, datarate_label):
divisor = 1
datarate_text = "b/s"
self.rates(self)
framerate = self.framerate
datarate = self.datarate
if self.logged_in == 1 and self.framerate_before == 0 == framerate:
self.framebufferUpdateRequest(
width=800, height=800)
if datarate > 1000000:
divisor = 1000000
rateText = "Mb/s"
elif datarate > 1000:
divisor = 1000
rateText = "Kb/s"
self.framerate_before = framerate
framerate_label.setText(f"Framerate: {framerate}")
datarate_label.setText(
f"Datarate: {round(datarate / divisor, 2)} {datarate_text}")
threading.Timer(1, self.updateRates, args=(self,
framerate_label, datarate_label)).start()
class rdc(Protocol):
def __init__(self):
self._packet = ""
self._expected_len = 0
self._cnt_framerate = 0
self._cnt_datarate = 0
self.framerate = 0
self.datarate = 0
self.logged_in = 0
def rates(self):
self.setRates(self)
self.resetCounter(self)
def setRates(self):
self.framerate = self._cnt_framerate
self.datarate = self._cnt_datarate
def resetCounter(self):
self._cnt_datarate = 0
self._cnt_framerate = 0
def incFramerate(self):
self._cnt_framerate += 1
def addDataSize(self, size):
self._cnt_datarate += size
The classes have more methods and members than what I showed, but wanted to cut it to the most important stuff.
Tried to put the method in different classes and played around with the names of the attributes
class rdc is in another file which is imported as clientProtocol.
This seems like an inheritance issue. Maybe try replacing
clientProtocol.rdc.__init__(self)
with
super(RDCToGUI, self).__init__()
I'm not an expert on inheritance either and haven't really used it, but there is a ton to read on the super() function and you could maybe start at Understanding Python super() with __init__() methods and just follow it down the rabbit hole :)

Class Variable Updating

I built a class to handle a lot of different functions that take common inputs. However, I just ran into the situation where one of the variables that's fed down through self needs to be changed. How do I do this? This is an example:
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
#property
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
Thank you!
You should drop the #property attribute. Then, you can set it by just doing x.test_var = 5. E.g.,
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
x = Test(-1)
print(x.some_function())
x.test_var = 5
print(x.some_function())
returns
New Output
5

calling a method inside a class-Python

class Time:
def __init__(self,x,y,z):
self.hour=x
self.minute=y
self.second=z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(time):
minutes=time.hour*60+time.minute
seconds=minutes*60+time.second
return seconds
def int_to_time(seconds):
time=Time()
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(t1,t2):
seconds=time_to_int(t1)+time_to_int(t2)
return int_to_time(seconds)
start=Time(9,45,00)
running=Time(1,35,00)
done=add_time(start,running)
print(done)
I am new to python and i've been doing some practice lately.I came across a question and i've written the code for the same.But I am repeatedly getting an error: "add_time is not defined". I tried defining a main() method but then it doesn't print anything.Please help.
You haven't created an object to the above class.
Any function/method inside a class can only be accessed by an object of that class .For more information on the fundamentals of Object Oriented Programming, please check this page.
Meanwhile for this to work, define your class in the following way :
class Time:
def __init__(self,x=None,y=None,z=None):
self.hour=x
self.minute=y
self.second=z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(time):
minutes=time.hour*60+time.minute
seconds=minutes*60+time.second
return seconds
def int_to_time(seconds):
time=Time()
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(t1,t2):
seconds=time_to_int(t1)+time_to_int(t2)
return int_to_time(seconds)
and outside the class block, write the following lines :
TimeObject = Time()
start=Time(9,45,00)
running=Time(1,35,00)
TimeObject.add_time(start,running)
print "done"
I however suggest you to write the add_time function outside the class because you are passing the objects to the class as the parameters to the function within the same class and it is considered as a bad design in object oriented programming.
Hope it helps. Cheers!
This works fine for me as long as you specified 3 args in your constructor
def int_to_time(seconds):
time=Time(0,0,0) # just set your 3 positionals args here
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
Another way to avoid it could be:
class Time:
def __init__(self,x=0,y=0,z=0):
self.hour=x
self.minute=y
self.second=z
If you want to add your functions to your class (such as time_to_int, int_to_time or even add_time) then you will need to indent with one more level of 4 spaces and add self to your method parameters
Hii Mathers25,
I solve your problem try this below code to get the best output,
class TimeClass:
def __init__(self,x,y,z):
self.hour = x
self.minute = y
self.second = z
def __str__(self):
return "({:02d}:{:02d}:{:02d})".format(self.hour, self.minute, self.second)
def time_to_int(self,time):
minutes = (time.hour * 60) + time.minute
seconds = (minutes * 60) + time.second
return seconds
def int_to_time(self,seconds):
time = TimeClass(0,0,0)
minutes,time.second=divmod(seconds,60)
time.hour,time.minute=divmod(minutes,60)
return time
def add_time(self,t1,t2):
seconds = self.time_to_int(t1) + self.time_to_int(t2)
# Call method int_to_time() using self keyword.
return self.int_to_time(seconds)
# First time object create that time set value is 0 of hour,minute and second
TimeObject = TimeClass(0,0,0)
# After create second object
start=TimeClass(9,45,00)
# After create thired Object
running=TimeClass(1,35,00)
# Store the value which return by add_time()
done = TimeObject.add_time(start,running)
# Display the value of done variable
print(done)
class Employee:
def __init__(self):
self.wage = 0
self.hours_worked = 0
def calculate_pay(self):
return self.wage * self.hours_worked
alice = Employee()
alice.wage = 9.25
alice.hours_worked = 35
print('Alice:\n Net pay: {:.2f}'.format(alice.calculate_pay()))
barbara = Employee()
barbara.wage = 11.50
barbara.hours_worked = 20
print('Barbara:\n Net pay: {:.2f}'.format(barbara.calculate_pay()))
Works for me:
class C:
def f(a, b):
return a + b
x = f(1,2)
print(C.x)
but you should not do such things. Code in class-level is executing when class is "creating", usually you want static methods or class methods (decorated with #staticmethod or #classmethod) and execute code in some function/instantiated class. Also you can execute it on top (module) level if this is the simple script. Your snippet is "bad practice": class level (i'm talking about indentation) is for declarations, not for execution of something. On class-level is normal to execute code which is analogue of C macros: for example, to call decorator, to transform some method/attribute/etc - static things which are "pure" functions!

Python pass a class reference to another class during construction

I'm intending to create a data distributor class as a mutable class:
class DataDistributor(object):
def __init__(self):
self.target_trackid = -1
def next_sen(self):
self.target_trackid += 1
return self.target_trackid
So that I can globally keep a pointer on my data.
I have another class:
class Env(object):
def __init__(self, distributor):
self.distributor = distributor
self.target_trackid = 0 # init
def reset(self):
self.target_trackid = self.distributor.next_sen()
So that when I create many Env instances, each Env instance will get a different data point.
So I use this to create my instances:
ddist = DataDistributor()
env = Env(ddist)
envs = [pickle.loads(pickle.dumps(env)) for _ in range(12)]
envs[0].reset()
envs[1].reset()
envs[2].reset()
print envs[0].target_trackid
print envs[1].target_trackid
print envs[2].target_trackid
And the results are all the same: a bunch of 0s.
I'm not exactly sure how Python is handling this :( and if there is a viable solution to achieve what I want to achieve!
How about creating a class variable for keeping track of the objects created? Your simple class structure will be like:
class Env(object):
my_counter = 0 # Your class variable
def __init__(self, param1, param2):
# some initialization
Env.my_counter += 1 # increament everytime object is created
# some logic
Sample run:
>>> e1 = Env('p11', 'p12') # creation of first object
>>> Env.my_counter
1 # value of counter set as 1
>>> e1 = Env('p21', '22') # creation of second object
>>> Env.my_counter
2 # value of counter set as 2
Passing object of different class just for tracking the created object of some other class, it is definitely not the right approach.
pickle.load will create different objects which means the datadistributor variable in each env object will refere

When do you use instances? Python 3

I'm trying to understand when you would want to have an instance of a class, and what exactly the difference is between these two variations of code:
Class A takes a time and and assigns it to a new variable, and then returns that new variable.
class A:
def B(time):
seconds = time
return seconds
seconds = A.B(int)
Class C takes a time in as well, but also creates an instance of function D (using self) and then returns self.seconds.
class C:
def D(self, time):
self.seconds = time
return self.seconds
seconds = C().D(int)
They end up returning the same values. I'm have difficulty understanding how these two pieces of code are different. Is one superior in certain situations vs. the other?
Thank you!
EDIT: Added calls to both functions.
Perhaps the following (very simplified) example helps to see where it can be useful to have an instance of a class:
class A:
minutes = 2
def time(seconds):
return 60*A.minutes + seconds
class B:
minutes = 2
def time(self, seconds):
return 60*self.minutes + seconds
print("Class:")
print(A.time(30))
a1 = A
a2 = A
a1.minutes = 3
a2.minutes = 4
print(a1.time(30)) # 60*4 + 30
print(a2.time(30)) # 60*4 + 30
print("Instance:")
print(B().time(30))
b1 = B()
b2 = B()
b1.minutes = 3
b2.minutes = 4
print(b1.time(30)) # 60*3 + 30
print(b2.time(30)) # 60*4 + 30
This results in:
Class:
150
270
270
Instance:
150
210
270
At the core, what you are asking for is understanding the difference between a Static Method and a normal Method, and what the advantages of OOP are.
A Static method can be called without instantiating the class, such as in your first example. This allows you to group related functions under a single header (the class), but it is not, technically, OOP.
However, a Static method has no instance data to act upon, as there is no instance.
A class instance allows you to keep track of Object specific data, and act upon them within your methods.
For example:
import time
class Stopwatch:
def __init__(self, name, start):
self.name = name
self.time = start
self.active = False
def start(self):
self.active = True
def stop(self):
self.active = False
def reset(self, time):
self.time = time
def isComplete(self):
return (self.time == 0)
def tick(self):
if self.active:
self.time -= 1
print(self.name+": ",self.time)
if self.time == 0:
print("Timer of " + self.name + " has reached zero!")
self.stop()
watchA = Stopwatch("A", 10)
watchB = Stopwatch("B", 5)
watchA.start()
watchB.start()
while (not watchA.isComplete()) or (not watchB.isComplete()):
time.sleep(1)
watchA.tick()
watchB.tick()
Running this outputs:
A: 9
B: 4
A: 8
B: 3
A: 7
B: 2
A: 6
B: 1
A: 5
B: 0
Timer of B has reached zero!
A: 4
A: 3
A: 2
A: 1
A: 0
Timer of A has reached zero!
Notice how the time of each watch is tracked separately, despite using the same code. This would not be possible using Static methods, as the data is attached not to the Class, but to the Instanced objects themselves.

Categories

Resources