How can I use the results in functions in a loop? - python

I want to define two functions, one inside the other, and loop it until it reaches the value I'm looking for. However, the values in the function are not accessible from outside the function, so the codes do not work properly. Can I get some help with that? Is there a way to achieve this?
def count_div(number):
counter = 0
for ite in range(1,number+1):
if number % ite == 0:
counter += 1
else:
continue
else:
#print(number, counter)
return counter
def sum_of(order):
num = 0
for a in range(order+1):
num = num + a
count_div(num)
#sum_of(7)
for o1 in range(100):
if sum_of(o1) == 20:
print(o1)
break
else:
continue
else:
print('can\'t reach')
there is my work but in for loop sum_of func. not give an usable result for comparison..
Thanks You.

You need to return the result of the function you call.
def sum_of(order):
num = 0
for a in range(order+1):
num = num + a
return count_div(num)
When there is no explicit return statement in a function python automatically returns None. Therefore the line if sum_of(o1) == 20: was comparing None to 20 every iteration.
Just FYI for the function count_div you can use sum for a more pythonic approach:
sum(not number%(n+1) for n in range(number)
And sum_of this is just adding all positive integers from 1-n. This can also be done using this equation n*(n+1)//2 for sake of efficiency vs a looping method, thus making sum_of pretty much irrelevant.
def count_div(num):
return sum(not num%(n+1) for n in range(num*(num+1)//2))
Then for your last loop:
for o1 in range(100):
if count_div(o1) == 20:
print(o1)
break

Your sum_of function is not returning anything which is why your if condition will never work. Add a return on the last line in sum_of function:
return count_div(num)
Also you have lots of unnecessary else: statements which you should remove, here is an example:
def count_div(number):
counter = 0
for ite in range(1,number+1):
if number % ite == 0:
counter += 1
#print(number, counter)
return counter
def sum_of(order):
num = 0
for a in range(order+1):
num = num + a
return count_div(num)
#sum_of(7)
for o1 in range(100):
if sum_of(o1) == 20:
print(o1)
break
else:
print('can\'t reach')

Related

if function inside function returns true, do something (python 3)

have 2 functions. first one generates a list and the second one checks if theres duplicates. if theres duplicates it returns True
so i want to call function 2 from function 1 and if it returns true do something
heres my code
import random
def x(list):
for i in range(len(list)):
count = 0
for k in range(len(list)):
if list[i] == list[k]:
count += 1
if count > 1:
return True
if count == 1:
return False
def generated_list(N):
list = []
for i in range(N):
list.append(random.randint(1, 365))
x(list)
if generated_list(25) is True:
print('is true')
There were some logical errors, check this one :
import random
def check_duplicate(numbers):
for i in range(len(numbers)):
count = 0
for k in range(len(numbers)):
if i == k:
continue
if numbers[i] == numbers[k]:
count += 1
if count > 1:
return True
return False
def generated_list(n):
numbers = []
for i in range(n):
numbers.append(random.randint(1, 365))
return check_duplicate(numbers)
if generated_list(25) is True:
print('is true')
Also, avoid reserved keyword for naming your variables.

Python 3 Count updating within function, but value doesn't update outside of it

I'm guessing that there is a scope issue here that I missed somewhere. This function squares all of the numbers and adds them together. It should stop if the number hits 1 or 89, otherwise keep going. Here's my code:
count = 0
def chain(x,count):
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
return False
else:
chain(x, count)
chain(145, 0)
print(count)
The problem is, when I print count when x == 89, I get 1. But when I print count at the end, it comes out as 0. I've looked over and I don't seem to be setting it to anything else, and I've also tried adding in return, return count, return True, and nothing seems to fix it. If someone could point out my error, I would greatly appreciate it!
Solution 1:
make count a global variable
count = 0
def chain(x):
global count
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
return False
else:
chain(x)
chain(145)
print(count)
Solution 2:
return count and receive it when recursively called.
def chain(x,count):
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
pass # you may want to use -1 or something as flag
else:
count = chain(x, count)
return count
print(chain(145,0))
These are two different variables with the same name. the count outside the function will not change when the count inside the function will so printing at the end will give 0
Well, the count is not exactly a reference since it's a primitive, so you don't get the same object every time (it is immutable).
Also, the count you are referencing outside of the function is not the same you pass initially (since your first call feeds it a 0, not the same variable).
Make count a global variable by removing it from the function parameters and using the modifier global
Example
count = 0
def chain(x):
global count
...
Make the count a mutable type and pass it from the very beginning (e.g. a Class, a Dict, a list).
Example
line 01: count = {'total': 0}
line 20: chain(145, count)

About a function on Python

I'm a absolute beginner, and when I made a function to count the number of even ints on a given list, it didn't went as expected, and I can't see where I'm doing it wrong.
nums = [2,2,4,4,5,6,7,8,9]
def count_even(nums):
for number in nums:
num = 0
if number % 2 == 0:
num += number
return num
else:
continue
The output is:
count_even(nums)
2
It stops on nums[1] for some obscure reason.
Or it just prints the first "2" and adds it, and I don't know how to fix it, yet.
You have three problems here.
You're setting num = 0 every time through the loop, instead of just once at the start. So you're only going to get the very last count that you do.
You're doing num += number, instead of num += 1, so instead of counting the even numbers, you're adding them.
You're doing a return num as soon as the first even number is found, instead of only at the end of the function, after the loop. (And that also means that if there are no even numbers, instead of returning 0, you return None).
While we're at it, you don't need else: continue, because continuing is already what happens by default when you fall off the end of a loop.
Anyway, this means it's not stopping at nums[1], it's stopping at nums[0]—but it's adding 2 instead of 1 there, which makes things confusing. (It's always fun when bugs interact like that. Even more fun when they happen to exactly cancel out for your test case, like if you did nums = [6,2,4,4,5,6,7,8,9] and got back 6 and thought everything was working…)
So:
def count_even(nums):
num = 0
for number in nums:
if number % 2 == 0:
num += 1
return num
Your function stops on nums[1] because the return keyword exits the function and returns num (which is set to 0 + number). If you want to print out the sum of all the even numbers in nums you could move the return statement to the end and take the num = 0 expression out of the for loop (because it will reset to 0 after each iteration), like this:
def count_even(nums):
num = 0
for number in nums:
if number % 2 == 0:
num += number
else:
continue
return num
Also, your else statement is redundant here, so you could simply remove it, leaving you with the following:
def count_even(nums):
num = 0
for number in nums:
if number % 2 == 0:
num += number
return num
And you could simplify that further to:
def count_even(nums):
evens = [number for number in nums if number % 2 == 0]
return sum(evens)
Another solution:
def count_even(nums):
return len([i for i in nums if i % 2 == 0])
There are a couple of problems in your code:
Your num needs be defined outside the loop, so you can count every even number found. If you define it inside the loop, it resets to 0 every iteration.
When you find an even number, you increment it towards the counter num. You need to instead increment num by 1.
You return immediately when a even number is found, this means the function exits on the first even number. You instead want to return the total num at the end.
You have an unnecessary continue in the else block. If a uneven number is found, simply ignore it.
Which these suggestions, you could implement your code like this:
nums = [2,2,4,4,5,6,7,8,9]
def count_even(nums):
num = 0
for number in nums:
if number % 2 == 0:
num += 1
return num
print(count_even(nums))
# 6

Division by values in a dictionary (Python)

I am building a prime generator (I know, another one and probably not a very good one at that, but that is for another question.) I am using a dictionary for my collection of primes and ignoring composites by dividing by the previous primes. However it doesn't seem to be iterating properly in the final stage of the function and I get a number of incorrect results. isWhole is a self explanatory call to another function. This is my code where x = the number of primes to be generated:
def prime_generator(x):
count = 2
counter = 2
p = {1: 2}
while len(p) <= x:
if count % 2 == 0:
count += 1
continue
test1 = (math.sqrt(count))
if isWhole(test1) == True:
count += 1
continue
for k, a in p.items():
if count % a == 0:
break
else:
p[ counter ] = count
counter += 1
break
count += 1
return p
Your design intent is not entirely clear, but you may be intending to have the else clause apply to the for loop rather than the if statement. Try un-indenting the entire else clause so that it only runs if the loop terminates without hitting a break.

How do I print a fibonacci sequence to the nth number in Python?

I have a homework assignment that I'm stumped on. I'm trying to write a program that outputs the fibonacci sequence up the nth number. Here's what I have so far:
def fib():
n = int(input("Please Enter a number: "))
if n == 1:
return(1)
elif n == 0:
return(0)
else:
return (n-1) + (n-2)
mylist = range[0:n]
print(mylist)
I'm thinking I could use separate functions but I can't figure out how to pass the argument that calculates the fibonacci sequence. Then the next step would be to to print out the sequence of numbers up to that number.
Non-recursive solution
def fib(n):
cur = 1
old = 1
i = 1
while (i < n):
cur, old, i = cur+old, cur, i+1
return cur
for i in range(10):
print(fib(i))
Generator solution:
def fib(n):
old = 0
cur = 1
i = 1
yield cur
while (i < n):
cur, old, i = cur+old, cur, i+1
yield cur
for f in fib(10):
print(f)
Note that generator solution outperforms the non-recursive (and non-recursive outperforms recursive, if memoization is not applied to recursive solution)
One more time, recursive with memoization:
def memoize(func):
memo = dict()
def decorated(n):
if n not in memo:
memo[n] = func(n)
return memo[n]
return decorated
#memoize
def fib(n):
#added for demonstration purposes only - not really needed
global call_count
call_count = call_count + 1
#end demonstration purposes
if n<=1:
return 1
else:
return fib(n-1) + fib(n-2)
call_count = 0 #added for demonstration purposes only - not really needed
for i in range(100):
print(fib(i))
print(call_count) #prints 100
This time each fibbonacci number calculated exactly once, and than stored. So, this solution would outperform all the rest. However, the decorator implementation is just quick and dirty, don't let it into production. (see this amazing question on SO for details about python decorators :)
So, having fib defined, the program would be something like (sorry, just looping is boring, here's some more cool python stuff: list comprehensions)
fib_n = int(input("Fib number?"))
fibs = [fib(i) for i in range(fib_n)]
print " ".join(fibs)
this prints all numbers in ONE line, separated by spaces. If you want each on it's own line - replace " " with "\n"
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(int(input())))
And since you want to print up to the nth number:
[print(fibonacci(n)) for n in range (int(input()))]
And for python2.7 change input to raw_input.
Please note, in your call
You are not calling fib() recursively
You need a wrapper method so that the input is not requested every time the method is called recursively
You do not need to send in a list. Just the number n is good enough.
This method would only give you the nth number in the sequence. It does not print the sequence.
You need to return fib(n-1) + fib(n-2)
def f():
n = int(input("Please Enter a number: "))
print fib(n)
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1)+fib(n-2)
This might be faster incase of long list
# Get nth Fibonacci number
def nfib(nth):
sq5 = 5**.5
phi1 = (1+sq5)/2
phi2 = -1 * (phi1 -1)
resp = (phi1**(nth+1) - phi2**(nth+1))/sq5
return long(resp)
for i in range(10):
print i+1, ": ", nfib(i)
OUTPUT
1 : 1
2 : 1
3 : 2
4 : 3
5 : 5
6 : 8
7 : 13
8 : 21
9 : 34
10 : 55
def fib(n):
if n == 1:
return(1)
elif n == 0:
return(0)
else:
return fib(n-1) + fib(n-2)
my_num = int(input("Enter a number:"))
print fib(my_num)
Im not really sure what your question is... but the answer is probably something like this
Separate functions would be best, as the recursive function would be far easier to deal with. On the other hand, you could code an iterative function that would take only one parameter
Recursively::
def fib(n):
if n == 1:
return (1);
elif n == 0:
return (0);
else:
return fib(n-1) + fib(n-2);
def callFib():
n = int(raw_input('Enter n::\t'));
mylist = fib(n);
print mylist;
callFib();
Iteratively::
def fib():
n = int(raw_input('Enter n::\t'));
terms = [0,1];
i=2;
while i<=n:
terms.append(terms[i-1] + terms[i-2]);
i=i+1;
print terms[n];
fib();
for a recursive solution:
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
x=input('which fibonnaci number do you want?')
print fib(x)
explanation:
if n is 0, then ofcourse the '0th' term is 0, and the 1st term is one. From here, you know that the next numbers will be the sum of the previous 2. That is what's inferred by the line after the else.
It looks like you might be trying to solve the same homework problem I was, where you don't actually need user input. You just pass in the parameter when you call the function.
def compute_nth_fib(num):
if num == 0:
return 0
elif num == 1:
return 1
else:
return compute_nth_fib(num-1) + compute_nth_fib(num-2)
#test with different parameters
print(compute_nth_fib(3))
Hope that's helpful to someone!

Categories