distance formula in python bug - python

I'm calculating the length of a line segment in python, but I don't understand why one piece of code gives me zero and the other gives the right answer.
This piece of code gives me zero:
def distance(a, b):
y = b[1]-a[1]
x = b[0]-a[0]
ans=y^2+x^2
return ans^(1/2)
This one gives me the right answer:
import math as math
def distance(a, b):
y = b[1]-a[1]
x = b[0]-a[0]
ans=y*y+x*x
return math.sqrt(ans)
Thank you.

In your first snippet you have written this:
ans^(1/2)
In Python the power operator is not ^, that's the XOR-operator. The power operator in Python is **. On top of that, in Python 2.x by default the result of the division of two integers is an integer, so 1/2 will evaluate as 0. The correct way would be this:
ans ** 0.5
And another thing, the function you have implemented here can be done a lot easier with math.hypot:
import math
def distance(a, b):
return math.hypot(b[0] - a[0], b[1] - a[1])

Try doing x**2 rather than x^2 ( which is XOR)
Or use the math.pow function
And also, 1/2 is 0 and not 0.5

Related

How to turn this code into a one-liner or make it shorter?

I am a middle school student and just started learning about functions. This code is about exponents, but I cannot use import math. Is there a way to make this code into a one-liner or make it shorter?
def power(a, n):
x = 1
if n == 0:
print(1)
elif n > 0:
for i in range(n):
x = x * a
else:
for i in range(-n):
x = x * a
return x
print(power(2, 5))
You can use the pow function instead of "x = x * a". Also even if you don't want to use that function, you can simplify it as "x *= a".
You could look into recursive functions, they are a bit tricky at first but are a good brain exercise.
A recursive power function would look like that :
def power(a, n):
if n == 0:
return 1
elif n == 1:
return a
else:
return a * power(a, n-1)
You can use the in-built operator **.
Example:
print(2**2) # Will return 4
Use the ** operator directly:
print(2 ** 5)
You can use this
**
which will return the value of 4 to the power of 3 (same as 4 * 4 * 4):
You can use ** This is an exponentiation operator.
def power(a, n):
return a**n
print(power(2, 5))
or simply use lambda function. You can read about it here.
print((lambda x,y:x**y)(2,5))
If you want to shorten your function with one line, you can use lambda statements like this: Shortening code with lambda statement in python
And you can use the ** builtin operator in place of multiplying the number over and over in a loop. So for example, 5**4 is equivalent to 5 * 5 * 5 * 5 and will give the exact same output.
P.S. I am also just beginning with programming, so I might not have the best answer.
If the goal is to use your own function. You can shorter an if with:
value_when_true if condition else value_when_false;
Putting a simple if-then-else statement on one line
I can see your overall need is to get the power of x.
If you can't use import math, then go with the inbuilt arithmetic operator for exponential that is **
Ex. You need 5 to the power 4 then code will be
print(5**4) # In one line
def power(b,n):
n=abs(n)
print(b**n)
print(power(2,-5))
well how about this here you can use the abs function to convert negative number to positive so no need for extra code simple use of ** can do everything

how can write this formula in python?

how can i write a function that takes 2 integer parameters, a and b.
Inside the function I need calculate the value of x using the formula below (where the term 2a indicates that 2 is multiplied by a).
I'm quite lost with doing this can someone please give me a hint on how to start this code in python?
You can use the below method to achieve your goal.
# remember to import math
x = lambda a, b: (math.sqrt(b**2 - 1) + b)/(2 * a)
Now you can use this function:
x(5, 10) # gives 1.99498743710662 (roughly)
Here is how:
def x(a, b):
return (b+(b**2-1)**0.5)/(2*a)
In python, we use ** for power symbols.

How can I use sympy to find the error in approximation of a definite integral?

Our assignment is to use sympy to evaluate the exact definite integral of a function and then compare it with the approximation of the definite integral obtained from another python function we wrote. With simple polynomial functions my code works fine, but with a complicated sine function it keeps either breaking or returning nan.
from numpy import *
def simpson(f,a,b,n):
if n<=0 or n%2!=0:
print('Error: the number of subintervals must be a positive even number')
return float('NaN')
h = float(b - a) / float(n)
x = arange(a,b+h,h)
fx = f(x)
fx[1:n:2] *= 4.0
fx[2:n:2] *= 2.0
return (h/3.)*sum(fx)
this is in one file (simpandtrap) and gives the approximation for the definite integral of f from a to b using a simpson's rule approximation with n subintervals
from pylab import *
def s(x):
return x*sin(3./(x+(x==0)))
This is the function giving me trouble, in a file called assignment8functions
import assignment8functions as a
import SimpAndTrap as st
import sympy as sp
x = sp.symbols('x')
Exact_int_q = sp.integrate(a.q(x),(x,0,2)).evalf(25)
Exact_int_s = sp.integrate(x*sp.sin(3./(x)),(x,0,2)).evalf(25)
q(x) is another function we're supposed to use that everything works fine for - it's just a polynomial. When I try to do the integration the same way it breaks, so I had to put the function for s(x) directly into the call instead of importing the one from the other file
n = a.array([10,100,1000,10000,10000,1000000])
s_error_simp_array = a.zeros(6)
for i in a.arange(6):
s_error_simp_array[i] = abs(Exact_int_s - st.simpson(a.s,0,2,n[i])
here I try to find the error in the approximation. the problem is first of all that Exact_int_s is apparently -4.5*Si(zoo) + 8.16827746848576, and I have no idea what that's supposed to mean, and also that the simpson function always returns nan.
I know it's a lot of words and code, but does anybody know what's wrong?
To avoid the answer -4.5*Si(zoo)+ 8.--- just start the integration at a small positive number, e.g.:
x = sp.Symbol('x')
print sp.integrate( x * sin(3./x), (x, 0.000001, 2) )
and you'll get an answer like 1.0996940...
You can justify this because |s(x)| <= x for small x, so the interval [0, epsilon] can't contribute that much.
Btw - your simpson implemention seems to check out.

Why is sin(180) not zero when using python and numpy?

Does anyone know why the below doesn't equal 0?
import numpy as np
np.sin(np.radians(180))
or:
np.sin(np.pi)
When I enter it into python it gives me 1.22e-16.
The number π cannot be represented exactly as a floating-point number. So, np.radians(180) doesn't give you π, it gives you 3.1415926535897931.
And sin(3.1415926535897931) is in fact something like 1.22e-16.
So, how do you deal with this?
You have to work out, or at least guess at, appropriate absolute and/or relative error bounds, and then instead of x == y, you write:
abs(y - x) < abs_bounds and abs(y-x) < rel_bounds * y
(This also means that you have to organize your computation so that the relative error is larger relative to y than to x. In your case, because y is the constant 0, that's trivial—just do it backward.)
Numpy provides a function that does this for you across a whole array, allclose:
np.allclose(x, y, rel_bounds, abs_bounds)
(This actually checks abs(y - x) < abs_ bounds + rel_bounds * y), but that's almost always sufficient, and you can easily reorganize your code when it's not.)
In your case:
np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds)
So, how do you know what the right bounds are? There's no way to teach you enough error analysis in an SO answer. Propagation of uncertainty at Wikipedia gives a high-level overview. If you really have no clue, you can use the defaults, which are 1e-5 relative and 1e-8 absolute.
One solution is to switch to sympy when calculating sin's and cos's, then to switch back to numpy using sp.N(...) function:
>>> # Numpy not exactly zero
>>> import numpy as np
>>> value = np.cos(np.pi/2)
6.123233995736766e-17
# Sympy workaround
>>> import sympy as sp
>>> def scos(x): return sp.N(sp.cos(x))
>>> def ssin(x): return sp.N(sp.sin(x))
>>> value = scos(sp.pi/2)
0
just remember to use sp.pi instead of sp.np when using scos and ssin functions.
Faced same problem,
import numpy as np
print(np.cos(math.radians(90)))
>> 6.123233995736766e-17
and tried this,
print(np.around(np.cos(math.radians(90)), decimals=5))
>> 0
Worked in my case. I set decimal 5 not lose too many information. As you can think of round function get rid of after 5 digit values.
Try this... it zeros anything below a given tiny-ness value...
import numpy as np
def zero_tiny(x, threshold):
if (x.dtype == complex):
x_real = x.real
x_imag = x.imag
if (np.abs(x_real) < threshold): x_real = 0
if (np.abs(x_imag) < threshold): x_imag = 0
return x_real + 1j*x_imag
else:
return x if (np.abs(x) > threshold) else 0
value = np.cos(np.pi/2)
print(value)
value = zero_tiny(value, 10e-10)
print(value)
value = np.exp(-1j*np.pi/2)
print(value)
value = zero_tiny(value, 10e-10)
print(value)
Python uses the normal taylor expansion theory it solve its trig functions and since this expansion theory has infinite terms, its results doesn't reach exact but it only approximates.
For e.g
sin(x) = x - x³/3! + x⁵/5! - ...
=> Sin(180) = 180 - ... Never 0 bout approaches 0.
That is my own reason by prove.
Simple.
np.sin(np.pi).astype(int)
np.sin(np.pi/2).astype(int)
np.sin(3 * np.pi / 2).astype(int)
np.sin(2 * np.pi).astype(int)
returns
0
1
0
-1

Floating point precision in Python

I have written this function in python:
import math
def radical(a, b, k):
return (1-((a**2-b**2)/a**2)*(math.sin(math.pi*(2*k-1)/180))**2)**.5
def f(a, b):
sigma = 0
for k in range(1,180/4):
sigma = sigma + radical(a, b, k)
return 8*a*math.sin(math.pi/180)*sigma
print f(25.,35.)
When I calculate this function in Wolphramapha and Maple I will get 189.797 but with python I will get 184.91089913
What is the problem in my program?
You are off by one. The range method excludes the end point. Try adding one:
for k in range(1,180/4 + 1):
Result: 189.797208409
Well, first of all, python assumes integer division, so there is some serious round off in this code. I believe there is an import in division for this. Also, Here is some information on python's floating point arithmetic issues/problems:
http://docs.python.org/2/tutorial/floatingpoint.html

Categories