I'm trying to get a RPN calculator by reusing the class CalculatorEngine as follows. But when I run it, it shows an Attribute Error: 'RPNCalculator' object has no attribute 'dataStack'. How do I solve this?
(I didn't include the Stack class as there'd be too much code.)
class CalculatorEngine(object):
def __init__(self):
self.dataStack = Stack()
def pushOperand(self, value):
self.dataStack.push(value)
def currentOperand(self):
return self.dataStack.top()
def performBinary(self, fun):
right = self.dataStack.pop()
left = self.dataStack.top()
self.dataStack.push(fun(left, right))
def doAddition(self):
self.performBinary(lambda x, y: x + y)
def doSubtraction(self):
self.performBinary(lambda x, y: x - y)
def doMultiplication(self):
self.performBinary(lambda x, y: x * y)
def doDivision(self):
try:
self.performBinary(lambda x, y: x / y)
except ZeroDivisionError:
print("divide by 0!")
exit(1)
def doTextOp(self, op):
if (op == '+'):
self.doAddition()
elif (op == '-'):
self.doSubtraction()
elif (op == '*'):
self.doMultiplication()
elif (op == '/'): self.doDivision()
class RPNCalculator(CalculatorEngine):
def __init__(self):
super(CalculatorEngine, self).__init__()
def eval(self, line):
op = line.split(" ")
try:
for item in op:
if item in '+-*/':
self.doTextOp(item)
elif item in '%':
self.performBinary(lambda x, y: x % y)
else:
self.pushOperand(int(item))
return self.currentOperand()
except ZeroDivisionError:
print 'divide by 0!'
class X(object):
def __init__(self, name):
self._name = name
def doit(self, bar):
print("Hello")
class Y(X):
def __init__(self):
# super(X, self).__init__()
X.__init__(self, "DDXX")
i = X("Yuze")
j = Y()
Or you can use this snippet to fix it.
I need help in my code, I don't know why I'm getting 'IndentationError:unexpected unindent' in the line 10 (def plus(self, v):), someone could help me?
class Vector(object):
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple(coordinates)
self.dimension = len(coordinates)
def plus(self, v):
new_coordinates = [x + y for x, y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def __eq__(self, v):
return self.coordinates == v.coordinates
v = Vector([8.218, -9.341])
w = Vector([-1,129, 2.111])
print (v.plus(w))
Try this:
class Vector(object):
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple(coordinates)
self.dimension = len(coordinates)
except:
pass #TODO domething here
def plus(self, v):
new_coordinates = [x + y for x, y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def __eq__(self, v):
return self.coordinates == v.coordinates
v = Vector([8.218, -9.341])
w = Vector([-1,129, 2.111])
print (v.plus(w))
In your __init__ function, you are missing an except block. If you do not include this, your try statement is essentially useless. Make sure to add the except block to handle your ValueError!
The error is coming from when you are calling try what you need to do is add and except to it like such:
try:
if not coordinates:
raise ValueError
self.coordinates = tuple(coordinates)
self.dimension = len(coordinates)
except:
# do something here to handle error
The try and except concept means that you are trying to perform an action in python but if an error occurs within the try scope then whatever is in the except scope will run.
Hope this helps :)
I'm gonna take a guess and say the code should look like this:
class Vector(object):
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple(coordinates)
self.dimension = len(coordinates)
except ValueError as e:
pass
# Code here?#
def plus(self, v):
new_coordinates = [x + y for x, y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def __eq__(self, v):
return self.coordinates == v.coordinates
if __name__ == '__main__':
v = Vector([8.218, -9.341])
w = Vector([-1,129, 2.111])
print (v.plus(w))
The indentation in the code you provided was indeed wrong but i think the interpreter was expecting an 'except' statement(here just shown to pass but you should make it do something)
See the documentation on exceptions.
class Vector(object):
def __init__(self, coordinates):
# try: # every try must be paired with an 'except'
if not coordinates:
raise ValueError
self.coordinates = tuple(coordinates)
self.dimension = len(coordinates)
def plus(self, v):
new_coordinates = [x + y for x, y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def __eq__(self, v):
return self.coordinates == v.coordinates
v = Vector([8.218, -9.341])
w = Vector([-1,129, 2.111])
print (v.plus(w))
I just made a generic number class.
this class is so simple, descriptions are below
from any ordered character list, make number class representing that ordered character list.
create_number_class("01") returns binary number class
create_number_class("0123456789") returns decimal number class
create_number_class("abcdefghij") return decimal number class but representing each digit as a alphabet.
belows is generic number class definition.
I think it is well-made class definition.
are there something needed improvement in that class definition?
thank you all. always.
ex)
ABC_Class = create_number_class("abc")
x = ABC_Class("baa")
y = ABC_Class("bbb")
print(x+y)
#output digits: abc, v: cbb, decimal_v: 22
below is class definition
def create_number_class(alphabet):
class temp(object):
digits = alphabet
def __init__(self, v):
self.v = v
self.decimal_v = self.to_decimal(self)
#staticmethod
def to_decimal(self):
r = 0
for i in range(0, len(self.v)):
r += len(temp.digits)**(len(self.v)-i-1)*(temp.digits.index(self.v[i]))
return r
#classmethod
def from_decimal(cls, decimal_v):
r = []
mod = len(temp.digits)
if decimal_v < mod:
return cls(temp.digits[decimal_v])
while True:
remainder = decimal_v % mod
r.append(remainder)
decimal_v = int((decimal_v - remainder)/ mod)
if decimal_v < mod:
r.append(decimal_v)
break
r = "".join(list(reversed([temp.digits[x] for x in r])))
#r = "".join(list(reversed([str(temp.digits.index(str(x))) for x in r])))
return cls(r)
def __add__(self, other):
return temp.from_decimal(self.decimal_v+other.decimal_v)
def __sub__(self, other):
return temp.from_decimal(self.decimal_v-other.decimal_v)
def __mul__(self, other):
return temp.from_decimal(self.decimal_v*other.decimal_v)
def __floordiv__(self, other):
return temp.from_decimal(self.decimal_v//other.decimal_v)
def __str__(self):
return "digits: {}, v: {}, decimal_v: {}".format(temp.digits, self.v, self.decimal_v)
def convert_to(self, new_class):
return new_class.from_decimal(self.decimal_v)
return temp
below are example
BinClass = create_number_class("01")
DecimalClass = create_number_class("0123456789")
x = BinClass("111")
x = BinClass("1000")
y = BinClass("10")
HexClass = create_number_class('0123456789ABCDEF')
x = HexClass('1')
y = HexClass('AA')
print(x+y)
print(x-y)
print(x*y)
print(x//y)
print(x.convert_to(DecimalClass))
isinstance(x, BinClass)
I have a code error that I need to debug but I'm not sure where I went wrong. When I run my code I got:
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
c3_plus_0i = create_complex(create_ordinary(3), create_ordinary(0))
File "<pyshell#30>", line 2, in create_complex
return get("make","complex")(x,y)
TypeError: 'NoneType' object is not callable
This is the code that I have:
from generic_arith_min import *
def install_complex_package():
def make_com(x,y):
return tag(repcom(x,y))
def repcom(x,y):
return (x,y)
def real(x):
return x[0]
def imag(x):
return x[1]
def tag(x):
return attach_tag("complex",x)
# add,sub,mul,div: (RepCom, RepCom) -> Generic-Com
def add_com(x,y):
return make_com( add(real(x), real(y)),
add(imag(x), imag(y)) )
def sub_com(x,y):
return make_com( sub(real(x), real(y)),
sub(imag(x), imag(y)) )
def mul_com(x,y):
return make_com(sub(mul(real(x), real(y)),
mul(imag(x), imag(y))),
add(mul(real(x), imag(y)),
mul(real(y), imag(x))))
def div_com(x,y):
com_conj = complex_conjugate(y)
x_times_com_conj = content(mul_com(x, com_conj))
y_times_com_conj = content(mul_com(y, com_conj))
return make_com(div(real(x_times_com_conj), real(y_times_com_conj)),
div(imag(x_times_com_conj), real(y_times_com_conj)));
def complex_conjugate(x):
return (real(x),negate(imag(x)))
def negate_com(x): # (RepCom) -> Generic-Com
return make_com(negate(real(x)), negate(imag(x)))
def is_zero_com(x): # (RepCom) -> Py-Bool
if is_zero(real(x)) and is_zero(imag(x)):
return True
else:
return False
def is_eq_com(x,y): # (RepCom, RepCom) -> Py-Bool
if is_equal(real(x),real(y)) and is_equal(imag(x),imag(y)):
return True
else:
return False
put("make","complex", make_com)
put("add",("complex","complex"), add_com)
put("sub",("complex","complex"), sub_com)
put("mul",("complex","complex"), mul_com)
put("div",("complex","complex"), div_com)
put("negate",("complex",), negate_com)
put("is_zero",("complex",), is_zero_com)
put("is_equal",("complex","complex"), is_eq_com)
def repord_to_repcom(x):
return repcom(create_ordinary(x),create_ordinary(0))
def CCmethod_to_OCmethod(method):
return lambda ord, com: method(repord_to_repcom(ord), com)
def CCmethod_to_COmethod(method):
return lambda com, ord: method(com, repord_to_repcom(ord))
put("add",("ordinary","complex"), CCmethod_to_OCmethod(add_com))
put("add",("complex","ordinary"), CCmethod_to_COmethod(add_com))
put("sub",("ordinary","complex"), CCmethod_to_OCmethod(sub_com))
put("sub",("complex","ordinary"), CCmethod_to_COmethod(sub_com))
put("mul",("ordinary","complex"), CCmethod_to_OCmethod(mul_com))
put("mul",("complex","ordinary"), CCmethod_to_COmethod(mul_com))
put("div",("ordinary","complex"), CCmethod_to_OCmethod(div_com))
put("div",("complex","ordinary"), CCmethod_to_COmethod(div_com))
put("is_equal",("ordinary","complex"), CCmethod_to_OCmethod(is_eq_com))
put("is_equal",("complex","ordinary"), CCmethod_to_COmethod(is_eq_com))
def create_complex(x,y):
return get("make","complex")(x,y)
#################
# Do not change #
#################
n3 = create_ordinary(3)
c3_plus_0i = create_complex(create_ordinary(3), create_ordinary(0))
c2_plus_7i = create_complex(create_ordinary(2), create_ordinary(7))
def gradeThis_complex_package():
complexA = is_equal(n3, c3_plus_0i)
complexB = is_equal(sub(add(n3, c2_plus_7i), c2_plus_7i), n3)
if complexA and complexB:
print("Well done! Your install_complex_package is complete!")
else:
print("Please check your solution for install_complex_package.")
gradeThis_complex_package()
Below is the supported file that it is imported from:
_operation_table = {} #variables with prefixed with an _ are by convention, for internal use and should not be touched.
def attach_tag(tag, content):
return (tag, content)
def type_tag(datum):
if type(datum) == tuple and len(datum) == 2:
return datum[0]
raise Exception('Bad tagged datum -- type_tag ', datum)
def content(datum):
if type(datum) == tuple and len(datum) == 2:
return datum[1]
raise Exception('Bad tagged datum -- content ', datum)
def put(op, types, value):
if op not in _operation_table:
_operation_table[op] = {}
_operation_table[op][types] = value
def get(op, types):
if op in _operation_table and types in _operation_table[op]:
return _operation_table[op][types]
else:
return None
def apply_generic(op, *args):
type_tags = tuple(map(type_tag, args))
proc = get(op, type_tags)
if proc:
return proc(*map(content, args))
raise Exception('No method for these types -- apply_generic', (op, type_tags))
##########################
# Generic Number Package #
##########################
#generic operators we want to support
def add(x,y):
return apply_generic("add", x, y)
def sub(x,y):
return apply_generic("sub", x, y)
def mul(x,y):
return apply_generic("mul", x, y)
def div(x,y):
return apply_generic("div", x, y)
def negate(x):
return apply_generic("negate", x)
def is_zero(x):
return apply_generic("is_zero", x)
def is_equal(x, y):
return apply_generic("is_equal", x, y)
#composite generic operators
def square(x):
return mul(x,x)
#Generic ordinary number package
def install_ordinary_package():
def make_ord(x):
return tag(x)
def tag(x):
return attach_tag("ordinary", x)
# add,sub,mul,div: (RepOrd, RepOrd) -> Generic-OrdNum
def add_ord(x,y):
return make_ord(x+y)
def sub_ord(x,y):
return make_ord(x-y)
def mul_ord(x,y):
return make_ord(x*y)
def div_ord(x,y):
return make_ord(x/y)
def negate_ord(x): # (RepOrd) -> Generic-Ord
return make_ord(-x)
def is_zero_ord(x): # (RepOrd) -> Py-Bool
return x == 0
def is_equal_ord(x,y): # (RepOrd, RepOrd) -> Py-Bool
return x == y
put("make","ordinary", make_ord)
put("negate",("ordinary",), negate_ord)
put("is_zero",("ordinary",), is_zero_ord)
put("add",("ordinary","ordinary"), add_ord)
put("sub",("ordinary","ordinary"), sub_ord)
put("mul",("ordinary","ordinary"), mul_ord)
put("div",("ordinary","ordinary"), div_ord)
put("is_equal",("ordinary","ordinary"), is_equal_ord)
install_ordinary_package()
def create_ordinary(x):
return get("make", "ordinary")(x)
Where exactly did the above code cause the rise to this error? If anyone could help I would really appreciate it. Thank you!
Your _operation_table dictionary does not contain an entry with make and complex therefore your get() function returns None which in fact is not callable.
print("complex" in _operation_table["make"])
False
Perhaps you've forgotten to call install_complex_package (in the same way you called install_ordinary_package) which adds the required function to _operation_table. Once called, your code works fine.