I am relatively new to python. I have a class Time, and I want to check if a set of Time objects contains another set of Time objects.
a = {Time(10,10)}
print {Time(10,10)}.issubset(a) >> "result is False"
for i in a:
print i in a >> "result is True"
And in the class, I have implemented these methods
def to_min(self):
return self.h * 60 + self.m
def __cmp__(self, other):
if isinstance(other, Time):
if self.to_min() > other.to_min():
return 1
else:
if self.to_min() == other.to_min():
return 0
else:
return -1
def __eq__(self, other):
if isinstance(other, Time):
if self.to_min() == other.to_min():
return True
else:
return False
def __gt__(self, other):
return self.to_min() > other.to_min()
def __ge__(self, other):
return self.to_min() >= other.to_min()
def __lt__(self, other):
return self.to_min() < other.to_min()
def __le__(self, other):
return self.to_min() <= other.to_min()
def __str__ (self):
return str(self.h) + ":" + str(self.m)
def __hash__(self):
return self.to_min()
I wonder what else should I implement or change to make the following lines of code to print to true. I have read the=at there is a contains method. But I am not going check if one Time object contains other components.
a = {Time(10,10)}
print {Time(10,10)}.issubset(a) >>
I replaced this
self.to_min() == other.to_min()
with this
self.__hash__() == other.__hash__()
And also edited the eq to return boollean, rather than integer
Now it works, I still wonders.
Anyway, this is full code if anyone is interested:
class Time(object):
'''
classdocs
'''
def __init__(self, h, m):
if isinstance(h, int) and isinstance(h, int):
self.m = m
self.h = h
if(self.m >= 60):
self.h += self.m // 60
self.m %= 60
def __add__(self, m):
return Time(self.h, self.m + m)
def to_min(self):
return self.h * 60 + self.m
def __cmp__(self, other):
print "__cmp__"
if isinstance(other, Time):
if self.to_min() > other.to_min():
return 1
else:
if self.__hash__() == other.__hash__():
return 0
else:
return -1
def __eq__(self, other):
print "__eq__"
if isinstance(other, Time):
if self.to_min() == other.to_min():
return True
else:
return False
def __gt__(self, other):
return self.to_min() > other.to_min()
def __ge__(self, other):
return self.to_min() >= other.to_min()
def __lt__(self, other):
return self.to_min() < other.to_min()
def __le__(self, other):
return self.to_min() <= other.to_min()
def __str__ (self):
return str(self.h) + ":" + str(self.m)
def __hash__(self):
print "__hash__"
return self.to_min()
# return 1
def __ne__(self, other):
print "__ne__"
return not self == other
# a = set([Time(10,10), Time(10,20)])
# b = set([Time(10,10)])
# print a in set([b])
a = {Time(10,10)}
print {Time(10,10)}.issubset(a)
# print b.issubset( a)
# for i in a:
# print i in a
Related
tell me how to overload the operator > (lt) or < (gt) etc so that it can work with different types (especially with 0)
for example:
class CRational(object):
def __init__(self, a = 0, b = 1):
self.a = a
self.b = b
def __neg__(self):
return CRational(-self.a, self.b)
def __add__(self, other):
return CRational(self.a * other.b + other.a * self.b, self.b * other.b)
def __sub__(self, other):
return CRational(self.a * other.b - other.a * self.b, self.b * other.b)
def __mul__(self, other):
return CRational(self.a * other.a, self.b * other.b)
def __truediv__(self, other):
return CRational(self.a * other.b, self.b * other.a)
def __eq__(self, other):
return self.a * other.b == other.a * self.b
def __ne__(self, other):
return not self.__eq__(other)
def __lt__(self, other):
return self.a * other.b < other.a * self.b
def __le__(self, other):
return self.a * other.b <= other.a * self.b
def __gt__(self, other):
return self.a * other.b > other.a * self.b
def __ge__(self, other):
return self.a * other.b >= other.a * self.b
error output:
File "lessons/python/square_eq.py", line 66, in __gt __
return self.a * other.b > other.a * self.b AttributeError: 'int' object has no attribute 'b'
in code:
s_a = "" if a > 0 else "-"
how do you fix it?
s_a = "" if a > CRational(0) else "-"
the method described above helps, but it is not beautiful :)
If you want to compare a CRational object with an int then your __gt__ method should works with integers too. I.e., if other is an integer, you clearly can't do something like other.b. Here is a possible solution:
class CRational:
def __init__(self, a = 0, b = 1):
self.a = a
self.b = b
def __gt__(self, other):
if isinstance(other, CRational):
return self.a * other.b > other.a * self.b
elif isinstance(other, int):
# Compare self (a CRational object) with other (an int)
# TODO
else:
raise NotImplemented()
Now you can do something like this:
a = CRational()
if a > 3:
...
Be careful though! Even if you implement correctly all the methods, you still can't do 3 > a. Order is important!! 3 > a would call the __gt__ method of the int class. You can only do a > 3, a < 3, a >= 3 etc.
With regards to your error output: you are getting the error because your "other" is an int and CRational.__gt__ is trying to access an attribute that it does not have a b:
def __gt__(self, other): # passing in an int here
return self.a * other.b > other.a * self.b
With regards to your code example, assuming a is another CRational object, then a > 0 will cause the AttributeError you are seeing above and the only way to fix it is by comparing it with either another CRational object or some other object that has attribues a and b.
Sounds like you're wanting to test for what kind of object you are working with. Maybe something like:
import numbers
def __gt__(self, other):
if isinstance(other, type(self)):
return self.a * other.b > other.a * self.b
elif isinstance(other, numbers.Number):
return self.a > other
else:
err_str = "Unknown type in comparison with %s object: %s" % (type(self).__name__, type(other).__name__)
raise(TypeError(err_str))
Here, type(self) is a generic way of getting the CRational class. That way you don't have to modify the class's code if you simply change the name later.
isinstance checks to see if a given object is of the given type, or a child type. Python documentation.
I made up the numeric case, because I don't know how you'd want to define that.
I have following class:
class Word:
def __init__(self, key: str):
self.key = key
self.value = ''.join(sorted(key))
def __lt__(self, other):
if self.value < other.value:
return True
return False
def __gt__(self, other):
if self.value > other.value:
return True
return False
def __eq__(self, other):
val = other.value
if self.value == val:
return True
return False
and < works. But when I try <= I get following error:
TypeError: '<=' not supported between instances of 'Word' and 'Word'
How to override <= for python class?
You need to implement __ge__ & __le__
class Word:
def __init__(self, key: str):
self.key = key
self.value = ''.join(sorted(key))
def __lt__(self, other):
if self.value < other.value:
return True
return False
def __gt__(self, other):
if self.value > other.value:
return True
return False
def __le__(self, other):
if self.value <= other.value:
return True
return False
def __ge__(self, other):
if self.value >= other.value:
return True
return False
def __eq__(self, other):
val = other.value
if self.value == val:
return True
return False
You need to override def __le__(self, other) (lesser-equal) and def __ge__(self, other) (greater equal) as well.
Beside that you should check if your given other actually is a Word instance, else you might crash because no other.value can be accessed:
w = Word("hello")
print( w > 1234 ) # crash: AttributeError: 'int' object has no attribute 'value'
Source / Documentation of all of them: object.__le__
See
python overloading operators
Potential fix for comparison:
def __lt__(self, other):
if isinstance(other, Word):
if self.value < other.value:
return True
else:
# return True or False if it makes sense - else use better exception
raise ValueError(f"Cannot compare Word vs. {type(other)}")
return False
There is another special method for this:
def __le__(self, other):
if self.value <= other.value:
return True
else:
return False
My code works perfectly except the last part. I want to recreate the object with repr function but it clearly doesn't work. I tried everything here and on the web but i'm still so confuse. Is there any way to do it and if so what is the syntax ?
class Modulo(object):
def __init__(self, grondtal, waarde = 0):
self.grondtal = grondtal
self.waarde = waarde % grondtal
def __call__(self, m):
return Modulo(self.grondtal, m)
def __add__(self, other):
return Modulo(self.grondtal, self.waarde + other.waarde)
def __sub__(self, other):
return Modulo(self.grondtal, self.waarde - other.waarde)
def __mul__(self, other):
return Modulo(self.grondtal, self.waarde * other.waarde)
def __eq__(self, other):
return self.waarde == other.waarde and self.grondtal == other.grondtal
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return '[%s %% %s]' % (str(self.grondtal), str(self.waarde))
def __repr__(self):
return '%s' %Modulo(self.grondtal, self.waarde)
You probably want this:
def __repr__(self):
return "Modulo(%d,%d)" % (self.grondtal, self.waarde)
Or, a little bit more generic:
def __repr__(self):
return "%s(%d,%d)" % (self.__class__.__name__, self.grondtal, self.waarde)
For example:
>>> m = Modulo(3,2)
>>> repr(m)
'Modulo(3,2)'
I would like to emulate a SNMP device, who i don't have the MIB file from device.
I just need to emulate one function, a writable OctectString value.
Here is my code:
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
import time, bisect
from pysnmp import debug
debug.setLogger(debug.Debug('all'))
class SysDescr:
name = (1, 3, 6, 1, 2, 1, 1, 1, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'PySNMP responder'
)
class Domabox:
name = (1, 3, 6, 1, 2, 1, 1, 2, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'Domabox responder'
)
class Uptime:
name = (1, 3, 6, 1, 2, 1, 1, 3, 0)
birthday = time.time()
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].TimeTicks(
(time.time()-self.birthday)*100
)
class Remote:
name = (1, 3, 6, 1, 2, 1, 1, 4, 0)
def __eq__(self, other): return self.name == other
def __ne__(self, other): return self.name != other
def __lt__(self, other): return self.name < other
def __le__(self, other): return self.name <= other
def __gt__(self, other): return self.name > other
def __ge__(self, other): return self.name >= other
def __call__(self, protoVer):
return api.protoModules[protoVer].OctetString(
'Remote'
)
mibInstr = (
SysDescr(), Domabox(), Uptime(), Remote(), # sorted by object name
)
mibInstrIdx = {}
for mibVar in mibInstr:
mibInstrIdx[mibVar.name] = mibVar
def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
while wholeMsg:
msgVer = api.decodeMessageVersion(wholeMsg)
pMod = api.protoModules[api.protoVersion1]
reqMsg, wholeMsg = decoder.decode(
wholeMsg, asn1Spec=pMod.Message(),
)
rspMsg = pMod.apiMessage.getResponse(reqMsg)
rspPDU = pMod.apiMessage.getPDU(rspMsg)
reqPDU = pMod.apiMessage.getPDU(reqMsg)
print "reqPDU", reqPDU
varBinds = []; pendingErrors = []
errorIndex = 0
# GETNEXT PDU
if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
# Produce response var-binds
for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
errorIndex = errorIndex + 1
# Search next OID to report
nextIdx = bisect.bisect(mibInstr, oid)
if nextIdx == len(mibInstr):
# Out of MIB
varBinds.append((oid, val))
pendingErrors.append(
(pMod.apiPDU.setEndOfMibError, errorIndex)
)
else:
# Report value if OID is found
varBinds.append(
(mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer))
)
elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
if oid in mibInstrIdx:
varBinds.append((oid, mibInstrIdx[oid](msgVer)))
else:
# No such instance
varBinds.append((oid, val))
pendingErrors.append(
(pMod.apiPDU.setNoSuchInstanceError, errorIndex)
)
break
elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):
print "request ?"
else:
print "unsupported..."
# Report unsupported request type
pMod.apiPDU.setErrorStatus(rspPDU, 'genErr')
pMod.apiPDU.setVarBinds(rspPDU, varBinds)
# Commit possible error indices to response PDU
for f, i in pendingErrors:
f(rspPDU, i)
transportDispatcher.sendMessage(
encoder.encode(rspMsg), transportDomain, transportAddress
)
return wholeMsg
transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerRecvCbFun(cbFun)
# UDP/IPv4
transportDispatcher.registerTransport(
udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161))
)
# UDP/IPv6
transportDispatcher.registerTransport(
udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161))
)
transportDispatcher.jobStarted(1)
try:
# Dispatcher will never finish as job#1 never reaches zero
transportDispatcher.runDispatcher()
except:
transportDispatcher.closeDispatcher()
raise
When i send a snmp write value, i got
;AttributeError: 'module' object has no attribute 'setRequestPDU'
from line
elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):
var reqPDU content:
reqPDU SetRequestPDU().setComponentByPosition(0, Integer(1639861451)).setComponentByPosition(1, Integer('noError')).setComponentByPosition(2, Integer(0)).setComponentByPosition(3, VarBindList().setComponentByPosition(0, VarBind().setComponentByPosition(0, ObjectName(1.3.6.1.2.1.1.4.0)).setComponentByPosition(1, ObjectSyntax().setComponentByPosition(0, SimpleSyntax().setComponentByPosition(1, OctetString('57'))))))
Thanks.
You probably meant pMod.SetRequestPDU() in your code (notice capital 'S').
However, instead of writing your own emulator, I'd suggest considering a general purpose SNMP simulator which could be configured to emulate a full blown SNMP-capable device.
This is the trajectory of a pedestrian moving in jam
As you can see, his/her head perform an oscillation-like movement. So not a perfect sinus curve but neither a line.
Is it possible to define for this irregular curve an "amplitude" and a "frequency"?
UPDATE:
So far I tried two different approaches:
The first one is based on calculating the turning points and then make a spline with them.
The second approach is based on the suggestion of unutbu and uses the Ramer-Douglas-Peucker algorithm.
The results are as follows:
The problem that I see with the RDP is the free parameter dist. low values (means more details) imply oscillations in the resulting trajectories. So I'm forced to be careful with this parameter. Besides, the splined curve is much more smoother.
What do you think?
There is no absolute correct way to do this. Below is just one way.
Let's start with the assumption/claim that people generally intend to walk in straight lines. So you could use the Ramer-Douglas-Peucker algorithm to estimate the intended path of the person with a small set of line segments. (There is a Python implementation of the algorithm here.)
Then generate the distances of the true data points from the line segments.
timeseries = []
for point in points:
timeseries.append(
min((distance between point and segment)
for segment in segments))
This array of distances is a timeseries. You could then take the root-mean-squared of the timeseries as a measure of amplitude, and take a Fourier transform to find its dominant frequency (or frequencies).
Here is an update to RDP module you were linked to that should work with Python 3.x using Vectors:
import functools
def autocast(function):
#functools.wraps(function)
def wrapper(self, other):
if isinstance(other, self.__class__):
if len(other) != len(self):
raise ValueError('Object dimensions are not equivalent!')
return function(self, other)
return function(self, self.__class__(size=len(self), init=other))
return wrapper
class Vector:
__slots__ = '__data'
def __init__(self, *args, size=0, init=0):
self.__data = list(map(float, args if args else [init] * size))
def __repr__(self):
return self.__class__.__name__ + repr(tuple(self))
#autocast
def __cmp__(self, other):
return (self.__data > other.__data) - (self.__data < other.__data)
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __eq__(self, other):
return self.__cmp__(other) == 0
def __ne__(self, other):
return self.__cmp__(other) != 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def __bool__(self):
return any(self)
def __len__(self):
return len(self.__data)
def __getitem__(self, key):
return self.__data[key]
def __setitem__(self, key, value):
self.__data[key] = float(value)
def __delitem__(self, key):
self[key] = 0
def __iter__(self):
return iter(self.__data)
def __reversed__(self):
return reversed(self.__data)
def __contains__(self, item):
return item in self.__data
#autocast
def __add__(self, other):
return Vector(*(a + b for a, b in zip(self, other)))
#autocast
def __sub__(self, other):
return Vector(*(a - b for a, b in zip(self, other)))
#autocast
def __mul__(self, other):
return Vector(*(a * b for a, b in zip(self, other)))
#autocast
def __truediv__(self, other):
return Vector(*(a / b for a, b in zip(self, other)))
#autocast
def __floordiv__(self, other):
return Vector(*(a // b for a, b in zip(self, other)))
#autocast
def __mod__(self, other):
return Vector(*(a % b for a, b in zip(self, other)))
#autocast
def __divmod__(self, other):
result = tuple(divmod(a, b) for a, b in zip(self, other))
return Vector(*(a for a, b in result)), Vector(*(b for a, b in result))
#autocast
def __pow__(self, other):
return Vector(*(a ** b for a, b in zip(self, other)))
#autocast
def __radd__(self, other):
return Vector(*(a + b for a, b in zip(other, self)))
#autocast
def __rsub__(self, other):
return Vector(*(a - b for a, b in zip(other, self)))
#autocast
def __rmul__(self, other):
return Vector(*(a * b for a, b in zip(other, self)))
#autocast
def __rtruediv__(self, other):
return Vector(*(a / b for a, b in zip(other, self)))
#autocast
def __rfloordiv__(self, other):
return Vector(*(a // b for a, b in zip(other, self)))
#autocast
def __rmod__(self, other):
return Vector(*(a % b for a, b in zip(other, self)))
#autocast
def __rdivmod__(self, other):
result = tuple(divmod(a, b) for a, b in zip(other, self))
return Vector(*(a for a, b in result)), Vector(*(b for a, b in result))
#autocast
def __rpow__(self, other):
return Vector(*(a ** b for a, b in zip(other, self)))
#autocast
def __iadd__(self, other):
for key in range(len(self)):
self[key] += other[key]
return self
#autocast
def __isub__(self, other):
for key in range(len(self)):
self[key] -= other[key]
return self
#autocast
def __imul__(self, other):
for key in range(len(self)):
self[key] *= other[key]
return self
#autocast
def __itruediv__(self, other):
for key in range(len(self)):
self[key] /= other[key]
return self
#autocast
def __ifloordiv__(self, other):
for key in range(len(self)):
self[key] //= other[key]
return self
#autocast
def __imod__(self, other):
for key in range(len(self)):
self[key] %= other[key]
return self
#autocast
def __ipow__(self, other):
for key in range(len(self)):
self[key] **= other[key]
return self
def __neg__(self):
return Vector(*(-value for value in self))
def __pos__(self):
return Vector(*(+value for value in self))
def __abs__(self):
return Vector(*(abs(value) for value in self))
def __get_magnitude(self):
return sum(value ** 2 for value in self) ** 0.5
def __set_magnitude(self, value):
self *= value / self.magnitude
magnitude = property(__get_magnitude, __set_magnitude)
###############################################################################
def point_line_distance(point, start, end):
if start == end:
return (point - start).magnitude
es, sp = end - start, start - point
return abs(es[0] * sp[1] - es[1] * sp[0]) / es.magnitude
def rdp(points, epsilon):
dmax = index = 0
start, *middle, end = points
for i in range(1, len(points) - 1):
d = point_line_distance(points[i], start, end)
if d > dmax:
index, dmax = i, d
if dmax >= epsilon:
return rdp(points[:index+1], epsilon)[:-1] + \
rdp(points[index:], epsilon)
return start, end
Similar to the demonstration given by the original module, the following is an example usage scenario:
>>> from pprint import pprint
>>> line = [Vector(0.0, 0.0),
Vector(1.0, 0.0),
Vector(2.0, 0.0),
Vector(2.0, 1.0),
Vector(2.0, 2.0),
Vector(1.0, 2.0),
Vector(0.0, 2.0),
Vector(0.0, 1.0),
Vector(0.0, 0.0)]
>>> pprint(rdp(line, 1.0))
(Vector(0.0, 0.0),
Vector(2.0, 0.0),
Vector(2.0, 2.0),
Vector(0.0, 2.0),
Vector(0.0, 0.0))
>>>