i m new to python and its great!. but i m facing difficulties in finding the result of this series:
1-x+(x^2)/2!-(x^3)/3!+(x^4)/4!-..............up to n terms
what i wrote was:
import math
a=input("ENter the no")
x=input("ENter value of x")
i=1
s=0
s1=0
s2=1
p=1
while(i<=a):
if(i%2!=0):
s=s-math.pow(x,i)/p*i
else:
s1=s1+math.pow(x,i)/p*i
i=i+1
else:
s2=s2+s1+s
print s2
please let me know of the correct program and the mistakes:)!! Thanks in advance.
let me know it without directly using the factorial function?
This is the Taylor's series development of exp(-x). Recognizing this gives you a good opportunity to check your result against math.exp(-x).
Simple syntax improvements
You don't need an 'else' after the while. Just add the code to be run after the loop at the same indentation level as before the while loop.
Mathematical problems
Most importantly, the computing of the factorial is simply never done. Writing p*i does not store in p the product of p and i. You need to do that.
Then, there is a problem with the operator precedence. When you write pow(...)/p*i, Python understands ( pow(...) / p ) * i, which is not what you mean.
Finally, most of the terms in the series cancel out, but you add all positive terms on one side and all negative terms on the other. This means that you will grow two very big values (and risk overflows if you were using integers), and then take the difference between them to get the result. Because double precision on a computer is finite, this is a bad practice precision-wise. It is better to keep all the terms in your sum with the same sort of orders of magnitudes.
Improved for correctness
import math
a=input("Enter the no")
x=input("Enter value of x")
s=1
p=1
for i in range(1,a):
p=p*i
if(i%2!=0):
s=s-math.pow(x,i)/p
else:
s=s+math.pow(x,i)/p
print s
print math.exp(-x)
Note how the use of a for loop and less intermedis-ry sums makes it all easier to read.
Removing the branch
pow(-x,i) is negative if i is uneven, positive otherwise. Thus -pow(x,i) if i%2 != 0 else pow(x,i) can be rewritten pow(-x,i). Removing an if in an inner loop is (almost ?) always a good thing, for performance. So a simplified version is :
import math
a=input("Enter the no")
x=input("Enter value of x")
s=1
p=1
for i in range(1,a):
p=p*i
s=s+math.pow(-x,i)/p
print s
print math.exp(-x)
That also has the benefit of making the code shorter (and thus more readable).
import math #imported to use the factorial function
def exp(x,n):
ans = 1 #initializing it with 1 because the first term is a constant:1
for i in xrange(1,n+1): #starts looping from 1 to n terms
ans+=(-1**i*(float(x)**i)/math.factorial(i)) #changing the sign of 1, adding.
# -1**i equals to 1 if i is even and -1 if i is odd
# ** operator stands for the pow() function , (2**3 =8)
# float(x) returns a floating value if value of x entered is integer
# You can remove this is you are already entering floating values.
# math.factorial() returns factorial of a given argument,
return ans
If you don't want to use the math.factorial() then you can try :
def exp(x,n):
ans = 1
dummy_factorial = 1
for i in xrange(1,n+1):
dummy_factorial*=i
print dummy_factorial
ans+=(-1**i*(float(x)**i)/(dummy_factorial))
return ans
Related
I'm trying to become comfortable with python. I've been trying some simple activities that I've given in my beginning c++ classes when I was teaching. I did one involving functions and writing a file which worked flawlessly. I thought this one would be easier. It acts like it is in a silent endless loop, but it won't even let me trace it. Can someone see where I am going awry?
# Find Adam Numbers
def isAdamNumber(candidate):
isAdam = False
rev = reverse(candidate)
square = candidate * candidate
revsq = rev*rev
if revsq == reverse(square):
isAdam = True
return isAdam
def reverse(num):
rev=0
while num > 0:
rev = rev * 10 + num%10
num/=10
return rev
for x in range (11,25):
if isAdamNumber(x):
print(x, " is an adam number\n")
The quick fix is to change /= with the integer division version, //=
Inside the reverse function, you are going into an infinite loop. num value always will be greater than 0, therefore the while loop will continuously run. In python, you can get the reverse of the function without much effort. Convert the integer to string and reverse the string and now change the string back to integer.
def reverse(num):
num_str = str(num)[::-1]
return int(num_str)
I think this function definition can solve your problem.
To visualize the python to learn and teach, use this link
The problem has already been addressed by the other answers, so here's the expanded and simplified version of the slicing that's going on [this doesn't actually use slicing]:
def reverse(num):
rev = ''
num = str(num)
for i in range(len(num) - 1, -1, -1):
rev += num[i]
return int(rev)
This counts backward from the last element in the string version of num, and adds all the elements of num (in reverse order) to rev.
num > 0 is never False. Dividing a positive number by 10 repeatedly makes it smaller, but it never becomes zero, so the while loop keeps repeating.
Use //= instead. It rounds to the nearest integer, so it will reach 0.
This also wouldn't reverse numbers (unless I'm missing something). Alternatively, you can use
int(str(num)[::-1])
which converts the number to a string, reverses it using slicing, and turns it back into an integer.
I'm receiving a "maximum recursion depth exceeded" error when executing my program to solve this problem. Project Euler's question #5 asks to find:
The smallest positive number that is evenly divisible by all of the numbers from 1 to 10.
I've tried to write a program that recursively checks if x is divisible by each integer 1-10, and if it doesn't then we call it again with x incremented by 1 and repeat until x is found. (In this case the answer is 2520, which is why I added the if statement.)
def euler5(x):
if x < 2521:
for i in range(1, 11):
if x % i == 0:
print(x)
else:
euler5(x+1)
else:
print(x)
x = 2
print(euler5(x))
The reason for this is that Python (or CPython, at least) has a limited stack size and no tail call optimization. So you cannot use unbounded recursion in Python, unlike Scheme (for example).
The solution is to use a regular loop:
x = 0
while True:
x += 1
# Put loop body here
In you defined function, you could you a loop even if you do not know math functions. However, your code is not efficient as program has to keep checking the values to see if it matches the condition. Recursion is not recommended as it should be flexible to be used with other values not just for this question. Euler questions are meant to train your coding practices.
A better method can be used to simplify your code:
from functools import reduce
from fractions import gcd
def lcm(a,b):
return a*b//gcd(a,b) #gcd is greatest common divisor AKA HCF
print (reduce(lcm, range(1, 20+1)))
Can someone explain why this code works with the sample number 13195, but crashes when I use the problem's number
num = 13195
def isprime(num):
for i in range(2,num):
if num % i == 0:
ans = i
return ans
print isprime(isprime(isprime(num)))
In Python 2, range constructs a list. So the program is trying to contain an enormous list in memory, and it can't. Use xrange which will generate the numbers on demand for iteration instead of all at once.
You also need to end the loop early or it will spend forever checking so many numbers. So once you find a divisor, use it to divide the original number and make it smaller and thus manageable.
You need to assign a default value to ans.
When the input number is a prime number, the program never assigns anything to the variable ans. So that, when the function tries to return that variable, it is not actually defined.
print "------------ EPIDEMIOLOGY --------------\n"
def divide(A,B):
return A/B
print " [Population] point Prevalence rate: "
A = input("Enter value for people with disease: " )
B = input("Enter value for total population: " )
prevalence = divide(A,B)
print " Population Prevalence rate is: ",prevalence
A and B are user input and do not know if they are integers or floats. My answer is always 0 when i run this program. (I'm new in Python). How do i fix this or change in my function to avoid this problem?
the input part of code works, the math does not.
You get the answer 0 because you are using Python2 and performing integer division. The fact that the population with disease cannot be higher than the total population is the reason that you get zero for every reasonable input (except when both values are the same).
Two fixes:
def divide(a,b):
if b == 0:
# decide for yourself what should happen here
else:
return float(a)/b
This will make sure that your function performs floating point division, not matter what numbers you pass to it. The second fix is that you should use raw_input in Python2 and cast the input to a number (float would be fine here).
a = float(raw_input("Enter value for people with disease: ")) # add error checking as needed
b = float(raw_input("Enter value for total population: " )) # add error checking as needed
The problem with input() is that it is equivalent to eval(raw_input()).
In python 2.x is performed integer division. If dividend is less than divisor, the operation returns zero.
So you have two options:
Make one of operands as float:
def divide(A,B):
return float(A)/B
import feature from Python 3
from __future__ import division
print "------------ EPIDEMIOLOGY --------------\n"
def divide(A,B):
return A/B
I am trying to do project euler problem 4 using python. The problem statement goes like this:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I wrote down a solution for it:
s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
while z>=1:
s=s*10+z%10
z=z/10
if z==s:
list.append(z)
while x<=999:
while y<=999:
palindrome()
y=y+1
x=x+1
y=100
print list
It ended up giving an error along the lines of 'z referenced beyond assignment'.
I searched for a solution to this error before finally deciding to use the syntax 'global' to bypass this error.
s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
global z
global s
global x
global y
global list
while z>=1:
s=s*10+z%10
z=z/10
if z==s:
list.append(z)
while x<=999:
while y<=999:
palindrome()
y=y+1
x=x+1
y=100
print list
Now it doesn't give an error, but it gives an empty list as output. I tried to debug the code by inserting print statements in between. The loops appear to work fine, as 'x' and 'y' print all the values they are supposed to. However, I get an empty list as an output to the print list command and 'z' does not apparently change values and is stuck at 100000 despite me using while loops to change the values of x and y.
I am at a loss on how to proceed from here.
The error you got was probably:
UnboundLocalError: local variable 'z' referenced before assignment
This means that z was not defined, at least not within the palindrome() function. Your solution of adding the global keyword is technically correct. However, as others have pointed out already, use of globals makes the code hard to follow.
It's not clear to me what palindrome() is supposed to do. Is it supposed to check if a number is a palindrome? Generate palindrome numbers? To fix this problem, you should think about structuring your code. There are many ways to do this, of course, and with time you will find your own style.
My advice, then, is to think about how you would solve this in general. If you don't know the solution, coding won't help you. Sometimes, when solving problems like this one, I write functions without declaring their bodies. You can do this top-down or bottom-up, both work. For example:
def is_palindrome(n):
""" Check if n is a palindrome number. """
pass
def multiples_of_3_digits():
""" Return all numbers that are the product of two 3-digit numbers ."""
pass
def main():
print max(n for n in multiples_of_3_digits() if is_palindrome(n))
This way you can focus on solving the problem, then on the actual coding. Maybe you will add helper functions or realize you can solve the problem in a more efficient way, but it's a start. Good luck!
min=100
max=999
max_palindrome = 0
for a in range(min,max + 1):
for b in range(a + 1, max + 1):
prod = a*b
if prod > max_palindrome and str(prod)==(str(prod)[::-1]):
max_palindrome = prod
print max_palindrome
Here we are only concerned with the maximum palindrome, and so we don’t spend any time storing other palindromes once they are known to be non-maximum. Also, the if statement first checks if the given product is larger than the maximum known palindrome before using the string cast and list slice to check whether or not the number is even a palindrome. This should speed up our code a bit since the greater than comparison will often fail, regardless of whether the product in question is a palindrome. When we run this, we get the following.
906609
Alternate Way:
I would discourage you to use the global variables because of the reasons pointed out by others. I would also like you to refer to Andre's approach as it will teach you to organize yourself. In this approach too I will be using 2 functions is_palindrome(num) [to check if the number is palindrome or not] and find_max_palindrome [to find the largest palindrome]
def is_palindrome(num):
reversed = 0
original = num
if num < 10:
return True
if num % 10 == 0:
return False
while num >= 1:
reversed = (reversed * 10) + (num % 10)
num = num/10
if original == reversed:
return True
else:
return False
def find_max_palindrome():
max_palindrome = 0
a = 999
b = 999
prod = 0
while a > 99:
b = 999
while b >= a:
prod = a*b
if prod > max_palindrome and is_palindrome(prod):
max_palindrome = prod
b = b -1
a = a - 1
return max_palindrome
print find_max_palindrome()