Extracting from a queue in python

I'm having a problem trying to extract elements from a queue until a given number. If the given number is not queued, the code should leave the queue empty and give a message saying that.

Instead, I get this error message, but I'm not able to solve it:

Traceback (most recent call last):
  File "python", line 45, in <module>
IndexError: list index out of range

This is my current code:

class Queue():
  def __init__(self):
      self.items = []
  def empty(self):
    if self.items == []:
      return True
    else:
      return False
  def insert(self, value):
        self.items.append(value)
  def extract(self):
    try:
      return self.items.pop(0)
    except:
      raise ValueError("Empty queue")
  def last(self):
    if self.empty():
      return None
    else:
      return self.items[0]

import random
def randomlist(n2,a2,b2):
    list = [0]  * n2
    for i in range(n2):
      list[i] = random.randint(a2,b2)
    return list

queue1=Queue()
for i in range (0,10):
  queue1.insert(randomlist(10,1,70)[i])
if queue1.empty()==False :
  print("These are the numbers of your queue:\n",queue1.items)

test1=True
while test1==True:
  s=(input("Input a number:\n"))
  if s.isdigit()==True :
   test1=False
   s2=int(s)
  else:
    print("Wrong, try again\n")

for i in range (0,10) :    
  if queue1.items[i]!=s2 :
    queue1.extract()
  elif queue1.items[i]==s2 :
    queue1.extract()
    print ("Remaining numbers:\n",queue1.items)
    break
if queue1.empty()==True :
  print ("Queue is empty now", cola1.items)

Upvotes: 2

Views: 1198

Answers (4)

user8202635
user8202635

Reputation:

The test code operates from 0 to 10, but when you extract an element, that decreases the size of the queue.

So if the queue is originally 10 element long, the index i you provide will eventually be >= the length of the queue.

Hence an IndexError.

Try one of the other suggested code segments.

Upvotes: 0

Patrick Artner
Patrick Artner

Reputation: 51643

Modifying a list while going through it is a bad idea.

 for i in range (0,10) :    
    if queue1.items[i]!=s2 :
        queue1.extract()
    elif queue1.items[i]==s2 :
        queue1.extract()
        print ("Remaining numbers:\n",queue1.items)

This code modifies your queue - items, it shortens the items-list but you still itereate over the full range if no items is found. So your internal list will get shorter and shorter and your range (i) advances towards i.

Somewhen you access an items[i] that is no longer in your queue.

Solution (Edited thanks to Stefan Pochmann's comment):

 for _ in range(len(queue1.items)):    # no hardcoded length anymore
    item = queue1.extract()              # pop item
    if item == s2 :                      # check item for break criteria
        print ("Remaining numbers:\n",queue1.items)
        break

Upvotes: 1

Stefan Pochmann
Stefan Pochmann

Reputation: 28596

extract elements from a queue until a given number. If the given number is not queued, the code should leave the queue empty and give a message saying that.

while not queue.empty():
    if queue.extract() == target:
        print('Found! Remaining numbers:', queue.items)
        break
else:
    print('Not found! Remaining numbers:', queue.items)

Upvotes: 1

user2603796
user2603796

Reputation:

You can try replacing the last part of your code i.e.

for i in range (0,10) :    
  if queue1.items[i]!=s2 :
    queue1.extract()
  elif queue1.items[i]==s2 :
    queue1.extract()
    print ("Remaining numbers:\n",queue1.items)
    break
if queue1.empty()==True :
  print ("Queue is empty now", cola1.items)

with

poptill = -1 # index till where we should pop
for i in range(0,len(queue1.items)): # this loop finds the index to pop queue till
  if queue1.items[i]==s2:
    poptill = i
    break

if poptill != -1: # if item to pop was found in queue
  i = 0
  while i <= poptill: # this loop empties the queue till that index
    queue1.extract()
    i += 1
  if queue1.empty()==True :
    print ("Queue is empty now", queue1.items)
  else:
    print ("Remaining numbers:\n",queue1.items)
else: # else item was not found in list
  for i in range(0,len(queue1.items)): # this loop empties the queue
    queue1.extract()
  print ("no item found, so emptied the list, numbers:\n",queue1.items)

Here we find the index location till where we should pop in the first loop, and then pop the queue till that index in the second loop, finally if the item to pop was not found in list we empty list in the third loop.

Upvotes: 0

Related Questions