im new..
my script is pretty long so I'll write down the specific parts.
str= ''
#str is a long DNA sequence
def FIND_UPPER(str):
global x
x=str.upper()
y=0
while y>(-1):
y=x.find('CTTTGATTCCT')
z=x[y+11:y+22]
x=x[y+23:]
variability(z)
#variability is another function
FIND_UPPER(str)
and then I get this message:
list indices must be integers, not str
about those lines:
variability(z)
FIND UPPER(str)
How can I fix this?
thanks
edit:
this is variability:
A=[0]*10
C=[0]*10
T=[0]*10
G=[0]*10
def variability(z):
for i in z:
if i=='A':
A[i]=A[i]+1
i=i+1
elif i=='T':
T[i]=T[i]+1
i=i+1
elif i=='C':
C[i]=C[i]+1
i=i+1
elif i=='G':
G[i]=G[i]+1
i=i+1
return G
return C
return T
return A
I fixed it, can u tell me if I got u right?
:
def variability(z):
for i in range(len(z)):
if i=='A':
A[i]=z[i]
A[i]+=1
i+=1
elif i=='T':
T[i]=z[i]
T[i]+=1
i+=1
elif i=='C':
C[i]=z[i]
C[i]+=1
i+=1
elif i=='G':
G[i]=z[i]
G[i]+=1
i+=1
return G,C,T,A
def variability(z):
for i in z:
if i=='A':
A[i]=A[i]+1
i=i+1
Assume i == 'A', then A[i] is actually translated to A['A'] which returns:
list indices must be integers, not str
Which means you can't access a list by a string index, list indices are integers.
Moreover, Python doesn't support multiple return statements:
return G
return C
return T
return A
This will always return G
If you want to return all of these values, then replace it with:
return G,C,T,A
The above return statements returns a tuple consists G,C,T,A
If you want to return just one, place each return statement inside your elif clauses.
In the loop you have to do something like:
for i in range(len(z)):
letter = A[i]
If you iterate over range function result, "i" will take numeric values. If you iterate over the string i will take each character of the string
An then compare variable "letter"
if letter == 'A':
...
Be careful in the variability function, only the value in the first return statement will be returned.
Related
I have this exercise:
Write a recursive function that takes a string and returns all the characters that are not repeated in said string.
The characters in the output don't need to have the same order as in the input string.
First I tried this, but given the condition for the function to stop, it never evaluates the last character:
i=0
lst = []
def list_of_letters_rec(str=""):
if str[i] not in lst and i < len(str) - 1:
lst.append(str[i])
list_of_letters_rec(str[i+1:])
elif str[i] in lst and i < len(str) - 1:
list_of_letters_rec(str[i+1:])
elif i > len(str) - 1:
return lst
return lst
word = input(str("Word?"))
print(list_of_letters_rec(word))
The main issue with this function is that it never evaluates the last character.
An example of an output:
['a', 'r', 'd', 'v'] for input 'aardvark'.
Since the characters don't need to be ordered, I suppose a better approach would be to do the recursion backwards, and I also tried another approach (below), but no luck:
lst = []
def list_of_letters_rec(str=""):
n = len(str) - 1
if str[n] not in lst and n >= 0:
lst.append(str[n])
list_of_letters_rec(str[:n-1])
elif str[n] in lst and n >= 0:
list_of_letters_rec(str[:n-1])
return lst
word = input(str("Word?"))
print(list_of_letters_rec(word))
Apparently, the stop conditions are not well defined, especially in the last one, as the output I get is
IndexError: string index out of range
Could you give me any hints to help me correct the stop condition, either in the 1st or 2nd try?
You can try:
word = input("> ")
result = [l for l in word if word.count(l) < 2]
> aabc
['b', 'c']
Demo
One improvement I would offer on #trincot's answer is the use of a set, which has better look-up time, O(1), compared to lists, O(n).
if the input string, s, is empty, return the empty result
(inductive) s has at least one character. if the first character, s[0] is in the memo, mem, the character has already been seen. Return the result of the sub-problem, s[1:]
(inductive) The first character is not in the memo. Add the first character to the memo and prepend the first character to the result of the sub-problem, s[1:]
def list_of_letters(s, mem = set()):
if not s:
return "" #1
elif s[0] in mem:
return list_of_letters(s[1:], mem) #2
else:
return s[0] + list_of_letters(s[1:], {*mem, s[0]}) #3
print(list_of_letters("aardvark"))
ardvk
Per your comment, the exercise asks only for a string as input. We can easily modify our program to privatize mem -
def list_of_letters(s): # public api
def loop(s, mem): # private api
if not s:
return ""
elif s[0] in mem:
return loop(s[1:], mem)
else:
return s[0] + loop(s[1:], {*mem, s[0]})
return loop(s, set()) # run private func
print(list_of_letters("aardvark")) # mem is invisible to caller
ardvk
Python's native set data type accepts an iterable which solves this problem instantly. However this doesn't teach you anything about recursion :D
print("".join(set("aardvark")))
akdrv
Some issues:
You miss the last character because of i < len(str) - 1 in the conditionals. That should be i < len(str) (but read the next points, as this still needs change)
The test for if i > len(str) - 1 should come first, before doing anything else, otherwise you'll get an invalid index reference. This also makes the other conditions on the length unnecessary.
Don't name your variable str, as that is already a used name for the string type.
Don't populate a list that is global. By doing this, you can only call the function once reliably. Any next time the list will still have the result of the previous call, and you'll be adding to that. Instead use the list that you get from the recursive call. In the base case, return an empty list.
The global i has no use, since you never change its value; it is always 0. So you should just reference index [0] and check that the string is not empty.
Here is your code with those corrections:
def list_of_letters_rec(s=""):
if not s:
return []
result = list_of_letters_rec(s[1:])
if s[0] not in result:
result.append(s[0])
return result
print(list_of_letters_rec("aardvark"))
NB: This is not the most optimal way to do it. But I guess this is what you are asked to do.
A possible solution would be to just use an index instead of splicing the string:
def list_of_letters_rec(string="", index = 0, lst = []):
if(len(string) == index):
return lst
char = string[index]
if string.count(char) == 1:
lst.append(char)
return list_of_letters_rec(string, index+1, lst)
word = input(str("Word?"))
print(list_of_letters_rec(word))
The function is supposed to take a string as its input and return (if all members of the string are digits) and integer version of that string. The string provided in this example is a 3 digit number. the function's for loop seems to only return the first digit only hence the continue may not be working as expected.
e = '484'
def resolving(e):
for i, o in enumerate(e):
if o in "0123456789":
s = []
s.append(o)
i += 1
continue
elif o not in "0123456789":
print(type(e))
return e
k = str(s)
y = k.replace("'","").replace("[","").replace("]","").replace(",","").replace(" ","")
p = int(y)
print(type(p))
return p
print(resolving(e))
Because you make the list in the loop. Just make it outside the loop. Also instead of str(s) which makes a string representation of the list use str.join as it will join all the elements of the list into a string. Also there is no need for the continue statement. As the elif won't run if the if is True.
for i, o in enumerate(e):
s = []
if o in "0123456789":
s.append(o)
else:
print(type(e))
return e
k = ''.join(s)
p = int(y)
return p
At the risk of completely missing the point of what you're trying to do, this entire function could just be:
def resolve(e):
"""If e is convertible to an int, return its int value;
otherwise print its type and return the original value."""
try:
return int(e)
except ValueError:
print(type(e))
return e
You have return in there, so the first time you hit a non-numeric character you're going to return that character and exit. As written, the continue won't do anything since the following elif won't be hit by any character that sends you down the first branch of the if statement.
If you regard only the integers of a string as its integer version, you can use isnumeric() check:
def resolve(e)
return int(''.join([i for i in e if i.isnumeric()]))
How do I write a code in python by only using the recursion without loops and any build in methods or functions? I tried:
def myRemove(x, cont): # x is a string inside of the list cont
if x == cont:
return None
elif len(x) > len(cont):
return None
else:
if "x" not in cont[0]:
return myRemove(x,cont[1:])
else:
return cont
Some problems I see in your code:
1. Difference between a string and a variable
You have the following line in your code which is semantically wrong:
if "x" not in cont[0]:
...
Here "x" is the string 'x' and not the value of x. To fix this remove the quotation marks.
if x not in cont[0]:
...
2. Difference between list and variable
To check if a variable is in a list use in. e.g.
>>> "test" in ["test", "wow", "u"]
true
To check if a variable is equal to another variable use ==. e.g.
>>> "test" == ["test", "wow", "u"][0]
true
The fixed part of your code: (Because cont[0] returns a value and not a list)
if x == cont[0]:
...
3. Returns in recursion
You have to concatenate the returned list with the list part before the other list.
Otherwise, you are always returning the last part of the list.
One possible solution
def remove(string, string_list):
if string_list[0] == string:
return string_list[1:]
else:
return string_list[:1] + remove(string,string_list[1:])
def recursive_remove(x: str, cont: list):
""" removes items equal to x using recursion only
cont: list of strings
x: string to remove from list
"""
if len(cont) == 0:
return []
if cont[0] != x:
return [cont[0]] + recursive_remove(x=x, cont=cont[1:])
else:
return recursive_remove(x=x, cont=cont[1:])
list_without_banana = recursive_remove(x='banana', cont=['apple', 'banana', 'strawberry', 'peanut'])
print(list_without_banana)
>>>['apple', 'strawberry', 'peanut']
I'm trying to complete a recursive function which given a number, returns a string where the returned value has duplicate of each digit
Example: if 507, returns 550077
if the number is only 0 then just return 0
also if it is a negative number, return the negative sign only once
Example: -507 returns -550077
I haven't yet implemented anything to recognize a negative number, I was just trying to get my function to work first
so far I have:
def double(x):
if x == 0:
return x
else:
x = str(x)
return x[0]*2 + double(x[1: ])
print(double(527))
however this returns IndexError: string index out of range
I had it working by printing the result instead of returning the result, but the problem I am trying to solve strictly wants the result returned, not printed. What am I doing wrong?
This works recursively, fixes the x==0 termination error, checks whether a character is a digit before doubling, and returns the final answer as an int (instead of a str).
def double(x):
x = str(x)
if len(x) == 0:
return ''
else:
first_char = x[0]
# only double if it's an integer
if first_char in map(str, range(10)):
first_char *= 2
return int(first_char + str(double(x[1: ])))
print(double(-527))
>>> -552277
Something like this might work.
def double(x):
if x == 0:
return x
else:
x = str(x)
l=[]
for a in x:
if a == '-':
l.append(a)
else:
l.append(a*2)
return ''.join(l)
I am trying to produce code that will first find me all the perfect squares under modulos p, in a function perfectsq(p).
With that list of perfect squares. I want to find all solutions of the equation y^2=x^3+Ax+B. I am doing this by using the list in perfectsq(p) to check that m=x^3+Ax+B is in that list. Can someone tell me why this code isn't compiling?
def perfectsq(p):
x=[]
for i in range(1,p):
m=(i**2)%p
x.extend(m)
i+=1
def ellipticpt(a, b, p):
x=perfectsq(p)
if 4*(a**3)+27*(b**2) != 0:
for i in range(0,p):
m=(i**3+a*i+b)%p
if m in x:
i=x.index(m)+1
print (m,i)
i+=1
else:
i+=1
else:
print "Error"
perfectsq x.extend(m) TypeError: 'int' object is not iterable
You can't .extend() a list with a single number argument, it's for extending a list with another list. Use .append() to add to the end of a list instead.
Also perfectsq() doesn't return anything
Try:
def perfectsq(p):
x=[]
for i in range(1,p):
m=(i**2)%p
x.append(m)
i+=1
return x
def ellipticpt(a, b, p):
x=perfectsq(p)
if 4*(a**3)+27*(b**2) != 0:
for i in range(0,p):
m=(i**3+a*i+b)%p
if m in x:
i=x.index(m)+1
print (m,i)
i+=1
else:
i+=1
else:
print "Error"