moodygeek
moodygeek

Reputation: 127

how can i use arithmetic operations on class attributes?

I am trying to write a code that can solve arithmetic operations. The classes mult and plus are meant to solve problems like:

e1 = mult(const(3),const(4))
e1 = plus(const(3),const(4)

and return a result (resp. 12 and 7)

Now the assignment from the lecturer wants us to write the program that can solve a problem like this:

e1 = mult(plus(const(3),const(4)),const(5)) # should print 35
e2 = plus(mult(const(3),const(4)),const(5)) # should print 12

I tried solving the problem using lists so that the constants are stored in lists(i.e store_const), then the classes mult(const(n),const(n)) and plus(const(n),const(n)) would solve the problem and return a result. My problem is for each class mult/plus, I created the method eval that adds or multiplies the store_const[0] and [1], but every time I run the program: e1 returns 12 and e2 return 7

I figured this is because mult/plus only take store_const[0] = 3 and store_const[1] = 4 and leaves out store_const[2] = 5.

So how can I solve this:

e1 = mult(plus(const(3),const(4)),const(5)) 

where the result of the plus is stored as a new const(n), and then the mult class can execute to produce 35k

Here is my code:

class expr(object): #ignore class
   pass


class const(expr):
   store_const = [] #list to store constants

   def __init__(self, n): #initial constructor
       self.n = n
       const.store_const.append(self.n) #store constants in list


class binOp(expr): #sublcass of expr

   def __init__(self, expr1, expr2): #initial constructor arguments
      self.expr1 = expr1
      self.expr2 = expr2

class mult(binOp):
   def __int__(self, *args):
      super(mult, self).__init__(*args) #inheriting the superclass constructor arguments

   def eval(self):
      self.expr1 = const.store_const[0]
      self.expr2 = const.store_const[1]
      self.result = self.expr1 * self.expr2
      return self.result


class plus(binOp):
   def __init__(self, *args):
      super(plus, self).__init__(*args) #inheriting the superclass constructor arguments

   def eval(self):
      self.expr1 = const.store_const[0] #assigning the 1st elem of list to expr1
      self.expr2 = const.store_const[1] #assigning the 2nd elem of list to expr2
      self.result1 = self.expr1 + self.expr2
      return self.result1

#input
e1 = mult(plus(const(3), const(4)),const(5))
print e1.eval()
e2 = plus(mult(const(3), const(4)),const(5))
print e2.eval()

#output
12
7

Upvotes: 0

Views: 146

Answers (2)

fredtantini
fredtantini

Reputation: 16566

I tried solving the problem using lists so that the constants are stored in lists

I think that's your problem as you suspected:

I figured this is because mult/plus only take store_const[0] = 3 and store_const[1] = 4 and leaves out store_const[2] = 5

As this is obviously an assignment, and you are almost there, I will only give you hints:

You don't need to store const. You can access them with .n:

>>> x = const(3)
>>> y = const(4)
>>> x.n
3
>>> y.n
4

In your eval methods, you have to "guess" what is the class of expr1 and expr2 and call .eval if it's mult or plus and .n if it's a const. In pseudo-code:

if expr1 is a const:
   new_expr1 = expr1.n
else:
   new_expr1 = expr1.eval()
if expr2 is a const:
   new_expr2 = expr2.n
else:
   new_expr2 = expr2.eval()
result = new_expr1 + new_expr2 #or * in the mult class

But you have to do that for the 2 expr (1 and 2) and there is a better way: as you may guess if const have a eval method that returns .n, then you don't have to "guess" and can do self.expr1.eval()+self.expr2.eval() (or * for the class mult).

self.expr1.eval() will return either .n for a constant, or the result of the mult/plus operation.

Upvotes: 0

Kevin
Kevin

Reputation: 76254

You don't need to store the consts in an outside collection if you give the const class an eval method. Also, your binOp eval methods will have to recursively call eval on its left and right arguments.

class expr(object): #ignore class
   pass


class const(expr):
   store_const = [] #list to store constants

   def __init__(self, n): #initial constructor
       self.n = n
   def eval(self):
       return self.n

class binOp(expr): #sublcass of expr

   def __init__(self, expr1, expr2): #initial constructor arguments
      self.expr1 = expr1
      self.expr2 = expr2

class mult(binOp):
   def __int__(self, *args):
      super(mult, self).__init__(*args) #inheriting the superclass constructor arguments

   def eval(self):
      return self.expr1.eval() * self.expr2.eval()


class plus(binOp):
   def __init__(self, *args):
      super(plus, self).__init__(*args) #inheriting the superclass constructor arguments

   def eval(self):
      return self.expr1.eval() + self.expr2.eval()

#input
e1 = mult(plus(const(3), const(4)),const(5))
print e1.eval()
e2 = plus(mult(const(3), const(4)),const(5))
print e2.eval()

Result:

35
17

Upvotes: 1

Related Questions