Why is my recursive function is not concatenatening string? - python-3.x

I am writing a recursive function to print a string backwards. I am wondering why my string formatting of the return statement is not working? I am using python 3.7.
It would be very helpful if someone please can tell me why I can not write a recursive function like following?
def back(word):
if len(word)>1:
print (word[-1] + (back(word[:len(word)-1])), end="")
elif len(word)==1:
return word
else:
print ("end")
back("stack")

As khelwood mentioned in the comments, doing a print() is not a substitute for return.
The fix for your problem is:
def back(word):
ln = len(word)
if ln >1:
wmo = word[-1]
# Changed print() to return
return (wmo + (back(word[:len(word)-1])))
elif ln ==1:
return word
else:
print ("end")
# Changed to print() the returned values from function
print(back("stack"))
As you can see above, in the fixed solution, we are returning the value from function and printing it outside.
Hope this helps!

Related

How do I figure out my issue with placing the "try" function?

So I have been struggling to find out what is wrong with my exception code which is to only accept strings but also display text whenever there are non string inputs between the brackets which depends on where I put the "try" and except functions.
The first code I have here which 'try' is before return, any strings entered in will be accepted into the function, however the except functions will not work whenever non-strings are entered between the bottom brackets.
'''
def string_processor(string):
countA = 0
if (string.isalpha()):
for c in string:
if c == "a":
countA = countA + 1
try:
return countA / len(string)
except AttributeError:
print("Please enter a string instead")
except IndexError:
print("Please enter a string with quotation marks ")
else:
print("Please only enter a string")
string_processor("000")
'''
The second code I have which I put "try:" can sort out some things such as AttributeErrors, but only strings with letters can be inputted between the brackets and any string that contains non-numbers are omitted from the function.
'''
def string_processor(string):
try:
countA = 0
if (string.isalpha()):
for c in string:
if c == "a":
countA = countA + 1
return countA / len(string)
except AttributeError:
print("Please enter a string instead")
except SyntaxError:
print("Please enter a string with quotation marks ")
else:
print("Please only put letters in your string")
string_processor("000")
'''
I request help to fix this problem so my program can get any type of string, and will process except functions for any non-string values.
I could be wrong understanding your question. But here are my suggestions to solve your problem.
First of all, I couldn't understand your code because the else statement is not reachable there, so I slightly changed it, but nothing dramatically changed.
def string_processor(string):
# This is a bad way to check the types and the value
try:
if string.isalpha():
# If string has a type "string" and contains only letters
return string.count('a')/len(string)
elif string.isnumeric():
# If string has numbers only
print("Please enter a string instead")
except:
if isinstance(string, list):
# If type of the "string" is actually a list
print('This is not a string, this is a list')
elif type(string) == tuple:
# If type of the "string" is actually a tuple
print('This is not a string, this is a tuple')
else:
# If none of the above worked
print('It is definitely not a pure string')
a = string_processor(234)
As I commented, this is not a good way to implement the solution, the better way may be this:
def string_processor_another(value):
# It is better to RAISE exceptions, not to print them
if not isinstance(value, str):
raise TypeError('This must be a string')
# So if we come to this step we can be sure that we work with strings, so we can use the methods
if value.isalpha():
# If string has a type "string" and contains only letters
return value.count('a')/len(value)
elif value.isnumeric():
# If string has numbers only
print("Please enter a string instead")
b = string_processor_another(234)
And if you are going to add some extra logics or you want to have a cleaner code, I'd suggest you to make this in oop way
class StringProcessor:
def __init__(self, string):
self.__check_for_str(string)
self.string = string
#staticmethod
def __check_for_str(string):
return isinstance(string, str)
# Here you can add short functions to make all of your logic statements
def check_is_numeric(self):
print(self.string.isnumeric())
def check_is_alpha(self):
print(self.string.isalpha())
sp = StringProcessor('1234')
sp.check_is_numeric() # True
sp.check_is_alpha() # False
Hope it helped.

Why if there is no break this code keep returning my input?

Could anyone help me to understand why if I didn't put break there, the code give me multiple output. For example:
In : myfunc('abogoboga')
Out : 'aBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGaaBoGoBoGa'
def myfunc(*args):
output = []
for strg in args:
for char in strg:
for i in range(len(strg)):
if i % 2 == 0:
output.append(strg[i].lower())
else:
output.append(strg[i].upper())
break
return ''.join(output)
but, after putting break as above:
In : myfunc('abogoboga')
Out : 'aBoGoBoGa'
Your nested for loops accomplish the same thing. for char in strg is assigning char to each character in strg, but you never use it. Instead, you iterate over strg again, and the reason it works with the break is that if you break after performing one loop of for char in strg, you are turning the for loop into a simple statement. A simpler way of doing this is removing for char in strg:
def myfunc(*args):
output = []
for strg in args:
for i in range(len(strg)):
if i % 2 == 0:
output.append(strg[i].lower())
else:
output.append(strg[i].upper())
return ''.join(output)

A simple question about Collatz Function,Why this is a unreachable code?

I'm a new learner of python, when I try to write a Collatz function I find that pycharm shows me one line is unreachable. I wonder why the function can't run the code
def Collatz(numBer):
if numBer%2 == 0:
return numBer//2
else:
return 3*numBer+1
print(numBer) #this code is unreachale
print('Please input the number:')
numBer = int(input())
while numBer != 1:
Collatz(numBer)
print(Collatz(numBer)) #because the former code are unreachable,so I write this to print the results
numBer = Collatz(numBer)
All code within the same scope below a return statement is unreachable because the function will finish its execution there. In your case you are returning the result so there is no need to rerun the function again to print it. Just take it in a variable and use it:
def Collatz(numBer):
if numBer%2 == 0:
return numBer//2
else:
return 3*numBer+1
print('Please input the number:')
numBer = int(input())
while numBer != 1:
numBer = Collatz(numBer)
print(numBer)
Hello welcome to Stack Overflow!
The reason why the print is "unreachable" is because of the return before the print. return ends a control flow so any code after the return is disregarded. Basically, the control flow goes like this (based on your function):
"Is the numBer divisible by 2?"
"If yes, then give me the integer division of that number and 2"
"Otherwise, give me the 3*number + 1"
If you wanted to print the number before you return it, it would be best to store it first into a variable and then return that variable, like so:
def Collatz(numBer):
if Collatz % 2 == 0:
value = numBer // 2
else:
value = 3 * numBer + 1
print(value)
return value

Python3 reversing an inputed sentence

I am trying to create a function that reverses a sentence that a user inputs but when I run the program I am not getting the sentence in reverse. Bellow is my code
sentence=input('Enter a sentence: ')
def sentence_reverse(sentence):
words=sentence.split()
newsentence=words.reverse()
return (newsentence)
print(sentence_reverse(sentence))
def sentence_reverse(s):
return ' '.join(s.split()[::-1])
print(sentence_reverse(sentence))
you can do this
def reverse(s):
if len(s) == 0:
return s
else:
return reverse(s[1:]) + s[0]
or :
def reverse2(s):
return s[::-1]
reverse() is an in-place operation, meaning it reverses words itself and doesnt return anything. So instead of returning newsentence, you want to return words like so:
sentence=input('Enter a sentence: ')
def sentence_reverse(sentence):
words=sentence.split()
words.reverse()
return words
print(sentence_reverse(sentence))
>>>Enter a sentence: hello world
>>>['world', 'hello']
Here is a simplest way to solve your problem:
sentence=input('Enter a sentence: ')
def sentence_reverse(sentence):
words= sentence.split() # breaks the sentence into words
rev_sentence= ''
for word in words:
rev_sentence = ' ' + word + rev_sentence
return rev_sentence
print(sentence_reverse(sentence))
Input: Hi please reverse me
Ouput: me reverse please Hi
Hope this helps you. Kindly let me know if anything else is needed.
Welcome to StackOverflow!
The reason is because you are using split() but it does not convert your input string into the list of its character. It just make a list with one element, which is your input string. Instead, convert the string to list using list() function, and then convert it back to string using join() function. In addition to that, reverse() returns nothing. So, you have to returns the words variable instead.
sentence=input('Enter a sentence: ')
def sentence_reverse(sentence):
words=list(sentence)
words.reverse()
return ''.join(words)
print(sentence_reverse(sentence))

Python. Trying to write a function called one_frame. Does not seem to work. Help would be greatly appreciated

As of right now, this is my code:
def get_orf(DNA):
codon = ''
if(DNA[0:3] == 'ATG'):
codon = DNA[0:3]
for x in range(3,len(DNA)+1,3):
if DNA[x:x+3] == "TAG" or DNA[x:x+3] == "TAA" or DNA[x:x+3] == "TGA":
return codon
else: codon = codon + DNA[x:x+3]
if codon[-3:] in ["TAG", "TAA", "TGA"]:
return codon
else: return 'No ORF'
def one_frame(DNA):
x = 0
ORFlist = []
while x < len(DNA):
codon = DNA[x:]
if DNA.startswith('ATG'):
get_orf(DNA[x:])
if codon:
ORFlist.append(codon)
x += len(codon)
return(ORFlist)
get_orf function works fine but my one_frame function doesn't work.
The one_frame function is supposed to take a DNA string as input. It searches that
string from left to right in multiples of three nucleotides–that is, in a single reading frame. When
it hits a start codon “ATG" it calls get_orf on the slice of the string beginning at that start codon
(until the end) to get back an ORF. That ORF is added to a list of ORFs and then the function skips
ahead in the DNA string to the point right after the ORF that we just found and starts looking for
the next ORF. This is repeated until we’ve traversed the entire DNA string.
I can see a few obvious problems but not sure exactly what you want so hope this helps. Firstly your for loop in one_frame will never end unless DNA starts with 'ATG'. I think you want to check codon.startswith instead of DNA.startswith. You also need to do the x+= command outside of the if statement, or it will never be updated when you don't hit 'ATG' and so your loop will continue forever. You're also not using the value of get_orf at all.
I think this will do the trick,
def one_frame(DNA):
x = 0
ORFlist = []
while x < len(DNA):
codon = DNA[x:]
# Check codon instead of DNA
if codon.startswith('ATG'):
# Record the return value of get_orf
orf_return_value = get_orf(DNA[x:])
if orf_return_value:
ORFlist.append(orf_return_value)
x += len(orf_return_value)
# Increment by 3 if we don't hit ATG
else:
x += 3
return(ORFlist)

Resources