I am writing a function in Python that takes a number 'n' and a base 'b' that will convert a decimal number to another base using recursive function.
This is what I have so far:
def convert_number(n, b):
if n >= 1:
convert_number(n // b)
print(n % b, end = "")
When I test the function with convert_number(15, 3) this is what i get:
TypeError: convert_number() missing 1 required positional argument: 'b'
Nevertheless, the function works if I use a default value for b.
Since I'm new to programming, I've no idea what that means and what to change.
Thanks in advance for help :)
You probably want to return the result of your recursive call, and you need to make sure that you call the function correctly (it expects an n and b argument).
Generally in a recursive function you first handle the "base case" (the one where the input is small enough to not require recursion), and then you divide the input into one part that you can handle now and one part that needs to be handled by another (recursive) call to the function.
In this function, the base case is n < b (i.e. it's a single digit number), and for the recursive case we can use divmod to get the next digit and the remainder of the number that needs to be converted.
>>> def convert_number(n, b):
... if n < b:
... return str(n)
... n, digit = divmod(n, b)
... return convert_number(n, b) + str(digit)
...
>>> convert_number(10, 2)
'1010'
Related
I found a basic code in python to find the numbers of paths you can take in a (m,n) grid if you can only go either down or right.
def gridtraveller(m,n):
if m == 0 or n == 0:
return 0
elif m == 1 or n == 1:
return 1
return gridtraveller(m-1,n) + gridtraveller(m,n-1)
But I dont understand why is this working for two thing:
What does def something (m,n) do ?
And why does here we return the definition ? ( I do understand why we return
m-1 and n-1 , but I don't understant the concepte of a def returning a def)
Thanks to you and sorry english is not my first language.
In Python the def keyword is simply used to define a function, in this case it's the function gridtraveller(m,n). What you're seeing with that last return statement is actually a function returning the value of another function. In this case it's returning the value of another call to gridtraveller, but with different parameter values; this is called recursion. An important part of recursion is having appropriate base cases, or return values that won't end in another recursive call(i.e. the return 0 or return 1 you see).
It can be easier to understand by simply stepping through a few iterations of the recursive calls. If your first function call starts with m = 2 and n = 1, the first call will end with return gridtraveller(1,1) + gridtraveller(2,0). The first call in that statement will then return 1 since either m or n are 1 and the second returns 0 since n = 0 here giving a total result of 1. If larger values of m and n are used it will obviously result in a higher number since more calls to gridtraver(m,n) will happen.
I recently had an idea of doing sigma(Σ) using python
So, I wrote this code.
def sigma(i,target,condition='i'):
if condition=='i':
a=0
for f in range(i,target+1): #the loop sums all the numbers from i to the target given
a+=f
print(a)
'''if user enters a condition than,
every number will follow condition and then be added to each other'''
else:
lis=list()
condition for i in range(i,target+1):
lis.append(i)
print(sum(lis))
but the code I wrote above just gives me a wrong output as it takes the variable condition as type 'string'.
The problem is actully to take the argument condition not as a string
for example, let's say user entered:
sigma(1,100,condition='i'*2)
so the code should run for loop like this:
i*2 for i in range(i, target+1)
but it runs like this:
'ii' for i in range(i, target+1)
For what I can understand, you should pass an anonymous function as argument to accomplish what you are looking for.
Consider that this is not a valid syntax: i*2 for i in range(i, target+1), so I consider it as a pseudo code explained by your comment.
You should change your method in this way:
def sigma(i, target, condition='i'):
if condition=='i':
a=0
for f in range(i,target+1):
a+=f
print(a)
else:
lis=list()
for i in range(i, target+1):
lis.append(i)
print(condition(sum(lis)))
So that if you call sigma(1,100,'i') #=> 5050 you fall in the true part of the statement.
For the false part of the statement you need to call the method passing a lambda expression as parameter:
sigma(1,100, lambda i: 2*i) #=> 10100
It happens that the argument condition when passed as lambda works as if it was defined as:
def condition(i):
return 2 * i
I would like to point out that the sum of the first n natural numbers is given by a math formula, so you don't need a loop:
n * (n + 1) // 2
Also should be better to return a value than to print.
I'd rewrite the method:
def sigma_2(i, target, condition=None):
sum_i_to_target = (target*(target+1)-(i-1)*i)//2
if condition is not None:
return condition(sum_i_to_target)
else: # need to check that condition is a lambda function
return sum_i_to_target
So call this way:
sigma_2(2, 20) #=> 209
sigma_2(2, 20, lambda i: 2*i) #=> 418
You've initialized i from what I can see from your code as a string.
If you would like for the compiler to read it as int then initialize i as int.
For example:
i=1
My parameter, n is a phone number as an integer.
Using recursion I want to return the first three numbers in the integer.
I've turned the integer into a list of individual number characters and I'm attempting to delete the last number over and over again until I'm left with the last three, but I'm stuck on how to repeat it.
def areaCodes(n):
n = str(n)
n = list(n)
del n[-1]
#n = reduce(opperator.add, n)
n = ''.join(n)
n = int(n)
return n
I know I'm supposed to repeat the name in the return somehow, but because n isn't an integer that I can use to repeat. What do I do?
How about something like this?
def areaCodes(n):
# if n is less than 1000, what does it mean about the number of digits?
if n < 1000:
return # fill...
# otherwise, if n is greater than 1000, how can we alter n to remove the last
# digit? (hint: there's an operation similar to division called f...r division)
return areaCodes( # operate on n somehow...)
I assume that this is an exercise where recursion is necessary. If so, try this (there are better ways to accomplish your end goal, but I tried to modify your existing code as little as possible):
def areaCodes(n):
n_lst = list(str(n))
del n_lst[-1]
n_str = ''.join(n_lst)
n_int = int(n_str)
if len(n_lst) > 3:
return areaCodes(n_int)
return n_int
This will call the function again if the length of the number is greater than three, and return the number otherwise. Basically, the only part you were missing in your original function was the following, which is the recursive part:
if len(n_lst) > 3:
return areaCodes(n_int)
Remember that for a function to be recursive, it will have two main attributes:
It will at some point call itself. (this is what makes it 'repeat')
It will have some stopping condition (or base case).
You mentioned #1 when you wrote that you're supposed to use "the name in the return," so that's great! You just need to write that in your code:
return areaCodes(n), Where n is the updated phone number with a digit removed.
As you can see, each recursive call should do some work towards the solution, and should pass its mini-solution to the next recursive call.
Along with #2 above, you need to specify a base case, where the recursion will cease. So, since you're taking away a digit each time you call your function, you should include some kind of check to see if the current input is the length you want yet.
If it is the right length, you're done, and you should return the current number (not another recursive call).
Otherwise, you aren't done with the recursion yet.
import sys
def areaCodes(n):
#Create a list
myList = list(str(n))
#Delete last element
del myList[-1]
#Combine your elements into string list
myListStr = ''.join(myList)
#Type cast to int
myListInt = int(myListSte)
#Check whether your list satisfies your condition
if len(myList) > 3:
#Recusivley call the function again
return areaCodes(myListInt)
#Return your list when recursion completes
return myListInt
n = 12345
print areaCodes(n)
Currently I'm experimenting a little bit with recursive functions in Python. I've read some things on the internet about them and I also built some simple functioning recursive functions myself. Although, I'm still not sure how to use the base case.
I know that a well-designed recursive function satisfies the following rules:
There is a base case.
The recursive steps work towards the base case.
The solutions of the subproblems provide a solution for the original problem.
Now I want to come down to the question that I have: Is it allowed to make up a base case from multiple statements?
In other words is the base case of the following self written script, valid?
def checkstring(n, string):
if len(string) == 1:
if string == n:
return 1
else:
return 0
if string[-1:] == n:
return 1 + checkstring(n, string[0:len(string) - 1])
else:
return checkstring(n, string[0:len(string) - 1])
print(checkstring('l', 'hello'))
Yes, of course it is: the only requirement on the base case is that it does not call the function recursively. Apart from that it can do anything it wants.
That is absolutely fine and valid function. Just remember that for any scenario that you can call a recursion function from, there should be a base case reachable by recursion flow.
For example, take a look at the following (stupid) recursive function:
def f(n):
if n == 0:
return True
return f(n - 2)
This function will never reach its base case (n == 0) if it was called for odd number, like 5. You want to avoid scenarios like that and think about all possible base cases the function can get to (in the example above, that would be 0 and 1). So you would do something like
def f(n):
if n == 0:
return True
if n == 1:
return False
if n < 0:
return f(-n)
return f(n - 2)
Now, that is correct function (with several ifs that checks if number is even).
Also note that your function will be quite slow. The reason for it is that Python string slices are slow and work for O(n) where n is length of sliced string. Thus, it is recommended to try non-recursive solution so that you can not re-slice string each time.
Also note that sometimes the function do not have strictly base case. For example, consider following brute-force function that prints all existing combinations of 4 digits:
def brute_force(a, current_digit):
if current_digit == 4:
# This means that we already chosen all 4 digits and
# we can just print the result
print a
else:
# Try to put each digit on the current_digit place and launch
# recursively
for i in range(10):
a[current_digit] = i
brute_force(a, current_digit + 1)
a = [0] * 4
brute_force(a, 0)
Here, because function does not return anything but just considers different options, we do not have a base case.
In simple terms Yes, as long as it does not require the need to call the function recursively to arrive at the base case. Everything else is allowed.
#Calculates to the index position of a fib number.
def f3(n):
if n < 2:
return n
return f3(n-2) + f3(n-1)
The function only accepts one argument, yet two are being sent in the return, yet, it works! What's happening here?
If I return f3(n-3), the function breaks down. What effect does the concatenation have?
Addition results in a single value.
>>> 1 + 2
3
>>> [1] + [2]
[1, 2]
Python evaluates the expression f3(n-2) + f3(n-1) before returning it, so its actually returning the value of them combined. The same is the case for f3(n-2), its first evaluating n-2 and then passing it as a value to f3().
The number of return arguments has nothing to do with the number of arguments a function takes as input.
The line f3(n-2) + f3(n-1) is returning only one value, the result of calculating f3 for the input n-2 and then adding that value to the result of calculating f3 for the input n-1
In Python, the mechanism for returning multiple values from a function is by packing them inside a tuple and then extracting them at the time of invoking the function (not the case in your question!) For example:
def multivalue(x, y)
return (x, y)
a, b = multivalue(5,10)
# here a holds 5, and b holds 10