0

I'm trying to do this but it is always wrong. I don't understand how Am I supose to do this... This is my code:

class WrongStack:
def __init__(self):        
    self.__items = numpy.array([])

def push(self, item): 
    numpy.concatenate(self.__items,item)

def pop(self):  
    return numpy.delete(self.__items,0,-1)

def peek(self):  
    return self.__items[len(self.__list) - 1]

def is_empty(self):            
    return len(self.__items) == 0

def size(self):                 
    return len(self.__items)


s = WrongStack()
number = input('Choose a number, 0 to finish')
while number != '0':
  s.push(numpy.array([nmr]))
  number = input('Choose a number, 0 to finish')
while not s.is_empty():
  number = s.pop()
  print(number)

The error is:

File "C:/Users/JJ/OneDrive - ISCTE-IUL/EDA/Aula 4.py", line 55, in <module>
s.push(numpy.array([nmr]))

File "C:/Users/JJ/OneDrive - ISCTE-IUL/EDA/Aula 4.py", line 38, in push
numpy.concatenate(self.__items,item)

File "<__array_function__ internals>", line 6, in concatenate
TypeError: only integer scalar arrays can be converted to a scalar index

I know this is not how to build a normal stack but I have to do this in this way.

3
  • 1
    Is there a reason you're using numpy array rather than a simple list? Commented Mar 20, 2020 at 15:51
  • @DarrylG This is an exercise from my Data Structures and Algoritms class. I think the main goal,after implementing this algoritm, is to say if it has a good performance in comparance with the normal stack algoritm (using a list). Commented Mar 20, 2020 at 15:57
  • I'm afraid for this purpose the performance will probably be worse than using a list. Numpy has overhead, but its worthwhile when there are computations on large amounts of data. It will probably be slower for your simple usage. Commented Mar 20, 2020 at 16:02

2 Answers 2

1

Made mods to your code to get it to work.

Placed 'Mod' at places where I changed the code.

Code

import numpy as np

class WrongStack:
  def __init__(self):        
      self.__items = np.array([])

  def push(self, item): 
      # Mod--concatenate takes list contains items to concatenate
      self.__items = np.concatenate([self.__items,item])

  def pop(self):  
      # Mod--np.delete returns a new array
            # also retrieve last element before delete
      last = self.__items[-1]
      self.__items = np.delete(self.__items,-1, 0)
      return last

  def peek(self):  
      return self.__items[len(self.__list) - 1]

  def is_empty(self): 
      # Mod--use function size    
      return self.size() == 0

  def size(self):                 
      return len(self.__items)

  def __str__(self):
    # Mod--added for display the array
    return str(self.__items)

s = WrongStack()
number = input('Choose a number, 0 to finish: ')
while len(number) > 0 and number != '0': #Mod done if no input or '0' entered
  # Mod--convert numer to integer
  s.push(np.array([number], dtype=np.int32)) # specify type (i.e. int32)
  number = input('Choose a number, 0 to finish: ')

# Mod--print array created
print('Array created:', s)

while not s.is_empty():
  number = s.pop()
  print('number: ', number)

Test

Choose a number, 0 to finish: 1
Choose a number, 0 to finish: 2
Choose a number, 0 to finish: 3
Choose a number, 0 to finish: 4
Choose a number, 0 to finish: 5
Choose a number, 0 to finish: 0
Array created: [1. 2. 3. 4. 5.]
number:  5.0
number:  4.0
number:  3.0
number:  2.0
number:  1.0

Alternative

Relies on Numpy fixed size array. Uses slices and range checking to insure we stay within allocated size.

import numpy as np

class WrongStack:
  def __init__(self, maxlen=100):        
      self.__items = np.array([0]*maxlen) # Fixed size Numpy array
      self._count = 0
      self._maxlen = maxlen

  def push(self, item): 
      # Mod--concatenate takes list contains items to concatenate
      if self._count < self._maxlen:
        self.__items[self._count] = item
        self._count += 1
      else:
        print('push: no more space')


  def pop(self):  
      # Mod--np.delete returns a new array
            # also retrieve last element before delete
      if self._count > 0:
        last = self.__items[self._count-1]
        self._count -= 1
        return last
      else:
        return None

  def peek(self):
      if self._count > 0:
        return self.__items[self._count-1]
      else:
        return None

  def is_empty(self): 
      # Mod--use function size    
      return self.size() == 0

  def size(self):                 
      return self._count

  def __str__(self):
    # Mod--added for display the array
    return str(self.__items[:self._count])

s = WrongStack(10) # will handle stack with up to 10 elements
number = input('Choose a number, 0 to finish: ')
while len(number) > 0 and number != '0': #Mod done if no input or '0' entered
  # Mod--convert numer to integer
  s.push(number) # specify type (i.e. int32)
  number = input('Choose a number, 0 to finish: ')

# Mod--print array created
print('Array created:', s)

while not s.is_empty():
  number = s.pop()
  print('number: ', number)
Sign up to request clarification or add additional context in comments.

8 Comments

I have at least one question. In the pop function, when you write: self.__items = np.delete(self.__items,-1, 0), does this creates a new array without the element that you delete or is changes the original array? I hope you understand what I'm trying to say. And does the original array becomes empty after: while not s.is_empty(): number = s.pop() print('number: ', number) ???
@JoãoJúlio--according to the documentation delete returns a new array.
@JoãoJúlio--here is a shared online version of my running code you can try.
@JoãoJúlio--to expand on my previous comment since delete returns a new array, that means that in your original pop method return numpy.delete(self.__items,0,-1) leaves self.__items unchanged.
@JoãoJúlio--as this answer points out Numpy arrays are fixed in size so can't be changed. So the delete operation has to create a new array. So you're right, Numpy arrays are inefficient to use as a stack since we keep creating new arrays as we add (push) and delete (pop) elements from the stack. That's why a simple list is much better for this purpose.
|
0

You're trying to use a numpy array as a stack, which might not work as well as you hope. Numpy arrays are designed for mathematical computation, not as general-purpose data structures.

Instead just use a Python list to implement your stack. In fact the Python documentation even includes a section on how to do just that:

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

1 Comment

I already did this type of stack. Now I need to build the stack using the array, and I'm getting trigered because arrays aren't supossed to this type of "jobs" and I don't know how to correct this code. @robbrit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.