razorcode7
razorcode7

Reputation: 55

how to multiply all numbers in a stack

Trying to multiply all the numbers in a stack, I originally thought of popping all elements into a list and then multiplying but wasn't sure how to/ if that was right.

this is my current code but I'm getting:

TypeError: 'method' object cannot be interpreted as an integer.

def multi_stack(s):
  stack = Stack()
  mult = 1
  size = my_stack.size
  for number in range(size):
    tmp = my_stack.pop(size)
    mult = mult * tmp
    L.append(tmp)
  for number in range(size):
    my_stack.push(L.pop())
    print(must)

I made a test case aswell

  my_stack = Stack()
  my_stack.push(12)
  my_stack.push(2)
  my_stack.push(4)
  my_stack.push(40)
  print(multi_stack(my_stack))
  print(my_stack.size())`

this should print out :

3840
0

The Stack class I'm using

class Stack(): 

def __init__(self): 
    self.items = [] 

def is_empty(self): 
    return self.items == [] 

def push(self,items):
    return self.items.append(items) 

def pop(self): 
    if self.is_empty() == True:
        raise IndexError("The stack is empty!") 
    else: 
        return self.items.pop() 

def peek(self):
    if self.is_empty() == True: 
        raise IndexError("The stack is empty!") 
    else:
        return self.items[len(self.items) - 1] 
def size(self):
    return len(self.items)

Upvotes: 0

Views: 1010

Answers (2)

SoreDakeNoKoto
SoreDakeNoKoto

Reputation: 1185

Your code doesnt work because size = my_stack.size returns a method object and not the integer you expected; you forgot to add the parentheses at the end to actually call the method. So when you tried for number in range(size):, you get an exception because you are passing a method object instead of an integer to range(). There are also a bunch of other mistakes: you didnt use the parameter passed to the function at all, instead affecting global variable my_stack (unless that was your intent); you're performing operations on some unknown variable L; you created stack at the top of your function and did nothing with it, and so on. In general, too convoluted for such a simple goal. There are more efficient ways to do this but correcting your code:

def multi_stack(s):
  mult = 1
  size = s.size()
  for i in range(size):
    tmp = s.pop()
    mult = mult * tmp
  return mult

This should return your expected product, though it wont empty the stack. If you want to do that, then get rid of the function parameter, and substitute s for my_stack as before.

Upvotes: 1

Count Zero
Count Zero

Reputation: 146

Python lists support append() and pop() methods that allow you to replicate LIFO stack behavior. Use append() to add to the end and pop() to remove the last element.

However, the underlying data structure is still a list. You can use many things to multiply a list together. for example, assuming a non-empty list:

import functools

mylist = [i for i in range(1, 10)]
product = functools.reduce(lambda x, y: x * y, mylist)

or

mylist = [i for i in range(1, 10)]
product = mylist[0]
for j in mylist[1:]: 
    product *= j

EDIT: Here is an example using your Stack class:

import functools


stack = Stack()
stack.push(1)
stack.push(3)
stack.push(9)

def multi_stack(s):
    """
    s: a Stack() object
    """
    return functools.reduce(lambda x, y: x * y, s.items)

def multi_stack_readable(s):
    """
    s: a Stack() object
    """
    if s.size() > 1:
        product = s.items[0]
        for i in s.items[1:]:
            product *= i

        return product
    elif s.size() == 1:
        return s.items
    else:
        raise IndexError("the stack is empty!")


print(multi_stack(stack))
print(multi_stack_readable(stack))

Using lambda functions is sometimes considered less readable, so I included a more readable version using a for loop. Both produce the same result.

Upvotes: 1

Related Questions