I'm trying to learn how to correctly use classes in python, I'm fairly new to it but I cant get this class to return a string output of all the values. Ideally I'd like to be able to just str(packet) into a network socket.
class ARP():
dst_addr = ''
src_addr = ''
type = '\x08\x06'
payload = '\x00\x01\x08\x00\x06\x04\x00'
arptype = '\x01'
src_mac_addr = ''
src_ip_addr = ''
dst_mac_addr = ''
dst_ip_addr = ''
def __repr_(self):
return 'ARP'
def __str__(self):
return dst_addr + src_addr + type + payload + arptype \
+ src_mac_addr + src_ip_addr + dst_mac_addr + dst_ip_addr
p = ARP()
p.dst_addr = router_mac
p.src_addr = random_mac()
p.arptype = '\x02'
p.src_mac_addr = local_mac
p.src_ip_addr = ip_s2n(target_ip)
p.dst_mac_addr = router_mac
p.dst_ip_addr = ip_s2n(router_ip)
print 'PACKET: ', str(p)
return str(p)
This code outputs nothing at all. repr() outputs <__main__.ARP instance at 0x2844ea8> which I guess is what it's meant to do?
You are missing an underscore in your __repr__ method name:
def __repr_(self):
# ---------^
Python looks for __repr__, not __repr_.
Next, your __str__ method should refer to attributes on self, not to globals. Perhaps a str.join() call would be helpful here too:
def __str__(self):
return ''.join([getattr(self, attr) for attr in (
'dst_addr', 'src_addr', 'type', 'payload', 'arptype', 'src_mac_addr',
'src_ip_addr', 'dst_mac_addr', 'dst_ip_addr')])
Related
So this is the class i'm testing:
class Test:
def find_string(self, string):
self.string = string
return string.find(string)
def add_string(self, string):
found = self.find_string('bar')
if found == -1:
string = string + ' bar'
return string
Here is my setup:
test_string = 'foo'
Test1 = Test()
new_string = Test1.add_string(string)
Results
Expected result: foo bar
Result: foo
If I replace the method call in add_string with the direct function find() it works fine. Please help me.
As for me all problem is that variables have similar names and this can be misleading.
Your string.find(string) means "bar".find("bar") but you expect "foo".find("bar")
You would have to use self.string = string in add_string() (instead of find_string()) and later in find_string() use self.string.find(string) instead of string.find(string) - and then you will have "foo" in self.string and "bar" in string so finally self.string.find(string) will mean "foo".find("bar")
class Test:
def find_string(self, string):
return self.string.find(string)
def add_string(self, string):
self.string = string
found = self.find_string('bar')
if found == -1:
string = string + ' bar'
return string
# --- main ---
test_string = 'foo'
test = Test() # PEP8: `lower_case_names` for variables
new_string = test.add_string(test_string)
print(new_string)
PEP 8 -- Style Guide for Python Code
I have a text file a.txt. I want to perform some preprocess on it like remove punct. and split it into words.
I have written the following code to perform few operations.
class pre:
def __init__(self,textfilepath):
self.textfilepath = textfilepath
def __str__(self,textfilepath):
return str(textfilepath)
def process(textpathfile):
with open(textpathfile, r) as abc:
a = abc.translate(string.maketrans("",""), string.punctuation)
a = a.split(' ')
return a
pre("a.txt")
I tried executing it.But it gave an error pre doesn't take arguments. Can any one help me with how to do this? Thanks all.
You shouldn't pass arguments to __str__. Instead you can access them through the properties of self:
class pre:
def __init__(self,textfilepath):
self.textfilepath = textfilepath
def __str__(self):
return self.textfilepath
def process(self):
with open(self.textfilepath, r) as abc:
a = abc.translate(string.maketrans("",""), string.punctuation)
a = a.split(' ')
return a
p = pre("a.txt")
print(p)
filedata = p.process()
print(filedata)
Create graph:-
def loadGraphFile(file):
graph = []
for line in file:
contents = line.split()
movieName = contents[0]
actorNames = [contents[i]+ " " + contents[i+1] for i in range(1, len(contents), 2)]
movieNode = findNode(graph, movieName)
if movieNode == None:
movieNode = mkNode(movieName)
graph.append(movieNode)
for actorName in actorNames:
actorNode = findNode(graph,actorName)
if actorNode == None:
actorNode = mkNode(actorName)
graph.append(actorNode)
actorNode.neighbor.append(movieNode)
movieNode.neighbor.append(actorNode)
return graph
def loadGraphFileName('file.text'):
return loadGraphFile(Open('file.text'))
You declared your function wrong:
def loadGraphFileName('file.text'): # change this
return loadGraphFile(Open('file.text'))
To this:
def loadGraphFileName(): # You don't use it anyway
return loadGraphFile(Open('file.text'))
Or:
def loadGraphFileName(filename='file.text'): # file.text will be the default. if you give an parameter with it, filename will change to that parameter
return loadGraphFile(Open(filename)) # And use it here
You cannot have literals as function params
You can instead do
def loadGraphFileName(f = 'file.txt'):
return loadGraphFile(Open(f))
I'm using python 3.3.4. Here is my code:
class ojaxi(object):
nomeri = 0
def __init__(self):
self.wevri = []
def damateba(self, adamiani):
if adamiani in self.wevri:
print("We Already Have That one")
else:
self.wevri.append(adamiani)
def __repr__(self):
return self.wevri
class adamiani(ojaxi):
def __init__(self, saxeli, shuasax, asaki):
self.saxeli = saxeli
self.shuasax = shuasax
self.asaki = asaki
def __str__(self):
return self
baramidze = ojaxi()
N1 = adamiani("tyler", "durden", 18)
N2 = adamiani("joe", "black", 20)
baramidze.damateba(N1)
baramidze.damateba(N2)
print(baramidze)
Problem i have is that i can't make a function print out all the members in "baramidze". I want __repr__ or __str__ to print out something like this:
["N1", "N2"]
all i get is an error saying:
__str__ returned non-string (type list)
Like the error says, you must return a string from __str__. To do what you want you may like this :
def __str__(self):
return repr(self.wevri)
You should do:
def __str__(self):
return ' '.join(self.saxeli+self.shuasax+str(self.asaki))
This is a class which will take in as input and then output a polynomial in string form (both ways same format). Some arithmetic is performed in the various methods. I've been trying to inherit this class into another class that will then use the __mod__() special method of the first class (or make it's own special method if necessary but I don't see how you can't just use the original method) to perform the mod on intake. Seems like this goes into __init__() but I've tried 5 different versions of this, even going so far as to change the parent class, and I'm getting nowhere. I'm teaching myself Python so I'm sure that even a junior Python dev can see where I'm going totally wrong.
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)
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
letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)]
m = 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
d = [1 if x in c else (1 if x==0 else (1 if x=='x' else 0)) for x in xrange(m, -1, -1)]
return key,d
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 __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
The desired result is to be able to call it on a new (child) class with the parent type and while changing the parent class as little as possible (if even at all). Note that class "BinaryField" is the intended child class:
p=GF2Polynomial("x**2+x**1+x**0")
a=BinaryField("x**1+x**0", p)
b=BinaryField("x**1", p)
On intake, the given polynomial should be modulus divided by the 2nd element (here it's 'p'). This is necessary for finite field math.
EDIT:
when running it with --
## "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 = "y**6 + y**2 + 1"
d = GF2Polynomial(poly4); e = GF2Polynomial(poly5); f = GF2Polynomial(poly6)
bf1 = BinaryField(poly1,b); print bf1
bf2 = BinaryField(poly4,e); print bf2
Both of these styles are possible because of the way I coded it, but they should both return the same answer. However the result on that code is:
>>>
x**5 + x**4 + x**3 + 1
x**5 + x
Also, when using BinaryField(poly4,d), which is just the same string with it's GF2Polynomial() initialization, this errors as:
AttributeError: 'int' object has no attribute 'string'
Does this solves your problem?
class BinaryField(GF2Polynomial):
def __init__(self, string, mod):
modded = GF2Polynomial(string) % mod
super(BinaryField, self).__init__(modded.string)
>>> p = GF2Polynomial("x**2+x**1+x**0")
>>> a = BinaryField("x**1+x**0", p)
>>> print a
x + 1
You can also make the BinaryField class to be just a factory method:
def BinaryField(string, mod):
return GF2Polynomial(string) % mod