How do i fix the 'element not found' in binary search? - python-3.x

I have been trying to implement this code whose work is to find a particular element using Binary search.Now the code works fine if element is present in the list but it is unable to display the intended block if the search element is not present.I have assumed that the list is sorted in ascending order.Help on this would be appreciated
I have tried giving an else part with the while: but it doesn't help.Its unable to show the error for element not found
def binarysearch(l,item):
low=0
u=len(l)-1
while low<=u:
mid=int((low+u)/2)
if item==l[mid]:
return mid
elif item<l[mid]:
high=mid-1
else:
low=mid+1
l=eval(input("Enter the list of elements"))
item=int(input("Enter search item:"))
index=binarysearch(l,item)
if index>=0:
print(item,"found at index",index)
else:
print("Element not found") #i am unable to reach this part
If input is:
Enter the list of elements[8,12,19,23]
Enter search item:10
I expect the result to be "Element not found" .but the program does nothing in this situation

I will give you a tip and later on I will test better this code and try to explain why it is happening.
The tip is to use in to check if the items exist in a list or not. In is more performatic than use a loop.
Exemplo working:
def binarysearch(elem, item):
if item in elem:
return elem.index(item)
else:
return -1 # because your if verifying if the return is equal or greater than 0.
Update 1
When I tried to run your code I got in one infinite loop, it's happening because of the expression mid=int((low+u)/2) - I couldn't understand why you did it. If we run this code happens this:
list [8,12,19,23] and Item 10
u=len(l)-1 u = 3 because 4 - 1
Get in the while because the condition is True
mid=int((low+u)/2) here mid will be (0+3)/2 as you force it to be int the result will be 1
if item==l[mid]: 10 == 12 -- l[mid] - l[1] - False
elif item<l[mid]: 10<12 True
high=mid-1 high will be 1 - 1 = 0
You go to the next iteration starting on the number 3, and that is why you get in an infinite loop
To go through all positions in a list, you could use the low that starts in 0 and increase if the item is not == the value in that position. So you could use the while but in that way:
def binarysearch(l,item):
low=0
u=len(l)-1
while low<=u:
if item==l[low]:
return low
else:
low+=1
return -1
l=eval(input("Enter the list of elements"))
item=int(input("Enter search item:"))
index=binarysearch(l,item)
if index>=0:
print(item,"found at index",index)
else:
print("Element not found")
To debug your code you can use [1]: https://docs.python.org/3/library/pdb.html

Related

Checking for index out of bounds in a list Python

I am trying to write a function that checks if values index exists or does not. The function checks if n causes an out of bounds error. How would I be able to check this?
values = ["a", "b", "1"]
def check(n):
if values[n]:
print("value exists")
else:
print("value doesnt exist")
check(1)
check(4)
check(2)
Use Exception handling
def check(n):
try:
print(values[n])
except IndexError:
# Index Out of Bound
print("value doesnt exist")
You don't need to use exception handling and it's better to avoid it.
def check(n):
if n >= 0 and n < len(values):
print("value exists")
else:
print("value doesnt exist")
In calling an item in a list, Python takes 1 as the 2nd of the list, and 0 as the 1st of the list, 3 as the 4th of the list, and so on. Translating the next three lines of the code after the function defined, "check list No.2, check list No. 5, check list No. 3". there is no more than 3 items, so check(4) raises the error. Tweak the definition of check(n), something like the one shown below:
values = ["a", "b", "1"]
def check(n):
try:
print(values[n], 'exists')
except:
print("value doesn\'t exist")
The try keyword just tests if it raises no errors. If it does, it hops on over to except keyword, executing that one. The code above specifies the value item, and the comma would be not belting an error. Try it again, and the output:
b exists
value doesn't exist
1 exists
Be careful though, if you're trying to print out one line of string for one error, don't just type (except:) when it is supposed to be (except name of error:) for every single unique error planned to be in the program. It'll execute only the very first one, and not the rest.

how to fix list index out of range error in this case?

crossword vertical solve function,
the program gives list index out of range in 'if crosswords[num]==None' sratement
that statement is provided to eliminate such error
def find_word_vertical(crosswords,word):
word_list=[i for i in word]
l=len(word_list)
index=[]
for col in range(len(crosswords[0])):
for row in range(len(crosswords)):
if word_list[0]==crosswords[row][col]:
num=row
ok=True
for ch in range(l):
if crosswords[num]==None:
break
ok=False
else:
if word_list[ch]==crosswords[num][col]:
num+=1
else:
ok=False
if ok:
return [row,col]
return None
i can't find the mistake because the program runs for some example test case but the error shows up at an unknown test case. the exact test case does not appear on the screen because of 'out of index' error.
Sample Question=find_word_vertical([['s','d','o','g'],['c','u','c','m'],['a','c','a','t'],['t','e','t','k']],'cat')
if crosswords[num]==None:
break
k=False
this statement was wrong and the correct statement is:
if num>=len(crosswords):
k=False
break
if element doesn't exist in list it does not return None but rather an error.

Duplicate entries in the list

Having to enter 8 unique entries, logic should detect if any entry is duplicate otherwise continue until all 8 entries are entered.
I've played around with the For loop but it seems to not give me desired output, i want to go back to last entry if duplicate entry is scanned instead it will give a message "Duplicate SCAN, please rescan" but also the counter moves on.
sorry, i'm new to this i thought i've included code. Hoping it goes through this time.
x=1
mac_list = []
while (x <=8):
MAC1 = input("SCAN MAC"+str(x)+":")
for place in mac_list:
print (mac_list)
if place==MAC1:
print ("place"+place)
print ("Duplicate SCAN, please rescan")
else:
mac_list.append(MAC1)
x+=1
Python's in comparison should do what you need:
values = []
while True:
value = input('Input value: ')
if value in values:
print('Duplicate, please try again')
else:
values.append(value)
if len(values) > 7:
break
print(values)
Would something like this not work?
Sets can only hold unique elements and thus remove any duplicates by default - that should solve a lot of your worries. This should work better for larger datasets over elementwise comparison.
entries = set()
while len(entries)<8:
entries = entries ^ set([input("You do not have enough unique items yet, add another")])
To detect a change you can have an old list and a new one:
entries = set()
new=set()
while True:
latest = input("You do not have enough unique items yet, add another")
new = entries ^ set([latest])
if len(new) == len(entries):
print("you entered a duplicate:",latest, " Please rescan")
else:
entries = new
if len(entries) == 8 : break
Store the entries in a set, check if the set has fewer than 8 elements. If it does not, break the loop.
entries = set()
counter = 0
while len(entries) < 8:
counter += 1
entries.add(input("Enter an item: "))

How to return the result of for loop count using python?

I am using below code to compare each value from the string i have given and if any of the character matches with 4 i need the total matching occurrences for it.
I have tried the below snipped but i am getting only 0, can any one check and advise , where i went wrong?
def wordcount(list):
count=0
values=[]
for i in range (len(list)):
if int(list[i])==4:
print("the value taken from the loop is: ",list[i])
print("comparison result is: ",list[i]==4)
count=count+1
print("match count=",count)
values.append(count)
return values
else:
values.append(count)
return values
# return count
print(wordcount("1452454878594521564"))
expecting 5 as count
The reason why your code doesn't work is because once return statement is executed, the loop will not execute again. The control will be out of the function. Here's how you can fix your code:
def wordcount(l):
count=0
for i in range(len(l)):
if int(l[i])==4:
count=count+1
return count
print(wordcount("1452454878594521564"))
I removed the empty values list because honestly, I didn't see the purpose of it.
Also, if you want to count a particular character in a string just use the count method:
print("1452454878594521564".count('4'))
The result your getting is correct in case you want to find out if an item was repeated 4 times in the string. The below code will demonstrate how many times an item occurred repeatedly 4 times or over:
def wordcount(list):
count=0
values=[]
for item in list:
innercount=0
for initem in list:
if item == initem:
innercount=innercount+1
if innercount >=4:
count=count+1
values.append([item,innercount])
#list = list.replace(item, "")
return values, count
If you want a unique occurrence un-hash the commented line.

Finding an item not in list : Python

What happens when you search for 35 in the list [10,20,30,40,50]?
To simplify this i'll just post the options,
1.The program would handle the case by printing a suitable message that the element is not found
2.The value 30 is returned as it is the closest number less than 35 that is present in the list
3.The value 40 is returned as it is the closest number greater than 35 that is present in the list
4.The program will abruptly come to an end without intimating anything to the user.
Alright, so this statement will return False.
35 in [10,20,30,40,50]
What you can then do is expand on this however you want, if you want it to print whether or not it is in the list as such:
if 35 in [10,20,30,40,50]:
print("Element found in list")
else:
print("Element not found in list")
In python, when you search for an item in a list in this way, it will return a Boolean (True or False), it will not return anything else unless you want it to by programming it to do so.
If you do want to implement something like finding the closest item in a list to your search query, you could do it like this (Stolen from https://stackoverflow.com/a/12141207/8593865):
def findClosest(myNumber, myList):
return min(myList, key=lambda x:abs(x-myNumber))
If you just want to do something if an item is not in a list:
if 35 not in [10,20,30,40,50]:
#Do something

Resources