rfind implementation using find - python

I am new to python and I am trying to implement rfind function using find.
def rfind_imp(s,t):
ss = s
fpos = 0
while(True):
fpos = s.find(t,fpos)
ss=ss[fpos:]
if(ss):
fpos = fpos +1
else:
return fpos
print rfind_imp("I saw a donkey,I saw a saw "," ")
print "I saw a donkey,I saw a saw ".rfind(" ")
But the issue I am facing is I am getting 16th charcter as rfind value. Can some one help me find where I am doing a mistake. Also any suggestions for better implementation of rfind using find should be helpful.

I think your algorithm should be implemented like this:
def rfind_imp(s, t):
fpos = -1
while True:
pos = s.find(t, fpos + 1)
if pos == -1:
return fpos
fpos = pos
Another algorithm that's probably faster for strings with many ocurrences of t:
(Edit: made it work for strings with more than one character)
def rfind2(s, t):
pos = s[::-1].find(t[::-1])
if pos == -1:
return pos
return len(s) - pos - len(t)

Maybe something like:
def rfind_imp(s, t):
fpos = 0
while(True):
fpos = s.find(t, fpos)
if fpos == -1:
return pfpos
else:
pfpos = fpos
fpos += 1

Related

passing parameters into a linear search function on python

I have this linear search where there is a list of words and a single word. the search checks whether the word is in the list or not. I keep on trying to pass my parameters to test the function but when i run the program nothing comes up. it would be great if you could look at this code and tell me where im going wrong.
def isin(alist, word):
found = False
length = len(alist)
pos = 0
while found == False and pos < length:
if alist[pos] == word:
found == True
else:
pos = pos + 1
return found
words = ["child","adult","cat","dog","whale"]
if isin(words, "dog"):
print("yes")
else:
print("no")
You are doing a lot extra works. Do it like this:
def isin(alist, word):
if word in alist:
return True
else:
return False
words = ["child","adult","cat","dog","whale"]
if isin(words, "dog"):
print("yes")
else:
print("no")
You have a problem with line found == True. It should be found = True.
def isin(alist, word):
found = False
length = len(alist)
pos = 0
while found == False and pos < length:
if alist[pos] == word:
found = True
else:
pos = pos + 1
return found
You could simplify the method to do the same task in one line as:
def isin(alist, word):
return True if word in alist else False

index out of range in a recursive call

I´m getting index out of range when I try to call my function more than once. I´m new to programming and cant figure out why or how to solve it.
the code works fine when:
if n == 9:
return strng
here is my code:
def swap(n, strng): # helper
s = ""
for i in range(len(strng)):
s += strng[i-n]
return s
def encode(n, strng):
temp_lst = []
result = ""
space_idx = [i for i in range(len(strng)) if strng[i] == " "]
if n == 8: # works when 9
return strng
temp_lst.extend(encode(n-1, swap(n, "".join(strng.split()))))
for insert_idx in space_idx:
temp_lst.insert(insert_idx, " ")
for i in "".join(temp_lst).split():
result += encode(n-1, swap(n % len(i), i))
result += " "
return result
print(encode(10, "the quick brown fox jumps over the lazy dog."))
thanks in advance, and let me know if you need more information.

printing out or returning strings between brackets

I'm trying to write a function in similar manner as started, so that I will get what it's doing. I'm assuming this can be done with one line of code, with some fancy functions, but for the sake of practice and understanding I'm trying to come up with similar solution.
The task is the following: the function takes a text once it encounters enclosed square brackets [ word ] It should print out or return all words which are between square brackets. For example, if the text string would be "[a]n example[ string]", you are expected to print out "a string".
def string():
text = "some random text [and I need this bit of txt] but I don't know how to continue [to get this bit as well]"
for i in text:
for j in range(len(text)):
if text[j] == '[':
new = text.find(']')
return(text[j+1:new])
print(string())
Try this:
def extract(text, skip_chars=("\n", )):
output = ""
flag = False
for c in text:
if c == "]":
flag = False
if flag and not c in skip_chars:
output += c
if c == "[":
flag = True
return output
print(extract("""[a]n example[
stri
ng]"""))
# -> "a string"
def string():
result = []
text = "some random text [and I need this bit of txt] but I don't know how to continue [to get this bit as well]"
for i in text:
if i == '[':
new = text.find(']')
result.append(text[text.index(i) + 1:new])
return " ".join(result)
print(string())
def parse(source):
i = source.index("[") # throw an exception
result = ""
while i < len(source):
if s[i] == "[":
i += 1
while i < len(source):
temp = ""
if source[i] == "]":
result += temp
break;
temp += source[i]
i += 1
i += 1
return result

Why does my Python recursive function not break?

I have this code that should break once it fulfills a certain condition, ie when the isuniquestring(listofchar) function returns True, but sometimes it doesn't do that and it goes into an infinite loop. I tried printing the condition to check if there's something wrong with the condition, but even when the condition is printed true the function still continues running, I have no idea why.
one of the strings that throws up an infinite loop is 'thisisazoothisisapanda', so when I do getunrepeatedlist('thisisazoothisisapanda'), it goes into an infinite loop.
would be really grateful if someone could help
thanks!
Here's my code:
def getunrepeatedlist(listofchar):
for ch in listofchar:
if isrepeatedcharacter(ch,listofchar):
listofindex = checkrepeatedcharacters(ch,listofchar)
listofchar = stripclosertoends(listofindex,listofchar)
print (listofchar)
print (isuniquestring(listofchar))
if isuniquestring(listofchar):
return listofchar
#print (listofchar)
else:
getunrepeatedlist(listofchar)
return listofchar
just for reference, these are the functions I called
def isrepeatedcharacter(ch,list):
if list.count(ch) == 1 or list.count(ch) == 0:
return False
else:
return True
def checkrepeatedcharacters(ch,list):
listofindex=[]
for indexofchar in range(len(list)):
if list[indexofchar] == ch:
listofindex.append(indexofchar)
return listofindex
def stripclosertoends(listofindices,listofchar):
stringlength = len(listofchar)-1
if listofindices[0] > (stringlength-listofindices[-1]):
newstring = listofchar[:listofindices[-1]]
elif listofindices[0] < (stringlength-listofindices[-1]):
newstring = listofchar[listofindices[0]+1:]
elif listofindices[0] == (stringlength-listofindices[-1]):
beginningcount = 0
endcount = 0
for index in range(listofindices[0]):
if isrepeatedcharacter(listofchar[index],listofchar):
beginningcount += 1
for index in range(listofindices[-1]+1,len(listofchar)):
if isrepeatedcharacter(listofchar[index],listofchar):
endcount += 1
if beginningcount < endcount:
newstring = listofchar[:listofindices[-1]]
else:
#print (listofindices[0])
newstring = listofchar[listofindices[0]+1:]
#print (newstring)
return newstring
def isuniquestring(list):
if len(list) == len(set(list)):
return True
else:
return False
It may be due to the fact that you are changing listofchar in your for loop. Try cloning that variable to a new name and use that variable for manipulations and return the new variable.

Inteviewstreet Median in python. Fails on all but the first test case

So i wrote this code and it passes the first test case, and fails all the rest. However, I can't seem to find an input that breaks it. Maybe it's because I've been staring at the code too long, but i would appreciate any help.
The algorithm uses two priority queues for the smallest and largest halves of the current list. Here's the code:
#!/bin/python
import heapq
def fix(minset, maxset):
if len(maxset) > len(minset):
item = heapq.heappop(maxset)
heapq.heappush(minset, -item)
elif len(minset) > (len(maxset) + 1):
item = heapq.heappop(minset)
heapq.heappush(maxset, -item)
N = int(raw_input())
s = []
x = []
for i in range(0, N):
tmp = raw_input()
a, b = [xx for xx in tmp.split(' ')]
s.append(a)
x.append(int(b))
minset = []
maxset = []
for i in range(0, N):
wrong = False
if s[i] == "a":
if len(minset) == 0:
heapq.heappush(minset,-x[i])
else:
if x[i] > minset[0]:
heapq.heappush(maxset, x[i])
else:
heapq.heappush(minset, -x[i])
fix(minset, maxset)
elif s[i] == "r":
if -x[i] in minset:
minset.remove(-x[i])
heapq.heapify(minset)
elif x[i] in maxset:
maxset.remove(x[i])
heapq.heapify(maxset)
else:
wrong = True
fix(minset, maxset)
if len(minset) == 0 and len(maxset) == 0:
wrong = True
if wrong == False:
#Calculate median
if len(minset) > len(maxset):
item = - minset[0]
print int(item)
else:
item = ((-float(minset[0])) + float(maxset[0])) / 2
if item.is_integer():
print int(item)
continue
out = str(item)
out.rstrip('0')
print out
else:
print "Wrong!"
Your original was not so legible, so first I made it object-oriented:
MedianHeapq supports methods rebalance(), add(), remove(), size(), median(). We seriously want to hide the members minset,maxset from the client code, for all sorts of sensible reasons: prevent client from swapping them, modifying them etc. If client needs to see them you just write an accessor.
We also added a __str__() method which we will use to debug visually and make your life easier.
Also added legibility changes to avoid the indexing with [i] everywhere, rename s,x arrays to op,val, add prompts on the raw_input(), reject invalid ops at the input stage.
Your actual computation of the median confuses me (when do you want float and when integer? the rstrip('0') is a bit wack), so I rewrote it, change that if you want something else.
A discussion of the algorithm is here.
Now it is legible and self-contained. Also makes it testable.
You might be making sign errors in your code, I don't know, I'll look at that later.
Next we will want to automate it by writing some PyUnit testcases. doctest is also a possibility. TBC.
Ok I think I see a bug in the sloppiness about locating the median. Remember the minset and maxset can have a size mismatch of +/-1. So take more care about precisely where the median is located.
#!/bin/python
import heapq
class MedianHeapq(object):
def __init__(self):
self.minset = []
self.maxset = []
def rebalance(self):
size_imbalance = len(self.maxset) - len(self.minset)
if len(self.maxset) > len(self.minset):
#if size_imbalance > 0:
item = heapq.heappop(self.maxset)
heapq.heappush(self.minset, -item)
#elif size_imbalance < -1:
elif len(self.minset) > (len(self.maxset) + 1):
item = heapq.heappop(self.minset)
heapq.heappush(self.maxset, -item)
def add(self, value, verbose=False):
if len(self.minset) == 0:
heapq.heappush(self.minset,-value)
else:
if value > self.minset[0]:
heapq.heappush(self.maxset, value)
else:
heapq.heappush(self.minset, -value)
self.rebalance()
if verbose: print self.__str__()
return False
def remove(self,value,verbose=False):
wrong = False
if -value in self.minset:
minset.remove(-value)
heapq.heapify(self.minset)
elif value in maxset:
maxset.remove(value)
heapq.heapify(self.maxset)
else:
wrong = True
self.rebalance()
if verbose: print self.__str__()
return wrong
def size(self):
return len(self.minset)+len(self.maxset)
def median(self):
if len(self.minset) > len(self.maxset):
item = - self.minset[0]
return int(item)
else:
item = (-self.minset[0] + self.maxset[0]) / 2.0
# Can't understand the intent of your code here: int, string or float?
if item.is_integer():
return int(item)
# continue # intent???
else:
return item
# The intent of this vv seems to be round floats and return '%.1f' % item ??
#out = str(item)
#out.rstrip('0') # why can't you just int()? or // operator?
#return out
def __str__(self):
return 'Median: %s Minset:%s Maxset:%s' % (self.median(), self.minset,self.maxset)
# Read size and elements from stdin
N = int(raw_input('Size of heap? '))
op = []
val = []
while(len(val)<N):
tmp = raw_input('a/r value : ')
op_, val_ = tmp.split(' ')
if op_ not in ['a','r']: # reject invalid ops
print 'First argument (operation) must be a:Add or r:Remove! '
continue
op.append(op_)
val.append(int(val_))
mhq = MedianHeapq()
for op_,val_ in zip(op,val): # use zip to avoid indexing with [i] everywhere
wrong = False
if op_ == 'a':
wrong = mhq.add(val_)
elif op_ == 'r':
wrong = mhq.remove(val_)
assert (mhq.size()>0), 'Heap has zero size!'
assert (not wrong), 'Heap structure is wrong!'
if not wrong:
print mhq.__str__()

Categories