I have written a bisect function that takes a word list "t" and a word "val". It recursively halves the list until the index of the list is the word or returns false. If it finds the word, it is supposed to return it.
I have read multiple books, the documentation, and all the applicable questions here on SO but I still cannot determine what I am doing wrong: why won't the function return the value? It will print the value just fine, but no return except None.
Any help is greatly appreciated!
def bisect(t, val):
if t[len(t)/2] < val and len(t) > 1:
t = t[len(t)/2:]
bisect(t, val)
elif t[len(t)/2] > val and len(t) > 1:
t = t[:len(t)/2]
bisect(t, val)
elif t[len(t)/2] == val:
t = t[len(t)/2]
#print type(t), t
return t
else:
return False
b = make_list(t)
x = bisect(b, 'and')
print x
The main issue here is that you need to return t from each call to the recursively called function. Picture the call stack using my modified code below:
def main():
b = ['a', 'able', 'ability', 'abort', 'and', 'arc', 'zygote']
x = bisect(b, 'and')
print x
def bisect(t, val):
if t[len(t)/2] < val and len(t) > 1:
t = t[len(t)/2:]
t = bisect(t, val)
elif t[len(t)/2] > val and len(t) > 1:
t = t[:len(t)/2]
t = bisect(t, val)
elif t[len(t)/2] == val:
t = t[len(t)/2]
print type(t), t
else:
return False
return t
if __name__ == '__main__':
main()
The first time bisect is called, t is set to ['abort', 'and', 'arc', 'zygote'].
On the second call to bisect, t is set to ['abort', 'and']
On the third call, we have 'and' located, and return that value.
IF you returned as you had (only returning from the exact match or False result), then you return to the second call (['abort', 'and']), then the first call (['abort', 'and', 'arc', 'zygote']), and finally you return without hitting a return t in that first call. Thus, nothing is returned.
Rewriting your original code as I have, everything is the same until we find the match. However, with my code, the final call returns t back into the t variable used in the second call. That returns the value to the first call, which returns the result back to the calling code.
Hopefully, that clears up your question.
This modified version works:
def bisect(t, val):
mid = len(t)//2
mid_ele = t[mid]
end = len(t)
if mid_ele < val and end > 1:
t = t[mid:]
return bisect(t, val)
elif mid_ele > val and end > 1:
t = t[:mid]
return bisect(t, val)
elif mid_ele == val:
t = mid_ele
return t
else:
return False
b = ['she', 'he', 'you', 'and', 'me']
print(bisect(b, 'and'))
prints the desired:
and
I made it Python 3 proof using // for integer division and added two returnsbefore the recursive call.
Related
Write a python function accordian(l) that takes as input a list of integer l and returns True if the absolute difference between each adjacent pair of elements alternates between increasing strictly and decreasing strictly
Code witten by Debkanta Mondal #Python3
def accordian(l):
di=[]
res=[]
for x,y in zip(l[:],l[1:]):
d1=abs(y-x)
di.append(d1)
#print(di)
for i,j in zip(di[:],di[1:]):
if i<j:
flag=1
elif i==j:
flag=2
else:
flag=0
res.append(flag)
#print(flag)
for s in res:
if s==2:
return False
break
return all(m!=n for m,n in zip(res,res[1:]))
def expanding(l):
c1=abs(l[1]-l[0]) # Difference of 1st 2 integers.
for j in range(2,len(l)):
c2=abs(l[j]-l[j-1]) # Next difference = l[2]-l[1]
if c2 <= c1: # if next diff smaller/equal to prev diff
return(False) #return false
else: # if next diff > prev diff
c1=c2 # next diff be prev diff for next iteration.
return(True)
def accordian(l):
"""
Function : takes as input a list of integer l and returns True
if the absolute difference between each adjacent pair of elements
alternates between increasing strictly and decreasing strictly.
Input : List
Return : Boolean
"""
size = len(l)
diff = []
if size < 3:
return False
for i in range(size-1):
abs_diff = abs(l[i+1]-l[i])
diff.append(abs_diff)
if len(diff) == 2:
if abs(diff[0] - diff[1]) == 0:
return False
else:
return True
result = [a < b for a, b in zip(diff, diff[1:])]
for i in range(len(result)-1):
if result[i] == result[i+1]:
return False
return True
Alright, so i have a situation where there is a sequence which has to be executed in particular order inside try statement, if any of the steps fails, return value has to be returned. Also there is a finally statement where i perform some kind of 'go-back-to-safe-state-if-anything-fails' sequence which also has to be executed in particular order. For each step (both try and finally statement), if it fails, some kind of message has to be logged with reason why it failed and execution has to be stopped at this point. Return value of sequence inside finally statement doesn't matter to me (I'm only interested in return value of try statement). This is the way that i decided to deal with it:
def whatever():
ret_val = True
try:
x = foo()
if isinstance(x, str):
print "%s" % x
ret_val = False
return
y = bar()
if isinstance(y, str):
print "%s" % y
ret_val = False
return
finally:
a = safe_state_step_1()
if isinstance(a, str):
print "%s" % a
return ret_val
b = safe_state_step_2()
if isinstance(b, str):
print "%s" % b
return ret_val
return ret_val
What I want to find out if there is a more 'pythonic'/'smarter' way of dealing with this kind of situation?
I have tried to find an answer to this in vain, so here goes:
The goal is to have a dictionary that has a few lists as values, and then have a function that (depending on user input) will take one of those lists and combine it with other lists, and finally I should get the final list printed.
Seems simple enough but what I get is a type error (lists being unhashable). The combine2 function seems to be working perfectly fine with any other two lists I try to feed it, except for when it tries to get a list that is a dictionary value (??). Does anybody know what I'm doing wrong?
dic = {
'reptiles': ['lizzard', 'crocodile', 'T-Rex'],
'birds': ['canary', 'parrot', 'seagul'],
'mammals': ['monkey', 'cat', 'dog'],
'insects': ['ant', 'bee', 'wasp']
}
FishList = ['goldfish', 'shark', 'trout']
def combine2 (a, b): # returns the combinations of 2 lists' items
tmp = []
n = 0
while n < len(a):
for i in b:
if 8 <= len(str(a[n])+str(i)) and 16 >= len(str(a[n])+str(i)):
tmp.append(str(a[n]) + str(i))
n += 1
return tmp
def animals_mix(k, l): # just some arbitrary combinations of lists
list1 = combine2(FishList, dic[k])
list2 = combine2(list1, dic[k])
list3 = combine2(dic[k], FishList)
l = dic[k] + list1 + list2 + list3
def animals():
print '''\n\nwhat's your favourite animal group?\n
1) reptiles
2) birds
3) mammals
4) insects
'''
while True:
x = raw_input("[+] pick a number > ")
tmp = []
if x == '1':
animals_mix(dic['reptiles'], tmp)
break
elif x == '2':
animals_mix(dic['birds'], tmp)
break
elif x == '3':
animals_mix(dic['mammals'], tmp)
break
elif x == '4':
animals_mix(dic['insects'], tmp)
break
elif x == '':
break
else:
print "\nError: That wasn't in the list of options\nType one of the numbers or press ENTER to move on\n"
return tmp
print animals()
For "TypeError: unhashable type: 'list'", it is because you are actually passing the list in your dict when you seemingly intend to pass the key then access that list:
animals_mix(dic['reptiles'], tmp)
...
def animals_mix(k, l):
list1 = combine2(FishList, dic[k])
in the first line of animals_mix() you are actually trying to do dic[dic['reptiles']] and dicts can not be keyed by un-hashable types, hence the error.
I'm working on an assignment for a university Python class, given this code to create a binary search tree,
# creates an empty tree
def createEmptyTree():
return None
# adds a value to a BST and returns a pointer to the modified BST
def add(tree, value):
if tree == None:
return {'data':value, 'left':None, 'right':None}
elif value < tree['data']:
tree['left'] = add(tree['left'],value)
return tree
elif value > tree['data']:
tree['right'] = add(tree['right'],value)
return tree
def main():
myTree = createEmptyTree()
myTree = add(myTree, 20)
myTree = add(myTree, 2)
myTree = add(myTree, 25)
myTree = add(myTree, 14)
myTree = add(myTree, 75)
myTree = add(myTree, 93)
print hasSum(myTree, 22)
In one function, hasSum(tree, Sum) I'm asked to check(True/False) if a given integer is attainable with any sum combination of the nodes in the BST.
Here is my code so far,
def hasSum(tree, Sum):
if tree == None :
return False
else :
leftSum = hasSum(tree['left'], Sum)
rightSum = hasSum(tree['right'], Sum)
if leftSum == Sum or rightSum == Sum :
return True
But it's returning None, please tell me what I'm doing wrong, I'm still working on mastering recursion.
Thank you.
Okay, this one matches true for 20,22,36,45,120,213
def hasSum(tree, Sum):
if tree is not None:
Decrement = tree['data']
Sum = Sum - Decrement
if Sum == 0:
return True
else:
return hasSum(tree['right'], Sum) or hasSum(tree['left'], Sum)
i = 0
while (i<300):
i+=1
if hasSum(myTree,i):
print i, hasSum(myTree,i)
Do an in-order traversal.
For each node, compute the difference ("k - currentnode's value", where K is final sum).
Keep track of node values you've seen so far, in a 'set'.
If the target is in the set, return True.
Else, add currentnode's value to the set.
def checkSum(root, k, seen = set()):
if root:
checkSum(root.left, k, seen)
target = k-root.value
#print "Seen", seen
#print "Value", root.value
#print "Target", target
if target in seen:
return True
else:
seen.add(root.value)
checkSum(root.right, k, seen)
return False
I'm trying to implement a function to find occurrences in a list, here's my code:
def all_numbers():
num_list = []
c.execute("SELECT * FROM myTable")
for row in c:
num_list.append(row[1])
return num_list
def compare_results():
look_up_num = raw_input("Lucky number: ")
occurrences = [i for i, x in enumerate(all_numbers()) if x == look_up_num]
return occurrences
I keep getting an empty list instead of the ocurrences even when I enter a number that is on the mentioned list.
Your code does the following:
It fetches everything from the database. Each row is a sequence.
Then, it takes all these results and adds them to a list.
It returns this list.
Next, your code goes through each item list (remember, its a sequence, like a tuple) and fetches the item and its index (this is what enumerate does).
Next, you attempt to compare the sequence with a string, and if it matches, return it as part of a list.
At #5, the script fails because you are comparing a tuple to a string. Here is a simplified example of what you are doing:
>>> def all_numbers():
... return [(1,5), (2,6)]
...
>>> lucky_number = 5
>>> for i, x in enumerate(all_numbers()):
... print('{} {}'.format(i, x))
... if x == lucky_number:
... print 'Found it!'
...
0 (1, 5)
1 (2, 6)
As you can see, at each loop, your x is the tuple, and it will never equal 5; even though actually the row exists.
You can have the database do your dirty work for you, by returning only the number of rows that match your lucky number:
def get_number_count(lucky_number):
""" Returns the number of times the lucky_number
appears in the database """
c.execute('SELECT COUNT(*) FROM myTable WHERE number_column = %s', (lucky_number,))
result = c.fetchone()
return result[0]
def get_input_number():
""" Get the number to be searched in the database """
lookup_num = raw_input('Lucky number: ')
return get_number_count(lookup_num)
raw_input is returning a string. Try converting it to a number.
occurrences = [i for i, x in enumerate(all_numbers()) if x == int(look_up_num)]