I am looking at this example right now
class TravellingSalesmanProblem(Annealer):
"""Test annealer with a travelling salesman problem.
"""
# pass extra data (the distance matrix) into the constructor
def __init__(self, state, distance_matrix):
self.distance_matrix = distance_matrix
super(TravellingSalesmanProblem, self).__init__(state) # important!
Cloned from simanneal
If I decide to change the constructor
def __init__(self, state, distance_matrix):
self.state = state
super(TravellingSalesmanProblem, self).__init__(distant_matrix)
This is how class Anealer looks like
class Annealer(object):
__metaclass__ = abc.ABCMeta
# defaults
Tmax = 25000.0
Tmin = 2.5
steps = 50000
updates = 100
copy_strategy = 'deepcopy'
user_exit = False
save_state_on_exit = False
# placeholders
best_state = None
best_energy = None
start = None
def __init__(self, initial_state=None, load_state=None):
if initial_state is not None:
self.state = self.copy_state(initial_state)
elif load_state:
self.load_state(load_state)
else:
raise ValueError('No valid values supplied for neither \
initial_state nor load_state')
signal.signal(signal.SIGINT, self.set_user_exit)
It has bunch of other methods too,but that would take too much space.
How would the new TravellingSalesmanProblem instance differ with the previous one?
How would the new TravellingSalesmanProblem instance differ with the previous one?
In step 1, you would assign the state
self.state = state
In step 2 you would pass the distant matrix as a parameter to the init method
super(TravellingSalesmanProblem, self).__init__(distant_matrix)
That init method take the first parameter and interpret it as initial_state.
self.state = self.copy_state(initial_state)
That means: the original state is lost and the distant matrix becomes your state.
Conclusion: It's a mess.
Related
So here's one example. I have a module with multiple classes for computing properties, let's say, Density. Then, I have substances, whom I make inherit the properties, so I can call them afterwards:
class Density():
def __init__(self):
self.rho_method_1_A = None
self.rho_method_1_B = None
self.rho_method_2_A = None
self.rho_method_2_B = None
def density_method_1(self,T):
return self.rho_method_1_A*T + self.rho_method_1_B*T**2
def density_method_2(self,T,P):
return P*(self.rho_method_2_A/T + self.rho_method_1_B*log(T))
class Water(Density):
def __init__(self):
self.rho_method_1_A = 0.2
self.rho_method_1_B = 0.0088
self.rho_method_2_A = 1.9
self.rho_method_2_B = 10
Water.density_method_1(T=300)
Basically, I want the user to be able to set beforehand the method of choice. The problem is, depending on the model that he/she chose, it will either accept only T, or both T and P (in some other cases, maybe T won't even be accepted). Essentially:
density_method = density_method_2 # This is chosen by the user in an outer module
Water.density_method(code magically knows what to put here by detecting the arguments that
density_method_2 accepts)
To be clear: The user itself will know which arguments the method accepts, so if he chose method_2, P will be known on the outer module. I suspect **kwargs and/or decorators are part of the solution, but I can't quite figure it out. Any help is appreciated. Thanks and have a great weekend.
Update: It is relevant to notice that density_method will be called inside a temporal loop of tens of thousands of iterations. So, I'm trying to avoid if/else statements by completely defining density_method before starting the temporal loop.
Possible solution (tested with Python 3.8):
from math import log
class Density():
def __init__(self, method=1):
self.method = method
self.rho_method_1_A = None
self.rho_method_1_B = None
self.rho_method_2_A = None
self.rho_method_2_B = None
def density_method_1(self, T):
return self.rho_method_1_A*T + self.rho_method_1_B*T**2
def density_method_2(self, T, P):
return P*(self.rho_method_2_A/T + self.rho_method_1_B*log(T))
def density_method(self, *args, **kwargs):
if self.method == 1:
return self.density_method_1(*args, **kwargs)
elif self.method == 2:
return self.density_method_2(*args, **kwargs)
else:
raise ValueError("No density method found")
class Water(Density):
def __init__(self, method):
super(Water, self).__init__(method=method)
self.rho_method_1_A = 0.2
self.rho_method_1_B = 0.0088
self.rho_method_2_A = 1.9
self.rho_method_2_B = 10
class Air(Density):
def __init__(self, method):
super(Air, self).__init__(method=method)
self.rho_method_1_A = 0.2
self.rho_method_1_B = 0.0088
self.rho_method_2_A = 1.9
self.rho_method_2_B = 10
water = Water(method=1)
air = Air(method=2)
print(water.density_method(T=1))
print(air.density_method(T=1, P=2))
The solution can be improved but the general idea is to have a "wrapper" method density_method that calls the relevant density_method_* for each sub-class of Density.
Edit (following the comments to my answer):
You should look into python method overloading, like the example here:
https://www.geeksforgeeks.org/python-method-overloading/
from multipledispatch import dispatch
#passing one parameter
#dispatch(int,int)
def product(first,second):
result = first*second
print(result);
#passing two parameters
#dispatch(int,int,int)
def product(first,second,third):
result = first * second * third
print(result);
#you can also pass data type of any value as per requirement
#dispatch(float,float,float)
def product(first,second,third):
result = first * second * third
print(result);
#calling product method with 2 arguments
product(2,3,2) #this will give output of 12
product(2.2,3.4,2.3) # this will give output of 17.985999999999997
I am using Transitions, a very useful FSM tool for python. I would like to make the states more, um, stateful... so that variables can be local to states, and their values changed when the state is entered or left. I am ending up with a fair number of instance variables in the machine - I really want some of those values in the state (how long have I been in this state, for example). They aren't attributes of the model, they are attributes of progress through the states.
I wonder if there is a 'best way' to do this? Subclass State?
thanks
I am not aware of a 'best way' but a reasonable approach depends on what you want to achieve. You can either a) subclass State, b) decorate initialised states or c) manually initialise (subclassed) states and pass these to the machine.
A) If every state has the same attributes you can subclass states as you suggested:
import transitions.extensions.nesting as nesting
class CounterState(nesting.NestedState):
def __init__(self, *args, **kwargs):
super(CounterState, self).__init__(*args, **kwargs)
self.entered = self.exited = 0
def enter(self, event_data):
self.entered += 1
def exit(self, event_data):
self.exited += 1
def __str__(self):
return "State {0} has been entered {1} times and exited {2} times".format(self.name, self.entered, self.exited)
class CounterMachine(nesting.HierarchicalMachine):
#staticmethod
def _create_state(*args, **kwargs):
return CounterState(*args, **kwargs)
machine = CounterMachine(states=['A', 'B'], initial='A')
a = machine.get_state('A')
b = machine.get_state('B')
print(a) # >>> State A has been entered 0 times and exited 0 times
machine.to_B()
print(a) # >>> State A has been entered 0 times and exited 1 times
print(b) # >>> State B has been entered 1 times and exited 0 times
I have used NestedMachine here because _create_state is not available in Machine so far. Update: Starting from version 0.4.4 it is also available for Machine.
B) Another approach involves some decoration of the initiated state objects by the model:
from transitions import Machine
class Model(object):
def __init__(self):
self.machine = Machine(model=self, states=['A', 'B'], initial='A',
before_state_change='exit_state',
after_state_change='enter_state')
# loop through all the states and attach attributes
for state in self.machine.states.values():
state.entered = 0
state.exited = 0
def enter_state(self):
# retrieve the state object by name
self.machine.get_state(self.state).entered += 1
def exit_state(self):
self.machine.get_state(self.state).exited += 1
def print_state(state):
print("State {0} has been entered {1} times and exited {2} times".format(state.name, state.entered, state.exited))
m = Model()
a = m.machine.get_state('A')
b = m.machine.get_state('B')
print_state(a)
m.to_B()
print_state(a)
print_state(b)
C) In cases where every state has to be treated individually, you can initiate the states manually and pass the instances to the machine instead of the names:
from transitions import Machine, State
class TicketState(State):
def __init__(self, name, tickets):
super(TicketState, self).__init__(name)
self.tickets = tickets
class Model(object):
def __init__(self):
# Using our own state
a = TicketState('A', 10)
# Setting tickets ourselves
b = State('B')
b.tickets = 3
self.machine = Machine(self, states=[a, b], initial='A',
before_state_change='decrease_tickets')
def tickets_left(self):
return self.machine.get_state(self.state).tickets > 0
def decrease_tickets(self):
s = self.machine.get_state(self.state)
s.tickets -= 1
if s.tickets < 0:
raise Exception('No Tickets left!')
print("State {0} has {1} tickets left.".format(s.name, s.tickets))
m = Model()
m.to_B() # >>> State A has 9 tickets left.
m.to_A() # >>> State B has 2 tickets left.
The amount of attributes and names could differ here of course. Instead of using the machine callback before_state_change, you can also pass on_enter/exit callbacks to the State object to treat each state individually during transitions. Or subclass State.enter(self, event_data) if you just require a set of different state types like TimedState and/or CounterState.
I'm working under python pyramid, with Python3.
I have a model that looks like this:
class OneTimeCode(Base):
__tablename__ = 'otc_one_time_codes'
otc_one_time_code_id = Column(Integer, primary_key=True)
otc_one_time_code = Column(String(32))
otc_usr_user_id = Column(Integer, ForeignKey('usr_users.usr_user_id'), nullable=True)
otc_expire_time = Column(DateTime)
def __init__(self, otc_usr_user_id, otc_expire_time=None):
self.otc_usr_user_id = otc_usr_user_id
if otc_expire_time is None:
self.otc_expire_time = (datetime.now() + timedelta(6*365/12)).isoformat()
else:
self.otc_expire_time = otc_expire_time
#classmethod
def get_code(self, hlength=6):
seed = datetime.now() + timedelta(random.randrange(1,10000))
tmp_hash = hashlib.md5(seed.strftime("%Y-%m-%d %H:%M:%S.%F").encode('utf-8')).hexdigest()
if hlength == 32:
self.otc_one_time_code = tmp_hash
else:
self.otc_one_time_code = tmp_hash[0 : hlength]
print(self.otc_one_time_code)
The problem is, when I instantiate one of these objects and then explicitly call get_code, the print line at the end prints to the screen the code successfully.
However, in my view, if I explicitly try to print that property, it's 'None'
Here's what my view code looks like:
otc = OneTimeCode(
otc_usr_user_id = user.usr_user_id
)
otc.get_code()
pprint.pprint(vars(otc))
session.add(otc)
And the console output looks like this:
0d097c
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x50877d0>, 'otc_expire_time': '2015-02-13T10:56:14.244447', 'otc_usr_user_id': 1} 2014-08-14 22:56:14,245
INFO [sqlalchemy.engine.base.Engine][Dummy-2] INSERT INTO otc_one_time_codes (otc_one_time_code, otc_usr_user_id, otc_expire_time) VALUES (%(otc_one_time_code)s, %(otc_usr_user_id)s, %(otc_expire_time)s) RETURNING otc_one_time_codes.otc_one_time_code_id 2014-08-14 22:56:14,245
INFO [sqlalchemy.engine.base.Engine][Dummy-2] {'otc_one_time_code': None, 'otc_expire_time': '2015-02-13T10:56:14.244447', 'otc_usr_user_id': 1} 2014-08-14 22:56:14,247
INFO [sqlalchemy.engine.base.Engine][Dummy-2] COMMIT
You can see the value inside the model: 0d097c, and also the pprint object, where it doesn't look like the property exists.
Why can't I get access to this property?
Looks like you should be using a #property instead of a OTC, however it also seems like this may be something you DON'T want to calculate each time!
# for all the docstrings, let multi = Multi(2)
class Multi(object):
def __init__(self, attribute):
"""When instantiated, set self.attribute to attribute"""
self.attribute = attribute
#property
def attribute_times_ten(self):
"""accessed via multi.attribute_times_ten
and will return 20. Use properties to signify
a variable that requires some work done to it
that needs to calculated each time it's called."""
return attribute_times_ten
#classmethod
def times_ten(cls, num):
"""Not the best example, but a #classmethod will
give the class as its first argument, NOT the
instance. This is useful in lots of constructor
settings, e.g. CreateClass.fromstring("attributes")"""
return num * 5
def generate_number(self, multiplier):
"""This is just a normal method. This is what I think
you want, tbh, and you should probably call it in your
__init__ method since you NEED this to run in your OTC
for it to work as intended. Methods (like properties)
are automagically passed the instance as the first
argument, so we can CHANGE self.attribute with that."""
self.attribute = self.attribute * multiplier
Docstrings should be self descriptive, but:
multi = Multi(2)
multi.attribute_times_ten # returns 20
Multi.times_ten(8) # returns 80, note the capital M!
multi.generate_number(3) # self.attribute is now 6
multi.attribute_times_ten # returns 60
A real-world case where you might need all of the above:
class _Tile(object):
def __init__(self, x, y):
"""A naive implementation of Tile that doesn't care
what its side length is and doesn't have any properties
to hide its attributes"""
self.x = x
self.y = y
#classmethod
def tiles_to_pixels(cls, tile):
return cls(tile._x * tile.side_length, tile._y * tile.side_length)
#classmethod
def tiles_to_tiles(cls, tile):
return cls(tile._x, tile._y)
class Tile(object):
def __init__(self, x, y, side_length):
"""A tile object in a map"""
self._x = x # x-coord in tiles
self._y = y # y-coord in tiles
self.side_length = side_length # pixels per tile
#property
def in_pixels(self):
"""self.in_pixels returns an object whose .x and .y
correspond to the x and y position IN PIXELS of the
top-left corner of the tile."""
_tile = _Tile.tiles_to_pixels(self)
return _tile
#property
def in_tiles(self):
"""self.in_tiles returns an object whose .x and .y
correspond to the x and y position IN TILES of the
top-left corner of the tile."""
_tile = _Tile.tiles_to_tiles(self)
return _tile
def change_side_length(self, new_length):
"""Use to change the side length. This can break
your whole map since it's naive, so be careful."""
self.side_length = new_length
my_tile = Tile(0,0,32) # 32 pixel tile starting at (0,0)
my_tile.x # NameError, since it's called my_tile._x
my_tile.in_tiles.x # 0
my_tile.in_pixels.y # 0
other_tile = Tile(4,7,32) # 32 pixel tile starting at (4,7)
other_tile.y # NameError, see above
other_tile.in_tiles.y # 7
other_tile.in_pixels.x # 128
I'm currently self-learning Python, and I'm reading 'Problem Solving with Algorithms and Data Structures' (Brad Miller, David Ranum). I've stumbled upon the basic example of inheritance. Although I can see what it does, I need an explanation, how it works actually. The Code is as follows:
class LogicGate:
def __init__(self,n):
self.name = n
self.output = None
def getName(self):
return self.name
def getOutput(self):
self.output = self.performGateLogic()
return self.output
class BinaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pinA = None
self.pinB = None
def getPinA(self):
if self.pinA == None:
return int(input("Enter Pin A input for gate "+self.getName()+"-->"))
else:
return self.pinA.getFrom().getOutput()
def getPinB(self):
if self.pinB == None:
return int(input("Enter Pin B input for gate "+self.getName()+"-->"))
else:
return self.pinB.getFrom().getOutput()
def setNextPin(self,source):
if self.pinA == None:
self.pinA = source
else:
if self.pinB == None:
self.pinB = source
else:
print("Cannot Connect: NO EMPTY PINS on this gate")
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
class OrGate(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a ==1 or b==1:
return 1
else:
return 0
class UnaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pin = None
def getPin(self):
if self.pin == None:
return int(input("Enter Pin input for gate "+self.getName()+"-->"))
else:
return self.pin.getFrom().getOutput()
def setNextPin(self,source):
if self.pin == None:
self.pin = source
else:
print("Cannot Connect: NO EMPTY PINS on this gate")
class NotGate(UnaryGate):
def __init__(self,n):
UnaryGate.__init__(self,n)
def performGateLogic(self):
if self.getPin():
return 0
else:
return 1
class Connector:
def __init__(self, fgate, tgate):
self.fromgate = fgate
self.togate = tgate
tgate.setNextPin(self)
def getFrom(self):
return self.fromgate
def getTo(self):
return self.togate
def main():
g1 = AndGate("G1")
g2 = AndGate("G2")
g3 = OrGate("G3")
g4 = NotGate("G4")
c1 = Connector(g1,g3)
c2 = Connector(g2,g3)
c3 = Connector(g3,g4)
print(g4.getOutput())
main()
I'm mostly doubted by the tgate.setNextPin(self) statement in Connector class __init__. Is it a method call? If it is, why is it called with just one parameter, when there are two actually required by the setNexPin function in UnaryGate and BinaryGate classes (self, source)? How does the fromgate variable ends up as the source arrgument? Does this statement 'initiliaze' anything actually, and what?
Next thing which troubles me is, for example, when I print(type(g4)) before declaring g4.getOutput(), I get <class '__main__.OrGate'>, but when the g4.getOutput() starts, and functions start calling each other, to the point of calling getPin function, if I put print (self.pinA) before return self.pinA.getFrom().getOutput(), I get the <__main__.Connector object at 0x2b387e2f74d0>, although self.Pin is a variable from g4 OrGate instance. How can one variable from one class instance can become object of another class, which isn't inheriting it? Does this have something with a work of setNextPin() function?
Can someone explain this to me as I am new to OOP and thorougly confused by this piece of code. Thank you.
Regarding your first question, tgate.setNextPin(self) is a method call. tgate is an object, presumably an instance of one of the gate types. When you access instance.method, Python gives you a "bound method" object, which works pretty much like a function, but which puts the instance in as the first argument when it is actually called. So, tgate.setNextPin(self) is really calling type(tgate).setNextPin(tgate, self)
Your second question seems to reflect a misunderstanding of what attributes are. There's no requirement that an object's attributes be of its own type. In the various LogicGate sub-classes, the pin/pinA/pinB attributes are either going to be None (signaling that the user should be prompted for an input value) or an instance of a Connector (or something else with a getFrom method). Neither of those values is a LogicGate instance.
As for where the Connector instance you saw came from, its going to be one of the c1 through c3 values you created. Connector instances install themselves onto a pin of their tgate argument, with the setNextPin call you were asking about in your first question. I can't really speak to the g4 gate you are looking at, as it seems to be different than the g4 variable created in your example code's main() function (it is a different type), but I suspect that it is working as designed, and it's just a bit confusing. Try accessing the pinX attributes via g4.pinA rather than inspecting them inside of the methods and you may have a bit less confusion.
Here's a bit of code with outputs that should help you understand things a bit better:
# create a few gates
g1 = AndGate("G1")
g2 = OrGate("G2")
# at this point, no connectors have been hooked up, so all pinX attrs are None:
print("G1 pins:", g1.pinA, g1.pinB) # "None, None"
print("G2 pins:", g2.pinA, g2.pinB) # "None, None"
# test that the gates work independently of each other:
print("G1 output:", g1.getOutput()) # will prompt for two inputs, then print their AND
print("G2 output:", g2.getOutput()) # will prompt for two inputs, then print their OR
# create a connection between the gates
c1 = Connector(g1, g2) # connects output of g1 to first available pin (pinA) of g2
# we can see that g2.pinA has changed
print("G2 pins after connection:", g2.pinA, g2.pinB)
# "<__main__.Connector object at SomeHexAddress>, None"
# now, if we get g2's output, it will automatically request g1's output via the Connector
print("G2 output:", g2.getOutput())
# will prompt for 2 G1 inputs, and one G2 input and print (G1_A AND G1_B) OR G2_B
If you want to play around with these classes more, you might want to add a __str__ (and/or __repr__) method to some or all of the classes. __str__ is used by Python to convert an instance of the class into a string whenever necessary (such as when you pass it as an argument to print or str.format). Here's a quick __str__ implementation for Connector:
def __str__(self):
return "Connector between {} and {}".format(self.fgate.name, self.tgate.name)
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)