By using message passing to fuifill the code such that
s = make_stack()
print(s("is_empty")) # True
s("push")(1)
s("push")(2)
print(s("peek")) # [2]
print(str(s("pop"))) # [2]
My code is supposed to fill in the blanks of
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":
# blank #
elif msg == "clear":
# blank #
elif msg == "peek":
# blank #
elif msg == "push":
# blank #
elif msg == "pop":
# blank #
else:
raise Exception("stack doesn't" + msg)
return oplookup
I don't understand the tracing of the code. My own trial code is
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":=
return True
elif msg == "clear":
return []
elif msg == "peek":
return make_stack.items[-1]
elif msg == "push":
return items.append(msg)
elif msg == "pop":
return items.pop()
else:
raise Exception("stack doesn't" + msg)
return oplookup
Another question is for having s("push") (1), what argument does (1) take? Is it under msg or item?
I think the first issue you have is that you need to return something callable from oplookup, probably a function. The functions all need to manipulate (or test) the items list (which they can access because they are closures).
Here's what that code might look like:
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":
def empty():
return not items
return empty
elif msg == "clear":
def clear():
items[:] = [] # slice assignment, to clear in-place
return clear
#...
Note that in clear I avoid doing an assignment directly to items because it's in the enclosing scope. In Python 2, it's impossible to reassign items, since it is neither local or global variable. In Python 3, reassignment is possible using the nonlocal keyword. Since I don't know what version of Python you're using, I used a slice assignment which works in both versions.
This style of code is not very Pythonic. A much more natural way to do this would be to make a class with methods (but you'd end up with a slightly different API):
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return not self.items
def clear(self):
self.items = [] # this time we can replace the list
def push(self, item):
self.items.append(item)
#...
Related
I have a Binary Search Tree and I am trying to trace recursively in order through the tree and append each key,value to a list. It is only appending the first key,value to the list and not going through the list in order. I pasted my code below, along with the test code I used at the bottom. Any help on how to get past this issue is super appreciated!
class TreeMap:
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.left = None
self.right = None
def __init__(self):
self.root = None
self.numsearches = 0
self.numcomparisons = 0
def add(self, newkey, newvalue):
newkey = newkey.lower()
if self.root == None:
self.root = TreeMap.Node(newkey, newvalue)
else:
TreeMap.add_helper(self.root, newkey, newvalue)
def add_helper(thisnode, newkey, newvalue):
if newkey <= thisnode.key:
if thisnode.left == None:
thisnode.left = TreeMap.Node(newkey, newvalue)
else:
TreeMap.add_helper(thisnode.left, newkey, newvalue)
else:
if thisnode.right == None:
thisnode.right = TreeMap.Node(newkey, newvalue)
else:
TreeMap.add_helper(thisnode.right, newkey, newvalue)
def print(self):
TreeMap.print_helper(self.root, 0)
def print_helper(somenode, indentlevel):
if somenode == None:
print(" "*(indentlevel),"---")
return
if not TreeMap.isleaf(somenode):
TreeMap.print_helper(somenode.right, indentlevel + 5)
print(" "*indentlevel + str(somenode.key) + ": " +str(somenode.value))
if not TreeMap.isleaf(somenode):
TreeMap.print_helper(somenode.left, indentlevel + 5)
def isleaf(anode):
return anode.left == None and anode.right == None
def listify(self, whichorder="in"):
'''
Returns a list consisting of all the payloads of the tree. (This returns a plain old Python List.)
The order of the payloads is determined by whichorder, which defaults to inorder.
The other possibilities are "pre" and "post".
If the tree is empty, return the empty list.
'''
assert type(whichorder) is str,"Whichorder is a string, and can only be pre, in or post"
assert whichorder in ["pre","in","post"],"Whichorder is a string, and can only be pre, in or post"
return TreeMap.listify_helper(self.root, whichorder)
def listify_helper(somenode, whichorder):
order_list = []
if somenode == None:
return order_list
elif somenode != None and whichorder == 'in':
TreeMap.listify_helper(somenode.left, 'in')
order_list.append(somenode.key+ '='+somenode.value)
TreeMap.listify_helper(somenode.right, 'in')
return order_list
TEST CODE:
import treemap
translator = treemap.TreeMap()
translator.add("cat", "Katze")
translator.add("bird", "Vogel")
translator.add("dog", "Hund")
translator.add("snake", "IDK")
translator.add("bear", "IDK")
translator.add("octopus", "Tintenfisch")
translator.add("horse", "Pferd")
translator.add("zebra", "IDK")
translator.print()
print("---------------------------------------------------")
print (translator.listify())
The problem is here:
def listify_helper(somenode, whichorder):
order_list = []
This function initialises its own local order_list every time it is invoked. Pass order_list as a parameter instead so that the same list is appended to by each recursive invocation.
Alternatively, append each element of the result of the recursive calls of listify_helper to order_list, although this approach could result in unneeded copying.
I'm given a .txt file with a total of 1 million songs and their respective authors. My given task is to write a HashMap in python which can store this information using either the Author or the Song as a key. I've written a HashMap that works but is running incredibly slow, taking up to 2 minutes to finish. (Expected time is apparently a few seconds at most, according to my tutor)
For collision handling I decided to use linked lists as from what I've gathered it's an effective way to handle collisions without drastically reducing performance.
from HashNode import HashNode
class HashTabell:
def __init__(self, size):
self.size = size
self.dict = {}
self.krock = 0
def store(self, nyckel, data):
hashval = self.__hash(nyckel)
## Shit is empty
if self.dict.get(hashval) != None:
get_val = self.dict[hashval]
## Is list, append normally
if isinstance(get_val, list):
list2 = self.dict[hashval]
found = False
for (k, val) in enumerate(list2):
if val.get_nyckel == nyckel:
list[k] = HashNode(nyckel, data) ## Update old value
found = True
break
if found:
self.dict[hashval] = list2
else:
self.dict[hashval] = get_val + [HashNode(nyckel, data)]
self.krock += 1
else:
## Create list
if get_val.get_nyckel() == nyckel:
self.dict[hashval] = HashNode(nyckel, data) ## Update old value
else:
self.dict[hashval] = [get_val, HashNode(nyckel, data)] ## Append to existing node
self.krock += 1
else:
self.dict[hashval] = HashNode(nyckel, data)
def __getitem__(self, nyckel):
return search(nyckel)
def __contains__(self, nyckel):
return (search(nyckel) != None)
def search(self, nyckel):
hashval = self.__hash(nyckel)
## Get val
get_val = self.dict.get(hashval)
if get_val == None:
raise KeyError("Key not found")
## Check if has multiple entries or not
if isinstance(get_val, list):
## Multiple
for value in get_val:
if(get_val.get_nyckel() == nyckel):
return get_val
raise KeyError("Key not found")
else:
## Single
if get_val.get_nyckel() == nyckel:
return get_val
else:
raise KeyError("Key not found")
## Hash function
def __hash(self, input):
inp = str(input) ## Get chars
value = 0
for k in input:
value += ord(k)
return (value % self.size)
def get_dict(self):
return self.dict
def get_krock(self):
return self.krock
Where the HashNode class is simply:
class HashNode:
def __init__(self, nyckel, data):
self.nyckel = nyckel
self.data = data
def get_nyckel(self):
return self.nyckel
def get_data(self):
return self.data
I've been staring myself blind with this issue for the past 2 weeks and I'm not getting any help from my lecturer/assistants, would greatly appreciate any advice on how to improve the speed.
I'm trying to teach myself about OOP in python and am really struggling.
I have the following:
def __init__(self, quantity):
''' '''
self.switchboard = []
self.state = False
self.quantity = quantity
for i in range(quantity):
self.switchboard.append(i)
def __str__(self):
self.on_list = []
for i in range(self.quantity):
if i == True:
self.on_list.append(i)
return("The following switches are on " + str(self.on_list))
def which_switch(self):
for i in range(len(self.switchboard)):
self.on_list = []
if self.switchboard[i] == True:
on_list.append(i)
print(on_list)
def flip(self, n):
if self.switchboard[n] == True:
self.switchboard[n] = False
else:
self.switchboard[n] = True
When I print it, I get The following switches are on [1]. Even though I put 10 in the parameters. I want it to display all the switches that are on which in this case should be zero since their initial state is 'off'.
In __str__ modify the line:
if i == True:
to:
if self.switchboard[i]:
Remember: i is just an index, what you want is to access the i-th item in switchboard!
There is also another bug, in method which_switch():
on_list.append(i)
should be:
self.on_list.append(i)
and same goes to the print line below it.
Output after the change:
The following switches are on [1, 2, 3, 4, 5, 6, 7, 8, 9]
Now, I can only guess that what you actually wanted to do in the constructor is:
def __init__(self, quantity):
''' '''
self.switchboard = []
self.state = False
self.quantity = quantity
for i in range(quantity):
self.switchboard.append(LightSwitch('off')) # create light-switch and set it to 'off'
and then, when you print them - print only the ones that are on:
def __str__(self):
self.on_list = []
for i in range(self.quantity):
if self.switchboard[i].state: # check state
self.on_list.append(i)
return("The following switches are on " + str(self.on_list))
Also the reason it's printing 1 as true, is because out of all the elements in list, it's just seeing everything as false and 1 as true (as in 0 == False, 1 == True).
You can shorten
def flip(self):
''' Sets switch to opposite position.'''
if self.state == True:
self.state = False
elif self.state == False:
self.state = True
to
def flip(self):
''' Sets switch to opposite position.'''
self.state = not self.state
and on your switchboard for
def flip_every(self, n):
for i in range(0, len(self.switchboard), n):
if self.switchboard[n] == True:
self.switchboard[n] = False
else:
self.switchboard[n] = True
to
def flip_every(self, n):
for i in range(0, self.quantity, n):
self.switchboard[n] = not self.switchboard[n]
# you could also just use self.flip(n) instead
and
def flip(self, n):
self.switchboard[n] = not self.switchboard[n]
As a nice touch: you use kind-of the same iteration in which_switch(self) and __str__(self): that operates on the indexes of switches that are on. I built a small def getOnIndexes(self): ... that returns you an int list of those indexes, and call this in both methods (DRY - dont repeat yourself principle) using a shorthand to create indexes based on a list comprehension.
def getOnIndexes(self):
return [i for i in range(self.quantity) if self.switchboard[i] == True]
In total a really nice small OOP example.
What had me stumped though, is why a Switchboard IS_A LightSwitch - I would model it slightly different, saying a SwitchBoard HAS LightSwitch'es, coming to this:
Your base class
class LightSwitch():
def __init__(self, default_state):
'''
default_state can only be 'on' or 'off'.
'''
if default_state == 'on':
self.state = True
elif default_state == 'off':
self.state = False
def turn_on(self):
self.state = True
def turn_off(self):
self.state = False
def flip(self):
self.state = not self.state
def __str__(self):
if self.state == True:
return 'I am on'
if self.state == False:
return 'I am off'
def isOn(self):
return self.state
def isOff(self):
return not self.isOn()
My alternative switch board:
class AlternateSwitchBoard():
''' '''
def __init__(self, quantity, default_state):
''' '''
self.default_state = default_state
self.switchboard = [LightSwitch(default_state) for x in range(quantity)]
self.state = False
self.quantity = quantity
def __str__(self):
retVal = ""
for i in range(self.quantity):
if self.switchboard[i].isOn():
retVal += ", On"
else:
retVal += ", Off"
return "Switchboard: " + retVal[1:].strip()
def which_switch(self):
print(self.getOnIndexes())
def flip(self, n):
self.switchboard[n].flip()
def flip_every(self,stride):
for i in range(0, self.quantity, stride):
self.switchboard[i].flip()
def reset(self):
self.switchboard = [LightSwitch(default_state) for x in range(quantity)]
def getOnIndexes(self):
return [i for i in range(self.quantity) if self.switchboard[i].isOn()]
s2 = AlternateSwitchBoard(10, "off")
s2.flip(2)
s2.flip(7)
print(str(s2))
s2.flip_every(2)
print(str(s2))
s2.which_switch()
Output:
Switchboard: Off, Off, On, Off, Off, Off, Off, On, Off, Off
Switchboard: On, Off, Off, Off, On, Off, On, On, On, Off
[0, 4, 6, 7, 8]
I have written a program that has to execute a file and draw it in turtle.
But when I try to call a fdl filename it cant find it.
import turtle
#I start out making the basic turtle commands
def lt (turtle, n):
turtle.lt(n)
def fd (turtle, n):
turtle.fd(n)
def bk (turtle, n):
turtle.bk(n)
def rt (turtle, n):
turtle.rt(n)
#Then i create a class that makes it possible to create a set of rules
class Rule(object):
#Here the rule based on a description string is initialized like ("F -> F L F L")
def __init__(self,repr):
#This is where the left and right part of the rule in "F -> F L F L" comes in
self.left, self.right = [a.strip() for a in repr.split("->")]
if self.left is None or self.right is None:
print("Invalid rule description!")
#Now i use the same princip like i did in task6. the Apply function
def apply_rule_on_elements(self,element):
return [self._apply_rule_for_element (element) for element in elements]
#This is a helper function that only works on one element at a time
def _apply_rule_for_element (self,element):
if element == self.left:
return self.right.split()
return element
#Here is a very simple helper function, handy in some cases
#This allows one to perform assignment multiple values og grouping
def split_command(command, *args):
return command, args
#Now i make a command class that wraps the execution of a given command
class Command(object):
def __init__(self,command):
#the name and number of arguments for the given command
self.name,self.args = split_command(*command.split())
def execute(self,turtle,length):
if self.name == "lt":
lt(turtle,int(self.args[0]))
elif self.name == "scale":
length[0] = length[0]*float(self.args[0])
elif self.name == "fd":
fd(turtle,length[0])
elif self.name == "bk":
bk(turtle,length[0])
elif self.name == "rt":
rt(turtle,int(self.args[0]))
elif self.name == "nop":
pass
#Here i write the main Fractal class
class Fractal(object):
def __init__(self):
#Initial and current state
self.state = []
#Rules associated with the current fractal
self.rules = []
#Commands associated with the current fractal
self.commands = {}
#since values are immutable and passed by value, I use an array (passed by reference value)
#to allow the modification of the variable
self.length = [0]
#The current depth
self.depth = 0
#Executes the command associated w/ the current states stored in the fractal
def execute_commands(self,turtle,states):
for state in states:
self.commands[state].execute(turtle,self.length)
#Flattens a list
def _flatten(self,l):
flattened_list = []
for element in l:
flattened_list.extend(element)
return flattened_list
#Here i compute the fractal, which does that actual iteration work
#It returns the state of the fractal after the computation
def compute(self):
current_depth = self.depth
current_state = self.state
while self.depth !=0:
current_state=self.compute_next_state(current_state)
self.depth-=1
return current_state
def _compute_next_state(self,state):
for rule in self.rules:
state = rule.apply_rule_on_elements(state)
return self._flatten(state)
#This parses the fdl file, creates a fractal and set it up with the values
#read in the fdl file
def read_fdl(filename):
import os
f = Fractal()
if os.path.exists(filename):
lines = open(filename).readlines()
for line in lines:
if not len(line.strip())==0:
name,arguments = split_command(*line.strip().split())
if name == "start":
f.state = arguments
elif name == "rule":
f.rules.append(Rule("".join(arguments)))
elif name =="length":
f.length = [int(arguments[0])]
elif name == "depth":
f.depth = int(arguments[0])
elif name == "cmd":
f.commands[arguments[0]] = Command("".join (arguments[1:]))
else:
print("File does not exist")
#no check is made, to see if we have a fractal that was completely initialized
return f
import sys
import turtle
if len(sys.argv)>1:
f=read_fdl(sys.argv[1])
f.execute_commands(turtle,f.compute())
read_fdl("sierpinski")
The message I get is "File does not exist", but it does.
No, it doesn't exist - at least not in the current directory and without an extension.
Try adding the right directory and extension to the name "sierpinski"
Given that this is an fdl (fractal definition language) file, try:
read_fdl("sierpinski.fdl")
Below I'm attempting to make a simple Keygen as a first project. Somewhere I'm getting the error the Self has not been defined.
I'm guessing it's probably something easy
import random
class KeyGenerator():
def __init__(self):
length = 0
counter = 0
key = []
Letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
def KeyGen4(self):
while self.counter != self.length:
a = random.choice(self.Letters)
print a #test
r = (random.randint(0,1))
print r #test
if r == True:
a = a.upper()
else:
pass
self.key.append(a)
self.counter += 1
s = ''
self.key = s.join(key)
print self.key
return self.key
def start(self):
selection = raw_input('[K]eygen4, [C]ustom length Keygen or [N]umbers? >')
if selection == 'K' or 'k':
length = 4
keyGen4(self)
elif selection == 'N' or 'n':
KeyGenN(self)
elif selection == 'C' or 'c':
length = int(raw_input("Key Length: "))
#KeyGen4(self) # Change later after creating method with more options
start(self)
Your indention is wrong, but I assume this is only a copy-pasting issue.
That start(self) at the bottom doesn't make sense,
and indeed self is not defined there. You should create an instance of the class, and then call its start method:
KeyGenerator().start()
# or
key_gen = KeyGenerator()
key_gen.start()
You have two problems:
you miss indentation on every class-function
you must create an object of the class before you can call any of its functions
Your class should look like this
import random
class KeyGenerator():
def __init__(self):
length = 0
counter = 0
key = []
Letters = ['a','b','c','d','e']
def KeyGen4(self):
while self.counter != self.length:
a = random.choice(self.Letters)
print a #test
r = (random.randint(0,1))
print r #test
if r == True:
a = a.upper()
else:
pass
self.key.append(a)
self.counter += 1
s = ''
self.key = s.join(key)
print self.key
return self.key
def start(self):
selection = raw_input('[K]eygen4, [C]ustom length Keygen or [N]umbers? >')
if selection == 'K' or 'k':
length = 4
self.keyGen4()
elif selection == 'N' or 'n':
self.KeyGenN()
elif selection == 'C' or 'c':
length = int(raw_input("Key Length: "))
#KeyGen4(self) # Change later after creating method with more options
#now make an instance of your class
my_key_gen = KeyGenerator()
my_key_gen.start()
Please note that when calling class functions inside the class, you need to use self.FUNCNAME. All class functions should take "self" as argument. If that is their only argument then you simply call them with self.func(). If they take arguments you still ommit the self, as self.func(arg1, arg2)