Combine string recursive-python - python

I have two string list:
A = ['YELLOW']
B = ['BA']
I want to combine these two string using a recursive function to get
['YBAEBALBALBAOBAWBA']
HERE IS my function :
def Combine(A, B):
if len(A) > 0:
return str(A[0]) + str(B) + Combine(A[:0], B)
--
I have no idea how recursive works?
Could someone please help me!

You were very close!
def Combine(A, B):
if len(A) > 0:
return str(A[0]) + str(B) + Combine(A[1:], B) # <-- fix 1
else:
return '' # <-- fix 2
in order to call recursively with the rest of A you should call A[1:]
you took care of the case that len(A) > 0 but forgot to take care of the case that A ran out of characters (the else)
Running
A = 'YELLOW'
B = 'BA'
print(Combine(A, B))
OUTPUT
YBAEBALBALBAOBAWBA

Related

using python recursion to calculate the Parenthesis part not working

If I enter input with parentheses it resolves only what is inside the parentheses and not what is after or before, if I enter two expressions with parentheses it returns None.
you can see it in the code.
def divide(a, b):
return a/b
def pow(a, b):
return a**b
def addA(a, b):
return a+b
def subA(a, b):
return a-b
def mul (a, b):
return a*b
operators = {
'+': addA,
'-': subA,
'*': mul,
'/': divide,
'^' : pow,
}
def calculate(s):
if s.isdigit():
return float(s)
elif '[' in s:
start = s.index('[')
end = s.rindex(']')
return calculate(s[start + 1:end])
for c in operators.keys():
left, operator, right = s.partition(c)
if operator in operators:
return operators[operator](calculate(left), calculate(right))
calc = input("Type calculation:\n")
print("Answer: " + str(calculate(calc)))
input: [2+2]+[2+2]
output: None
input [2+3]*2
output 5
Nice idea.
elif '[' in s:
...
return calculate(s[start + 1:end])
Beautifully simple.
But, alas, wrong.
Consider 1+1+1+[8+9]+2+2+2.
Is there a [ bracket in there? Yes.
And the recursive call correctly computes 17.
But we're ignoring the 1's and the 2's.
Also, when the for finishes and we fall of the
end of the function we return None.
Consider doing something else in that case,
perhaps raise a fatal error.
You probably want to invert the order of operations,
so higher priority ops will bind more tightly.
You will find you can iterate through the edit - debug
cycle much more quickly if you write some simple
unit tests
that lock in "working" behavior. Only the last test fails ATM.
class CalculateTest(unittest.TestCase):
def test_addition(self):
self.assertEqual(5, calculate("2+3"))
self.assertEqual(5, calculate("[2+3]"))
self.assertEqual(9, calculate("2+3+4"))
self.assertEqual(9, calculate("2+[3+4]"))
I found it convenient to have the function always return a float.
Once you have this function in better shape, please
let us know
how it turned out.
The calculate function took into account the first and last parenthesis, skipping the middle ones.
Try the following:
def extract_expression(s):
start = s.rindex('[')
end = s.rindex(']')
return s[start + 1:end]
def calculate(expr):
for c in operators.keys():
left, operator, right = expr.partition(c)
if operator in operators:
return operators[operator](float(left), float(right))
def solution(s):
while '[' in s:
sub_expression = extract_expression(s)
result = calculate(sub_expression)
s = s.replace('[' + sub_expression + ']', str(result))
if s.isdigit():
return float(s)
return calculate(s)
calc = input("Type calculation:\n")
print("Answer: " + str(solution(calc)))
input: [2+2]+[2+2],
output: 8.0
input: [2+3]*2,
output: 10.0
input: 2+[2+2],
output: 6.0

Python Subsequence of a String

The exercise asks me to write a program. It wrote
"Given a string s and a string t, check if s is a subsequence of t.
For example: "ac", "abcd" => True."
So I wrote this:
def isSubsequence(s, t):
s, t = map(list, [s, t])
for c in t:
if c in s:
s.pop(0)
return not s
It worked ok in most cases except one:
s = "rjufvjafbxnbgriwgokdgqdqewn"
t = "mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq"
I don't know why my code didn't work on this one. So if someone knows the answer, please tell me.
Here is what you can do:
def isSubsequence(s, t):
s = list(s)
for i,(a,b) in enumerate(zip(t,s)):
if a != b:
s.insert(i,'.')
return len(t) == len(s)
print(isSubsequence('Apes are goo.', 'Apples are good.'))
Output:
True
Your case is that that specific s is not a subsequence of that specific t. To prove it:
def isSubsequence(s, t):
s = list(s)
for i,(a,b) in enumerate(zip(t,s)):
if a != b:
s.insert(i,'.')
print(t)
print(''.join(s))
s = "rjufvjafbxnbgriwgokdgqdqewn"
t = "mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq"
isSubsequence(s, t)
Output:
mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq
......r...........................j.u...................f...............................................................v..............................j..................................................................................................a................f..b..............................................................................x............n...b....................g....................................................................................r...i.......................wgokdgqdqewn
UPDATED to include simpler implementation given by #StevenRumbalski at the comments:
def isSubsequence(s, t, start=-1):
return all((start:=t.find(c, start+1)) > -1 for c in s)
I suppose the order also matters
def isSubsequence(s, t): # order matters
s, t = list(s), list(t)
for c in s:
if c in t:
c_idx = t.index(c)
t = t[c_idx:]
else:
return False
return True
def isSubsequence(s, t):
start = -1
for i in s:
start = t.find(i, start + 1)
if start == -1:
return False
return True
If this is an excercise you probably should figure it out yourself :), but since you already posted your attempt, allow me to propose this simpler approach which may work for you:
from itertools import combinations
def isSubsequence(s, t):
return any(s == ''.join(c) for c in combinations(t, len(s)))
It's obviously less performant, but maybe at least a helpful suggestion.

Match two strings (char to char) till the first non-match using python

I am trying to match two strings sequentially till the first the non-matched character and then determine the percentage exact match. My code is like this:
def match(a, b):
a, b = list(a), list(b)
count = 0
for i in range(len(a)):
if (a[i]!= b[i]): break
else: count = count + 1
return count/len(a)
a = '354575368987943'
b = '354535368987000'
c = '354575368987000'
print(match(a,b)) # return 0.267
print(match(a,c)) # return 0.8
Is there any built-in method in python already which can do it faster ? For simplicity assume that both strings are of same length.
There's no built-in to do the entire thing, but you can use a built-in for computing the common prefix:
import os
def match(a, b):
common = os.path.commonprefix([a, b])
return float(len(common))/len(a)
I don't think there is such build-in method.
But you can improve your implementation:
No need to wrap the inputs in list(...). Strings are indexable.
No need for count variable, i already carries the same meaning. And you can return immediately when you know the result.
Like this, with some doctests added as a bonus:
def match(a, b):
"""
>>> match('354575368987943', '354535368987000')
0.26666666666666666
>>> match('354575368987943', '354575368987000')
0.8
>>> match('354575368987943', '354575368987943')
1
"""
for i in range(len(a)):
if a[i] != b[i]:
return i / len(a)
return 1
alternative
(Just now saw that the answer below me thought of the same thing while I was editing the post)
def match(l1, l2):
# find mismatch
try:
stop = next(i for i, (el1, el2) in enumerate(zip(l1, l2)) if el1 != el2)
return stop/len(l1)
except StopIteration:
return 1

python 3.6 put number is str

def binary(n):
if n>0:
return binary(n//2)*10 + (n%2)
else:
return 0
The answer is 10000000 but it have to be "10000000". How can I put str on the answer?
In python, to change the type of anything, the only thing you have to do is wrap that in str(), int(), float()... or whatever type you want to change it to.
more details: http://usingpython.com/python-casting/
edit: sorry, didn't realize the recursive problem, still, I don't see why you can't just change the type after the function returns, seems the easiest thing to do.
if you insist though:
def binary(n):
if int(n)>0:
return str( int(binary(str(int(n)//2)))*10 + (int(n)%2))
else:
return str(0)
I will suggest that you use nested/inner functions as shown below to solve you problem. This allows you to compute the result using integers, and then convert the result to a string, or any other type, before returning it.
def binary(n):
def inner(m):
if m>0:
return inner(m//2)*10 + (m%2)
else:
return 0
return str(inner(n))
Alternatively you can cast n to the correct type whenever you use it. This is, in my opinion, a horrible to solve the problem, but it should still do the trick.
def binary(n):
if int(n) > 0:
return str(int(binary(n//2))*10 + n%2)
else:
return "0"
The problem with simply wrapping your return in a cast to str(), is that the subsequent calls to binary() will be affected, not just the top-level call. After the deepest recursive call to binary has finished, it will return its result - which is a string - to the next deepest recursive call to the expression:
binary(n // 2) * 10 + (n % 2)
But since the return value is a string, it fails when used in the expression.
The obvious solution is to simply cast the return value of binary() to a string from wherever it's being called. However, if for some reason you cannot do this, you can make a second function nested under binary, call this function inside of binary(), and cast its result to a string:
>>> def binary(n):
def _binary(n):
if n > 0:
return _binary(n // 2) * 10 + (n % 2)
else:
return 0
return str(_binary(n))
>>> binary(128)
'10000000'
>>> binary(64)
'1000000'
>>> binary(32)
'100000'
>>> binary(16)
'10000'
>>> binary(8)
'1000'
>>> binary(4)
'100'
>>> binary(2)
'10'
>>>
As #StefanPochmann pointed out, this method would also work:
def binary(n):
return binary(n // 2) + str(n % 2) if n > 1 else str(n)

Loop gets stuck on 1st iteration

While trying to create a web crawler, I'm trying to define this function:
#a and b are lists.
def union(a, b):
i = 0
while i <= len(b):
if b[i] in a :
a = a.append(b[i])
i = i + 1
return a
then testing it, I input:
a = [1,2,3]
b = [2,4,6,9]
union(a,b)
It keeps giving me the error
TypeError: argument of type 'NoneType' is not iterable
I've seen a solution for this problem in another thread by editing my condition to if a and b[i] not in a:, but while testing, that only solves it until I append 1 element of b to a, then stops working.
See the updated and commented code below
#a and b are lists.
def union(a, b):
i = 0
while i <= len(b):
if b[i] in a :
# the problem lies here. append returns None
# a = a.append(b[i])
# this should work
a.append(b[i])
i = i + 1
return a

Categories

Resources