def function to compare two strings - python-3.x

we need to define a function that compares two strings and if they are different we want to know the index. the problem is that no matter what insert we use we always get -1 even when they are not the same.
def mutation_detector(seq1,seq2):
if DNAval(seq1) and DNAval(seq2) == True:
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return(i)
else:
return(-1)
else:
return('Wrong input')
else:
return('Wrong input')
print(mutation_detector('ATCGGGTA','ATCGGCTA'))

Basically you're using and wrong and have some basic Logic errors I think:
and doesn't say "do A and B" but rather"if A is True and B is True"
My attempt at fixing it is as follows:
if DNAval(seq1) and DNAval(seq2):
if len(seq1) == len(seq2):
for (i, (elem1, elem2)) in enumerate(zip(seq1, seq2)):
if elem1 != elem2:
return i
return -1
Your if-else in the loop always returns in the First loop iteration: it takes the first two chars and compares them; are they equal? No -> return -1

If you follow the logic, it begins comparing strings. If the two letters are the same, it goes for the ELSE (because they are not different) and ends the routine after checking only the first letter.
You only want the routine to return -1 if it makes it all the way through the for loop without returning an index number. So,
Change as below:
def test(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return(i)
return(-1)
else:
return('Wrong input')
print( test('Hello1', 'Hello2'))
print('done')

The problem is, that you are returning -1 on the first time you run through the for loop, because the else-clause is immediately entered.
Use the else clause with the for loop itself instead.
For example:
def compare_strings(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return i
else:
return -1
else:
return 'Wrong input'
(mind you, raising a custom exception might be better than returning "Wrong input" here...)

Here's how I would do it
def mutation_detector(seq1, seq2):
if not DNAval(seq1) or not DNAval(seq2) or len(seq1) != len(seq2):
return "Wrong input" # maybe raise ValueError if DNAval fails instead?
for index, (base1, base2) in enumerate(zip(seq1, seq2)):
if base1 != base2:
return index
return -1

Try this,
It will return index when unable to compare otherwise it will compare two character and to print equal again compare it with length of string.
def mutation_detector(seq1,seq2):
count=0
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return i
else:
count=count+1
if count==len(seq1):
return 'Equal'
print(mutation_detector('ATCGGCTA','ATCGGCTA'))

def comp_string(string1,string2):
if len(string1)!=len(string2):
return "length not equal"
else:
for i in range(len(string1)):
if string1[i] != string2[i]:
return i
return "equal"

Related

For loop, if statement and Zip python

a= ("Kiran","Narut","Sasue"]
b= ["Kiran","Naruto","Sasuke"]
def quality_check(x,y):
for i,j in zip(x,y):
if i == j:
return "Good to go"
else:
return "wrong names"
quality_check(a, b) # Good to go
It shows unexpected result. The results are shown just for the first element of the lists.
As you are using return It will only check for the first elements.
A return statement is used to end the execution of the function, Replace this with print() will loop over all the elements.
You should use yield instead of return
a= ["Kiran", "Narut","Sasue"]
b= ["Kiran", "Naruto","Sasuke"]
def quality_check(x,y):
for i,j in zip(x,y):
if i == j:
yield "good to go"
else:
yield "wrong"
for element in quality_check(a, b):
print(element)
this will return required results
every time you yield from function it returns a iterable object
Your function quality_check() is returning after the if i == j statement in the first iteration of your for loop. That if statement is comparing "Kiran" == "Kiran" (which is True).
Try checking for only 'Wrong names' in the for loop. Then return 'Good to go' once the loop completes and no Wrong names have been found.
a = ["Kiran", "Narut","Sasue"]
b = ["Kiran", "Naruto","Sasuke"]
c = ["Kiran", "Narut","Sasue"]
def quality_check(x,y):
for i,j in zip(x,y):
if i != j:
return "Wrong names"
return "Good to go"
print(quality_check(a,b))
#> Wrong names
print(quality_check(a,c))
#> Good to go

why there is no return value rather gives null

why does the return value in this function gives None
rather i think it should return count
output - None
def longestChain(num,count):
if num==1:
return count
elif num%2==0:
num = num/2
count+=1
longestChain(num,count)
elif num%2==1:
num =3*num+1
count+=1
longestChain(num,count)
print(longestChain(13,1))
CORRECTED ONE
def longestChain(num,count):
if num==1:
return count
elif num%2==0:
num = num/2
count+=1
return longestChain(num,count)
elif num%2==1:
num =3*num+1
count+=1
return longestChain(num,count)
print(longestChain(13,1))
You're only returning a value in case num==1. In the other cases, you are doing a recursive call, but you forgot to return a value there.

Next Palindrome number

I want the final number as returned by the function, the following code is running, but not returning the correct value, the correct value is printed by the print statement above return satatement, how can return it ??
the correct answer is 22. but 13 is too printed.
def palindrome(num):
num = num+1
num = str(num)
if num[::-1]!=num:
palindrome(int(num))
else:
print(int(num))
return int(num)
palindrome(12)
>RESULT---
22
13
Seems that this could be done in a better way.
def palindrome(num):
if str(num) == str(num)[::-1]:
print(num)
return num
else:
palindrome(num+1)
Your recursive function returns 13 because this is the result of the first call to your function. The other iterations from your recursion are lost since you don't save it in your recursive call to palindrome.
You'll want to set your call to palindrome as your return also:
if num[::-1] != num:
return palindrome(int(num))
a = int(input("enter the no. of choices"))
for i in range(a):
b = int(input("enter all no."))
for j in range(b , 10000000000000000):
count = 0
pal = str(j)
b += 1
if (pal == pal[::-1]):
print(j)
break
else:
continue

Recursive function that return result from 'if' statement instead of 'else' statement

I'm pretty new in Python and I'm trying to write a simple recursive function:
def bugged_recursion(inp_value,list_index=0):
'''Define a recursive function that tag lists according to one parameter.
'''
#check if a criterion is true at position 0 in the list
if list_index == 0:
if inp_value[list_index] == 'valid':
status = 'valid inp_value'
#if the criterion is false call the function at the next index
else:
status = 'invalid inp'
list_index +=1
bugged_recursion(inp_value,list_index=list_index)
#check if a criterion is true at position 1 in the list
else:
if inp_value[list_index] == 'valid':
status = 'index {} is a valid inp_value'.format(list_index)
else:
status = 'index is never a valid inp_value'
print(status)
#return the input and its status
return (inp_value,status)
if __name__ == '__main__':
inp_value = ['invalid','invalid']
bugged_recursion(inp_value)
I don't understand why this function return the status from the if statement, instead of returning the status contained in the last else statement.
For me, the strangest is that it prints the right status at some point but won't return it.
I'm unable to understand why... I'm really curious about how I could perform this task using a recursive function.
Wow wow, how tortured this is.
def bugged_recursion(inp_value, list_index=0):
# i don't get why you compare list_index here
if list_index == 0:
# you'll get an IndexError if list_index > len(inp_value)
if inp_value[list_index] == 'valid':
status = 'valid inp_value'
else:
status = 'invalid inp'
# there is only one place where you increment list_index
# i suppose there is something wrong here
list_index +=1
# you forgot to return here
return bugged_recursion(inp_value, list_index=list_index)
else:
if inp_value[list_index] == 'valid':
status = 'index {} is a valid inp_value'.format(list_index)
else:
status = 'index is never a valid inp_value'
return (inp_value,status)
That aside, people usually tend to avoid recursion as much as possible (for example on Dive into Python).
Does this cover your needs?
def no_recursion(inp_value):
for i, val in enumerate(inp_value):
# you probably have a good reason to test the index
if i == 0:
if val == 'valid':
yield 'valid inp_value: %s' % val
else:
yield 'invalid inp: %s' % val
else:
yield 'index %s is %s valid inp_value' % (
i,
'a' if val == 'valid' else 'never'
)
print tuple(no_recursion(inp_value))
Gives: ('invalid inp: invalid', 'index 1 is never valid inp_value')

FizzBuzz with commas instead of newlines

def fizz_buzz(i):
if i % 15 == 0:
return ("FizzBuzz")
elif i % 5 == 0:
return ("Buzz")
elif i % 3 == 0:
return ("Fizz")
else:
return (i)
for i in range(1, 21):
print(fizz_buzz(i))
Where and how would do a new line command here with commas?
Trying to get an output like this: 1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,Fizz,19, Buzz
but sideways and with commas.
Pass end=',' to print()
def fizz_buzz(i):
if i % 15 == 0:
return ("FizzBuzz")
elif i % 5 == 0:
return ("Buzz")
elif i % 3 == 0:
return ("Fizz")
else:
return (i)
for i in range(1, 21):
print(fizz_buzz(i), end=',')
# prints
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,Fizz,19,Buzz,
If you do not want the trailing comma, end the range at 20 and follow with print(fizz_buzz(20))
Consider making a list & joining the elements with a comma. There are some great examples here.
For example:
def fizz_buzz(i):
# your code
my_list = []
for i in range(1,21):
my_list.append( str(fizz_buzz(i)) )
print ",".join(my_list)
There are more elegant ways of doing this -- using generators &c, as in the linked answer --, but this simple code will do what you want. Note that the join() method accepts string only, hence the str() in the list.append(); alternatively you could ensure that your fizz_buzz function returns strings regardless.

Resources