x ** 1/3 in python? [duplicate] - python

This question already has answers here:
How to find integer nth roots?
(11 answers)
Closed 7 years ago.
Recently I encountered a problem:
I want to calculate various roots of various numbers like this:
x = x ** 1/y+1
None of the methods I know result in a working code.
Method 1:
x = 54
y = 2
x = x ** 1/y+1
print(x)
Printed value is 28.0 instead of 3.7798
Method 2:
x = 54
y = 2
x = x ** 1/(y+1)
print(x)
Printed value is 18.0 istead of 3.7798
Method 3:
x = 216
y = 2
x = x ** (1/(y+1))
print(x)
Printed value is 5.99 instead of 6
Is there a way that would work with y being up to 20?
Edit:
Another suggested method:
def nth_root(val, n):
ret = int(val**(1./n))
return ret + 1 if (ret + 1) ** n == val else ret
y = 1
print(nth_root(19, (y+1)))
prints 4

Since everyone else has already told you why your Method 3 is correct, I'll stick to getting you an accurate answer. You can read more about why you're not getting exactly 6, but basically it's because your computer doesn't represent the 1/3 exactly when doing the calculation and makes the final answer off.
So, the easiest solution is to use sympy:
import sympy
y = 216
x = 2
x = sympy.root(y,x+1)
print(x)

You don't seem to understand (yet) order of operations in a programming language. You need parentheses to make sure you add 1 to y, then take the reciprocal, and then use that as an exponent. The "natural" order is the opposite.
x = x ** (1.0/(y+1))

What you want is this (assuming you are using Python 3):
x = x ** (1/(y+1))
For Python 2, either of the following will work:
from __future__ import division
x = x ** (1/(y+1))
or (also fine on Python 3):
x = x ** (1.0/(y+1))
The issue is you need to apply the parentheses in the correct locations to get the order of operations right.
Method 3 is to do with floating point arithmetic. See: https://docs.python.org/3.5/tutorial/floatingpoint.html
For more info on Python 2 vs. Python 3 division:
Division in Python 2.7. and 3.3

Only your last code works because ** has higher precedence than / (and / has higher precendence than +).
The value is not exactly 6, because floating point numbers are not perfectly accurate. A third can not be represented as a float.

All your values are just as expected. According to the python operator precedence:
x ** 1/y+1 is parsed as ((x ** 1) / y) + 1, and
x ** 1/(y+1) is actually (x ** 1) / (y + 1).
What you probably want is x ** (1. / (y + 1)). Note, that 1. is a floating point number, causing the whole expression to be evaluated as floats. This also means that you will work with finite precision, e.g., getting 5.99999 instead fo 6 is to be expected.

Related

Python function that can compute cube roots, fourth roots, fifth roots and so on? [duplicate]

This question already has answers here:
What causes my function to return None at the end? [duplicate]
(5 answers)
Closed 1 year ago.
I am trying to make a function root(x, y) where it finds the yᵗʰ root of x.
I have tried to use math.sqrt() here, but it doesn't work.
Here is my code:
def root(x, y):
for i in range(y):
math.sqrt(x)
for i in range(10000):
print(root(i, 2))
And what it gives me:
None
None
None
None
None
and so on...
Please help me solve this problem. 😊
The nth root of x is just x ** (1.0/n), which you can evaluate directly in Python. Examples:
>>> 27 ** (1.0 / 3)
3.0
>>>
>>> 32 ** (1.0 / 5)
2.0
>>>
>>> 10 ** (1.0 / 6)
1.4677992676220695
>>>
In Python 3, you can use 1 / n in place of 1.0 / n, even if n is an integer, but I use 1.0 just to make it clear that it's a floating point divide.
def root(x, y):
return x**(1/y)

When I try to solve a equation python only uses integers

I am working on a new project, it is like a math site. I am trying to create a program that will solve equations.
It is working normally with simple equations for example x + 10 = 12, however when I try to do equations with exponents like x**2 + 3 = 5 it doesn't give me anything. I believe that this python code doesn't work with decimals.
Code in below
import math
def solve():
x = -1000
while x < 1001:
if x**2 + 1 == 4:
print("x = " + str(x))
x += 1
solve()
I expect the output to be 1.73205080757 and -1.73205080757.
However I get nothing (Because it couldn't find an answer).
You're expecting an answer that's between 1 & 2. You're starting at -1000 and incrementing by 1. So you'll go from -1000 to 0 to 1 to 2 to 3....skipping over your expected answer altogether.
You should be using something like: https://en.wikipedia.org/wiki/Newton%27s_method
(With floats i.e x=1.0)
Looking at your code, your minimal step is 1 (x was increased by x += 1), hence x can be only integer. There is no such integer can full-fill your condition x**2 + 1 == 4
this will only check integer values from x = - 1000 to x = 1000, ie it will ask is -1000 the answer? No, is -999 the answer? No etc, and never try 1.7 or 1.73 or 1.73...! The answer is a float not an integer, so the method as written can't possibly get it. You would need somehow to iterate closer and closer answers. This is a question of mathematical algorithm design I think, you can first look up math formulae how to approximate quadratic solutions (probably some 17th century mathematician did the formula!), then try convert this formula into Python. If you don't know about float, int, "duck typing" in Python difference, try googling this also may help you.
The code doesn't give nor will give the solution you expect because of two reasons:
The while loop increments x by 1 at each step, so there is no way x can be a float number. It will always be an integer.
The solution you expect for this case has infinite decimals, so even if x were a float, it could never be the desired value in order to solve the equation.
As a remark/suggestion, if you are trying to solve an equation in python, why don't you just create a function that give the result to an equation of the form: x^2 +a = b. The following code should be an example:
import numpy as np
def solve_prueba(a,b):
"""
The function solves a function of the form x^2 + a = b
"""
x = np.sqrt((b-a))
return x
This way is much more time effective rather than create a while loop has to pass over all the numbers with their infinite decimals to give the solution to a given equation.
Good luck!
It is not necessary to start at -1000 and go up to 1000 since you are looking for a value from 1 to 2. In your code, you increment with 1, which means that x will never be a decimal value. You could however increment with a very small number (e.g.) x += 0.0000000000001.
If you use this small increment, you should probably use math.isclose() instead of ==, because small float values tend to have some precision error. Like in your expected answer where you expect the outcome to be 1.73205080757 altough 1.73205080757**2 + 1 == 4.000000000003889 and not 4.
Using math.isclose((x**2 + 3), 4, rel_tol=1e-9) like this, it checks if the calculation from x**2 + 3 is somewhere close to 4 with a tolerance of 1e-9, which would output the values that you expect from this equation.
So for your code:
import math
def solve():
x = -1000
while x < 1001:
if math.isclose((x**2 + 1), 4, rel_rol=1e-9):
print("x = " + str(x))
x += 0.0000000000001
solve()

Sympy's subs limitations

I am working with some long equations but not really complex, and I wanted to use sympy to simplify and "factorize" them. But I have encountered a few problems. Here is a list of some minimal examples:
Problem 1: symmetry
from sympy import *
from __future__ import division
a = symbols('a')
b = symbols('b')
expr = 1/12*b + 1
expr.subs(1/12*b, a)
expr.subs(b*1/12, a)
The first line gives the expected result (ie. a+1) while in the second one there is no substitution.
Problem 2: factorized expressions
Some parts of the expression are factorized and when I expand the expression they get simplified, thus making the substitution impossible. For example
(((x+1)**2-x).expand()).subs(x**2+2*x, y+1)
will give x^2+x+1 and what I am looking for is y+2-x.
Question
Is there a way to solve these problems ? Or maybe I should use another symbolic mathematical tool ? Any suggestions are welcomed.
There is a major gotcha in SymPy, which is that, because of the way Python works, number/number gives a floating point (or does integer division if you use Python 2 and don't from __future__ import division).
In the first case and in your original expression, Python evaluates 1/12*b from left to right. 1/12 is evaluated by Python to give 0.08333333333333333, which is then multiplied by b. In the second case, b*1 is evaluated as b. Then b/12 is evaluated by SymPy (because b is a SymPy object), to give Rational(1, 12)*b.
Due to the inexact nature of floating point numbers, SymPy does not see the float 0.08333333333333333 as equal to the rational 1/12.
There is some more discussion of this issue here. As a workaround, you should avoid direct integer/integer without wrapping it somehow, so that SymPy can create a rational. The following will all create a rational:
b/12
Rational(1, 12)*b
S(1)/12*b
For (((x+1)**2-x).expand()).subs(x**2+2*x, y+1) the issue is that x**2 + 2*x does not appear exactly in the expression, which is x**2 + x + 1. SymPy generally only replaces things that it sees exactly.
It seems you don't mind adding and subtracting an x to make the replacement work. So I would suggest doing instead (((x+1)**2-x).expand()).subs(x**2, y+1 - 2*x). By only substituting a single term (x**2), the substitution will always work, and the 2*x will cancel out to leave whatever x term remains (in this case, -x).
Here's a possible solution to your problems:
from sympy import *
a = symbols('a')
b = symbols('b')
expr = 1 / 12 * b + 1
print(expr.subs((1 / 12) * b, a))
print(expr.subs(b * (1 / 12), a))
x = symbols('x')
y = symbols('y')
expr = ((x + 1)**2 - x).expand()
print(expr.subs(x**2 + x, y - x + 1))
Regarding problem 1, note that 1/12*b and b*1/12 are not the same thing in sympy. The first is a floating number mutliplied by a symbol, whereas the second is an exact symbolic expression (you can check it out by a simple print statement). Since expr contains 1/12*b, it is not surprising that the second subs does not work.
Regarding problem 2, the subs rule you provide is ambiguous. In particular the substitution rule implies that equation x**2+2*x==y+1. However, this equation has many interpretations, e.g,
x**2 == y + 1 - 2*x (this is the one you consider),
x**2 + x == y + 1 - x,
x == (y + 1 - x**2)/2,
For this reason, I consider sympy refusing to perform a substitution is actually a correct approach.
If it is the first interpretation you want, it is better to explicitly provide it in the subs rule, i.e.,
(((x+1)**2-x).expand()).subs(x**2, -2*x + y + 1)
-x + y + 2

Find the division remainder of a number

How could I go about finding the division remainder of a number in Python?
For example:
If the number is 26 and divided number is 7, then the division remainder is 5.
(since 7+7+7=21 and 26-21=5.)
For simple divisibility testing, see How do you check whether a number is divisible by another number?.
you are looking for the modulo operator:
a % b
for example:
>>> 26 % 7
5
Of course, maybe they wanted you to implement it yourself, which wouldn't be too difficult either.
The remainder of a division can be discovered using the operator %:
>>> 26%7
5
In case you need both the quotient and the modulo, there's the builtin divmod function:
>>> seconds= 137
>>> minutes, seconds= divmod(seconds, 60)
26 % 7 (you will get remainder)
26 / 7 (you will get divisor, can be float value)
26 // 7 (you will get divisor, only integer value)
If you want to get quotient and remainder in one line of code (more general usecase), use:
quotient, remainder = divmod(dividend, divisor)
#or
divmod(26, 7)
From Python 3.7, there is a new math.remainder() function:
from math import remainder
print(remainder(26,7))
Output:
-2.0 # not 5
Note, as above, it's not the same as %.
Quoting the documentation:
math.remainder(x, y)
Return the IEEE 754-style remainder of x with
respect to y. For finite x and finite nonzero y, this is the
difference x - n*y, where n is the closest integer to the exact value
of the quotient x / y. If x / y is exactly halfway between two
consecutive integers, the nearest even integer is used for n. The
remainder r = remainder(x, y) thus always satisfies abs(r) <= 0.5 *
abs(y).
Special cases follow IEEE 754: in particular, remainder(x, math.inf)
is x for any finite x, and remainder(x, 0) and remainder(math.inf, x)
raise ValueError for any non-NaN x. If the result of the remainder
operation is zero, that zero will have the same sign as x.
On platforms using IEEE 754 binary floating-point, the result of this
operation is always exactly representable: no rounding error is
introduced.
Issue29962 describes the rationale for creating the new function.
If you want to avoid modulo, you can also use a combination of the four basic operations :)
26 - (26 // 7 * 7) = 5
Use the % instead of the / when you divide. This will return the remainder for you. So in your case
26 % 7 = 5
We can solve this by using modulus operator (%)
26 % 7 = 5;
but
26 / 7 = 3 because it will give quotient but % operator will give remainder.
Modulo would be the correct answer, but if you're doing it manually this should work.
num = input("Enter a number: ")
div = input("Enter a divisor: ")
while num >= div:
num -= div
print num
You can find remainder using modulo operator
Example
a=14
b=10
print(a%b)
It will print 4
If you want the remainder of your division problem, just use the actual remainder rules, just like in mathematics. Granted this won't give you a decimal output.
valone = 8
valtwo = 3
x = valone / valtwo
r = valone - (valtwo * x)
print "Answer: %s with a remainder of %s" % (x, r)
If you want to make this in a calculator format, just substitute valone = 8
with valone = int(input("Value One")). Do the same with valtwo = 3, but different vairables obviously.
Here's an integer version of remainder in Python, which should give the same results as C's "%" operator:
def remainder(n, d):
return (-1 if n < 0 else 1) * (abs(n) % abs(d))
Expected results:
remainder(123, 10) == 3
remainder(123, -10) == 3
remainder(-123, 10) == -3
remainder(-123, -10) == -3
you can define a function and call it remainder with 2 values like rem(number1,number2) that returns number1%number2
then create a while and set it to true then print out two inputs for your function holding number 1 and 2 then print(rem(number1,number2)

How do you round UP a number?

How does one round a number UP in Python?
I tried round(number) but it rounds the number down. Example:
round(2.3) = 2.0
and not 3, as I would like.
The I tried int(number + .5) but it round the number down again! Example:
int(2.3 + .5) = 2
The math.ceil (ceiling) function returns the smallest integer higher or equal to x.
For Python 3:
import math
print(math.ceil(4.2))
For Python 2:
import math
print(int(math.ceil(4.2)))
I know this answer is for a question from a while back, but if you don't want to import math and you just want to round up, this works for me.
>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5
The first part becomes 4 and the second part evaluates to "True" if there is a remainder, which in addition True = 1; False = 0. So if there is no remainder, then it stays the same integer, but if there is a remainder it adds 1.
If working with integers, one way of rounding up is to take advantage of the fact that // rounds down: Just do the division on the negative number, then negate the answer. No import, floating point, or conditional needed.
rounded_up = -(-numerator // denominator)
For example:
>>> print(-(-101 // 5))
21
Interesting Python 2.x issue to keep in mind:
>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0
The problem is that dividing two ints in python produces another int and that's truncated before the ceiling call. You have to make one value a float (or cast) to get a correct result.
In javascript, the exact same code produces a different result:
console.log(Math.ceil(4500/1000));
5
You might also like numpy:
>>> import numpy as np
>>> np.ceil(2.3)
3.0
I'm not saying it's better than math, but if you were already using numpy for other purposes, you can keep your code consistent.
Anyway, just a detail I came across. I use numpy a lot and was surprised it didn't get mentioned, but of course the accepted answer works perfectly fine.
Use math.ceil to round up:
>>> import math
>>> math.ceil(5.4)
6.0
NOTE: The input should be float.
If you need an integer, call int to convert it:
>>> int(math.ceil(5.4))
6
BTW, use math.floor to round down and round to round to nearest integer.
>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)
I am surprised nobody suggested
(numerator + denominator - 1) // denominator
for integer division with rounding up. Used to be the common way for C/C++/CUDA (cf. divup)
The syntax may not be as pythonic as one might like, but it is a powerful library.
https://docs.python.org/2/library/decimal.html
from decimal import *
print(int(Decimal(2.3).quantize(Decimal('1.'), rounding=ROUND_UP)))
For those who want to round up a / b and get integer:
Another variant using integer division is
def int_ceil(a, b):
return (a - 1) // b + 1
>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5
Note: a and b must be non-negative integers
Here is a way using modulo and bool
n = 2.3
int(n) + bool(n%1)
Output:
3
Try this:
a = 211.0
print(int(a) + ((int(a) - a) != 0))
Be shure rounded value should be float
a = 8
b = 21
print math.ceil(a / b)
>>> 0
but
print math.ceil(float(a) / b)
>>> 1.0
The above answers are correct, however, importing the math module just for this one function usually feels like a bit of an overkill for me. Luckily, there is another way to do it:
g = 7/5
g = int(g) + (not g.is_integer())
True and False are interpreted as 1 and 0 in a statement involving numbers in python. g.is_interger() basically translates to g.has_no_decimal() or g == int(g). So the last statement in English reads round g down and add one if g has decimal.
In case anyone is looking to round up to a specific decimal place:
import math
def round_up(n, decimals=0):
multiplier = 10 ** decimals
return math.ceil(n * multiplier) / multiplier
Without importing math // using basic envionment:
a) method / class method
def ceil(fl):
return int(fl) + (1 if fl-int(fl) else 0)
def ceil(self, fl):
return int(fl) + (1 if fl-int(fl) else 0)
b) lambda:
ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)
>>> def roundup(number):
... return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20
This function requires no modules.
x * -1 // 1 * -1
Confusing but it works: For x=7.1, you get 8.0. For x = -1.1, you get -1.0
No need to import a module.
For those who doesn't want to use import.
For a given list or any number:
x = [2, 2.1, 2.5, 3, 3.1, 3.5, 2.499,2.4999999999, 3.4999999,3.99999999999]
You must first evaluate if the number is equal to its integer, which always rounds down. If the result is True, you return the number, if is not, return the integer(number) + 1.
w = lambda x: x if x == int(x) else int(x)+1
[w(i) for i in z]
>>> [2, 3, 3, 3, 4, 4, 3, 3, 4, 4]
Math logic:
If the number has decimal part: round_up - round_down == 1, always.
If the number doens't have decimal part: round_up - round_down == 0.
So:
round_up == x + round_down
With:
x == 1 if number != round_down
x == 0 if number == round_down
You are cutting the number in 2 parts, the integer and decimal. If decimal isn't 0, you add 1.
PS:I explained this in details since some comments above asked for that and I'm still noob here, so I can't comment.
If you don't want to import anything, you can always write your own simple function as:
def RoundUP(num):
if num== int(num):
return num
return int(num + 1)
To do it without any import:
>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3
I know this is from quite a while back, but I found a quite interesting answer, so here goes:
-round(-x-0.5)
This fixes the edges cases and works for both positive and negative numbers, and doesn't require any function import
Cheers
I'm surprised I haven't seen this answer yet round(x + 0.4999), so I'm going to put it down. Note that this works with any Python version. Changes made to the Python rounding scheme has made things difficult. See this post.
Without importing, I use:
def roundUp(num):
return round(num + 0.49)
testCases = list(x*0.1 for x in range(0, 50))
print(testCases)
for test in testCases:
print("{:5.2f} -> {:5.2f}".format(test, roundUp(test)))
Why this works
From the docs
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus n; if two multiples are equally close, rounding is done toward the even choice
Therefore 2.5 gets rounded to 2 and 3.5 gets rounded to 4. If this was not the case then rounding up could be done by adding 0.5, but we want to avoid getting to the halfway point. So, if you add 0.4999 you will get close, but with enough margin to be rounded to what you would normally expect. Of course, this will fail if the x + 0.4999 is equal to [n].5000, but that is unlikely.
You could use round like this:
cost_per_person = round(150 / 2, 2)
You can use floor devision and add 1 to it.
2.3 // 2 + 1
when you operate 4500/1000 in python, result will be 4, because for default python asume as integer the result, logically:
4500/1000 = 4.5 --> int(4.5) = 4
and ceil of 4 obviouslly is 4
using 4500/1000.0 the result will be 4.5 and ceil of 4.5 --> 5
Using javascript you will recieve 4.5 as result of 4500/1000, because javascript asume only the result as "numeric type" and return a result directly as float
Good Luck!!
I think you are confusing the working mechanisms between int() and round().
int() always truncates the decimal numbers if a floating number is given; whereas round(), in case of 2.5 where 2 and 3 are both within equal distance from 2.5, Python returns whichever that is more away from the 0 point.
round(2.5) = 3
int(2.5) = 2
My share
I have tested print(-(-101 // 5)) = 21 given example above.
Now for rounding up:
101 * 19% = 19.19
I can not use ** so I spread the multiply to division:
(-(-101 //(1/0.19))) = 20
I'm basically a beginner at Python, but if you're just trying to round up instead of down why not do:
round(integer) + 1

Categories