I have been attempting to program a calculator using the tkinter module in Python, and I have made 14 functions corresponding to each number and symbol on the calculator. The code below is for the number 1, for example.
The program doesn't return the values as it should, however. I use the values from the previous function in further functions as parameters, but they don't seem to go through and I constantly get result 0.
The variables a and b correspond to two numbers to be used in the calculation and num is a counter for the program to know when to give the number to a and when to give it to b. I have tried inserting a print in this code and a and b was printing correctly but it seems to be a problem with the return.
Any help would be appreciated.
def num1(num,a,b):
if num == 0:
a=a+1
num=num+1
elif num == 1:
b=b+1
return num
return a
return b
Python function only return one value. When you write return a;return b, you only return the first occurrence.
What you need to do , is pack those elements and return them as a tuple:
def num1(num,a,b):
if num == 0:
a=a+1
num=num+1
elif num == 1:
b=b+1
return num, a, b
you need to keep in mind that the first return statement that reaches the work flow causes the end of the current function and returns the value supplied.
the return a; return b lines will never be reached, the execution flow returns to the caller after the first return statement
You can return a list, dictionary,tuple, variable. But a function can't return multiple times. You can try inserting the values in a list and then return the list.
Related
I have used pylint to check my code and I am receiving the following suggestion.
'Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)'. The code block is below. I am passing in a value and need to return which value range it belongs to. If I move the return value outside of the if it will return the incorrect count value. Any suggestions?
def findRangeValue(ranges, number):
count = -1
n = 2
for x in range(len(ranges)-n+1):
count += 1
batch = range[x:x + n]
if batch[0] < number <= batch[1]:
return count
You need confirm the function always have a non-empty (not None) return value in most common situation.
Your code will return None when all if statement in the loop failed, need add a final return value outside loop.
example code:
def findRangeValue(ranges, number):
count = -1
n = 2
for x in range(len(ranges)-n+1):
count += 1
batch = ranges[x:x + n]
if batch[0] < number <= batch[1]:
return count
return -1
print(findRangeValue([1,3,5,7,9], 4))
print(findRangeValue([1,3,5,7,9], 10))
result:
1
-1
Your function is written in a way, that it returns a value only if a condition is met i.e .
if batch[0] < number <= batch[1]:
Assume a situation you are consuming the function something like
range_val = findRangeValue([1,2,3], 3)
If the condition was met the return value will be assigned to range_val. But if the condition was not met, then the function returns nothing and your range_val becomes None.
But your code expects it to be a number and not None. So, now you need to check the return value to avoid errors - an extra line of code.
Assume you are calling this function from various parts of your code, every where you need to bring in this check - more and more code.
To avoid this, a standard to follow is that, a function always returns what was promised. If it was not able to do so, raise an Exception so that, the caller is notified without an additional check.
In your particular scenario, you can use a break statement and always return a count outside (beware, if break was not met, the value could be not what you expect) Or use an additional flag variable with break, and raise an error if the flag variable was not set.
Sorta newbie here. So in trying to wrap my head around using recursive functions I wanted to try to make a program that:
1: Generates a list containing 10 random integers ranging from 0 - 20
2: Using a recursive function goes trough the list and finds out what elements of the list are even integers
3: Prints out only the aformentioned even numbers
Where I have gotten stuck is in how to print out the result. I can't seem to figure out what value i want to put inside the function when calling it ( F(?) )
I tried to integrate a counter that kept track on how many times the program found a even number but it always resulted in an error that the variable is not defined no matter how hard I tried to make it global.
How could I go about this? Am I totally in the wrong?
import random
numL = []
for i in range(10):
x = random.randint(0,20)
numL.append(x)
print(numL)
def F(x):
if numL[x] % 2 == 0:
return numL[x]
else:
return F(x+1)
print(F( ??? ))
First question asked on this forum, hopefully I did okay, appreciate any help!
Assuming you want to return a list of the even numbers then you have 4 cases to consider
This is the last number in the list and its even so return this number
This is the last number in the list and its odd dont retrun this number
There are more numbers to check and this number is even so return
this plus the function result
There are more numbers to check and this number is odd to return
only the function result and not this num
So we can code this as
import random
def get_even_nums(nums):
num = nums[0]
#This is our terminating case we definitivly return a value here
if len(nums) == 1:
return [num] if num % 2 == 0 else []
else:
#If we got here we will be recursivly calling the function
#If its even number return that number plus the result of the function
#it its not even then just return the reult of the function and not this num
if num % 2 == 0:
return [num] + get_even_nums(nums[1:])
else:
return get_even_nums(nums[1:])
numL = [random.randint(0, 20) for _ in range(10)]
print(numL)
print(get_even_nums(numL))
OUTPUT
[3, 6, 5, 10, 20, 18, 5, 0, 3, 9]
[6, 10, 20, 18, 0]
So I took your function and changed it up slightly (using a slightly different approach). There's no need to a global list, though you could do that as well, if you wanted. The problem that you have is the lack of a base case or rather an incorrect one.
If you run your original function with an argument 0, which basically is the first element of your generated array, the fucntion will run until it hits one even number. At that point it'll exit recursion, because the base case basically stops recursive calls once you hit an even number.
Now, to fix this, you have to approach the problem differently. I would put your generated array as the input argument to your function, then ask myself "What would be a good base case?" Probably one that stops your recursive calls once you reach the end of the input list.
if len(numL) == 0:
return ...
Also, we need a way to return the even numbers that we found during our search through the list. For that reason I'd introduce a new acc list, where we would append the even numbers that we found. Thus the function input arguments would be
def F(numL, acc):
...
Now, in the recursive call we should check wether the current element is even or not. If it is, great, we add it to the acc list and continue into the recursive call. If it's not, we don't add anything to the acc but just continue with recursion.
if numL[0] % 2 == 0:
acc.append(numL[0])
return F(numL[1:], acc)
Putting it all together, we get:
def F(numL, acc):
if len(numL) == 0:
return acc
else:
if numL[0] % 2 == 0:
acc.append(numL[0])
return F(numL[1:], acc)
where numL represents your generated list and acc represents the resulting list we'll return after we traverse the list.
This is your function (as I understand it, you wanted this):
import random
def F(i):
r = random.randint(0,20)
if r % 2 == 0:
print(r)
i += 1
if i != 10:
F(i)
F(0)
Given 1 to 100 numbers, for multiples of 3 it should print "he" ,for multiples of 5 it should print "llo" ,for both multiples of 3 and 5 it should print "hello".
This is what I have:
for i in range (1,100):
if(i%3==0):
print("he")
elif(i%5==0):
print("llo")
elif(i%3==0 and i%5==0):
print("hello")
How would I do this recursively?
How about the code below?
def find_multiples(current, last_num=100):
# Base Case
if current > last_num:
return
result = ""
if current % 3 == 0:
result += "he"
if current % 5 == 0:
result += "llo"
if result:
print(f"{current}: {result}")
find_multiples(current+1, last_num)
find_multiples(1)
Base case is if current reaches last_num or the maximum number you'd like to check.
Here is a general outline for doing simple recursive things in python:
BASE_CASE = 1 #TODO
def f(current_case):
if current_case == BASE_CASE:
return #TODO: program logic here
new_case = current_case - 2 #TODO: program logic here ("decrement" the current_case somehow)
#TODO: even more program logic here
return f(new_case) + 1 #TODO: program logic here
Of course, this doesn't handle all possible recursive programs. However, it fits your case, and many others. You would call f(100), 100 would be current_value, you check to see if you've gotten to the bottom yet, and if so, return the appropriate value up the call stack. If not, you create a new case, which, in your case, is the "decrement" logic normally handled by the "loop" construct. You then do things for the current case, and then call the function again on the new case. This repeated function calling is what makes it "recursive". If you don't have an "if then" at the beginning of the function to handle the base case, and somewhere in the function recall the function on a "smaller" value, you're probably going to have a bad time with recursion.
This recursive function prints multiples of a number! hope it helps
def multi(n,x):
if x == 12:
print(n*x)
else :
print(n*x,end =",")
multi(n,x+1)
print(multi(4,1));
I'm having troubles with a recursive function in Python. The objective is for the function to calculate the sum of the digits of a number recursively.
This is what I have so far -- I realise that this version isn't as succinct as it could be, but right now I'm just trying to understand why it isn't working as is:
total = 0 #global variable declaration
def digit_sum(n):
global total #to be able to update the same variable at every level of recursion
total += n % 10 #adding the last digit to the total
n //= 10 #removing the last digit of the number
if n < 10:
total += n
return total
else:
digit_sum(n)
print 'The return value of the function is: ', digit_sum(12345)
print 'The final value stored in total is: ', total
I obtain the following output:
The return value of the function is: None
The final value stored in total is: 15
My function is somewhat working, since the final value stored in the global variable total is correct, but printing the function output returns None instead of 15.
Could you please help me understand why?
Thank you.
Interesting problem, and an interesting solution! Let me debug with a more simple number - 421.
On first call, total is assigned the value 1 and n becomes 42. The else branch gets executed.
On second call, total gets value of 3 and n becomes 4. The if branch is executed and the value total = 7 is returned.
So, why are we seeing the None? Let's inspect the call-stack:
> digit_sum(n = 421)
> > digit_sum(n = 42) # call to digit_sum from inside digit_sum
> -< 7 # value returned by inner/second call
> None
As you can notice, the value being returned by the second call is received by the first call, but the first call doesn't return the value being returned by the second call, so that's why you are seeing None.
But why does't first call return the value being returned by the second call?
Because of this line:
else:
digit_sum(n)
You are calling the function a second time, but you are not returning its return value.
Hope it helps! :)
The problem is that you didn't add a return statement in your else clause.
Adding 'return digit_sum(n)' should solve your problem:
if n < 10:
total += n
return total
else:
return digit_sum(n)
Example
When you have a recursive function (I'll take n! as example), calls are made until you reach a 'base case' (2 in n! and for you if n<10).
Let's take a look at factorial:
def fact(n):
if(n<=2):
return n
else:
return n*fact(n-1)
Without the return statement in else clause, if you ask for fact(4), this will also return none.
Here are the 'calls' with the return statement:
return (4*fact(3))
return (4*(3*fact(2)))
return (4*(3*(2)))
Which gives 24.
Here are those without:
(4*fact(3))
(4*(3*fact(2)))
(4*(3*(2)))
So the calculus is made, but nothing is returned.
I hope this will help you to understand.
NB: Here is a factorial implementation where recursivity is explained.
my solution is
def f(n):
if n/10 == 0:
return n
return n%10 + f(n/10)
output:
f(12345) = 15
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.