Im working on computer algebra and im trying to make an interface for fields.
Trying not to bore you with all the details this is whath im trying to get working:
class PrimeField():
prime = 2
def __init__(self,p):
self.prime = p
class element():
def __init__(self,n):
self.descriptor = n
def someFunctionOfNandP(self):
return 2*self.n % self.parrent.p
field = PrimeField(7)
el = field.element(5)
print(el.someFunctionOfNandP())
What im trying to achieve is that PrimeField creates a generator as you will that makes elements (which are objects) who's functions depend on the field the came from.
Although I can think of workarounds that use different structures (for example making a general element class that takes two elements and a function in the field that inits these), something among the lines shown above would have preference due to its resemblance to the underlying mathematics and the program is written for somebody else who is a mathematician.
Can this be done, and if so, how?
Thank you
One possibility is to treat PrimeField and PrimeFieldElement as separate objects:
class PrimeFieldElement():
def __init__(self, p, n):
self.p = p
self.n = n
def someFunctionOfNandP(self):
return 2 * self.n % self.p
class PrimeField():
prime = 2
def __init__(self, p):
self.prime = p
def element(self, n):
return PrimeFieldElement(self.prime, n)
field = PrimeField(7)
el = field.element(5)
print(el.someFunctionOfNandP())
This seems to match what you want best: each call to .element() will produce a new element and it'll have the values of p and n stored in it. It's also possible to pass the PrimeField along with it and access it inside PrimeFieldElement:
def element(self, n):
return PrimeFieldElement(self, n)
together with:
class PrimeFieldElement():
def __init__(self, field, n):
self.field = field
self.n = n
def someFunctionOfNandP(self):
return 2 * self.n % self.field.prime
Related
For the stack class below
class stack(list):
def __init__(self):
self.stack = []
self.top = -1
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
S = stack()
S.isempty() #True
S.push(5) #[5]
S.push(100) #[5,100]
print(S) # Returns empty stack []
Why does it not return the updated [5,100]?
The problem that you're asking about is that you're inheriting from list, even though you're not trying to act like a list. All this is doing is causing confusion. In particular, you're letting the list superclass define how your objects get displayed, and since you never do anything like self.append, only self.stack.append, that means it's always going to display like an empty list.
Once you fix that, your objects will always print something like this:
<__main__.stack at 0x11d919dd8>
If you want to customize that, you need to write a __repr__ method, and decide what you want it to look like.
class stack:
def __init__(self):
self.stack = []
self.top = -1
def __repr__(self):
return f'<stack({self.stack})>'
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
There are additional bugs in your code—you've still got a method that mutates the global S instead of self, and you're returning the result of list.append, which always returns None, and maybe more beyond—but these two changes will together solve the specific problem you're asking about.
class LogicGate(object):
def __init__(self, n):
self.label = n
self.output = None # ????????????
def getOutput(self):
self.output = self.performGateLogic()
return self.output
def getLabel(self):
return self.label
class BinaryGate(LogicGate):
def __init__(self, n): # ?????????????????
LogicGate.__init__(self, n)
self.pinA = None # ??????????????
self.pinB = None # ??????????????
def getPinA(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
def getPinB(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
class UnaryGate(LogicGate):
def __init__(self, n): # ??????????????
LogicGate.__init__(self, n)
self.pin = None # ?????????????
def getPin(self):
return int(raw_input('Enter Pin input for gate' + self.getLabel() + '-->'))
class AndGate(BinaryGate):
def __init__(self, n): # ????????????
BinaryGate.__init__(self, n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a == 1 and b == 1:
return 1
else:
return 0
This code belongs to Problem Solving with Algorithms and Date Structures.
When I remove the lines before the comment '# ????????', the code can run normally.
Why does the author write the code like this?
Whether is it a good code style?
Can I always remove these lines before the comment '# ????????' ?
The author writes the code like that because it is good practice to never have uninitialised members and class parents, static checkers moan if you do.
The reason that it is not good practice is for future maintainability - let us say that the base class, LogicGate, was to gain a new property - say propagation_delay and a new method that allowed simulations to called get_response_time which relied on the current output state and the required, possibly new, state. If all the code that was derived from that class did the correct initialisations then it would all work fine, without any changes. If you remove those lines and such a new method was introduced you would have to go back through all of the child classes adding them back in before your final class would work for that method, with the chance that you would miss one.
Daft as it sounds doing things properly now is actually future laziness - it only takes you seconds when you are creating a class to make sure everything is initialised - debugging an uninitialised class can take hours.
First:
The __init__ functions are the constructors of the classes, you can read about them here.
Second:
Your code will run without those lines but the question is why and is it ok to remove them?
For example if you remove the following init
class UnaryGate(LogicGate): # LogicGate is the superclass
def __init__(self, n):
LogicGate.__init__(self, n)
The constructor of the super-class LogicGate will be called directly.
Third:
Ok, so can we remove the self.xxx = None?
class BinaryGate(LogicGate):
def __init__(self, n):
LogicGate.__init__(self, n)
self.pinA = None
self.pinB = None
We could remove those 2 Lines too but consider this code
bg = BinaryGate("binaryGate1")
print bg.pinA
This would throw an error because pinA is undefined.
If you do not remove the self.pinA = None in __init__ the code will run and None will be printed.
I have been subclassing an Python's random number generator to make a generator that doesn't repeat results (it's going to be used to generate unique id's for a simulator) and I was just testing to see if it was consistent in it's behavior after it has been loaded from a previours state
Before people ask:
It's a singleton class
No there's nothing else that should be using that instance (a tear down sees to that)
Yes I tested it without the singleton instance to check
and yes when I create this subclass I do call a new instance ( super(nrRand,self).__init__())
And yes according to another post I should get consistent results see: Rolling back the random number generator in python?
Below is my test code:
def test_stateSavingConsitantcy(self):
start = int(self.r.random())
for i in xrange(start):
self.r.random()
state = self.r.getstate()
next = self.r.random()
self.r.setstate(state)
nnext = self.r.random()
self.assertEqual(next, nnext, "Number generation not constant got {0} expecting {1}".format(nnext,next))
Any help that can be provided would greatly appreciated
EDIT:
Here is my subclass as requested
class Singleton(type):
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton,self).__call__(*args,**kwargs)
return self._instances[self]
class nrRand(Random):
__metaclass__ = Singleton
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
super(nrRand,self).__init__()
self.previous = []
def random(self):
n = super(nrRand,self).random()
while n in self.previous:
n = super(nrRand,self).random()
self.previous.append(n)
return n
def seed(self,x):
if x is None:
x = long(time.time()*1000)
self.previous = []
count = x
nSeed = 0
while count < 0:
nSeed = super(nrRand,self).random()
count -= 1
super(nrRand,self).seed(nSeed)
while nSeed < 0:
super(nrRand,self).seed(nSeed)
count -= 1
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
def setstate(self,state):
self.previous = state[0]
super(nrRand,self).setstate(state[1])
getstate and setstate only manipulate the state the Random class knows about; neither method knows that you also need to roll back the set of previously-generated numbers. You're rolling back the state inherited from Random, but then the object sees that it's already produced the next number and skips it. If you want getstate and setstate to work properly, you'll have to override them to set the state of the set of already-generated numbers.
UPDATE:
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
This shouldn't directly use self.previous. Since you don't make a copy, you're returning the actual object used to keep track of what numbers have been produced. When the RNG produces a new number, the state returned by getstate reflects the new number. You need to copy self.previous, like so:
def getstate(self):
return (self.previous[:], super(nrRand, self).getstate())
I also recommend making a copy in setstate:
def setstate(self, state):
previous, parent_state = state
self.previous = previous[:]
super(nrRand, self).setstate(parent_state)
When I try to make and hash objects from a file, containing one million songs, I get a weird segmentation error after about 12000 succesfull hashes.
Anyone have any idea why this:
Segmentation fault: 11
happens when I run the program?
I have these classes for hashing the objects:
class Node():
def __init__(self, key, value = None):
self.key = key
self.value = value
def __str__(self):
return str(self.key) + " : " + str(self.value)
class Hashtable():
def __init__(self, hashsize, hashlist = [None]):
self.hashsize = hashsize*2
self.hashlist = hashlist*(self.hashsize)
def __str__(self):
return self.hashlist
def hash_num(self, name):
result = 0
name_list = list(name)
for letter in name_list:
result = (result*self.hashsize + ord(letter))%self.hashsize
return result
def check(self, num):
if self.hashlist[num] != None:
num = (num + 11**2)%self.hashsize#Kolla här jättemycket!
chk_num = self.check(num)#här med
return chk_num#lär dig
else:
return num
def check_atom(self, num, name):
if self.hashlist[num].key == name:
return num
else:
num = (num + 11**2)%self.hashsize
chk_num = self.check_atom(num, name)#läs här
return chk_num#läs det här
def put(self, name, new_atom):
node = Node(name)
node.value = new_atom
num = self.hash_num(name)
chk_num = self.check(num)
print(chk_num)
self.hashlist[chk_num] = node
def get(self, name):
num = self.hash_num(name)
chk_num = self.check_atom(num, name)
atom = self.hashlist[chk_num]
return atom.value
And I call upon the function in this code:
from time import *
from hashlist import *
import sys
sys.setrecursionlimit(1000000000)
def lasfil(filnamn, h):
with open(filnamn, "r", encoding="utf-8") as fil:
for rad in fil:
data = rad.split("<SEP>")
artist = data[2].strip()
song = data[3].strip()
h.put(artist, song)
def hitta(artist, h):
try:
start = time()
print(h.get(artist))
stop = time()
tidhash = stop - start
return tidhash
except AttributeError:
pass
h = Hashtable(1000000)
lasfil("write.txt", h)
The reason you're getting a segmentation fault is this line:
sys.setrecursionlimit(1000000000)
I assume you added it because you received a RuntimeError: maximum recursion depth exceeded. Raising the recursion limit doesn't allocate any more memory for the call stack, it just defers the aforementioned exception. If you set it too high, the interpreter runs out of stack space and accesses memory that doesn't belong to it, causing random errors (likely segfaults, but in theory anything is possible).
The real solution is to not use unbounded recursion. For things like balanced search trees, where the recursion depth is limited to a few dozen levels, it's okay, but you can't replace long loops with recursion.
Also, unless this is an exercise in creating hash tables, you should just use the built in dict. If it is an exercise in creating hash tables, consider this a hint that something about your hash table sucks: It indicates a probe length of at least 1000, more likely several thousand. It should only be a few dozen at most, ideally in the single digits.
I am fairly new to python. I have tried to define a class, I then want to create an instance from a file, then refer to specific pieces of it, but cannot seem to. This is Python 3.3.0
Here's the class....
class Teams():
def __init__(self, ID = None, Team = None, R = None, W = None, L = None):
self._items = [ [] for i in range(5) ]
self.Count = 0
def addTeam(self, ID, Team, R=None, W = 0, L = 0):
self._items[0].append(ID)
self._items[1].append(Team)
self._items[2].append(R)
self._items[3].append(W)
self._items[4].append(L)
self.Count += 1
def addTeamsFromFile(self, filename):
inputFile = open(filename, 'r')
for line in inputFile:
words = line.split(',')
self.addTeam(words[0], words[1], words[2], words[3], words[4])
def __len__(self):
return self.Count
Here's the code in Main
startFileName = 'file_test.txt'
filename = startFileName
###########
myTestData = Teams()
myTestData.addTeamsFromFile(startFileName)
sample data in file
100,AAAA,106,5,0
200,BBBB,88,3,2
300,CCCC,45,1,4
400,DDDD,67,3,2
500,EEEE,90,4,1
I think I am good to here (not 100% sure), but now how do I reference this data to see... am i not creating the class correctly? How do I see if one instance is larger than another...
ie, myTestData[2][2] > myTestData[3][2] <----- this is where I get confused, as this doesn't work
Why don't you create a Team class like this :
class Team():
def __init__(self, ID, Team, R=None, W = 0, L = 0)
# set up fields here
Then in Teams
class Teams():
def __init__(self):
self._teams = []
def addTeam (self, ID, Team, R=None, W = 0, L = 0)
team = Team (ID, Team, R=None, W = 0, L = 0)
self._teams.append (team)
Now If i got it right you want to overwrite the > operator's behaviour.
To do that overload __gt__(self, other) [link]
So it will be
class Team ():
# init code from above for Team
def __gt__ (self, otherTeam):
return self.ID > otherTeam.ID # for example
Also be sure to convert those strings to numbers because you compare strings not numbers. Use int function for that.
The immediate problem you're running into is that your code to access the team data doesn't account for your myTestData value being an object rather than a list. You can fix it by doing:
myTestData._items[2][2] > myTestData._items[3][2]
Though, if you plan on doing that much, I'd suggest renaming _items to something that's obviously supposed to be public. You might also want to make the addTeamsFromFile method convert some of the values it reads to integers (rather than leaving them as strings) before passing them to the addTeam method.
An alternative would be to make your Teams class support direct member access. You can do that by creating a method named __getitem__ (and __setitem__ if you want to be able to assign values directly). Something like:
def __getitem__(self, index):
return self._items[index]
#Aleksandar's answer about making a class for the team data items is also a good one. In fact, it might be more useful to have a class for the individual teams than it is to have a class containing several. You could replace the Teams class with a list of Team instances. It depends on what you're going to be doing with it I guess.