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)
Related
This is a codewars challenge where you have to return the sum of the given arguments.
Instructions:
Calculate the sum of all the arguments passed to a function.
Note: If any of the arguments is not a finite number the function should return false/False instead of the sum of the arguments.
Here's my code:
def sum_all(*args):
sum = 0
for str(num) in args:
if not num.isdigit():
return False
else:
int(sum) += num
return sum
Currently I'm getting this error:
File "", line 9
SyntaxError: can't assign to function call
That error message is actually happening in two places:
Here:
for str(num) in args:
and here:
int(sum) += num
You cannot cast to string and int the way you are attempting to.
What you should do instead, is keep your iteration as:
for num in args:
Then, you can check if digit by doing this:
if not str(num).isdigit():
Finally, when you get to summing everything, simply cast num to int(num) to handle the case if you pass something like [1, 2, '3', 4] (not the 3 as a string):
sum += num
So, with that in mind, your code will look like this:
def sum_all(*args):
sum = 0
for num in args:
if not str(num).isdigit():
return False
else:
sum += int(num)
return sum
However, as you pointed out in your comment, there is a test case for negative numbers. This is where the above code breaks. Because, negative numbers as a string:
"-343"
Do not pass isdigit.
If you put this in your interpreter, it will return False:
"-343".isdigit()
So, with all this in mind, you can actually further simplify your code when you remove that to just have this:
def sum_all(*args):
try:
return sum(int(i) for i in args)
except:
return False
Demo:
print(sum_all(1,2,3,4,5))
Outputs:
15
First of all, don't overwrite existing functions such as sum. Use a different variable name (e.g. sum_). Second, your problem is on the for str(num) in args line. This needs to be for num in args:, with a modification of the following line for str(num).
def sum_all(*args):
sum_ = 0
for num in args:
if not str(num).isdigit():
return False
else:
sum_ += float(num)
return sum_
>>> sum_all('a', 2)
False
>>> sum_all(1, 2)
3.0
>>> sum_all(1, 2, '4')
7.0
Here is an alternative approach to coding the function that uses a generator comprehension to try and sum the arguments but returns False if it fails:
def sum_all2(*args):
try:
return sum(i for i in args)
except:
return False
>>> sum_all2(1, 2, '4.5')
False
>>> sum_all2(1, 2, '4') # I argue that '4' is a string, not a finite number.
False
>>> sum_all2(1, 2)
3
>>> sum_all2(1, 2, 3.5)
6.5
>>> sum_all2(1, 2, -3.5)
-0.5
You're overthinking this. There are two parts to this to note:
sum is a function that already takes in a collection and gives you its sum.
You want to reject the collection if none of them are numeric types.
Here's a start: this particular method will reject if none of the values are int. I leave expanding this out to float types as an exercise for the reader.
def sum_or_reject(li):
return sum(li) if all([isinstance(i, int) for i in li]) else False
The minimal change to make your logic run is:
def sum_all(*args):
sum = 0
for s in args:
num = str(s)
if not num.isdigit():
return False
else:
sum += int(num)
return sum
The line number in the question is misleading, and there are two issues: First, you need a variable for the iteration. Second, you need a variable for the += assignment. In both cases you try to apply a cast, bust the result of that would not longer be a variable and thus cannot be used as target for the assignment.
Likewise a minimal change to your code:
def sum_all(*args):
try:
return sum(int(i) for i in args)
except:
return False
print(sum_all(10,'-1',10))
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"))
I try convert a float to int when the number don't have decimals.
I make this
from math import modf
def float_like_int(n):
if abs(modf(n)[0]) < 1e-6:
return int(n)
return n
print float_like_int(10.1)
print float_like_int(10.00001)
print float_like_int(10.000001)
print float_like_int(10.0)
exist a standard function or a more general way ? (without 1e-6)
I think the following is a bit more readable than your version:
def float_like_int(n):
if round(n, 6) == round(n):
return int(round(n))
return n
Note that this does have a slightly different meaning than your function, since it would also round something like 9.9999999 to 10.
Those approach that you are using trys to make a number integer if a fractional part is less than 1e-6 (0.000001 ). This means if you have a number 4.000001, (which is float actually) your function will throw away fractional part. You can change 1e-6 to another value and those numbers, which meet your criteria will be converted to int.
Here is my code without any extra modules imported. This code will not throw away any fractional part.
def Func(a):
if (a * 10) % 10 == 0:
return int(a)
else:
return a
f = 4.03
print Func(23.45)
print Func(f)
print Func(2.3)
Maybe something like this is more natural?
def float_like_int(n):
if int(n) == float(n):
return int(n)
else:
return float(n)
You can use this function :
def isWhole(x):
if(x%1 == 0):
return True
else:
return False
I am creating a program to figure out the highest number of decimals in a list of numbers. Basically, a list with [123, 1233] would return 4 because 1233 has four numbers in it and it is the largest. Another example would be that [12, 4333, 5, 555555] would return 6 because 555555 has 6 numbers.
Here is my code.
def place(listy):
if len(listy) == 1:
decimal = len(str(listy[0]))
print(decimal)
else:
if len(str(listy[0])) >= len(str(listy[1])):
new_list = listy[0:1]
for i in listy[2:]:
new_list.append(i)
place(new_list)
else:
place(listy[1:])
Now, when I use print(decimal) it works, but if I change print(decimal) to return decimal, it doesn't return anything. Why is this? How do I fix this? I have come across these return statements which doing run a lot of times. Thanks in advance!
When you do a recursive call (i.e. when place calls place, and the called place returns a value, then the calling place must return it as well (i.e. the return value "bubbles up" to the initial caller).
So you need to replace every recursive call
place(...)
with
return place(...)
As others have said, there are easier solutions, such as using max(). If you want to keep a recursive approach, I would refactor your code as follows:
def place2(listy):
if len(listy) < 1:
return None
elif len(listy) == 1:
return len(str(listy[0]))
else:
v0, v1 = listy[0], listy[1]
if v1 > v0:
return place2(listy[1:])
else:
return place2([listy[0]]+listy[2:])
Although this is tail-recursive, Python does not really care so this approach will be inefficient. Using max(), or using a loop will be the better solution in Python.
It's not that the return doesn't do anything, it's that you don't propagate the return from your recursive call. You need a few more returns:
def place(listy):
if len(listy) == 1:
decimal = len(str(listy[0]))
return decimal
else:
if len(str(listy[0])) >= len(str(listy[1])):
new_list = listy[0:1]
for i in listy[2:]:
new_list.append(i)
return place(new_list) # <-- return added
else:
return place(listy[1:]) # <-- return added
You can see the print at any level, but to get it back to the caller it needs to be propagated.
The function does return the value, but it's not printing it out.
A simple way to solve this is, just call the function within a print statement.
That is:
print(place(listy))
If all you want is to find the maximum length of a list of integers, consider:
max([len(str(n)) for n in N])
For example
N = [1,22,333,4444]
max([len(str(n)) for n in N]) # Returns 4
N = [12, 4333, 5, 555555]
max([len(str(n)) for n in N]) # Returns 6
Note: This will only work for positive integers.
Or more simply:
len(str(max(N)))
Which will also only work for positive integers.
Use ''global variable'' (google it) to access and change a variable defined outside of your function.
I've just started exploring the wonders of programming. I'm trying to write a code to identify numeric palindromes. Just looking at numbers and not texts. I'm trying to learn to use recursion here. But I'm just not getting anywhere and I can't figure out what's wrong with it.
My idea was to check first string vs the last, then delete these two if they match, and repeat. Eventually there'll be nothing left (implying it is a palindrome) or there will be a couple that doesn't match (implying the reverse).
I know there are better codes to finding palindromes in but I just wanted to try my hand at recursion.
So what's wrong?
def f(n):
global li
li=list(str(n))
if (len(li)==(1 or 0)):
return True
elif li[len(li)-1]==li[0]:
del li[0]
del li[len(li)-1]
if len(li)==0:
return True
if len(li)>0:
global x
x=''.join(li)
str(x)
f(x)
else:
return False
Thanks in advance!
A few comments
Why are x and li globals? In recursion, all variables should be local.
Why are you converting back and forth between str and list? You can subscript both of them
You need to return the result of your recursive call: return f(x)
Try these suggestions, and see how it works out.
Before looking into it too much, if (len(li)==(1 or 0)): doesn't do what you're expecting it to do. (1 or 0) will always evaluate to 1.
You probably want:
if len(li) in (1, 0):
There are a couple of problems with your solution. Let me analyse them line by line.
You don't need global statements if you don't intend to change variables outside of function scope. Thus, I removed two lines with global from your code.
li=list(str(n)): casting a string to a list is unnecessary, as a string in Python has a similar interface to an immutable list. So a simple li = str(n) will suffice.
if (len(li)==(1 or 0)):: although it looks OK, it is in fact an incorrect way to compare a value to a few other values. The or operator returns the first "true" value from its left or right operand, so in this case it always returns 1. Instead, you can use the in operator, which checks whether the left operand is an element of a right operand. If we make the right operand a tuple (1, 0), all will be well. Furthermore, you don't need parentheses around the if statement. You should write: if len(li) in (1, 0):
elif li[len(li)-1]==li[0]: is fine, but we can write this shorter in Python, because it supports negative list indexing: elif li[-1] == li[0]:
Because we don't use lists (mutable sequences) because of point 2., we can't do del li[0] on them. And anyway, removing the first element of a list is very inefficient in Python (the whole list must be copied). From the very same reason, we can't do del li[len(li)-1]. Instead, we can use the "splicing" operator to extract a substring from the string: li = li[1:-1]
if len(li)==0: is unnecessary long. In Python, empty strings and lists resolve to False if tested by an if. So you can write if not li:
if len(li)>0:: You don't have to check again if li is not empty -- you checked it in point 6. So a simple else: would suffice. Or even better, remove this line completely and unindent the rest of the function, because the body of the if in 6. contains a return. So if we didn't enter the if, we are in the else without writing it at all.
x=''.join(li): We don't need to convert our string to a string, because of the decision made in 2. Remove this line.
str(x): This line didn't do anything useful in your code, because str() doesn't modify its argument in place, but returns a new value (so x = str(x) would have more sense). You can also remove it.
f(x): This is a valid way to call a recursive function in Python, but you have to do something with its value. Return it perhaps? We'll change it to: return f(li) (as we don't have an x variable any more).
We end up with the following code:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
if not li:
return True
return f(li)
else:
return False
It's almost what we need, but still a little refinement can be made. If you look at the lines if not li: return True, you'll see that they are not necessary. If we remove them, then f will be called with an empty string as the argument, len(li) will equal 0 and True will be returned anyway. So we'll go ahead and remove these lines:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
return f(li)
else:
return False
And that's it! Good luck on your way to becoming a successful programmer!
Split the whole show out into a list, then just:
def fun(yourList):
if yourList.pop(0) == yourList.pop(-1):
if len(yourList) < 2:
return True # We're a palindrome
else:
return fun(yourList)
else:
return False # We're not a palindrome
print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False
def palindrome(n):
return n == n[::-1]
It's hard to tell what you intend to do from your code, but I wrote a simpler (also recursive) example that might make it easier for you to understand:
def is_palindrome(num):
s = str(num)
if s[0] != s[-1]:
return False
elif not s[1:-1]:
return True
else:
return is_palindrome(int(s[1:-1]))
number = int(raw_input("Enter a number: "))
rev = 0
neg = number
original = number
if (number < 0):
number = number * -1
else:
number = number
while ( number > 0 ):
k = number % 10
number = number / 10
rev = k + ( rev * 10 )
if (number < 1):
break
if ( neg < 0 ):
rev = ( rev * -1)
else:
rev = (rev)
if ( rev == original):
print "The number you entered is a palindrome number"
else:
print "The number you entered is not a palindrome number"
This code even works for the negative numbers i am new to programming in case of any errors
dont mind.