python object in dictionary - python

I am trying to save the object candle in the dictionary candlebuffer, however it gives me the error below. I am struggling; what is incorrect with my syntax?
class Observer:
def __init__(self):
self.listeners = []
def attach(self, listener):
if not listener in self.listeners:
self.listeners.append(listener)
def notify(self, event):
for listener in self.listeners:
listener.update(event)
class CandleGenerator(Observer):
def __init__(self,freq):
Observer.__init__(self)
self.freq = freq
self.candle = Candle()
def update(self,tick):
self.candle.addTick(tick,self.freq)
if keyfunc(self.candle.timestamp,self.freq) != self.candle.ref_timestamp:
self.notify(self.candle)
self.candle = Candle()
class CandlePrinter:
def update(self, candle):
print "Bougie>>>>>> freq: %s %s %s %s %s %s %s %s %s " % (candle.freq,candle.last_price,candle.volume, candle.timestamp, candle.ref_timestamp, candle.open_price,candle.high_price,candle.low_price, candle.last_price)
class CandleBuffer:
def __init__(self,candle):
self.candlebuffer={0: candle}
def update(self,candle):
self.candlebuffer[candle.timestamp]= candle
print self.candlebuffer
print('begin')
tickGenerator = TickGenerator()
candleGenerator1 = CandleGenerator(1)
candlePrinter = CandlePrinter()
candleBuffer = CandleBuffer(5)
tickGenerator.attach(candleGenerator1)
candleGenerator1.attach(candlePrinter)
candleGenerator1.attach(candleBuffer)
tickGenerator.generate()
It gives the following output:
TypeError: __init__() takes exactly 2 arguments (1 given)

Since you have confirmed what I was suspecting, you have to pass another argument to the constructor, and use a dictionary instead of a set:
class CandleBuffer():
def __init__(self,candle):
self.candlebuffer={0 : candle}
def update(self,candle):
self.candlebuffer[candle.timestamp]= candle
# ...
candleBuffer = CandleBuffer(a_candle)
candleBuffer.update(another_candle)

This isn't what cause your error but you need to use : to create a dictionary.
self.candlebuffer = { 0 : candle }
It's on the format key : value.
I guessing that you're creating a CandleBuffer without giving an argument somewhere else in your code.

Related

Instances & classes: requiring x arguments when x-1 given

I have written the following classes to be able to test different encryption schemes. However, I'm having trouble instantiating objects from the different encryption scheme. Could someone point out to something that doesn't make sense that I'm not catching atm? I'm not sure why it doesn't work. It gives a TypeError: encrypt() takes exactly 3 arguments (2 given) but it does have self passed, so I don't know how to fix it on the basis of the rest of them.
class AXU:
def __init__(self, sec_param):
self.sec_param = sec_param
def getHash(self):
# sample a, b and return hash function
a = random.randrange(self.sec_param)
b = random.randrange(self.sec_param)
return lambda x : a*x+b % sec_param
class BC(object):
def __init__(self, sec_param):
# generate a key
self.sec_param = sec_param
def encrypt(self, message, key):
#encrypt with AES?
cipher = AES.new(key, MODE_CFB, sec_param)
msg = iv + cipher.encrypt(message)
return msg
class tBC(object):
def __init__(self, sec_param):
self.sec_param = sec_param
def encrypt(self, tweak, message):
#pass
return AES.new(message, tweak)
class Trivial(tBC):
def __init__(self):
self.bcs = {}
def encrypt(self, tweak, message):
if tweak not in self.bcs.keys():
bc = BC()
self.bcs[tweak] = bc
return self.bcs[tweak].encrypt(message)
class Our(tBC):
def __init__(self, sec_param):
self.bc1 = BC(sec_param)
self.bc2 = BC(sec_param)
self.bc3 = BC(sec_param)
self.bc4 = BC(sec_param)
# encryption over GF field
def encrypt(self, tweak, message):
return self.bc1.encrypt(self.bc2.encrypt(tweak) * self.bc3.encrypt(message) + self.bc4.encrypt(tweak))
You are passing in one argument to a bound method:
return self.bc1.encrypt(
self.bc2.encrypt(tweak) * self.bc3.encrypt(message) +
self.bc4.encrypt(tweak))
That's one argument to the BC.encrypt() method each, and this method takes 2 beyond self, message and key.
Either pass in a value for key, or remove that argument from the BC.encrypt() method definition (and get the key from some place else; perhaps from an instance attribute set in __init__).

Python not running as main for a pyserial class

I have made a small class to open a serial port (ttyUSB0) on python, but when I try to run it as main it gives me back a whole lot of stuff I really don't know.
I want the class to create a Serial port instance when I run it and have the propper functions (or methods) give me back what I ask them to with the classe's instance. instead I'm getting the output below when I run:
$ python3 entrada.py
How do I make it run as I intend it to?
Here's the code for entrada.py
import serial #for port opening
import sys #for exceptions
from collections import __main__
#
#configure the serial connections (the parameters differs on the device you are connecting to)
class Serializer:
def __init__(self, port, baudrate=9600, timeout=5):
self.port = serial.Serial(port = port, baudrate=baudrate,
timeout=timeout, writeTimeout=timeout)
def open(self):
''' Open the serial port.'''
self.port.open()
def close(self):
''' Close the serial port.'''
self.port.close()
def send(self, msg):
self.prot.write(msg)
def recv(self):
return self.port.readline()
PORT = '/dev/ttyUSB0' #Esto puede necesitar cambiarse
def main():
test_port = Serializer(port = PORT)
try:
test_port().open()
except:
print ("Could not open serial port: ", sys.exc_info()[0])
sys.exit(2)
while True:
print(test_port.recv())
if __name__ == __main__:
main()
and here's the output:
from builtins import property as _property, tuple as _tuple
from operator import itemgetter as _itemgetter
from collections import OrderedDict
class Point(tuple):
'Point(x, y)'
__slots__ = ()
_fields = ('x', 'y')
def __new__(_cls, x, y):
'Create new instance of Point(x, y)'
return _tuple.__new__(_cls, (x, y))
#classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Point object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != 2:
raise TypeError('Expected 2 arguments, got %d' % len(result))
return result
def _replace(_self, **kwds):
'Return a new Point object replacing specified fields with new values'
result = _self._make(map(kwds.pop, ('x', 'y'), _self))
if kwds:
raise ValueError('Got unexpected field names: %r' % list(kwds))
return result
def __repr__(self):
'Return a nicely formatted representation string'
return self.__class__.__name__ + '(x=%r, y=%r)' % self
#property
def __dict__(self):
'A new OrderedDict mapping field names to their values'
return OrderedDict(zip(self._fields, self))
def _asdict(self):
'Return a new OrderedDict which maps field names to their values.'
return self.__dict__
def __getnewargs__(self):
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
return None
x = _property(_itemgetter(0), doc='Alias for field number 0')
y = _property(_itemgetter(1), doc='Alias for field number 1')
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 0.714 hypot=14.018
Point(x=100, y=22)
Point3D(x, y, z)
TestResults(failed=0, attempted=66)
Thanks for the help.
if __name__ == "__main__":
do_it()
im suprised if __name__ == __main__: didnt give you an error about undefined __main__
FYI, you misspelled port in self.prot.write(msg) to self.port.write(msg)
What is not running? what errors is it giving? how is that an output?
Why are you doing sys.exit(2)? A simple sys.exit() should suffice.
Also, having your variable as PORT for PORT = '/dev/ttyUSB0' may mix up with test_port = Serializer(port = PORT) in your main() function.

Timeit module for qgis plugin

I'd like to use the python module timeit to time some functions in my QGIS plugin.
Here, I've called the time it function within a function that I call at the end of the last function. It seems, though, that the plugin is taking even longer to run than usual and I am wondering if i'm calling the timer in the wrong place. Is there a better way to set this up?
class myPluginName:
def firstFunction(self):
...
self.secondFunction()
def secondFunction(self):
...
self.timeThings()
def run(self):
self.firstFunction()
def timeThings(self):
QMessageBox.information(None, 'First Function', 'Time : %s' % timeit.timeit(self.firstFunction,number=1)
QMessageBox.information(None, 'Second Function', 'Time : %s' % timeit.timeit(self.secondFunction,number=1)
UPDATE: After following some advice, i've tried to implement the wrapper in the following way. I get however, a TypeError: firstFunction() takes exactly 1 argument (2 given) on ret = func(**args, **kwargs)
def time_func(func):
try:
name = func.__name__
except:
name = func.f__name
def tf_wrapper(*args, **kwargs):
t = time.time()
ret = func(*args, **kwargs)
QMessageLog.logMessage("{}: {}".format(name, time.time() - t))
return ret
return tf_wrapper
class myPlugin:
def initGui(self):
QObject.connect(self.dlg.ui.comboBox,SIGNAL("currentIndexChanged(int)"), self.firstFunction)
#time_func
def firstFunc(self):
registry = QgsMapLayerRegistry.instance()
firstID = str(self.dlg.ui.firstCombo.itemData(self.dlg.ui.firstCombo.currentIndex()))
secondID = str(self.dlg.ui.secondCombo.itemData(self.dlg.ui.secondCombo.currentIndex()))
self.firstLayer = registry.mapLayer(firstID)
self.secondLayer = registry.mapLayer(secondID)
#time_func
def secondFunc(self):
...
self.thirdFunc()
def thirdFunct(self):
...
def run(self):
self.dlg.ui.firstCombo.clear()
self.dlg.ui.secondCombo.clear()
for layer in self.iface.legendInterface().layers():
if layer.type() == QgsMapLayer.VectorLayer:
self.dlg.ui.firstCombo.addItem(layer.name(), layer.id())
self.dlg.ui.secondCombo.addItem(layer.name(), layer.id())
result = self.dlg.exec_()
if result == 1:
self.secondFunction()
OK, I don't know your exact situation, but I'd set it up though decorators:
import time
def time_func(func):
try:
name = func.__name__
except:
name = func.f_name
def tf_wrapper(*args, **kwargs):
t = time.time()
ret = func(*args, **kwargs)
print("{}: {}".format(name, time.time() - t)) # Or use QMessageBox
return ret
return tf_wrapper
class myPluginName:
#time_func
def firstFunction(self):
pass
#time_func
def secondFunction(self):
pass
def run(self):
self.firstFunction()
myPluginName().firstFunction()
With this code, any function wrapped in time_func will have the time taken to execute the function printed when it returns, along with its name. E.g. running it will print:
firstFunction: 1.430511474609375e-06
For your TypeError, you need to change;
def firstFunction(self):
pass
To:
def firstFunction(self, index):
pass

AttributeError: 'Rules' object has no attribute '_Rules__temperature'

I have a program that is aiming to take inputs from sensors and then act upon inputs from these sensors from some pre-defined rules that are stored and called within a class. I am having problems passing the variables that the sensors are defined as into the rules class. Where I get errors of 'Rules object has not attribute .rules_temperature. My code is below:
class myInterfaceKit():
__interfaceKit = None
def __init__(self ):
try:
self.__interfaceKit = InterfaceKit()
except RuntimeError as e:
print("Runtime Exception: %s" % e.details)
print("Exiting....")
exit(1)
def open(self):
try:
self.__interfaceKit.openPhidget()
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
def getInterfaceKit(self):
return self.__interfaceKit
def getSensor(self, sensor):
return self.__interfaceKit.getSensorValue(sensor)
class sensors():
__sound = 0
__temperature = 0
__light = 0
__motion = 0
__dbName = ""
__interfaceKit = None
__connection = None
__rules = None
def __init__(self, theInterfaceKit, dbName):
self.__sound = 0
self.__temperature=0
self.__light=0
self.__motion=0
self.__timeStamp=time.time()
self.__strTimeStamp=datetime.datetime.fromtimestamp(self.__timeStamp).strftime('%Y-%m-%d %H:%M:%S')
self.__dbName = dbName
self.__interfaceKit = theInterfaceKit
self.__connection = sqlite3.connect('testing1.db', check_same_thread=False) ######
def interfaceKitAttached(self, e):
attached = e.device
print("InterfaceKit %i Attached!" % (attached.getSerialNum()))
self.__interfaceKit.getInterfaceKit().setSensorChangeTrigger(0, 5)
self.__interfaceKit.getInterfaceKit().setSensorChangeTrigger(1, 35)
self.__interfaceKit.getInterfaceKit().setSensorChangeTrigger(2, 60)
self.__interfaceKit.getInterfaceKit().setSensorChangeTrigger(3, 200)
def sensorInputs(self, e):
temperature = (self.__interfaceKit.getSensor(0)*0.2222 - 61.111)
sound = (16.801 * math.log((self.__interfaceKit.getSensor(1))+ 9.872))
light = (self.__interfaceKit.getSensor(2))
motion = (self.__interfaceKit.getSensor(3))
# check temperature has changed - if yes, save and update
if temperature != self.__temperature:
self.__timeStamp=time.time()
self.__strTimeStamp=datetime.datetime.fromtimestamp(self.__timeStamp).strftime('%Y-%m-%d %H:%M:%S')
self.__temperature = temperature
print("Temperature is: %i:" % self.__temperature)
self.writeToDatabase( 'temperature', self.__temperature, self.__strTimeStamp)
#check sound has changed - if yes, save and update
if sound != self.__sound:
self.__timeStamp=time.time()
self.__strTimeStamp=datetime.datetime.fromtimestamp(self.__timeStamp).strftime('%Y-%m-%d %H:%M:%S')
self.__sound = sound
print("Sound is: %i " % self.__sound)
self.writeToDatabase( 'sound', self.__sound, self.__strTimeStamp )
#check light has changed - if yes, save and update
if light != self.__light:
self.__timeStamp=time.time()
self.__strTimeStamp=datetime.datetime.fromtimestamp(self.__timeStamp).strftime('%Y-%m-%d %H:%M:%S')
self.__light = light
print("Light is: %i " % self.__light)
self.writeToDatabase( 'light', self.__light, self.__strTimeStamp )
if motion != self.__motion:
self.__motion = motion
print ("motion is %i" % self.__motion)
def openDatabase(self):
cursor = self.__connection.cursor()
cursor.execute("CREATE TABLE " + self.__dbName + " (sensor text, value text, time_stamp text)")
def writeToDatabase(self, sensorType, data, time):
cursor = self.__connection.cursor()
cursor.execute("INSERT INTO " + self.__dbName + " VALUES (?, ?, ?)", (sensorType, data, time))
self.__connection.commit()
def closeDatabase():
self.__connection.close()
def start(self):
try:
self.__interfaceKit.getInterfaceKit().setOnAttachHandler(self.interfaceKitAttached)
self.__interfaceKit.getInterfaceKit().setOnSensorChangeHandler(self.sensorInputs)
self.openDatabase()
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
print("Exiting....")
exit(1)
This is where the problem lies:::
class Rules(sensors):
__tempLower=0
__tempUpper=0
def __init__(self):
self.__tempLower=28
self.__tempUpper=30
self.__temperature
def tempRule(self, sensors): ##Temperature rule
if self.__temperature == self.__tempLower:
print("testing")
phidgetInterface = myInterfaceKit()
phidgetInterface.open()
theSensors = sensors(phidgetInterface, "event156")
theSensors.start()
theRule = Rules()
theRule.tempRule()
chr = sys.stdin.read(1)
edit, error message:
Traceback (most recent call last):
File "H:\Project\Student\Prototype 1\eventProto.py", line 159, in
theRule = Rules()
File "H:\Project\Student\Prototype 1\eventProto.py", line 146, in init
self.__temperature
AttributeError: 'Rules' object has no attribute 'Rules_temperature'
Private members (starting with __) cannot be accessed by subclasses. (Well, they can be accessed using some hackery, but should not).
(see here)
In your case, __temperature is a private member of the base class sensors, but you're accessing it from the subclass Rules.
Replace the double underscore prefix with a single underscore (__temperature -> _temperature), and you're good to go.
Double underscore members are considered private, you have to prepend those with class name that defined said member.
Use these magic private members like this:
class sensors:
__temp = 42
assert sensors()._sensors__temp == 42
class Rules(sensors):
def test(self):
assert self._sensors__temp == 42
Rules().test()

Creating a slightly borg-like class

I'm trying to make a class that is borg-like. I'd like one particular property to be shared by all the instances, but other properites I would like to be unique to the instance. Here is what I have so far:
class SharedFacility:
_facility = None
def __init__(self):
entries = {'facility': self._facility}
self.__dict__.update(entries)
def _getfacility(self):
return self._facility
def _setfacility(self, value):
self._facility = value
facility = property(_getfacility, _setfacility)
class Warning(SharedFacility):
def __init__(self, warnlevel, warntext):
SharedFacility.__init__(self)
print "Warning.__init__()"
self.warntext = warntext
self.warnlevel = warnlevel
def __call__(self):
self.facility(self.warnlevel, self.warntext)
def functionOne(a,b):
print 'functionOne: a=%s, b=%s' % (a,b)
def functionTwo(a,b):
print 'functionTwo: a=%s, b=%s' % (a,b)
####################################################
w1 = Warning(1, 'something bad happened')
w1.facility = functionOne
w2 = Warning(5, 'something else bad happened')
import pdb; pdb.set_trace()
if w1.facility is w2.facility:
print "They match!"
w1() # functionOne: a=1, b='something bad happened'
w2() # functionOne: a=5, b='something else bad happened'
w2.facility = functionTwo
if w1.facility is w2.facility:
print "They match!"
w1() # functionTwo: a=1, b='something bad happened'
w2() # functionTwo: a=5, b='something else bad happened'
The above code does not work. I'd like w1.facility and w2.facility to be a reference to the same object, but w1.warntext and w2.warntext two be two different values. I'm working with python 2.4.3 (no sense in mentioning I upgrade because I can't).
Solution:
class Warning(object):
_facility = None
def __init__(self, warnlevel, warntext):
print "Warning.__init__()"
self._warntext = warntext
self._warnlevel = warnlevel
def __call__(self):
Warning._facility(self._warnlevel, self._warntext)
def _getfacility(self):
return Warning._facility
def _setfacility(self, value):
Warning._facility = value
facility = property(_getfacility, _setfacility)
#staticmethod
def functionOne(a,b):
print 'functionOne: a=%s, b=%s' % (a,b)
#staticmethod
def functionTwo(a,b):
print 'functionTwo: a=%s, b=%s' % (a,b)
Here's what I would do:
class BorgLike:
_shared = 'default'
def __init__(self, unique):
self.unique = unique
#property
def shared(self):
return BorgLike._shared
#shared.setter
def shared(self, value):
BorgLike._shared = value
I hope you know how to use this example for your own purpose. I wasn't really sure what you wanted with your code, so I refrained from guessing and wrote a minimal example.

Categories