Reputation: 29
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
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
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
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
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