Continue doesn't seem to work in this simple Python function - python

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()]))

Related

Return a list recursively

I need help with recursion I have a code right here which turns an integer into a list of strings. However, I'm struggling to make it recursive. Here is what I have so far.
def turnList( a ):
b = str(a)
c = []
for digit in b:
c.append(digit)
return c
For a recursive function you need a base case, i.e. when we have finished and no longer need to recurse and a generic recursive case
def turnList(a):
a=str(a)
if len(a)==1:
return [a]
else:
return [a[0]] + turnList(a[1:])
Our base case is when our recursive function gets a string of length one. And our recursive case returns the first value in its input as a string (in a list) combined with the list of all the 'future' recursive strings.
Start with a base case, in this case empty list for zero, then define the recursive behavior.
def turnList(a):
if a == 0: # base case
return []
a,d = divmod(a,10) # strip off last digit
return turnList(a) + [str(d)] # recurse
print(turnList(123))
Output:
['1', '2', '3']
There are multiple ways to do recursion. Here, we adjust bIndex.
b = "hello"
def turnList(c, bIndex):
if len(b) == bIndex:
return c
return turnList(c + [b[bIndex]],bIndex+1)
print(turnList([],0))
global an
an = []
def turnList(a):
global an
b=str(a)
an.append(b[len(b)-1])
try:
return turnList(int(b[:len(b)-1]))
except ValueError as e:
an.reverse()
return an
m = turnList(10)
print(m)
this might be the best i've ever written

How do I write a recursive function that multiplies each character in a string by 2?

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)

First index appearance in a string recursive

Im trying to write a recursive function that gets as an input a string and a char. the function return the first index appearance of the char in the string. If the char doesnt appear it returns None.
I have a problem only with returning None. In my case when the char isnt in the string the function throws an error, any advice?
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
return 1+ char_first_index(s[1:],c)
You are creating a new slice at each iteration, and you have to add 1 for each recursion. Instead, recurse on the index:
def char_first_index(s, c, index = 0):
if len(s) == index:
return None
if s[index] == c:
return index
return char_first_index(s, c, index + 1)
If the character is not in the input, your function tries to perform 1+None, hence the error. Try this instead:
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
answer = char_first_index(s[1:],c)
if answer is not None:
return 1+answer
else:
return answer
Firstly I'm assuming len_rec is a recursive function that gets the length of the string; you haven't written it so I've just changed it to len() for testing.
Secondly, I'm not sure how this function is supposed to handle the character not being in the string, as that will mean trying to add None to a number.
Here is an amended function that still uses your count idea, but handles the case of a None being returned:
def char_first_index(s,c):
if len(s)==0:
return None
elif s[0]==c:
return 0
else:
count = char_first_index(s[1:], c)
if count != None:
return count + 1
else:
return None

pop() empty deque() in logic

I want to be able to validate parenthesis so they enclose and ignore any type of characters. As long as there is the valid use of enclosure of strings with parenthesis then True else `False.
I am still new to python so I'm not sure how to properly create an if statement for this certain condition. I am trying to create an fi statement such that when I .pop() an empty deque() I will be able to return False instead of receiving the error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop from an empty deque
Perhaps there is another better method around solving this problem. If so I would be glad to see how someone else would solve it
For example:
a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false
b = 'dsf))))(((((dsfsdf' # false
c = '()()()()' # true
d = '((((asd(asd)asd)()()asd))' # true
my code:
# any letter is ignored
# jsut make sure that the parenthesis are equal
from collections import *
def str_valid(stringy):
param_stack = deque()
for n in stringy:
if n ==')':
param_stack.pop()
if n == '(':
param_stack.append('(')
if param_stack == []:
return True
else:
return False
a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false
b = 'dsf))))(((((dsfsdf' # false
c = '()()()()' # true
d = '((((asd(asd)asd)()()asd))' # true
print str_valid(a)
print str_valid(b)
print str_valid(c)
print str_valid(d)
If you just want an if statement to check if the deque is empty before pop(), you can use
if n ==')':
if param_stack:
param_stack.pop()
else:
return false
...
if param_stack will implicitly convert it to a boolean which return true if it contains some elements and false otherwise.
A few things to note: first, the only methods of deque you're using are append() and pop. So it's more natural to use an ordinary Python list. A deque isn't more efficient than a list unless you need to put things on, or take things off, "the left end".
Second, you already know how to test for an empty deque! You did that here:
if param_stack == []:
Now that's a little odd, because you're comparing a deque to a list, but it works. With a little more experience, you'll write that as:
if len(param_stack) == 0:
and with more experience still, you may use:
if not param_stack:
(an empty container generally behaves like False in truth-y contexts).
But however you write it, rather than introduce try/except blocks, it's easier and clearer to do something like:
if n ==')':
if param_stack: # i.e., if it's not empty
param_stack.pop()
else: # it's empty
return False
Clear?
If you just want to pop() an empty deque without problems:
from collections import deque
d = deque()
try:
d.pop()
except IndexError:
pass # do whatever you want in the case that there is nothing there
return False # is this what you want?
else:
pass # do whatever you want in the case that there is something there
Just a warning in case you don't know: keep the amount of code inside any of try/except/else/finally as short and focused as possible. It's easy to end up with errors popping up inside error handlers and leading to surprises.
If that's not what you need, please clarify what in your code is not working.
Simply catch the error and return False:
for n in stringy:
if n ==')':
try:
param_stack.pop()
except IndexError:
return False
Use try, except to catch the IndexError exception and then return False
try:
param_stack.pop()
except IndexError:
# catch your IndexError exception and do what you want
return False
As other people already mentioned you don't really need a queue, a simple counter is enough:
def str_valid(txt):
ctr = 0
for n in txt:
if n == '(':
ctr = ctr + 1
if n == ')':
ctr = ctr - 1
if ctr < 0:
return False
return ctr == 0
Or shorter:
def str_valid(txt):
ctr = 0
for n in txt:
ctr = ctr + (n == '(') - (n == ')')
if ctr < 0:
return False
return ctr == 0
Or a "hacky" one-liner :)
def str_valid(txt):
return not reduce(lambda t, c: t if t < 0 else t + (c == '(') - (c == ')'), txt, 0)

An error in python

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.

Categories