Python27: random() after a setstate() doesn't produce the same random number - python

I have been subclassing an Python's random number generator to make a generator that doesn't repeat results (it's going to be used to generate unique id's for a simulator) and I was just testing to see if it was consistent in it's behavior after it has been loaded from a previours state
Before people ask:
It's a singleton class
No there's nothing else that should be using that instance (a tear down sees to that)
Yes I tested it without the singleton instance to check
and yes when I create this subclass I do call a new instance ( super(nrRand,self).__init__())
And yes according to another post I should get consistent results see: Rolling back the random number generator in python?
Below is my test code:
def test_stateSavingConsitantcy(self):
start = int(self.r.random())
for i in xrange(start):
self.r.random()
state = self.r.getstate()
next = self.r.random()
self.r.setstate(state)
nnext = self.r.random()
self.assertEqual(next, nnext, "Number generation not constant got {0} expecting {1}".format(nnext,next))
Any help that can be provided would greatly appreciated
EDIT:
Here is my subclass as requested
class Singleton(type):
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton,self).__call__(*args,**kwargs)
return self._instances[self]
class nrRand(Random):
__metaclass__ = Singleton
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
super(nrRand,self).__init__()
self.previous = []
def random(self):
n = super(nrRand,self).random()
while n in self.previous:
n = super(nrRand,self).random()
self.previous.append(n)
return n
def seed(self,x):
if x is None:
x = long(time.time()*1000)
self.previous = []
count = x
nSeed = 0
while count < 0:
nSeed = super(nrRand,self).random()
count -= 1
super(nrRand,self).seed(nSeed)
while nSeed < 0:
super(nrRand,self).seed(nSeed)
count -= 1
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
def setstate(self,state):
self.previous = state[0]
super(nrRand,self).setstate(state[1])

getstate and setstate only manipulate the state the Random class knows about; neither method knows that you also need to roll back the set of previously-generated numbers. You're rolling back the state inherited from Random, but then the object sees that it's already produced the next number and skips it. If you want getstate and setstate to work properly, you'll have to override them to set the state of the set of already-generated numbers.
UPDATE:
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
This shouldn't directly use self.previous. Since you don't make a copy, you're returning the actual object used to keep track of what numbers have been produced. When the RNG produces a new number, the state returned by getstate reflects the new number. You need to copy self.previous, like so:
def getstate(self):
return (self.previous[:], super(nrRand, self).getstate())
I also recommend making a copy in setstate:
def setstate(self, state):
previous, parent_state = state
self.previous = previous[:]
super(nrRand, self).setstate(parent_state)

Related

Class that tracks data of all its active instantiations?

I have a class Foo with its instances having a "balance" attribute. I'm designing it in such a way that Foo can track all the balances of its active instances. By active I mean instances that are currently assigned to a declared variable, of part of a List that is a declared variable.
a = Foo(50) # Track this
b = [ Foo(20) for _ in range(5) ] # Track this
Foo(20) # Not assigned to any variable. Do not track this.
Another feature of Foo is that is has an overloaded "add" operator, where you can add two Foo's balances together or add to a Foo's balance by adding it with an int or float.
Example:
x = Foo(200)
x = x + 50
y = x + Foo(30)
Here is my code so far:
from typing import List
class Foo:
foo_active_instances: List = []
def __init__(self, balance: float = 0):
Foo.foo_active_instances.append(self)
self.local_balance: float = balance
#property
def balance(self):
"""
The balance of only this instance.
"""
return self.local_balance
def __add__(self, addend):
"""
Overloading the add operator
so we can add Foo instances together.
We can also add more to a Foo's balance
by just passing a float/int
"""
if isinstance(addend, Foo):
return Foo(self.local_balance + addend.local_balance)
elif isinstance(addend, float | int):
return Foo(self.local_balance + addend)
#classmethod
#property
def global_balance(cls):
"""
Sum up balance of all active Foo instances.
"""
return sum([instance.balance for instance in Foo.foo_active_instances])
But my code has several issues. One problem is when I try to add a balance to an already existing instance, like:
x = Foo(200)
x = x + 50 # Problem: This instantiates another Foo with 200 balance.
y = Foo(100)
# Expected result is 350, because 250 + 100 = 350.
# Result is 550
# even though we just added 50 to x.
print(Foo.global_balance)
Another problem is replacing a Foo instance with None doesn't remove it from Foo.foo_active_instances.
k = Foo(125)
k = None
# Expected global balance is 0,
# but the balance of the now non-existing Foo still persists
# So result is 125.
print(Foo.global_balance)
I tried to make an internal method that loops through foo_active_instances and counts how many references an instance has. The method then pops the instance from foo_active_instance if it doesn't have enough. This is very inefficient because it's a loop and it's called each time a Foo instance is made and when the add operator is used.
How do I rethink my approach? Is there a design pattern just for this problem? I'm all out of ideas.
The weakref module is perfect for this design pattern. Instead of making foo_active_instances a list, you can make it a weakref.WeakSet. This way, when a Foo object's reference count falls to zero (e.g., because it wasn't bound to a variable), it will be automatically removed from the set.
class Foo:
foo_active_instances = weakref.WeakSet()
def __init__(self, balance: float = 0) -> None:
Foo.foo_active_instances.add(self)
...
In order to add Foo objects to a set, you'll have to make them hashable. Maybe something like
class Foo:
...
def __hash__(self) -> int:
return hash(self.local_balance)
You can use inspect to check if the __init__ or __add__ methods have been called as part of an assignment statement. Additionally, you can keep a default parameter in __init__ to prevent increasing your global sum by the value passed to it when creating a new Foo object from __add__:
import inspect, re
def from_assignment(frame):
return re.findall('[^\=]\=[^\=]', inspect.getframeinfo(frame).code_context[0])
class Foo:
global_balance = 0
def __init__(self, balance, block=False):
if not block and from_assignment(inspect.currentframe().f_back):
Foo.global_balance += balance
self.local_balance = balance
def __add__(self, obj):
if from_assignment(inspect.currentframe().f_back) and not hasattr(obj, 'local_balance'):
Foo.global_balance += obj
return Foo(getattr(obj, 'local_balance', obj), True)
a = Foo(50)
b = [Foo(20) for _ in range(5)]
Foo(20)
print(Foo.global_balance) #150
x = Foo(200)
x = x + 50
y = Foo(100)
print(Foo.global_balance) #350

Nested classes — can't understand their functionality

I'm learning about classes in Python, particularly about nested classes.
I'm trying to execute the below code and I get an error: int object is not callable, but
I don't understand why!
All I want is to create an object that identify Man, and he has hands, and the hands have their own size, length, etc...
I want to be able to set the hand size and get its value in the most elegant and easy way as possible and nothing work for me... I tried the below code and I really thought it would work but it didn't and now I know that "I Don't know" what to do for real.
class Man:
def __init__(self, name):
self.name = name
self.hand = self.Hand_Object() # Here we reference an Object called
# "hand" to the subvlass "Hand_Object".
def length(self , length):
self.length = length
def handsize(self, size=None): # This "handsize()" function will call the
# subclass function "length()" out from the
# Hand_Object vlass when it will be issued
# in the program.
if size==None:
return = self.hand.length()
else:
self.hand.length(size) # The "length()" function of the "Hand_Object"
# class requires a variable, so when we call
# that function we need to add a variable to it.
class Hand_Object:
def length(self, length=None):
if length == None:
return self.length
else:
self.length = length
def fingers(self, fingers):
self.fingers = fingers
myman = Man('shlomi')
myman.handsize(6)
print(myman.handsize()) # Here I get the error.
The issue is the line self.length = length in Hand_Object. You're overwriting the function length with an integer. You should call the function and the variable something different.

Stack data structure in Python using lists

For the stack class below
class stack(list):
def __init__(self):
self.stack = []
self.top = -1
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
S = stack()
S.isempty() #True
S.push(5) #[5]
S.push(100) #[5,100]
print(S) # Returns empty stack []
Why does it not return the updated [5,100]?
The problem that you're asking about is that you're inheriting from list, even though you're not trying to act like a list. All this is doing is causing confusion. In particular, you're letting the list superclass define how your objects get displayed, and since you never do anything like self.append, only self.stack.append, that means it's always going to display like an empty list.
Once you fix that, your objects will always print something like this:
<__main__.stack at 0x11d919dd8>
If you want to customize that, you need to write a __repr__ method, and decide what you want it to look like.
class stack:
def __init__(self):
self.stack = []
self.top = -1
def __repr__(self):
return f'<stack({self.stack})>'
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
There are additional bugs in your code—you've still got a method that mutates the global S instead of self, and you're returning the result of list.append, which always returns None, and maybe more beyond—but these two changes will together solve the specific problem you're asking about.

How to Instantiate a Completely Fresh Temporary Object that Contains Lists

I'm currently using Python to parse CAN database files. I ran into a problem with lists during implementation and gave it a quick patch that makes it work, but it's kind of ugly and seems as if there's a more elegant solution.
I have defined an object CAN database and one of it's methods takes the file to be parsed, which contains definitions of messages in the database. I loop through each line in the file and when I come across a line indicating a message description, I create a temporary variable referencing an object I've defined for CAN messages, some of the members of which are lists. I put elements in these lists with a method based on the next handful of lines in the file.
Now when I'm done with this temporary object, I add it to the CAN database object. Since I no longer need the data referenced by this variable, I assign the value None to it and reinstantiate the clean slate variable on the next iteration through that detects a message descriptor. Or that was the plan.
When I go through the next iteration and need to use this variable, I add some values to these lists and find that they're not actually empty. It seems that despite assigning the variable to reference None the values in the lists persisted and were not cleaned up.
Below you can see my solution which was to stack more methods on specifically to get rid of the persisting list elements.
Here's some relevant portions of the file:
Parsing Loop
for line in file:
line = line.rstrip('\n')
line_number += 1 # keep track of the line number for error reporting
if line.startswith("BU_:"):
self._parseTransmittingNodes(line)
elif line.startswith("BO_"):
can_msg = self._parseMessageHeader(line).ResetSignals().ResetAttributes()
building_message = True
elif line.startswith(" SG_") and building_message:
can_msg.AddSignal(self._parseSignalEntry(line))
# can_msg.updateSubscribers()
elif line == "":
if building_message:
building_message = False
self._messages += [can_msg]
can_msg = None
Reset Methods
def ResetSignals(self):
"""
Flushes all the signals from the CANMessage object.
"""
self._signals = []
return self
def ResetAttributes(self):
"""
Flushes all the attributes from the CANMessage object.
"""
self._attributes = []
return self
How can I make this variable a fresh object every time? Should I have a method that clears all of it's internals instead of assigning it None like the IDispose interface in C#?
EDIT: Here's the full source for the CANMessage object:
class CANMessage:
"""
Contains information on a message's ID, length in bytes, transmitting node,
and the signals it contains.
"""
_name = ""
_canID = None
_idType = None
_dlc = 0
_txNode = ""
_comment = ""
_signals = list()
_attributes = list()
_iter_index = 0
_subscribers = list()
def __init__(self, msg_id, msg_name, msg_dlc, msg_tx):
"""
Constructor.
"""
self._canID = msg_id
self._name = msg_name
self._dlc = msg_dlc
self._txNode = msg_tx
def __iter__(self):
"""
Defined to make the object iterable.
"""
self._iter_index = 0
return self
def __next__(self):
"""
Defines the next CANSignal object to be returned in an iteration.
"""
if self._iter_index == len(self._signals):
self._iter_index = 0
raise StopIteration
self._iter_index += 1
return self._signals[self._iter_index-1]
def AddSignal(self, signal):
"""
Takes a CANSignal object and adds it to the list of signals.
"""
self._signals += [signal]
return self
def Signals(self):
"""
Gets the signals in a CANMessage object.
"""
return self._signals
def SetComment(self, comment_str):
"""
Sets the Comment property for the CANMessage.
"""
self._comment = comment_str
return self
def CANID(self):
"""
Gets the message's CAN ID.
"""
return self._canID
def AddValue(self, value_tuple):
"""
Adds a enumerated value mapping to the appropriate signal.
"""
for signal in self:
if signal.Name() == value_tuple[0]:
signal.SetValues(value_tuple[2])
break
return self
def AddAttribute(self, attr_tuple):
"""
Adds an attribute to the message.
"""
self._attributes.append(attr_tuple)
return self
def ResetSignals(self):
"""
Flushes all the signals from the CANMessage object.
"""
self._signals = []
return self
def ResetAttributes(self):
"""
Flushes all the attributes from the CANMessage object.
"""
self._attributes = []
return self
def Name(self):
return self._name
def TransmittingNode(self):
return self._txNode
def DLC(self):
return self._dlc
The problem you're seeing is because you used class attributes instead of instance attributes. If you move the initialization of the attributes you don't pass to __init__ from class scope into __init__, each instance will have its own set of lists.
Here's what that would look like:
class CANMessage:
"""
Contains information on a message's ID, length in bytes, transmitting node,
and the signals it contains.
"""
def __init__(self, msg_id, msg_name, msg_dlc, msg_tx):
"""
Constructor.
"""
self._canID = msg_id
self._name = msg_name
self._dlc = msg_dlc
self._txNode = msg_tx
self._name = ""
self._canID = None
self._idType = None
self._dlc = 0
self._txNode = ""
self._comment = ""
self._signals = list()
self._attributes = list()
self._iter_index = 0
self._subscribers = list()
# the rest of the class is unchanged, and not repeated here...

Python 2.7, what's the benefit of this kind of initialization in class?

class LogicGate(object):
def __init__(self, n):
self.label = n
self.output = None # ????????????
def getOutput(self):
self.output = self.performGateLogic()
return self.output
def getLabel(self):
return self.label
class BinaryGate(LogicGate):
def __init__(self, n): # ?????????????????
LogicGate.__init__(self, n)
self.pinA = None # ??????????????
self.pinB = None # ??????????????
def getPinA(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
def getPinB(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
class UnaryGate(LogicGate):
def __init__(self, n): # ??????????????
LogicGate.__init__(self, n)
self.pin = None # ?????????????
def getPin(self):
return int(raw_input('Enter Pin input for gate' + self.getLabel() + '-->'))
class AndGate(BinaryGate):
def __init__(self, n): # ????????????
BinaryGate.__init__(self, n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a == 1 and b == 1:
return 1
else:
return 0
This code belongs to Problem Solving with Algorithms and Date Structures.
When I remove the lines before the comment '# ????????', the code can run normally.
Why does the author write the code like this?
Whether is it a good code style?
Can I always remove these lines before the comment '# ????????' ?
The author writes the code like that because it is good practice to never have uninitialised members and class parents, static checkers moan if you do.
The reason that it is not good practice is for future maintainability - let us say that the base class, LogicGate, was to gain a new property - say propagation_delay and a new method that allowed simulations to called get_response_time which relied on the current output state and the required, possibly new, state. If all the code that was derived from that class did the correct initialisations then it would all work fine, without any changes. If you remove those lines and such a new method was introduced you would have to go back through all of the child classes adding them back in before your final class would work for that method, with the chance that you would miss one.
Daft as it sounds doing things properly now is actually future laziness - it only takes you seconds when you are creating a class to make sure everything is initialised - debugging an uninitialised class can take hours.
First:
The __init__ functions are the constructors of the classes, you can read about them here.
Second:
Your code will run without those lines but the question is why and is it ok to remove them?
For example if you remove the following init
class UnaryGate(LogicGate): # LogicGate is the superclass
def __init__(self, n):
LogicGate.__init__(self, n)
The constructor of the super-class LogicGate will be called directly.
Third:
Ok, so can we remove the self.xxx = None?
class BinaryGate(LogicGate):
def __init__(self, n):
LogicGate.__init__(self, n)
self.pinA = None
self.pinB = None
We could remove those 2 Lines too but consider this code
bg = BinaryGate("binaryGate1")
print bg.pinA
This would throw an error because pinA is undefined.
If you do not remove the self.pinA = None in __init__ the code will run and None will be printed.

Categories