I am learning about recursive functions and I have made a simple "string to ASCII" converter which returns the ASCII value of each character of a string.
Here is what I have made so far:
def cod(n):
if n == "":
return ""
else:
a = str(ord(n[0])) + cod(n[1:])
return a
This works fine like this:
=> cod('hello')
=> '104101108108111'
The problem is when I am trying to get an int as output instead of a string. I can't simply convert variable a because it's a recursive function, and it's not possible to iterate over an int.
After this point I am a little lost, can someone point out how to get an int as a final result of this recursive function?
def cod(n):
if n == "":
return ""
else:
a = str(ord(n[0])) + str(cod(n[1:]))
return int(a)
You might want to create another method for returning integer. Just to keep the code clean,
def cod(n):
if n == "":
return ""
else:
a = str(ord(n[0])) + cod(n[1:])
return a
def codI(n):
return int(cod(n))
print type(codI("hello"))
print type(cod("hello"))
Related
"Given a string of both letters and special characters/numbers, use recursion to concatenate the letters into a single string and return it."
My code is below, I'm still learning recursion and am stuck in trying to trace it. I tried a bunch of different lines in this code but idk how to fix what I do have so far:
def decoder(encryptedStr):
if len(encryptedStr) != 0:
if encryptedStr[0].isalpha() == True:
decoded = encryptedStr[0]
decoded.join(decoder(encryptedStr[1:]))
print(decoded)
else:
decoder(encryptedStr[1:])
I haven't had it return anything yet because I'm struggling with the part where I have to join the new letters to the output string. Instead of .join I also tried:
decoded += decoder(encryptedStr[1:])
but it doesn't work bc Nonetype??
Your main issue is that you didnt return, but there are some issues with your approach that make this more complex than need-be.
Think tail-first when doing recursion- What is your end condition, and how do you decide to continue. Typically with this kind of method you do something like, 1) process a single value in the list, 2) let the recursive method handle the rest of it, 3) combine the results.
An easy indicator of the tail-first return here would be to return nothing if the string is empty:
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
...
Now in each run we want to operate on one letter and pass the rest to a recursive call. Ignoring the special character requirement, you'd get something like this:
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
first = encryptedStr[0]
rest = decoder(encryptedStr[1:])
return first + rest
Now we can handle the special case where we want to omit letters.
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
first = encryptedStr[0]
rest = decoder(encryptedStr[1:])
if not first.isalpha():
first = ""
return first + rest
And that's all there is to it!
Bonus for some refactoring:
def clean(letter):
return letter if letter.isalpha() else ""
def decoder(encrypted):
if len(encrypted) == 0:
return ""
return clean(encrypted[0]) + decoder(encrypted[1:])
There's a bunch of problems here:
I don't think join does what you want it to do in that case. If you want to add some strings together simply use +=. join would insert decoded character between whatever decoder(encryptedStr[1:]) returns.
You don't have a case for len(encryptedStr) == 0, so it returns default value of None. That's why you cannot append it's results to decoded.
Return immediately if there is nothing to do. Otherwise take the first letter if it matches the condition and add the result of the recursive call (where the parameter is the current encrypted string without the first character).
def decoder(encrypted):
if not encrypted:
return ''
decrypted = encrypted[0] if encrypted[0].isalpha() else ''
return decrypted + decoder(encrypted[1:])
print(decoder('Abc123rtZ5'))
The result is AbcrtZ.
Bonus info (as #JonSG mentioned in the comments):
Run this with print(decoder('A' * 1000)) and you'll see why recursion is a bad idea for this task.
Every recursive function must have a base condition that stops the recursion or else the function calls itself infinitely.
To recursively concatenate ONLY the letters of an input string into a single output string:
some_string = "I2L4o2v3e+P;y|t!o#n"
def decoder(encryptedStr, decoded = ""):
if len(encryptedStr) == 0: # Base condition
return decoded
if encryptedStr[0].isalpha():
decoded += encryptedStr[0]
return decoder(encryptedStr[1:], decoded)
# If the char in the index [0] is not a letter it will be sliced out.
return decoder(encryptedStr[1:], decoded)
print(decoder(some_string))
Output:
ILovePython
I am trying to write a function that shows me the multiplication table of a number:
def tabellina(n):
for i in range (1,11):
print(n*i)
If I write the function in this way, it works fine.
If I put 4 instead of n, it prints:
4,8,12,16,20,24,28...40
But if I use return instead of print, it does not work anymore, and it just returns me the n value.
I have to use the return and I can’t use the print
What should I do? (I MUST use return NOT print)
The reason it returns the n value if you use return is because the loop doesn't run fully. When you use return, it returns the value, which exits the function. The rest of the loop never executes.
What you want instead is to return an array. The easiest way is probably a list comprehension:
def tabellina(n):
return [n*i for i in range(11)]
you could save the output in a string and then return that. for example:
def tabellina(n):
table = ''
for i in range (1,11):
table += ((n*i) + ' ')
return table
you could replace ' ' with any devider (like ',') as you want.
Try the following script:
def tabellina(n):
joint = ""
for i in range (1,11):
joint = joint + (" %s" % n*i)
return joint
def binary(n):
if n>0:
return binary(n//2)*10 + (n%2)
else:
return 0
The answer is 10000000 but it have to be "10000000". How can I put str on the answer?
In python, to change the type of anything, the only thing you have to do is wrap that in str(), int(), float()... or whatever type you want to change it to.
more details: http://usingpython.com/python-casting/
edit: sorry, didn't realize the recursive problem, still, I don't see why you can't just change the type after the function returns, seems the easiest thing to do.
if you insist though:
def binary(n):
if int(n)>0:
return str( int(binary(str(int(n)//2)))*10 + (int(n)%2))
else:
return str(0)
I will suggest that you use nested/inner functions as shown below to solve you problem. This allows you to compute the result using integers, and then convert the result to a string, or any other type, before returning it.
def binary(n):
def inner(m):
if m>0:
return inner(m//2)*10 + (m%2)
else:
return 0
return str(inner(n))
Alternatively you can cast n to the correct type whenever you use it. This is, in my opinion, a horrible to solve the problem, but it should still do the trick.
def binary(n):
if int(n) > 0:
return str(int(binary(n//2))*10 + n%2)
else:
return "0"
The problem with simply wrapping your return in a cast to str(), is that the subsequent calls to binary() will be affected, not just the top-level call. After the deepest recursive call to binary has finished, it will return its result - which is a string - to the next deepest recursive call to the expression:
binary(n // 2) * 10 + (n % 2)
But since the return value is a string, it fails when used in the expression.
The obvious solution is to simply cast the return value of binary() to a string from wherever it's being called. However, if for some reason you cannot do this, you can make a second function nested under binary, call this function inside of binary(), and cast its result to a string:
>>> def binary(n):
def _binary(n):
if n > 0:
return _binary(n // 2) * 10 + (n % 2)
else:
return 0
return str(_binary(n))
>>> binary(128)
'10000000'
>>> binary(64)
'1000000'
>>> binary(32)
'100000'
>>> binary(16)
'10000'
>>> binary(8)
'1000'
>>> binary(4)
'100'
>>> binary(2)
'10'
>>>
As #StefanPochmann pointed out, this method would also work:
def binary(n):
return binary(n // 2) + str(n % 2) if n > 1 else str(n)
My goal is to have the function SRA_Accession return it's values as a string e.g "Value1,Value2,Value3" the code so far is
def SRA_Accession():
SRA=1293518
while (SRA < 1293618):
SRA=SRA+1
print "SRA"+str(SRA)
if False:
break
the lack of tabs are making this not work and you need a return statement which returns everything.
def SRA_Accession():
SRA=1293518
my_list = []
while (SRA < 1293618):
SRA=SRA+1
my_list.append("SRA"+str(SRA))
return ','.join(my_list)
Judging by the way you are writing the statement I would say you were looking to use a yield statement which returns each SRA string all by itself. This means you will need to add commas outside the function like so.
def SRA_Accession():
SRA=1293518
while (SRA < 1293618):
SRA=SRA+1
yield "SRA"+str(SRA)
value = ','.join(list(SRA_Accession()))
print(value)
def Functional_Output(Validate_Input):
try:
while '(' in Validate_Input and ')' in Validate_Input:
Validate_Output = Validate_Input.count('(')
Intake_Input = Validate_Input.find('(')
fin = Validate_Input.find(')')+1
while Validate_Output > 1:
Intake_Input = Validate_Input.find('(', Intake_Input+1)
Validate_Output -= 1
receive_value = Validate_Input[Intake_Input:fin]
receive_input = calcula(receive_value.replace('(', ''). replace(')', ''))
Validate_Input = Validate_Input.replace(recieve_value, recieve_input)
DisplayAnswer = float(AddFunction(Validate_Input))
except:
DisplayAnswer = "Error"
return DisplayAnswer
def AddFunction(Validate_Input):
add_selection = Validate_Input.split()
while len(add_selection) != 1:
for index in range(len(add_selection)):
if add_selection[index] == '/':
add_selection[index] = str(float(add_selection[index-1]) / float(add_selection[index+1]))
add_selection.pop(index+1)
add_selection.pop(index-1)
break
elif add_selection[index] == '*':
add_selection[index] = str(float(add_selection[index-1]) * float(add_selection[index+1]))
add_selection.pop(index+1)
add_selection.pop(index-1)
break
if not '/' in add_selection and not '*' in add_selection:
while len(add_selection) !=1:
for index in range(len(add_selection)):
add_selection[index] = str(float(add_selection[index]) + float(add_selection[index+1]))
add_selection.pop(index+1)
break
return add_selection[0]
root = tkinter.Tk()
root.resizable(0, 0)
root.title("Calculator")
txtDisplay =tkinter.StringVar()
operator = ""
App_Function = Calculator_App(root)
root.mainloop()
How come when I click on the button '9' then '+' then '1' the entry returns the message 'Error' instead of '10'! Why is this?
Could it be something to do with the addFunction function and the indexing?
In your code:
line 98, in Functional_Output DisplayAnswer = float(AddFunction(Validate_Input))
AddFunction is returning a string: '8+9';
Then you are trying to convert this string to a float.
It trows a ValueError, cuz strings can't be turned to floats.
To fix this you need to go to you AddFunction and make that it returns 8+9 instead of '8+9',
I think your problem is in this line:
add_selection[index] = str(float(add_selection[index]) + float(add_selection[index+1]))
You are converting add_selection[index] to a float, then to a string. try removing the outer str()
EDIT:
The only way to know further is to print check this line:
Try doing this:
print add_selection[index], add_selection[index+1]
print type(add_selection[index]),type(add_selection[index+1])
EDIT2:
Looking better at your code there's two things that might fix you program.
1) The easy hack
In AddFunction change:
return add_selection[0]
to
return eval(add_selection[0])
Since the AddFunction is returning a '9+1' <type str>, using eval will evaluate this to 10 <type int>. Actually you could remove the whole AddFunction and just use DisplayAnswer = float(eval(Validate_Input)). But note that this is a dirty trick and a hack.
2) Rewrite
I note that you are using each button in the add_Components both the display information(a string) but also as the value for when pressing each button, thus concatenating operator with the new value. operator += self.value.
But mostly the problem is that you are dealing with strings instead of integers, when you set the value of the button to be '1' it's not the same as setting it to be 1, you should change your program to be using the proper type for the values, numbers being integers, strings for the operators. Then you will have to rewrite how your AddFunction to work with both.
And lastly you operator being a global variable is really frowned upon, and can lead to several problems further on.