Having an issue with Python's unittest - python

I am learning Python and trying to test a Polynomial class I wrote using unittest. It seems like I am getting different results from directly running a test in Python and running a test using unittest and I don't understand what's going on.
import unittest
from w4_polynomial import Polynomial
class TestPolynomialClass(unittest.TestCase):
def setUp(self):
self.A = Polynomial()
self.A[1] = 1
self.A[2] = 2
self.B = Polynomial()
self.B[1234] = 5678
def test_assertNotEq(self):
self.C = Polynomial()
self.C[1234] = 5678
self.C[1] = 1
self.C[2] = 3
self.assertNotEqual(self.A+self.B, self.C)
if __name__ == '__main__':
unittest.main()
Unittest fails... but I don't understand why. The two polynomials aren't the same. Here are the results from the same test done in a python script using print to compare. The polynomial is different, but same results:
A+B = 442x^123 + 12x^6 + 12x^4 + 5x^1 + 0x^0 + -99x^-12
C = 442x^123 + 12x^6 + 12x^4 + 5x^1 + 0x^0 + 99x^-12
A+B==C is False
Any help explaining what's going on would be greatly appreciated.
Sorry forgot the error from unittest,
FAIL: test_assertEq (__main__.TestPolynomialClass)
----------------------------------------------------------------------
Traenter code hereceback (most recent call last):
File "add.py", line 18, in test_assertEq
self.assertNotEqual(self.A+self.B, self.C)
AssertionError: <w4_polynomial.Polynomial object at 0x7f2d419ec390> == <w4_polynomial.Polynomial object at 0x7f2d419ec358>
And now the Polynomial Class:
class Polynomial():
def __init__(self, value=[0]):
self.v = []
self.n = []
temp = list(reversed(value[:]))
if value == [0]:
self[0] = 0
else:
for x in range(0, len(temp)):
self[x] = temp[x]
#self.__compress()
...
def __eq__(self, value):
temp1 = self.v[:]
temp2 = self.n[:]
temp3 = value.v[:]
temp4 = value.n[:]
temp1.sort()
temp2.sort()
temp3.sort()
temp4.sort()
return (temp1 == temp3 and temp2 == temp4)
def __ne__(self, value):
temp1 = self.v[:]
temp2 = self.n[:]
temp3 = value.v[:]
temp4 = value.n[:]
temp1.sort()
temp2.sort()
temp3.sort()
temp4.sort()
return (temp1 != temp3 and temp2 != temp4)
...
def main():
pass
if __name__=="__main__":
main()

I think the issue is with the implementation with def __ne__ function in Polynomial class.
assertNotEqual when called, expects a True value when the values passed are not equal. But in this class, you are directly sending the output of temp1 != temp3 and temp2 != temp4.
So, the function should be like this
def __ne__(self, value):
temp1 = self.v[:]
temp2 = self.n[:]
temp3 = value.v[:]
temp4 = value.n[:]
temp1.sort()
temp2.sort()
temp3.sort()
temp4.sort()
result = True if not (temp1 != temp3 and temp2 != temp4) else False
return result

Related

Need an OOP method for share variable between function?

I have a class and some functions. In the 'check_reflexive()' function, there is a variable called reflexive_list. I want to use this variable also in the 'antisymmetric' function.
I checked some examples about class but didn't find a specific example to solve this problem.
I'll be waiting for your advice. Hope you have a nice day
class MyClass():
def __init__(self):
def checkif_pair(k):
for a in k:
if a%2 == 0:
None
else:
return False
return True
def check_reflexive(k):
j = 0
z = 0
reflexive_list = []
while j < len(k):
i = 0
while i < len(k):
if k[i] == k[j]:
tup = k[j],k[i]
reflexive_list.append(tup)
i += 1
else:
None
j = j + 1
else:
None
print(reflexive_list)
if len(reflexive_list) == len(self.list1):
return True
else:
return False
def antisymmetric(k):
antisymettric_list = []
for b in k:
swap1 = b[0]
swap2 = b[1]
newtuple = (swap2, swap1)
antisymettric_list.append(newtuple)
for ü in reflexive_list:
if ü in antisymettric_list:
antisymettric_list.remove(ü)
else:
None
print(antisymettric_list)
for q in antisymettric_list:
if q in k:
print("The system is not Anti-Symmetric.")
break
print("The system is Anti-Symmetric.")
def transitive(k):
result = {}
for first, second in k:
result.setdefault(first, []).append(second)
print(result)
for a, b in k:
for x in result[b]:
if x in result[a]:
None
else:
print("There is no {} in the {}".format(x, result[a]))
return False
return True
You can just use reflexive_list as an instance variable. Just add a constructor where the variable is defined:
class MyClass():
def __init__(self):
self.reflexive_list = []
And everytime you want to use it inside the function, you use self.reflexive_list

Getting Pylint E1101 - Instance has no such member

Pylint doesn't like this code:
class sequence(list):
def __init__(self, n):
list.__init__(self)
self += self._generate_collatz_seq(n)
self.pivots = self._generate_pivots()
self.data = self._make_data()
def _collatz_function(self, n):
if n % 2 == 0:
return(int(n/2))
else:
return(3*n + 1)
def _generate_collatz_seq(self, x):
int(x)
sequence_holder = []
while x != 1:
sequence_holder.append(x)
x = self._collatz_function(x)
sequence_holder.append(1)
return sequence_holder
def _generate_pivots(self):
pivots_holder = []
for element in self:
if element % 2 != 0:
pivots_holder.append(element)
return pivots_holder
def _make_data(self):
data_holder = []
data_holder.append(len(self))
data_holder.append(len(self.pivots))
return data_holder
It says
E1101: Instance of 'sequence' has no 'pivots' member(56,36)
This is before I have made any instances of sequence. I'm sure I haven't gone about my task in the most efficient way, but I can't see that I've done anything wrong.

Why does passing a dictionary as a parameter take more time?

I tried to a leetcode problem. I find one of the following code throws a time limit exceeded error. I created the following testing code. I found the first one pass dictionary as a parameter takes more time the the other one. 0.94s vs 0.84s.
Can anyone explain this ?
class Solution(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
#dic = {}
def helper(s, dic):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1], dic)+2
else:
l1 = helper(s[:-1], dic)
l2 = helper(s[1:], dic)
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
d = {}
ans = helper(x, d)
#print (id(d), d)
return ans
class Solution1(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
dic = {}
def helper(s):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1])+2
else:
l1 = helper(s[:-1])
l2 = helper(s[1:])
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
ans = helper(x)
#print (id(dic), dic)
return ans
import time
if __name__ == "__main__":
x = "gphyvqruxjmwhonjjrgumxjhfyupajxbjgthzdvrdqmdouuukeaxhjumkmmhdglqrrohydrmbvtuwstgkobyzjjtdtjroqpyusfsbjlusekghtfbdctvgmqzeybnwzlhdnhwzptgkzmujfldoiejmvxnorvbiubfflygrkedyirienybosqzrkbpcfidvkkafftgzwrcitqizelhfsruwmtrgaocjcyxdkovtdennrkmxwpdsxpxuarhgusizmwakrmhdwcgvfljhzcskclgrvvbrkesojyhofwqiwhiupujmkcvlywjtmbncurxxmpdskupyvvweuhbsnanzfioirecfxvmgcpwrpmbhmkdtckhvbxnsbcifhqwjjczfokovpqyjmbywtpaqcfjowxnmtirdsfeujyogbzjnjcmqyzciwjqxxgrxblvqbutqittroqadqlsdzihngpfpjovbkpeveidjpfjktavvwurqrgqdomiibfgqxwybcyovysydxyyymmiuwovnevzsjisdwgkcbsookbarezbhnwyqthcvzyodbcwjptvigcphawzxouixhbpezzirbhvomqhxkfdbokblqmrhhioyqubpyqhjrnwhjxsrodtblqxkhezubprqftrqcyrzwywqrgockioqdmzuqjkpmsyohtlcnesbgzqhkalwixfcgyeqdzhnnlzawrdgskurcxfbekbspupbduxqxjeczpmdvssikbivjhinaopbabrmvscthvoqqbkgekcgyrelxkwoawpbrcbszelnxlyikbulgmlwyffurimlfxurjsbzgddxbgqpcdsuutfiivjbyqzhprdqhahpgenjkbiukurvdwapuewrbehczrtswubthodv"
print (x)
t0 = time.time()
sol = Solution()
print (sol.longestPalindromeSubseq(x))
t1 = time.time()
print(t1- t0)
sol1 = Solution1()
print (sol1.longestPalindromeSubseq(x))
t2 = time.time()
print(t2-t1)
Python uses something that is called call by sharing. The function gets only the alias on the parameter. With that in mind, it does't matter what you pass to the function.
But the script may take different time to execute. It is not constant. Using recursion makes it even harder to predict

nice decimal.Decimal autonormalization

This gonna be my first question here. I am trying to make a decimal.Decimal child class which mainly differs the parent by making autonormalization on itself and on the results of its callable arguments whose returns Decimal objects. The code below have the concept to
decorate all methods of Decimal to return MyDecimal instances (whose trim zeros of the end of their strings by creation) instead of decimal.Decimals. For this, metaclass was used.
However, I feel this code a bit hacky though. Moreover, according to the speed test results, it is also damn slow: 2.5 secs for the decimal.Decimal vs. 16 secs for MyDecimal on my system.
My question is: Is there a cleaner (and faster) way of doing this?
import decimal
class AutoNormalizedDecimal(type):
def __new__(cls, name, bases, local):
local_items = list(local.items())
parent_items = [i for i in bases[0].__dict__.items()
if i[0] not in local.keys()]
for a in local_items + parent_items:
attr_name, attr_value = a[0], a[1]
if callable(attr_value):
local[attr_name] = cls.decorator(attr_value)
return super(AutoNormalizedDecimal, cls).__new__(
cls, name, bases, local)
#classmethod
def decorator(cls, func):
def wrapper_for_new(*args, **kwargs):
new_string = args[1].rstrip('0').rstrip('.')
if not new_string:
new_string = '0'
newargs = (args[0], new_string)
return func(*newargs, **kwargs)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
if (isinstance(result, decimal.Decimal)
and not isinstance(result, MyDecimal)):
return MyDecimal(str(result))
return result
if func.__name__ == '__new__':
return wrapper_for_new
return wrapper
class MyDecimal(decimal.Decimal, metaclass=AutoNormalizedDecimal):
def __str__(self):
return decimal.Decimal.__str__(self).replace('.', ',')
n = MyDecimal('-5423.5420000')
def speedtest():
import time
start = time.time()
d = decimal.Decimal('6')
for i in range(1000000):
d += decimal.Decimal(str(i))
print(time.time()-start)
start = time.time()
d = MyDecimal('6')
for i in range(1000000):
d += MyDecimal(str(i))
print(time.time()-start)
Here is how this works:
>>> n
Decimal('-5423.542')
>>> type(n)
<class '__main__.MyDecimal'>
>>> str(n)
'-5423,542'
>>> x = MyDecimal('542.63') / MyDecimal('5.2331')
>>> x
Decimal('103.6918843515315969501824922')
>>> type(x)
<class '__main__.MyDecimal'>
>>> y = MyDecimal('5.5252') - MyDecimal('0.0052')
>>> y
Decimal('5.52')
>>> z = decimal.Decimal('5.5252') - decimal.Decimal('0.0052')
>>> z
Decimal('5.5200')
Thanks in advance!
PS: Credit goes to Anurag Uniyal for his code which gave me a way to start: https://stackoverflow.com/a/3468410/2334951
EDIT1: I came out to redefine as_tuple() method which I could call all the time I need the trimmed Decimal version:
class MyDecimal(decimal.Decimal):
def as_tuple(self):
sign, digits_, exponent = super().as_tuple()
digits = list(digits_)
while exponent < 0 and digits[-1] == 0:
digits.pop()
exponent += 1
while len(digits) <= abs(exponent):
digits.insert(0, 0)
return decimal.DecimalTuple(sign, tuple(digits), exponent)
def __str__(self):
as_tuple = self.as_tuple()
left = ''.join([str(d) for d in as_tuple[1][:as_tuple[2]]])
right = ''.join([str(d) for d in as_tuple[1][as_tuple[2]:]])
return ','.join((left, right))

Python -- TypeError on string format from binary output

I'm getting a getting a TypeError for unbound method (at the bottom). I'm teaching myself Python so this may be some simple mistake. The issue is with outFormat(), which didn't give me problems when I test it by itself but is not working within the class. Here's the class:
class gf2poly:
#binary arithemtic on polynomials
def __init__(self,expr):
self.expr = expr
def id(self):
return [self.expr[i]%2 for i in range(len(self.expr))]
def listToInt(self):
result = gf2poly.id(self)
return int(''.join(map(str,result)))
def prepBinary(a,b):
a = gf2poly.listToInt(a); b = gf2poly.listToInt(b)
bina = int(str(a),2); binb = int(str(b),2)
a = min(bina,binb); b = max(bina,binb);
return a,b
def outFormat(raw):
raw = str(raw); g = []
[g.append(i) for i,c in enumerate(raw) if c == '1']
processed = "x**"+' + x**'.join(map(str, g[::-1]))
#print "processed ",processed
return processed
def divide(a,b): #a,b are lists like (1,0,1,0,0,1,....)
a,b = gf2poly.prepBinary(a,b)
bitsa = "{0:b}".format(a); bitsb = "{0:b}".format(b)
difflen = len(str(bitsb)) - len(str(bitsa))
c = a<<difflen; q=0
while difflen >= 0 and b != 0:
q+=1<<difflen; b = b^c
lendif = abs(len(str(bin(b))) - len(str(bin(c))))
c = c>>lendif; difflen -= lendif
r = "{0:b}".format(b); q = "{0:b}".format(q)
#print "r,q ",type(r),type(q)
return r,q #returns r remainder and q quotient in gf2 division
def remainder(a,b): #separate function for clarity when calling
r = gf2poly.divide(a,b)[0]; r = int(str(r),2)
return "{0:b}".format(r)
def quotient(a,b): #separate function for clarity when calling
q = gf2poly.divide(a,b)[1]; q = int(str(q),2)
return "{0:b}".format(q)
This is how I'm calling it:
testp = gf2poly.quotient(f4,f2)
testr = gf2poly.remainder(f4,f2)
print "quotient: ",testp
print "remainder: ",testr
print "***********************************"
print "types ",type(testp),type(testr),testp,testr
testp = str(testp)
print "outFormat testp: ",gf2poly.outFormat(testp)
#print "outFormat testr: ",gf2poly.outFormat(testr)
This is the error:
TypeError: unbound method outFormat() must be called with gf2poly instance as first argument (got str instance instead)
Where you have this:
def outFormat(raw):
You probably want either this:
def outFormat(self, raw):
Or this:
#staticmethod
def outFormat(raw):
The former if you eventually need access to self in outFormat(), or the latter if you do not (as currently is the case in the posted code).

Categories

Resources