Why does recursive sequence not work correctly? - python

I'm totally new to Python and I'm trying to print the solution for a recursive sequence:
#Input sequence variables
a = float(raw_input("type in a = "))
n0 = int(raw_input("type in n_0 = "))
n1 = int(raw_input("type in n_1 = "))
y0 = float(raw_input("type in y_0 = "))
#Define function y_n (forward iteration)
def yn(n):
if (n==0):
return y0
else:
return (1/n)-a*yn(n-1)
#backward iteration
def yn_back(n):
return (1/a)*((1/n)-yn(n-1))
if(n1>=n0):
for i in range(n0,n1+1):
print(yn(i))
else:
for i in range(n0,n1+1):
print(yn_back(i))
But if I run this script with a=5, n0=1, n1=30 and y0=log(5/6)=0.182322 the solutions are very high (from 0.08839 to 3.29e+18) and the values are negative for even n. The solution is right for n=1. For other n, the (1/n) in the definition of yn(n) seems to be ignored.
Can someone help me?
Thanks a lot!

n is probably an integer, so 1/n is returning 0 for n greater than 1:
>>> 1/1
1
>>> 1/2
0
>>> 1.0/2
0.5
To make sure you're using float division, change 1 to 1.0 wherever you calculate 1/n:
(1.0/n)
Or convert n into a float.

Related

Sum of all prime numbers between 1 and N in Python

I'm new to programming. While trying to solve this problem, I'm getting the wrong answer. I checked my code a number of times but was not able to figure out the mistake. Please, help me on this simple problem. The problem is as follows:
Given a positive integer N, calculate the sum of all prime numbers between 1 and N (inclusive). The first line of input contains an integer T denoting the number of test cases. T testcases follow. Each testcase contains one line of input containing N. For each testcase, in a new line, print the sum of all prime numbers between 1 and N.
And my code is:
from math import sqrt
sum = 0
test = int(input())
for i in range(test):
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(max)) + 1
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
print(sum)
For input 5 and 10, my code is giving output 6 and 48 respectively, while the correct answer is 10 and 17 respectively. Please, figure out the mistake in my code.
Here, I implemented simple program to find the sum of all prime numbers between 1 to n.
Consider primeAddition() as a function and ip as an input parameter. It may help you to solve your problem.Try it.
Code snippet:
def primeAddition(ip):
# list to store prime numbers...
prime = [True] * (ip + 1)
p = 2
while p * p <= ip:
# If prime[p] is not changed, then it is a prime...
if prime[p] == True:
# Update all multiples of p...
i = p * 2
while i <= ip:
prime[i] = False
i += p
p += 1
# Return sum of prime numbers...
sum = 0
for i in range (2, ip + 1):
if(prime[i]):
sum += i
return sum
#The program is ready... Now, time to call the primeAddition() function with any argument... Here I pass 5 as an argument...
#Function call...
print primeAddition(5)
This is the most broken part of your code, it's doing the opposite of what you want:
res = x%y
if res==0:
sum = sum + x
break
You only increment sum if you get through the entire loop without breaking. (And don't use sum as you're redefining a Python built-in.) This can be checked using the special case of else on a for loop, aka "no break". I've made that change below as well as corrected some inefficiencies:
from math import sqrt
T = int(input())
for _ in range(T):
N = int(input())
sum_of_primes = 0
if N < 2:
pass
elif N == 2:
sum_of_primes = 2
else:
sum_of_primes = 2
for number in range(3, N + 1, 2):
for odd in range(3, int(sqrt(number)) + 1, 2):
if (number % odd) == 0:
break
else: # no break
sum_of_primes += number
print(sum_of_primes)
OUTPUT
> python3 test.py
3
5
10
10
17
23
100
>
A slight modification to what you have:
from math import sqrt
sum = 0
test = int(input())
max = int(input())
for x in range(test,max+1):
if x == 1:
pass
else:
half = int(sqrt(x)) + 1
for y in range(2,half):
res = x%y
if res==0:
break
else:
sum = sum + x
print(sum)
Your biggest error was that you were doing the sum = sum + x before the break rather than outside in an else statement.
PS: (although you can) I'd recommend not using variable names like max and sum in your code. These are special functions that are now overridden.
Because your logic is not correct.
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
here you check for the factors and if there is a factor then adds to sum which is opposite of the Primes. So check for the numbers where there is no factors(except 1).
from math import sqrt
test = int(input())
for i in range(test):
sum = 0
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(x)) + 1
if all(x%y!=0 for y in range(2,half)):
sum = sum + x
print(sum)
First of all, declare sum to be zero at the beginning of the for i loop.
The problem lies in the if statement at almost the very end of the code, as you add x to the sum, if the res is equal to zero, meaning that the number is indeed not a prime number. You can see that this is the case, because you get an output of 6 when entering 5, as the only non-prime number in the range 1 to and including 5 is 4 and you add 2 to the sum at the beginning already.
Last but not least, you should change the
half = int(sqrt(max)) + 1
line to
half = int(sqrt(x)) + 1
Try to work with my information provided and fix the code yourself. You learn the most by not copying other people's code.
Happy coding!
I believe the mistake in your code might be coming from the following lines of code:
for x in range(3,max+1):
half = int(sqrt(max)) + 1
Since you are looping using x, you should change int(sqrt(max)) to int(sqrt(x)) like this:
for x in range(3,max+1):
half = int(sqrt(x)) + 1
Your code is trying to see if max is prime N times, where you should be seeing if every number from 1-N is prime instead.
This is my first time answering a question so if you need more help just let me know.

How to define a variable by an equation containing it? (Python)

I´m solving a problem in which i have to print all the fibonacci numbers such that:
a <= f <= b
And i would like to start them by the smallest fibonacci number that is greater than or equal to a, in order to make my program run faster. For that, i need to define a variable "n", such that the nth Fibonacci number satisfies the condition above (smallest one that is greater than or equal to a). To define such variable, i need to find the smallest "n" that satisfies the fibonacci(n) general term equation.
I tried to find it by making a for loop, but it just ends up being as slow as if i started to check from the first Fibonacci Number. Anyone has any ideas on how to define it efficiently?
P.S. Here is my attempted code:
from math import sqrt, log, ceil
def Fibo(n):
if n == 1: return 1
elif n == 2: return 2
return Fibo(n-1) + Fibo(n-2)
while True:
try:
a, b = [int(i) for i in input().split()]
cont = 0
phi = (sqrt(5) + 1) / 2
i = ceil(log(a * sqrt(5), phi))
if Fibo(i-1) >= a: i -= 1
elif Fibo(n) < a: i += 1
while True:
if a <= Fibo(i) <= b: cont += 1
elif Fibo(i) > b:
break
i -= 1
print(cont)
except input() == "0 0":
break
Probably the most useful formula for your purpose for F(n), the nth Fibonacci number, is
from math import sqrt
phi = (sqrt(5) + 1) / 2 # the golden ratio
F(n) = round(phi**n / sqrt(5))
Therefore, one formula to get the value of n for a given value of a is
from math import sqrt, log, ceil
phi = (sqrt(5) + 1) / 2 # the golden ratio
n = ceil(log(a * sqrt(5), phi))
Due to approximation and rounding issues, you should check the values of n-1, n, and n+1 to ensure you got exactly the desired value. If you do this often, you should pre-define variables holding the value of the golden ratio and of the square root of five. If your value of a is too large for the float type to store it accurately, you would need a more complicated routine to handle the larger number.

Python: Closest Power of Two To Target

I am attempting to find the closest power of two that is greater than or equal to a target value. A for loop must be used to achieve this. However, I am unsure of what to put as the range value so that upon reaching the required value the exponent will stop increasing by i and instead exit the for loop. Thanks for your help.
target = int(input("Enter target number: "))
def power_of_two(target):
x = 2
change = 0
power = 0
for i in range():
number = x ** change
change = i
if number >= target:
power = number
return power
p = power_of_two(target)
print("The closest power of 2 >= {0:d} is {1:d}." .format(target, p))
since you have to use for:
def power_of_two(target):
if target > 1:
for i in range(1, int(target)):
if (2 ** i >= target):
return 2 ** i
else:
return 1
that is assuming you want the value to be greater than or equal to 2^0
I have corrected your code, so that it works. I think you learn best from your mistakes :)
target = int(input("Enter target number: "))
def power_of_two(target):
x = 2
change = 0
power = 0
for i in range(target+1):
# target is okay for this, function terminates anyway
# add one to avoid error if target=0
number = x ** change
change = i
if number >= target: # you had indentation errors here and following
power = number
return power
p = power_of_two(target)
print("The closest power of 2 >= {0:d} is {1:d}." .format(target, p))
You could find a perfect value for the end of the range using logarithm with base 2, but then you wouldn't need the for loop anyway ;)
As a suggestion: maybe take a look at the binary representation of powers of 2. You could use a for loop with bitshifting for this.
EDIT: I had indentation errors myself, because of the weird formatting system here... maybe you haven't had these before :D

Issue with program to approximate sin and cosine values

I'm trying to write a program that takes an angle in degrees, and approximates the sin and cos value based on a number of given terms that the user chooses. In case you don't know
how to find sin and cos. So, with that being said, here is my current code:
import math
def main():
print()
print("Program to approximate sin and cos.")
print("You will be asked to enter an angle and \na number of terms.")
print("Written by ME")
print()
sinx = 0
cosx = 0
x = int(input("Enter an angle (in degrees): "))
terms = int(input("Enter the number of terms to use: "))
print()
for i in range(1, terms+1):
sinx = sinx + getSin(i, x)
cosx = cosx + getCos(i, x)
print(cosx, sinx)
def getSin(i, x):
if i == 1:
return x
else:
num, denom = calcSinFact(i, x)
sin = num/denom
return sin
def getCos(i, x):
if i == 1:
return 1
else:
num, denom = calcCosFact(i, x)
cos = num/denom
return cos
def calcSinFact(i, x):
if i % 2 == 1:
sign = -1
if i % 2 == 0:
sign = +1
denom = math.factorial(i*2-1)
num = sign * (x**(i*2-1))
return num, denom
def calcCosFact(i, x):
if i % 2 == 1:
sign = -1
if i % 2 == 0:
sign = +1
denom = math.factorial(i*2)
num = sign * (x**(i*2))
return num, denom
It runs but if i use the example shown in the picture above, i get cos = -162527117141.85715 and sin = -881660636823.117. So clearly something is off. In the picture above the answers should be cos = 0.50000000433433 and sin = 0.866025445100. I'm assuming it's the way I'm adding together the values in the first loop but i could be wrong. Any help is appreciated!
There are several issues here as pointed out in Russell Borogove's comments.
Issue no 1 is that the formulas you are using
(see wikipedia) expect x to be in radians not degrees. Going once round a circle is 360 degrees or 2*pi, so you can convert from degrees to radians by multipling by pi/180, as shown below in python code to incorrectly and then correctly get the sin of 90 degrees.
>>> math.sin(90)
0.8939966636005579
>>> math.sin(90*math.pi/180)
1.0
Issue no 2 is the rest of the code. As pointed out in the comments, there are some bugs, and the best way to find them would be to use some strategic print statements. However, you could write your program with far fewer lines of code, and simpler programs tend to have fewer bugs and be easier to debug if they do have problems.
As this is an assignment, I won't do it for you, but a related example is the series for sinh(x).
(again from wikipedia)
You can produce the terms in "one shot", using a Python list comprehension. The list can be printed and summed to get the result, as in the program below
x = 90 * math.pi / 180 # 90 degrees
n = 5
terms = [x**(2*i+1)/math.factorial(2*i+1) for i in range(n)]
print terms
sinh = sum(terms)
print sinh, math.sinh(x)
The output of this program is
[1.5707963267948966, 0.6459640975062462, 0.07969262624616703, 0.004681754135318687, 0.00016044118478735975]
2.30129524587 2.30129890231
I produced the Python list comprehension code directly from the mathematical formula for the summation, which is conveniently given in "Sigma" notation on the left hand side. You can produce sin and cos in a similar way. The one missing ingredient you need is the signs at each point in the series. The mathematical formulas tell you you need (-1)n. The Python equivalent is (-1)**n, which can be slotted into the appropriate place in the list comprehension code.
First, a few notes. It's better to print \n at the end of the previous print or at the beginning of the following then empty print().
It's useful to use a debugging tool, use logging module or just use print and find the bug by comparing expected values with returned values.
Here is a code that is working for me:
import math
def main():
print()
print("Program to approximate sin and cos.")
print("You will be asked to enter an angle and \na number of terms.")
print("Written by ME")
print()
sinx = 0
cosx = 0
x = int(input("Enter an angle (in degrees): "))
terms = int(input("Enter the number of terms to use: "))
print()
x = x / 180.0 * math.pi; # added
for i in range(1, terms+1):
sinx = sinx + getSin(i, x)
cosx = cosx + getCos(i, x)
print("Cos:{0}, Sinus:{1}".format(cosx,sinx)); # changed
def getSin(i, x):
if i == 1:
return x
else:
num, denom = calcSinFact(i, x)
sin = float(num)/denom # changed
return sin
def getCos(i, x):
if i == 1:
return 1
else:
num, denom = calcCosFact(i, x)
cos = float(num)/denom # changed
return cos
def calcSinFact(i, x):
if i % 2 == 1:
sign = +1 # changed
if i % 2 == 0:
sign = -1 # changed
denom = math.factorial(i*2-1)
num = sign * (x**(i*2-1))
return num, denom
def calcCosFact(i, x):
if i % 2 == 1:
sign = +1 # changed
if i % 2 == 0:
sign = -1 # changed
denom = math.factorial(i*2-2) # changed
num = sign * (x**(i*2-2)) # changed
return num, denom
And what I have changed? (I hope I won't forget anything)
Your sign variables were wrong. Just the opposite. So I changed the signes in the conditions.
It is perhaps not necessary but I added conversion from int to float when you divided num by denom.
According to the definition of the approximation, the input x is in radians. So I added conversion from degrees to radians. x = x / 180.0 * math.pi;
Your index in calcCosFact was wrong. It was always higher by 2. (i.e. 4 instead of 2, 8 instead of 6...)
I got this result:
Enter an angle (in degrees): 180 Enter the number of terms to use: 5
Cos:-0.976022212624, Sinus:0.00692527070751
It should be correct now. I can also recommend WolphramAlpha when you need to quickly do some math.
Here is an improved version:
from math import radians
import sys
# version compatibility shim
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
rng = xrange
else:
# Python 3.x
inp = input
rng = range
def type_getter(type):
def fn(prompt):
while True:
try:
return type(inp(prompt))
except ValueError:
pass
return fn
get_float = type_getter(float)
get_int = type_getter(int)
def calc_sin(theta, terms):
# term 0
num = theta
denom = 1
approx = num / denom
# following terms
for n in rng(1, terms):
num *= -theta * theta
denom *= (2*n) * (2*n + 1)
# running sum
approx += num / denom
return approx
def calc_cos(theta, terms):
# term 0
num = 1.
denom = 1
approx = num / denom
# following terms
for n in rng(1, terms):
num *= -theta * theta
denom *= (2*n - 1) * (2*n)
# running sum
approx += num / denom
return approx
def main():
print(
"\nProgram to approximate sin and cos."
"\nYou will be asked to enter an angle and"
"\na number of terms."
)
theta = get_float("Enter an angle (in degrees): ")
terms = get_int ("Number of terms to use: ")
print("sin({}) = {}".format(theta, calc_sin(radians(theta), terms)))
print("cos({}) = {}".format(theta, calc_cos(radians(theta), terms)))
if __name__=="__main__":
main()
Note that because the Maclaurin series is centered on x=0, values of theta closer to 0 will converge much faster: calc_sin(radians(-90), 5) is -1.00000354258 but calc_sin(radians(270), 5) is -0.444365928238 (about 157,000 times further from the correct value of -1.0).
One can completely avoid all power and factorial computations by using and combining the recursive definitions of factorial and integer powers. Further optimization is obtained by computing both cos and sin values at once, so that the powers are only computed once.
PI = 3.1415926535897932384;
RadInDeg=PI/180;
def getCosSin(x, n):
mxx = -x*x;
term = 1;
k = 2;
cossum = 1;
sinsum = 1;
for i in range(n):
term *= mxx
term /= k; k+=1
cossum += term
term /= k; k+=1
sinsum += term
return cossum, x*sinsum
def main():
print "\nProgram to approximate sin and cos."
print "You will be asked to enter an angle and \na number of terms."
x = int(input("Enter an angle (in degrees): "))
terms = int(input("Enter the number of terms to use: "))
print
x = x*RadInDeg;
cosx, sinx = getCosSin(x,terms)
print cosx, sinx
if __name__=="__main__":
main()

Logical thinking for a Calculation of Square root

I've been trying to decipher this problem for the last hour right now and having some trouble here. This is the problem
This method for calculating the square root of a number n starts by
making a (non zero) guess at the square root. It then uses the
original guess to calculate a new guess, according to the formula
newGuess = ((n / oldGuess) + oldGuess) / 2.0;
Have two variables oldGuess and newGuess. Initialize oldGuess to
n / 2.0 and calculate newGuess according to the above formula. Use
a while loop to iterate as long as the absolute value of the
difference between the oldGuess and newGuess is greater than
1.0E-06. Do not forget to reset the value of oldGuess to the
newGuess value in the while loop.
In your program you will prompt the user to enter a positive number.
If the number is negative, print an error message and ask the user to
try again. For a positive number, calculate the square root using the
above method. Find the difference between the square root you obtained
and the value obtained from using the exponentiation operator. Write
out the value the user entered, the square root you computed, and the
difference (your square root - n ** 0.5)
This is my program so far
def main():
n = eval(input("Enter a positive number: "))
while (n <= 0):
print ("Error please re-input")
n = eval(input("Enter a positive number: "))
oldGuess = n / 2.0
newGuess = ((n / oldGuess) + oldGuess) / 2.0;
difference = n - n ** 0.5
while (difference < 1 * 10 ** -6):
print ("Error")
difference = abs(n - n ** 0.5)
print ("Difference:", difference)
main()
So I don't really understand how we can tell the program to make a guess and then calculate the square root of variable n. I don't even think my while statements are right in this context. I don't use the already embedded function the squareroot built into python so it has to be done manually I believe still lost on what it means by the guess function.
while True:
n = float(input("Enter a positive number: "))
if n > 0:
break
print ("Error please re-input")
oldGuess = n / 2.0
while True:
newGuess = ((n / oldGuess) + oldGuess) / 2.0;
oldGuess = newGuess
if -1e-6 < n - newGuess * newGuess < 1e-6:
break
print ("Difference:", abs(n ** .5 - newGuess))
Change those eval()s to float()s. eval() executes any code it's handed, so that means your user could type something malicious there.
Now, use this for the second part:
oldGuess = n / 2.0
newGuess = ((n / oldGuess) + oldGuess) / 2.0
while (abs(oldGuess - newGuess) > 1e-06):
oldGuess, newGuess = newGuess, ((n / oldGuess) + oldGuess) / 2.0
print("Guess: " + str(n))
print("My root: " + str(newGuess))
print("Accuracy: " + str(newGuess - (n**0.5)))
That comma syntax is a Python idiom useful for swapping values without having to do:
temp = new
new = old * something
old = temp
Your condition for the while loop is looking to end looping when your difference is less than that (very small) value. So you will loop so long as it is greater than that.
Note: you can also use math.sqrt(n) instead of n ** 0.5. You'll have to import math.
If you want to see what your program is doing, try printing the values of oldGuess and newGuess within the while loop. You'll see it's changing them until you've arrived at your answer.
Edit:
I notice that you seem to be tripped up on why you have to do oldGuess = newGuess. Let me explain: the = operator is not the same as the equals sign in mathematics. The equals sign says that the thing on the left is the same thing as the thing on the right; i.e. they are equivalent. In Python, the = operator says "give the thing on the left the same value as the thing on the right." It is called the assignment operator. You are thinking of the == operator, which tests for equivalency (basically).
>>> a = 10
>>> b = 4
>>> b = a
>>> b
10
>>> a == b
True
>>> c = 6
>>> b = c
>>> b
6
>>> a == b
False
>>> b == c
True
>>> a == c
False
>>> a,b,c
(10, 6, 6)
As you can see, when you use the = operator, you don't "link" the variables together, saying that they are now the same thing. If you set b = a and then set b = c, b == a becomes false because b does not have the same value as a anymore. a does not change either, because b was assigned its value, not the other way around. Think of the = operator looking like <- instead (I think some languages actually use this as the assignment operator).
Why does this matter? Well, you do assign something new to a variable, you forget the old value. Unless you have another variable storing the same value, it's lost forever. Your assignment says to update the oldGuess to the previous newGuess. In other words, if your guesses were "a", "b", "c", "d", then you'd start with oldGuess as "a" and from there compute newGuess as "b". Since this would obviously not be the correct guess, you say the oldGuess is now what the newGuess just was - "b", and you compute the next newGuess, which is "c".
You need the value of oldGuess to compute the value of newGuess. But, you need the value of newGuess (before you changed it) to update the value of oldGuess. It's a catch-22, unless you store the previous value of newGuess as I showed above (as the swapping example). That is why you need this.
So I figured it out thanks guys for help. I didn't know we can't post homework questions on here but I am trying to definitely learn how to code so I can get better at it. Here was my final solution.
def main():
n = float(input("Enter a positive number: "))
while (n <= 0):
print ("Error please re-input")
n = eval(input("Enter a positive number: "))
oldGuess = n / 2.0
newGuess = 0
difference = 10
while (difference >= 1 * 10 ** -6):
newGuess = ((n / oldGuess) + oldGuess) / 2.0
difference = abs(newGuess - oldGuess)
oldGuess = newGuess
print ("Square Root is: ", newGuess)
differenceSqrt = newGuess - n ** 0.5
print ("Difference is: ", differenceSqrt)
main()
I still don't know how to use breaks effectively so thanks gnibbler but couldn't really follow your code too well. (New to this, sorry)

Categories

Resources