I would like to know how to define a new numerical base in Python.
For example:
base dimension = 4
Charset = 'u', '$', '6', '}' (from the least important to the most)
I would like to know how to create and handle it, to be able to do simple arithmetic like:
$} + 6u * 6 = $$}
7 + 8 * 2 = 23
I know I could use replace to replace u -> 0, $ -> 1 and so on, and use the int() function. However int() is not defined for base > 36, and I will have to handle these cases.
I know I could make my own function to convert them to base 10, do the math, and convert them back, but I would like to avoid that if possible.
Rather than replace, you can use dictionaries to translate back and forth between the charset and regular ints, something like:
charset = 'u$6}'
b = len(charset) #base
vals = {c:i for i,c in enumerate(charset)}
digits = {vals[c]: c for c in vals} #inverse dictionary
def toInt(s):
return sum(vals[c]*b**i for i,c in enumerate(reversed(s)))
def toNewBase(n):
nums = [] if n > 0 else [0]
while n > 0:
n,r = divmod(n,b)
nums.append(r)
return ''.join(digits[i] for i in reversed(nums))
def add(s,t):
return toNewBase(toInt(s) + toInt(t))
def subtract(s,t):
return toNewBase(toInt(s) - toInt(t))
def multiply(s,t):
return toNewBase(toInt(s) * toInt(t))
def divide(s,t):
return toNewBase(toInt(s) // toInt(t))
typical output:
>>> add('$}',multiply('6u','6'))
'$$}'
def str_base(number, base):
# http://stackoverflow.com/a/24763277/3821804
(d,m) = divmod(number,len(base))
if d > 0:
return str_base(d,base)+base[m]
return base[m]
def charset(chars):
class cls(int):
__slots__ = ()
def __new__(cls, src):
if isinstance(src, str):
return int.__new__(
cls,
''.join(str(chars.index(i)) for i in src),
len(chars)
)
return int.__new__(cls, src)
def __str__(self):
return str_base(self, chars)
def __repr__(self):
return '%s(%r)' % (type(self).__name__, str(self))
cls.__name__ = 'charset(%r)' % chars
return cls
Usage:
test = charset('u$6}')
print(test( test('$}') + test('6u') * test('6') ) ) # => '$$}'
See it working online: http://rextester.com/WYSE48066
At the moment, I'm too tired to explain it.
Related
I have a little program here which try to generate a specific hash value for a website (Path of Exile Passive Tree).
Here is my code:
####### ByteEncoder.py (This is a python convert from the official js code )
class ByteEncoder:
def __init__(self):
self.dataString = ""
def intToBytes(self, t, n=4):
t = int(t)
i = [None] * n
s = n - 1
while True:
i[s] = 255 & t
t = t>>8
s -= 1
if s < 0:
break
return i
def appendInt(self, t, n):
i = self.intToBytes(t,n)
for r in range(0, n):
self.dataString += chr(i[r])
def appendInt8(self, t):
self.appendInt(t, 1)
def appendInt16(self, t):
self.appendInt(t, 2)
def getDataString(self):
return self.dataString
##### main.py
hashes = [465, 45035]
encoder = ByteEncoder()
encoder.appendInt(4,4) # Tree Version
encoder.appendInt8(2) # Class ID
encoder.appendInt8(0) # Ascendency class
encoder.appendInt8(1) # Fullscreen
for h in hashes:
encoder.appendInt16(h)
d = str(base64.b64encode(bytes(encoder.getDataString(),encoding='utf8')))
d = d.replace("+", "-").replace("/", "_")
print(d)
I get the Hash AAAABAIAAQHDkcKvw6s= but i should get AAAABAIAAQHRr-s=
Can someone tell me why?
If you wanna test this
What i want:
https://www.pathofexile.com/fullscreen-passive-skill-tree/3.6.6/AAAABAIAAQHRr-s=
What i get:
https://www.pathofexile.com/fullscreen-passive-skill-tree/3.6.6/AAAABAIAAQHDkcKvw6s=
Here is the Anwser from the comment of Victor.
Simply use base64.urlsafe_b64encode()
You are treating your text string as if it where bytes, and then encoding it with utf-8, which is a multi-byte encoding.
If you need a "transparent" text-to-bytes encoding, use "latin-1".
However, in this code, you should not have been using a text-string ("str") to startwith. It will also simplify things in that you can concatenate the integers directly into your data, instead of converting byte by byte:
...
class ByteEncoder:
def __init__(self):
self.data = bytes()
...
def appendInt(self, t, n):
i = self.intToBytes(t,n)
self.data += i
...
# Also,in Python, there is no sense in writting a "getter" to
# just return an attribute as it is - no need for an equivalent
# of your `.getDataString` method:
d = str(base64.b64encode(encoder.data))
So I am supposed to devise a program that counts a DNA sequence as well as count the individual base pairs. Here's what I have thus far:
class dnaString (str):
def __new__(self,s):
return str.__new__(self,s.upper())
def length (self):
return (len(self))
def getATCG (self,num_A,num_T,num_C,num_G):
num_A = self.count("A")
num_T = self.count("T")
num_C = self.count ("C")
num_G = self.count ("G")
return ( (self.length(), num_A, num_T, num_G, num_C) )
def printnum_A (self):
print ("Adenine base content: {0}".format(self.count("A")))
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
The program doesn't really do anything, and since I'm just starting out with python, I'm not sure how to fix this so it works. what else should I add? I know it's unfinished.
I'm not sure what is the question, but as you are not calling the method ´printnum_A`, nothing is printing. If you call it like this, it works:
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
x.printnum_A()
Update according to comments
It is not enough to declare the methods of a class, you need also to call then when you need them. Like here for printnum_T:
class dnaString (str):
def __new__(self,s):
return str.__new__(self,s.upper())
def length (self):
return (len(self))
def getATCG (self,num_A,num_T,num_C,num_G):
num_A = self.count("A")
num_T = self.count("T")
num_C = self.count ("C")
num_G = self.count ("G")
return ( (self.length(), num_A, num_T, num_G, num_C) )
def printnum_A (self):
print ("Adenine base content: {0}".format(self.count("A")))
# here the method is declared
def printnum_T (self):
print ("Adenine base content: {0}".format(self.count("T")))
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
x.printnum_A()
# Here I call my method on `x`
x.printnum_T()
I think the class can be simplified a bit:
class DnaString(str):
def __new__(self, s):
return str.__new__(self, s.strip().upper())
def __init__(self, _):
self.num_A = self.count("A")
self.num_C = self.count("C")
self.num_G = self.count("G")
self.num_T = self.count("T")
def stats(self):
return len(self), self.num_A, self.num_C, self.num_G, self.num_T
then
dna = raw_input("Enter a dna sequence: ")
d = DnaString(dna)
print(d)
print(d.stats())
gives
Enter a dna sequence: ACGTACGTA
ACGTACGTA
(9, 3, 2, 2, 2)
Does this help? It works in Python 2.7.3 and 3.2.3 that I happen to have installed.
import itertools
import sys
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
if sys.version_info[0] > 2:
return zip(a,b)
return itertools.izip(a, b)
class DnaSequence():
Names = {
'A' : 'adenine',
'C' : 'cytosine',
'G' : 'guanine',
'T' : 'thymine'
}
Bases = Names.keys()
def __init__(self, seq):
self._string = seq
self.bases = { x:0 for x in DnaSequence.Bases }
self.pairs = { x+y:0 for x in DnaSequence.Bases
for y in DnaSequence.Bases }
for base in seq:
if base in self.bases:
self.bases[base] += 1
for x,y in pairwise(seq):
pair = x+y
if pair in self.pairs:
self.pairs[pair] += 1
def printCount(self, base):
if base in DnaSequence.Names:
print(DnaSequence.Names[base].capitalize() +
" base content: " + str(self.bases[base]))
else:
sys.stderr.write('No such base ("%s")\n' % base)
def __repr__(self):
return self._string
d = DnaSequence("CCTAGTGTTAGCTAGTCTAGGGAT")
for base in DnaSequence.Bases:
d.printCount(base)
# Further:
print(d)
print(d.bases)
print(d.pairs)
It's a complete example that counts the bases (A, C, G, T) and all occurrences of adjacent pairs (e.g. in ACCGTA, the pairs AC, CC, CG, GT, TA would all be 1, the other 11 possible combinations of the Cartesian product ACGT x ACGT would all be 0).
The counting method used here scans the string once in the constructor, rather than scanning it four times every time getATGC() is called.
You can do this by using a dictionary to organize and retrieve your counts. For instance:
DNASeq = raw_input("Enter a DNA sequence: ")
SeqLength = len(DNASeq)
print 'Sequence Length:', SeqLength
BaseKey = list(set(DNASeq)) #creates a list from the unique characters in the DNASeq
Dict = {}
for char in BaseKey:
Dict[char] = DNASeq.count(char)
print Dict
I'm trying to use the parent class's __div__() in order to maintain the same type so that many operations can be called at once as in the last example mix1 = bf2/bf4*bf1%bf5 in main() below where multiple arithmetic operations are strung together. For some reason, I can use super() in __add__() but not in __div__(). The error is "IndexError: list index out of range" and I've been going over and over this without any progress. Note that this is all related to polynomial arithmetic within a finite field.
I'm including the parsePolyVariable() and it's dependents (sorry if it looks like there's a bit of code but I assure you it's all for a good cause and builds character), since that's where the list error seems to be stemming from but I can't for the life of me figure out where everything is going very wrong. I'm teaching myself Python, so I'm sure there are some other beginners out there who will see where I'm missing the obvious.
I've been looking over these but they don't seem to be related to this situation:
http://docs.python.org/2/library/functions.html#super
Python super(Class, self).method vs super(Parent, self).method
How can I use Python's super() to update a parent value?
import re
class GF2Polynomial(object): #classes should generally inherit from object
def __init__(self, string):
'''__init__ is a standard special method used to initialize objects.
Here __init__ will initialize a gf2infix object based on a string.'''
self.string = string #basically the initial string (polynomial)
#if self.parsePolyVariable(string) == "0": self.key,self.lst = "0",[0]
#else:
self.key,self.lst = self.parsePolyVariable(string) # key determines polynomial compatibility
self.bin = self.prepBinary(string) #main value used in operations
def id(self,lst):
"""returns modulus 2 (1,0,0,1,1,....) for input lists"""
return [int(lst[i])%2 for i in range(len(lst))]
def listToInt(self,lst):
"""converts list to integer for later use"""
result = self.id(lst)
return int(''.join(map(str,result)))
def parsePolyToListInput(self,poly):
"""
replaced by parsePolyVariable. still functional but not needed.
performs regex on raw string and converts to list
"""
c = [int(i.group(0)) for i in re.finditer(r'\d+', poly)]
return [1 if x in c else 0 for x in xrange(max(c), -1, -1)]
def parsePolyVariable(self,poly):
"""
performs regex on raw string, converts to list.
also determines key (main variable used) in each polynomial on intake
"""
c = [int(m.group(0)) for m in re.finditer(r'\d+', poly)] #re.finditer returns an iterator
if sum(c) == 0: return "0",[0]
letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)]
degree = max(c); varmatch = True; key = letter[0]
for i in range(len(letter)):
if letter[i] != key: varmatch = False
else: varmatch = True
if varmatch == False: return "error: not all variables in %s are the same"%a
lst = [1 if x in c else (1 if x==0 else (1 if x=='x' else 0)) for x in xrange(degree, -1, -1)]
return key,lst
def polyVariableCheck(self,other):
return self.key == other.key
def prepBinary(self,poly):
"""converts to base 2; bina,binb are binary values like 110100101100....."""
x = self.lst; a = self.listToInt(x)
return int(str(a),2)
def __add__(self,other):
"""
__add__ is another special method, and is used to override the + operator. This will only
work for instances of gf2pim and its subclasses.
self,other are gf2infix instances; returns GF(2) polynomial in string format
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
return GF2Polynomial(self.outFormat(self.bin^other.bin))
def __sub__(self,other):
"""
__sub__ is the special method for overriding the - operator
same as addition in GF(2)
"""
return self.__add__(other)
def __mul__(self,other):
"""
__mul__ is the special method for overriding the * operator
returns product of 2 polynomials in gf2; self,other are values 10110011...
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
bitsa = reversed("{0:b}".format(self.bin))
g = [(other.bin<<i)*int(bit) for i,bit in enumerate(bitsa)]
return GF2Polynomial(self.outFormat(reduce(lambda x,y: x^y,g)))
def __div__(self,other):
"""
__div__ is the special method for overriding the / operator
returns quotient formatted as polynomial
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.bin == other.bin: return 1
return GF2Polynomial(self.outFormat(self.bin/other.bin))
def __mod__(self,other):
"""
__mod__ is the special method for overriding the % operator
returns remainder formatted as polynomial
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.bin == other.bin: return 0
return GF2Polynomial(self.outFormat(self.bin%other.bin))
def __str__(self):
return self.string
def outFormat(self,raw):
"""process resulting values into polynomial format"""
raw = "{0:b}".format(raw); raw = str(raw[::-1]); g = [] #reverse binary string for enumeration
g = [i for i,c in enumerate(raw) if c == '1']
processed = "x**"+" + x**".join(map(str, g[::-1]))
proc1 = processed.replace("x**1","x"); proc2 = proc1.replace("x**0","1")
if len(g) == 0: return 0 #return 0 if list empty
return proc2 #returns result in gf(2) polynomial form
class BinaryField(GF2Polynomial):
def __init__(self, poly, mod):
if mod == "0": self.string = "Error: modulus division by 0"
elif mod == "0": self.string = "%s is 0 so resulting mod is 0"%(poly)
fieldPoly = GF2Polynomial(poly) % mod
if fieldPoly == 0: self.string = "%s and %s are the same so resulting mod is 0"%(poly,mod)
else: super(BinaryField, self).__init__(fieldPoly.string)
#self.degree = len(str(fieldPoly))
def polyFieldCheck(self,other):
return self.degree() == other.degree()
def __add__(self, other):
"""
inherited from GF2Polynomial
"""
return super(BinaryField, self).__add__(other) % min(other,self)
def __sub__(self,other):
"""
inherited from GF2Polynomial
"""
return self.__add__(other)
def __mul__(self, other):
"""
special method of BinaryField, needed for format adjustments between classes
"""
#print "self = %s,%s other = %s,%s "%(self.degree(),type(self.degree()),other.degree(),type(other.degree()))
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.polyFieldCheck(other) == False:
return "error: fields of %s and %s do not match"%(self.string,other.string)
else: print "Operation will proceed: fields of %s and %s match"%(self.string,other.string)
bitsa = reversed("{0:b}".format(self.bin))
g = [(other.bin<<i)*int(bit) for i,bit in enumerate(bitsa)]
result = reduce(lambda x,y: x^y,g)%min(self.bin,other.bin)
return GF2Polynomial(self.outFormat(result))
def __div__(self, other):
"""
special method of BinaryField, needed for format adjustments between classes
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.polyFieldCheck(other) == False:
return "error: fields of %s and %s do not match"%(self.string,other.string)
else: print "Operation will proceed: fields of %s and %s match"%(self.string,other.string)
if self.bin == other.bin: return 1
result = self.bin/other.bin
#return self.outFormat(result)
return super(BinaryField, self).__div__(other) #% min(other,self)
def degree(self):
return len(self.lst)-1
And here's the main():
if __name__ == '__main__':
## "x**1 + x**0" polynomial string style input
poly1 = "x**14 + x**1 + x**0"; poly2 = "x**6 + x**2 + x**1"; poly3 = "y**6 + y**2 + y**1"
a = GF2Polynomial(poly1); b = GF2Polynomial(poly2); c = GF2Polynomial(poly3)
## "x+1" polynomial string style input
poly4 = "x**14 + x + 1"; poly5 = "x**6 + x**2 + x"; poly6 = "x**8 + x**3 + 1"
d = GF2Polynomial(poly4); e = GF2Polynomial(poly5); f = GF2Polynomial(poly6)
poly7 = "x**9 + x**5 + 1"; poly8 = "x**11 + x**7 + x**4 + 1"; poly9 = "x**5 + x**4 + x**2 + x"
g = GF2Polynomial(poly7); h = GF2Polynomial(poly8); i = GF2Polynomial(poly9)
## g = GF2Polynomial("x**5 + x**4 + x**3 + 1"); h = GF2Polynomial("x**5 + x"); print "(g*h)%b = ",(g*h)%b
## dd = GF2Polynomial("x**0"); print "dd -- ",dd
## ee = GF2Polynomial("0"); print "ee -- ",ee
bf1 = BinaryField(poly1,b); print bf1; print "degree bf1 = ",bf1.degree()
bf2 = BinaryField(poly4,e); print "bf2 ",bf2; bf3 = BinaryField(poly4,d); print "bf3 ",bf3,type(bf3)
bf4 = BinaryField(poly4,h); bf5 = BinaryField(poly9,e); bf6 = BinaryField(poly8,i)
add1 = bf1+bf2
print "add1 ",add1
div1 = bf1/bf2
print "div1 ",div1,type(div1)
mix1 = bf2*bf1%bf5
print "mix1 ",mix1,type(mix1)
EDIT:
The full traceback --
Message File Name Line Position
Traceback
<module> C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 233
__div__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 197
__div__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 100
__init__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 20
parsePolyVariable C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 48
IndexError: list index out of range
For reference line 48 is degree = max(c); varmatch = True; key = letter[0].
Personal notes and information were removed, adjusting the line numbers.
Your return GF2Polynomial(self.outFormat(self.bin/other.bin)) line results in the string 1, which is then passed to the GF2Polynomial.parsePolyVariable() method.
This value has no letters, so the line:
letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)]
returns an empty list. The next line:
degree = max(c); varmatch = True; key = letter[0]
then fails because key = letter[0] gives a IndexError exception.
Your code is hard to read because you use one-letter variables and put multiple statements on one line, so it is hard to make out what your expectations are in that function.
The exception has otherwise nothing to do with super(). There is a simple bug in your own code somewhere.
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))
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).