What did I do wrong with this function? - python

I don't know what I did - it's wrong .
Can someone help me?
def insert_sequence(dna1, dna2, number):
'''(str, str, int) -> str
Return the DNA sequence obtained by inserting the second DNA sequence
at the given index. (You can assume that the index is valid.)
>>> insert_sequence('CCGG', 'AT', 2)
'CCATGG'
>>> insert_sequence('TTGC', 'GG', 2)
'TTGGGC'
'''
index = 0
result = '';
for string in dna1:
if index == number:
result = result + dna2
result = result + string
index += 1
print(result)

Here's a solution:
def insert_sequence(dna1, dna2, number):
'''(str, str, int) -> str
Return the DNA sequence obtained by inserting the second DNA sequence
at the given index. (You can assume that the index is valid.)
>>> insert_sequence('CCGG', 'AT', 2)
'CCATGG'
>>> insert_sequence('TTGC', 'GG', 2)
'TTGGGC'
'''
return dna1[:number] + dna2 + dna1[number:]

you needed an if-else loop here :
def insert_sequence(dna1, dna2, number):
result = '';
#you can use enumerate() to keep track of index you're on
for ind,x in enumerate(dna1):
if ind == number: #if index is equal to number then do this
result = result + dna2 +x
else: #otherwise do this
result = result + x
print(result)
insert_sequence('CCGG', 'AT', 2)
insert_sequence('TTGC', 'GG', 2)
output:
CCATGG
TTGGGC

There are already right working functions in other answers (specially the comment from Rakesh Pandit and the answer from JeffS), but your actual question is "why my original function doesn't work".
I copied a working version of your function, comments below:
def insert_sequence(dna1, dna2, number):
index = 0
result = ''
for character in dna1:
if index == number:
result = result + dna2
result = result + character
index += 1
print(result)
Python considers indentation, so you should print only at the end of things, outside loops and ifs.
When you "increase" your result, you do this only inside the "if" on your function, when actually you should increase "for every character in dna1", and only when/"if index == number" you should put the middle string inside.
I believe you are very new to Python or to programming in general, being probably from a biological background, but you really shouldn't iterate to get this type of string operation done, as others have shown.
Hope this helps!

You're never splitting the string apart, so you'll always prepend dna2 to dna1.
You probably want to return dna1[:number] + dna2 + dna1[number:]

You do nothing if the index is not at the insertion point, including incrementing the index. Your code needs an else and you are also printing prematurely:
def insert_sequence(dna1, dna2, number):
index = 0
result = '';
for char in dna1:
if index == number:
result = result + dna2
result = result + char
index += len(dna2) + 1
else:
result = result + char
index += 1
print(result)

mistakes made: a) parameter index is initialised to 0. b) "for sting in dia1:" should have been "for dia1_position in range(len(dia1)):" c) print result indentation is wrong and function isn't just supposed to print. It should return result. d) index need not be incremented now.
Answers are already there. Above briefly lists the mistakes made. I guess you didn't see any error because you never called the function. First error should be "number" not defined (not any more as question has been updated and parameter has number defined).

Related

Receiving exit code (1) when trying to manipulate strings from codewars assignment? How can I do it differently and avoid Index Errors?

I have been working on this codewars assignment the entire day, but I keep failing the test on code wars. Running into index errors and exit code (1) even though I am passing every test and attempt, the exit code seems so illusive yet confusing. I understand if my program doesn't do what it is supposed to but it is passing the tests, and right now there are some errors I don't quite understand messing up my program in ways that I can't even comprehend. Because they are returning the strings exactly as requested by the assignment, so why... is it not working? What have I done wrong? Please help me almighty code wizards, I am a noob...
Working on Split Strings: Complete the solution so that it splits the string into pairs of two characters. If the string contains an odd number of characters then it should replace the missing second character of the final pair with an underscore ('_').
Here is my Code:
def solution(string):
join_string = "-".join(string[i:i+2] for i in range(0, len(string), 2))
x_string = join_string.split("-")
underscore = "_"
index = (len(string) - len(x_string))
if index % 2 == 0:
for i in range(0, index):
return x_string
break
else:
x_string[index] = x_string[index] + underscore
return x_string
elif index > 2:
x_string[index] = x_string[index] + underscore
return x_string
elif index < 1:
x_string = []
return x_string
The error comes up at
x_string[index] = x_string[index] + underscore
IndexError: list index out of range
This line
join_string = "-".join(string[i:i+2] for i in range(0, len(string), 2))
already does the entire job you want, except for the underscore at the end if there were an odd number of characters in the input. Your code is making very heavy weather of this special case. Check if the input string has an odd number of characters:
if len(string) % 2 == 1:
and if it has, append an underscore to the returned value:
join_string += "_"
Your question doesn't say what the expected output is, and it's hard to tell from the code, so, to keep to the essential point, the whole function becomes
def solution(string):
join_string = "-".join(string[i:i+2] for i in range(0, len(string), 2))
if len(string) % 2 == 1:
join_string += "_"
return join_string
I get the output
>>> solution("123465")
'12-34-65'
>>> solution("1234657")
'12-34-65-7_'
>>> solution("1")
'1_'
>>> solution("")
''
If instead you want, say, a list of 2-strings, then do
return join_string.split("-")

Hacker rank string separated challenge

I'm trying to solve a hacker rank challenge:
Given a string, s , of length n that is indexed from 0 to n-1 , print its even-indexed and odd-indexed characters as 2 space-separated strings. on a single line (see the Sample below for more detail)
link: https://www.hackerrank.com/challenges/30-review-loop/problem
Error:
for example:
The input "adbecf" should output "abc def"
When I run python Visualizer my code seem to have the correct output.. but on hacker rank it's saying I have the wrong answer. Does anyone know what might be wrong with my code.
This is the code I tried -
class OddEven:
def __init__(self, input_statement):
self.user_input = input_statement
def user_list(self):
main_list = list(user_input)
even = []
odd = []
space = [" "]
for i in range(len(main_list)):
if (i%2) == 0:
even.append(main_list[i])
else:
odd.append(main_list[i])
full_string = even + space + odd
return(full_string)
def listToString(self):
my_string = self.user_list()
return(''.join(my_string))
if __name__ == "__main__":
user_input = str(input ())
p = OddEven(user_input)
print(p.listToString())
First of all, input is always string, you don't need to convert it here.
user_input = str(input())
Each line is provided to you as separate input. Number of strings equal to num in the first line. In this case 2, so...
count = input()
for s in range(int(count)):
...
user_input variable inside user_list function should be accessed as self.user_input, it's a property of an object, which you pass to function as self.
Also you can iterate over list directly.
Here:
full_string = even + space + odd
you're trying to concatenate list, which is not a good idea, you'll still get a list.
You can join list with separating them with some string using join string method.
' '.join(list1, list2, ..., listN)
It's better do define odd and even as empty strings.
And then join them the using concatenation (+).
Here:
if (i%2) == 0
you don't have to compare with 0. Python will evaluate what's to the right from condition as True or False. So:
if i % 2:
...
There is simpler solution:
def divide(self):
odd = even = ''
for i, c in enumerate(self.user_input):
if i % 2:
odd += c
else:
even += c
return even + ' ' + odd
Here is the simple code for this problem:)
T=int(input())
for i in range(0,T):
S=input()
print(S[0::2],S[1::2])

How To Fix String Index Out of Range in Python

I'm currently learning python. There is an exercise in the book which outlines code for decoding. I followed along with this code however I keep getting back an error in the middle of the program.
Here is the code that is causing the problem:
def decode(string_for_decoding):
result = ""
for i in range(0, len(string_for_decoding)):
if string_for_decoding[i+1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i+1])
elif string_for_decoding[i].isalpha():
result += string_for_decoding[i]
return result
string_for_decoding = input("Enter a string to decode: ")
print(decode(string_for_decoding))
Check if the index from range is larger than the number of chars in the string. It might look like this:
def decode(string_for_decoding: str):
result = ""
for i in range(0, len(string_for_decoding)):
if len(string_for_decoding) > i + 1 and string_for_decoding[i + 1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i + 1])
elif string_for_decoding.isalpha():
result += string_for_decoding[i]
return result
print(decode(input("Enter a string to decode: ")))
You are going from 0 to len(string) and inside for loop you are trying to access index: i+1
THis is the root cause! Either:
iterate till one length less e.g. till len(string) - 1
Or use indices
inside appropriately
Moreover it is highly discouraged to use range(len(x)). You can simply iterate over any collective datatype as for i in x: If you want indices too have a look at enumerate(). And you can forget about index errors all together.
You are trying to get index i+1 which cannot be equal or greater than len(string).

Return the number of times that the string "hi" appears anywhere in the given string -- Python codingbat problem

I'm aware that I can use the .count() function for this, but I tried to do this with a for loop and I keep getting a compile error in line 6. Does anyone see what's wrong with this code and why it wouldn't give the same output? Thanks in advance!
def count_hi(string):
# Create an empty list to add to
num_hi = []
# for every index in string , if the character is h and the next is i,
# add element to list
for index in string:
if string[index] == 'h' AND string[index + 1] == 'i':
num_hi.append('hi found')
return len(num_hi) # return length of list
Why not use count?
def count_hi(string):
return string.count('hi')
Fix for your code:
def count_hi(string):
count = 0
for i in range(1, len(string)):
if string[i - 1] == 'h' and string[i] == 'i':
count += 1
return count
Python is case sensitive, not AND but and.
Appending to list and counting it is a lot of overhead, you should just use a variable and increment it every time you find hi.
Instead of enumerate, you can use range to start from index 1 and check your string from i - 1 and 1. Avoids another check.
I'd prefer the previous solution using .count(). Why to write code when there is a built-in method for you?
See Harshal Parekh's Asnwer, it provides a better analysis and explanation.
When you iterate over a string, you're not iterating over indexes, but over the letters themselves. A quick fix for this could be:
def count_hi(string):
num_hi = []
# for every index in string , if the character is h and the next is i, add element to list
for index, _character in enumerate(string):
if index == len(string) - 1:
break # on the last one, you'd get an index error.
if string[index] == 'h' and string[index + 1] == 'i': # "and", not "AND"
num_hi.append('hi found')
return len(num_hi) # return length of list
The simplest way to do this is to use the builtin collection module.
from collections import Counter
def count_hi(string):
counts = Counter(string.split())
return print(counts['hi'])
You can try this, it should do the trick.
def count_hi(str):
counter = 0
str.lower()
str.replace(' ', '')
for i in range(0, len(str)-1):
if str[i] == 'h' and str[i+1] == 'i':
counter += 1
return counter
My solution:
def count_hi(str):
sum = 0
for i in range(len(str)-1):
if str[i:(i+2)] == "hi":
sum += 1
return sum

Longest Common Prefix with Python

I am trying to figure out an easy leetcode question and I do not know why my answer does not work.
Problem:
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
My Code:
shortest=min(strs,key=len)
strs.remove(shortest)
common=shortest
for i in range(1,len(shortest)):
comparisons=[common in str for str in strs]
if all(comparisons):
print(common)
break
else:
common=common[:-i]
The above trial does not work when the length of the strings in the list are same but works for other cases.
Thank you very much.
Friend, try to make it as 'pythonic' as possible. just like you would in real life.
in real life what do you see? you see words and maybe look for the shortest word and compare it to all the others. Okay, let's do that, let's find the longest word and then the shortest.
First we create an empty string, there the characters that are the same in both strings will be stored
prefix = ''
#'key=len' is a necesary parameter, because otherwise, it would look for the chain with the highest value in numerical terms, and it is not always the shortest in terms of length (it is not exactly like that but so that it is understood haha)
max_sentense = max(strings, key=len)
min_sentense = min(strings, key=len)
Okay, now what would we do in real life?
loop both one by one from the beginning, is it possible in python? yes. with zip()
for i, o in zip(max_sentense, min_sentense):
the 'i' will go through the longest string and the 'o' will go through the shortest string.
ok, now it's easy, we just have to stop going through them when 'i' and 'o' are not the same, that is, they are not the same character.
for i, o in zip(max_sentense, min_sentense):
if i == o:
prefix += i
else:
break
full code:
prefix = ''
max_sentense = max(strings, key=len)
min_sentense = min(strings, key=len)
for i, o in zip(max_sentense, min_sentense):
if i == o:
prefix += i
else:
break
print(prefix)
It's quickest to compare the first characters of all the words, and then the second characters, etc. Otherwise you're doing unnecessary comparisons.
def longestCommonPrefix(self, strs):
prefix = ''
for char in zip(*strs):
if len(set(char)) == 1:
prefix += char[0]
else:
break
return prefix
You can do this fairly efficiently in a single iteration over the list. I've made this a little verbose so that it's easier to understand.
import itertools
def get_longest_common_prefix(strs):
longest_common_prefix = strs.pop()
for string in strs:
pairs = zip(longest_common_prefix, string)
longest_common_prefix_pairs = itertools.takewhile(lambda pair: pair[0] == pair[1], pairs)
longest_common_prefix = (x[0] for x in longest_common_prefix_pairs)
return ''.join(longest_common_prefix)
In your code you cross check with the shortest string which can be one of the shortest strings if multiple same length strings are present. Furthermore the shortest might not have the longest common prefix.
This is not a very clean code but it does the job
common, max_cnt = "", 0
for i, s1 in enumerate(strs[:-2]):
for s2 in strs[i+1:]:
for j in range(1, min(len(s1), len(s2))+1):
if s1[:j] == s2[:j]:
if j > max_cnt:
max_cnt = j
common = s1[:j]
This function takes any number of positional arguments.
If no argument is given, it returns "".
If just one argument is given, it is returned.
from itertools import zip_longest
def common_prefix(*strings) -> str:
length = len(strings)
if not length:
return ""
if length == 1:
return strings[0]
# as pointed in another answer, 'key=len' is necessary because otherwise
# the strings will be compared according to lexicographical order,
# instead of their length
shortest = min(strings, key=len)
longest = max(strings, key=len)
# we use zip_longest instead of zip because `shortest` might be a substring
# of the longest; that is, the longest common prefix might be `shortest`
# itself
for i, chars in enumerate(zip_longest(shortest, longest)):
if chars[0] != chars[1]:
return shortest[:i]
# if it didn't return by now, the first character is already different,
# so the longest common prefix is empty
return ""
if __name__ == "__main__":
for args in [
("amigo", "amiga", "amizade"),
tuple(),
("teste",),
("amigo", "amiga", "amizade", "atm"),
]:
print(*args, sep=", ", end=": ")
print(common_prefix(*args))
Simple python code
def longestCommonPrefix(self, arr):
arr.sort(reverse = False)
print arr
n= len(arr)
str1 = arr[0]
str2 = arr[n-1]
n1 = len(str1)
n2 = len(str2)
result = ""
j = 0
i = 0
while(i <= n1 - 1 and j <= n2 - 1):
if (str1[i] != str2[j]):
break
result += (str1[i])
i += 1
j += 1
return (result)

Categories

Resources