print the ratio of Fibonacci numbers until a specific condition - python

I will print to screen first 70 Fibonacci numbers. And then in the same script I also want to print F(i+1)/F(i) ratio until a defined F(i+1)-F(i)<=536 condition is met.
My script prints first 70 Fibonacci numbers but it doesn't print the ratio F(i+1)/F(i).
It gives the following error:
Traceback (most recent call last):
File "fib.py", line 13, in
while b-a > 536:
NameError: name 'b' is not defined
In my code a and b represent F(i) and F(i+1), respectively. How can I fix my code?
#!/usr/bin/python
def F(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a+b
return a
for c in range(0, 70):
print(F(c))
while b-a > 536:
print 'Ratio:', b/a

Try this:
a,b = 0,1
l = []
def F(n):
global a
global b
a,b = 0,1
for i in range(0, n):
a, b = b, a+b
return a
for c in range(0, 70):
num = F(c)
print(num)
l.append(num)
for i in range(0, len(l)-2):
if l[i+1]-l[i] <= 536:
#print b
#print a
print 'Ratio:', float(b)/a

def F(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a+b
return a
factorials = []
for c in range(0, 70):
factorials.append((F(c)))
for i in xrange(1,len(factorials)-1):
if factorials[i+1] - (factorials[i]) > 536:
print "ratio :"+str(factorials[i+1]/float(factorials[i]))
The output mainly consists of integers starting with 1.61803, Is that what you were trying to achieve ?

def FR(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a+b
return a , b/float(a) if b-a > 536 else None
for c in range(0, 70):
fb , ra = FR(c)
print fb if ra is None else fb,' Ratio:', ra

b is not definied in your while (as a).
In fact a and b are only define in the F(n) function and they are local variables.
You should read some documentation about Programming and python first. But the following code should works:
(I suppose that you want while a/b <= 536 as this is not clear in your question)
def F(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a+b
return a, b
for c in range(0, 70):
a,b = F(c)
print(a)
while a/b <= 536:
print('Ratio:{}/{}'.format(b,a))
a, b = F(a)
An other solution is to totaly rewrite your code:
def F(a, b):
c = a + b
return c,a
a, b = 0, 1
for c in range (0,70):
a, b = F(a,b)
print (a)
while a/b <=536:
print(a/b)
a,b = F(a, b)

Related

How can I debug my Python code to check if data can form a triangle or not

The aim of the code is to find whether it is possible to form a triangle with the given arguments. The theory tells that the sum of the two arbitrary sides should be greater than the third side and according to I am coding but it is not showing the correct answer.
My task is to return True if the arguments make it possible and return False if it is not.
def isItATriangle(a, b, c):
if a + b > c or a + c > b or b + c > a:
return True
else:
return False
print(isItATriangle(1 , 1, 3))
Why the code does not works properly?
Instead of
if a + b > c or a + c > b or b + c > a:
return True
else:
return False
The main right code shows this
if a + b <= c:
return False
if b + c <= a:
return False
if c + a <= b:
return False
return True
How can I determine in which part of logic I am wrong?
In order to return true you must fulfill all the conditions, not only one of them. Because of that, your code should be:
def isItATriangle(a, b, c):
if a + b > c and a + c > b and b + c > a:
return True
else:
return False
print(isItATriangle(1 , 1, 3))
This is, changing your or for an and. You can learn more about Python logical operators here or here.
Corrected and simplified:
def isItATriangle(a, b, c):
return a + b > c and a + c > b and b + c > a:
print(isItATriangle(1 , 1, 3))

Specific Character Pattern Python

I am trying to achieve the following;
Write a program that produces the following output giving an integer input n.
The result should be the following;
n=1 n=2 n=3 n=4
+ A+B AA+BB AAA+BBB
+E+ A+E+B AA+E+BB
C+D +EEE+ A+EEE+B
C+E+D +EEEEE+
CC+DD C+EEE+D
CC+E+DD
CCC+DDD
I am having issues solving this problem.
When I enter 2 I am currently getting the following but unable how to make it look like the above.
Current result;
A+
B+
E+
C+
D
Here is my code;
def specific_pattern(n):
addition = "+"
alp = "A, B, E, C, D"
# myList = ["A, B, C, D, E"]
newList = []
for j in range(0, n):
for i in range(0, j):
if n == 1:
print(addition)
else:
letters = alp.split(", ")
for letter in range(len(letters)):
newList.append(letters[letter]*j+addition)
newchar = "".join(newList)
print(newchar[:-1])
n = int(input("Enter a number: "))
specific_pattern(n)
You can use simple iteration to create both the top and bottom of the desired diamond:
def sequence(d):
c, l = 0, 1
while c < d - 1:
if l%2:
yield l
c += 1
l += 1
def make_pattern(d):
t, b, r = f'{"A"*(d-1)}+{"B"*(d-1)}', f'{"C"*(d-1)}+{"D"*(d-1)}', list(sequence(d))
body = '\n'.join(f'{"A"*((r[-1]-i)//2)}+{"E"*i}+{"B"*((r[-1]-i)//2)}' for i in r[:-1]) + \
f'\n+{"E"*r[-1]}+\n'+'\n'.join(f'{"C"*((r[-1]-i)//2)}+{"E"*i}+{"D"*((r[-1]-i)//2)}' for i in r[:-1][::-1])
return f'{t}\n{body}\n{b}'
def diamond(d):
return {1:lambda _:'+', 2:lambda _:'A+B\n+E+\nC+D'}.get(d, make_pattern)(d)
print(diamond(3))
print('-'*5)
print(diamond(4))
Output:
AA+BB
A+E+B
+EEE+
C+E+D
CC+DD
-----
AAA+BBB
AA+E+BB
A+EEE+B
+EEEEE+
C+EEE+D
CC+E+DD
CCC+DDD

python: codingbat no_teen_sum - why my function isn't working as expected?

Below is the code I used for the no_teen_sum and subsequent fixed_teen functions.
The first code is what I submitted - and worked for all test cases:
def no_teen_sum(a, b, c):
# checks if value is a teen then child conditional checks whether
# fix_teen passes the value, otherwise initialize the value as 0
if 13 <= a <= 19:
if fix_teen(a):
a = a
else:
a = 0
if 13 <= b <= 19:
if fix_teen(b):
b = b
else:
b = 0
if 13 <= c <= 19:
if fix_teen(c):
c = c
else:
c = 0
return a + b + c
And the fix_teen function that is called:
def fix_teen(n):
# checks if n is 15 or 16 but checking if it is found in the set
# written this way to be expandable without becoming verbose
if n in {15, 16}:
return True
However, looking at this I saw a lot of repitition and realized maybe I had misread what the question was asking. It was valid in terms of finding a solution but not as clean as it could be. So I tried to work on an improvement.
Improved code:
def no_teen_sum(a, b, c):
fix_teen(a)
fix_teen(b)
fix_teen(c)
return a + b + c
And the modified fix_teen function:
def fix_teen(n):
# checks if n is a teen
if 13 <= n <= 19:
# checks if n is 15 or 16 but checking if it is found in the set
# if True then leave n as it is
if n in {15, 16}:
n = n
return n
# if it fails then n = 0
else:
n = 0
return n
# if n is not in the teens return it as is
return n
The issue I am having for example a test case of (1, 2, 18) is that it returns 21. It should return 3. I tried putting print statements in between each 'fix_teen' call in the main function to see what value it had for a, b, c and it just left them as is (1, 2, 18) rather than (1, 2, 0)
The weird part is if I called fixed_teen(18) independently it returns 0.
Your no_teen_sum(a, b, c) function is returning a + b + c (which is literally what gets passed to the function)! You should make a, b and c equal to the result from the fix_teen function to get the desired result!
def no_teen_sum(a, b, c):
a = fix_teen(a)
b = fix_teen(b)
c = fix_teen(c)
return a + b + c
def no_teen_sum(a, b, c):
return print(fix_teen(a) + fix_teen(b) + fix_teen(c))
def fix_teen(n):
if n in (13, 14, 17, 18, 19):
return 0
return n
no_teen_sum(1, 2, 3)
no_teen_sum(2, 13, 1)
no_teen_sum(2, 1, 14)
def no_teen_sum(a, b, c):
return fix_teen(a) + fix_teen(b) + fix_teen(c)
def fix_teen(n):
teen = [13, 14, 17, 18, 19]
if n in teen :
return 0
else:
return n

How to find the number of times function f is executed?

The function f is defined as such:
def f(a, b):
if a <= 0 or b <= 0:
return a + b
else:
s = 0
if b * b % (a + b) != 0:
s += f(a, b - 3)
if a * a % (a + b) != 0:
s += f(a - 2, b)
if a == b - 1:
s += f(a - 3, b - 2)
return s
The question is: "How many times will a function "f" be executed, given f(4, 9)?" For example, for f(0, 0) function "f" will be executed once, since the first time is taken into account as well. Can someone explain to me, how I can find the number of executions? (Examples will be ideal.) Than you in advance!
You can attach an attribute to the function:
def f(a, b):
f.num += 1
if a <= 0 or b <= 0:
...
Result:
>>> f.num = 0
>>> f(0, 0)
0
>>> print(f.num)
1
>>> f.num = 0
>>> f(3, 5)
4
>>> print(f.num)
13
You can increment a global counter, an int wrapped in a list, incrementing it in the function and printing the result after you call it:
i = [0]
def f(a, b):
i[0] += 1
if a <= 0 or b <= 0:
return a + b
else:
s = 0
if b * b % (a + b) != 0:
s += f(a, b - 3)
if a * a % (a + b) != 0:
s += f(a - 2, b)
if a == b - 1:
s += f(a - 3, b - 2)
return s
f(2, 34)
print(i[0])
I don't trust Global variable because of the highly available scope i.e. global variables are accessible to everyone. Instead, you can keep a recursion variable which counts the number of times the function has been called.
def f(a, b, count=0):
count+=1
if a <= 0 or b <= 0:
return [a + b, count]
else:
s = 0
if b * b % (a + b) != 0:
l = f(a, b - 3,count)
s += l[0]
count+=l[1]
if a * a % (a + b) != 0:
l = f(a - 2, b, count)
s += l[0]
count+=l[1]
if a == b - 1:
l = f(a - 3, b - 2, count)
s += l[0]
count+=l[1]
return [s,count]

Error in for loop. (Finding three integers)

So, our teacher gave us an assignment to find three integers a, b c. They are in all between 0 and 450 using Python.
a = c + 11 if b is even
a = 2c-129 if b is odd
b = ac mod 2377
c = (∑(b-7k) from k = 0 too a-1) +142 (Edited. I wrote it wrong. Was -149)
I tired my code that looks like this: (Still a newbie. I guess a lot of my code is wrong)
for a, b, c in range(0, 450):
if b % 2 == 0:
a = c + 11
else:
a = 2 * c - 129
b = (a * c) % 2377
c = sum(b - 7 * k for k in range(0, a - 1))
but I get the error:
for a, b, c in range(0, 450):
TypeError: 'int' object is not iterable
What am I doing wrong and how can I make it check every number between 0 and 450?
The answers by Nick T and Eric hopefully helped you solve your issue with iterating over values of a, b, and c. I would like to also point out that the way you're approaching this problem isn't going to work. What's the point of iterating over various values of a if you're going to re-assign a to something anyway at each iteration of the loop? And likewise for b and c. A better approach involves checking that any given triple (a, b, c) satisfies the conditions given in the assignment. For example:
from itertools import product, tee
def test(a, b, c):
flags = {'a': False,
'b': False,
'c': False}
if (b % 2 == 0 and a == c+11) or (b % 2 == 1 and a == 2*c-129):
flags['a'] = True
if b == (a * c) % 2377:
flags['b'] = True
if c == sum(b - 7*k for k in range(a-1)) - 149:
flags['c'] = True
return all(flags.values()) # True if zero flags are False
def run_tests():
# iterate over all combinations of a=0..450, b=0..450, c=0..450
for a, b, c in product(*tee(range(451), 3)):
if test(a, b, c):
return (a, b, c)
print(run_tests())
NOTE: This is a slow solution. One that does fewer loops, like in glglgl's answer, or Duncan's comment, is obviously favorable. This is really more for illustrative purposes than anything.
import itertools
for b, c in itertools.product(*[range(450)]*2):
if b % 2 == 0:
a = c + 11
else:
a = 2 * c - 129
derived_b = (a * c) % 2377
derived_c = sum(b - 7 * k for k in range(0, a - 1))
if derived_b == b and derived_c == c:
print a, b, c
You need to nest the loops to brute-force it like you are attempting:
for a in range(451): # range(450) excludes 450
for b in range(451):
for c in range(451):
...
It's very obviously O(n3), but if you want a quick and dirty answer, I guess it'll work—only 91 million loops, worst case.
The stuff with [0, 450] is just as a hint.
In fact, your variables are coupled together. You can immediately eliminate at least one loop directly:
for b in range(0, 451):
for c in range(0, 451):
if b % 2: # odd
a = 2 * c - 129
else:
a = c + 11
if b != (a * c) % 2377: continue # test failed
if c != sum(b - 7 * k for k in range(a)): continue # test failed as well
print a, b, c
should do the job.
I won't post full code (after all, it is homework), but you can eliminate two of the outer loops. This is easiest if you iterate over c.
You code should then look something like:
for c in range(451):
# calculate a assuming b is even
# calculate b
# if b is even and a and b are in range:
# calculate what c should be and compare against what it is
# calculate a assuming b is odd
# calculate b
# if b is odd and a and b are in range:
# calculate what c should be and compare against what it is
Extra credit for eliminating the duplication of the code to calculate c
a = c + 11 if b is even
a = 2c-129 if b is odd
b = ac mod 2377
c = (∑(b-7k) from k = 0 to a-1) +142
This gives you a strong relation between all 3 numbers
Given a value a, there are 2 values c (a-11 or (a+129)/2), which in turn give 2 values for b (ac mod 2377 for both values of c, conditioned on the oddity of the result for b), which in turn gets applied in the formula for validating c.
The overall complexity for this is o(n^2) because of the formula to compute c.
Here is an implementation example:
for a in xrange(451):
c_even = a - 11
b = (a*c_even) % 2377
if b % 2 == 0:
c = sum(b - 7 * k for k in range(a)) + 142
if c == c_even:
print (a, b, c)
break
c_odd = (a+129)/2
b = (a*c_odd) % 2377
if b % 2 == 1:
c = sum(b - 7 * k for k in range(a)) + 142
if c == c_odd:
print (a, b, c)
break

Categories