Python and Floats - Print only the Whole Number - c++

Is there a way in Python to print only the whole number portion of a float when no additional precision is required to express the number? For example, the float 1.0. Some other languages do this by default. Here are some examples:
In C++, this code prints 1, not 1.0:
int main()
{
float f = 1.0;
std::cout << f << "\n";
return 0;
}
./a.out
1
However, in Python, this code prints 1.0:
f = 1.0
print type(f)
<type 'float'>
print f
1.0
I'd like for the Python code to only print 1, not 1.0, when that's all that is required to fully represent the number.

Use the g formatting option:
f = 1.0
print(f"{f:g}") # Python 3.6 and above
or
print "{:g}".format(f)
or
print "%g" % f
This does something very similar to std::cout in default configuration. It will only print a limited number of digits, just like std::cout.

The modulo operator should work across all Python versions:
>>> f = 1.0
>>> if f % 1 == 0:
... print int(f)
... else:
... print f
...
1
>>>

Related

Derivative in JAX and Sympy not coinciding

For this vectorial function I want to evaluate the jacobian:
import jax
import jax.numpy as jnp
def myf(arr, phi_0, phi_1, phi_2, lambda_0, R):
arr = jnp.deg2rad(arr)
phi_0 = jnp.deg2rad(phi_0)
phi_1 = jnp.deg2rad(phi_1)
phi_2 = jnp.deg2rad(phi_2)
lambda_0 = jnp.deg2rad(lambda_0)
n = jnp.sin(phi_1)
F = 2.0
rho_0 = 1.0
rho = R*F*(1/jnp.tan(jnp.pi/4 + arr[1]/2))**n
x_L = rho*jnp.sin(n*(arr[0] - lambda_0))
y_L = rho_0 - rho*jnp.cos(n*(arr[0] - lambda_0))
return jnp.array([x_L,y_L])
arr = jnp.array([-18.1, 29.9])
jax.jacobian(myf)(arr, 29.5, 29.5, 29.5, -17.0, R=1)
I obtain
[[ 0.01312758 0.00014317]
[-0.00012411 0.01514319]]
I'm in shock with these values. Take for instance the element [0][0], 0.01312758. We know it's the partial of x_L with respect to the variable arr[0]. Whether by hand or using sympy that derivative is ~0.75.
from sympy import *
x, y = symbols('x y')
x_L = (2.0*(1/tan(3.141592/4 + y/2))**0.492)*sin(0.492*(x + 0.2967))
deriv = Derivative(x_L, x)
deriv.doit()
deriv.doit().evalf(subs={x: -0.3159, y: 0.52})
0.752473089673695
(inserting x, y, that are arr[0] and arr[1] already in radians). This is also the result I obtain by hand. What is happening with Jax results? I can't see what I'm doing bad.
Your JAX snippet inputs degrees, and so its gradient has units of 1/degrees, while your sympy snippet inputs radians, and so its gradient has units of 1/radians. If you convert the jax outputs to 1/radians (i.e. multiply the jax outputs by 180 / pi), you'll get the result you're looking for:
result = jax.jacobian(myf)(arr, 29.5, 29.5, 29.5, -17.0, R=1)
print(result * 180 / jnp.pi)
[[ 0.7521549 0.00820279]
[-0.00711098 0.8676407 ]]
Alternatively, you could rewrite myf to accept inputs in units of radians and get the expected result by taking its gradient directly.
Ok, I think I know what is happening... it is subtle.
The problem is that the conversion from degrees to rad done inside the function is not valid for jax. I think (but surely there're people who know more than me) that jax does the derivatives as soon as jax.jacobian(myf) is called and it evaluates only at last, when the values are passed (lazy evaluation, I think), so the transformation of values inside the function doesn't do anything. The correct code will be
def myf(arr, phi_0, phi_1, phi_2, lambda_0, R):
n = jnp.sin(phi_1)
F = 2.0
rho_0 = 1.0
rho = R*F*(1/jnp.tan(jnp.pi/4 + arr[1]/2))**n
x_L = (R*F*(1/jnp.tan(jnp.pi/4 + arr[1]/2))**n) *jnp.sin(n*(arr[0] - lambda_0))
y_L = rho_0 - (R*F*(1/jnp.tan(jnp.pi/4 + arr[1]/2))**n) *jnp.cos(n*(arr[0] - lambda_0))
return jnp.array([x_L,y_L])
arr = jnp.array([-18.1, 29.9])
jax.jacobian(myf)(jnp.deg2rad(arr), jnp.deg2rad(29.5),
jnp.deg2rad(29.5), jnp.deg2rad(29.5), jnp.deg2rad(-17.0),
R=1)
# [[ 0.7521549 0.00820279]
# [-0.00711098 0.8676407 ]]

How do I get sympy to simplify an expression containing sqrt(2)/2?

This code:
from sympy import *
x = Symbol('x', positive=True)
vp = Symbol('vp', positive=True)
num = integrate( (vp*sin(x))**2, (x, 0, 2*pi))
den = integrate( 1 , (x, 0, 2*pi))
print " num =",num
print " den =",den
vrms = sqrt(num/den)
print "vrms =",vrms
print "simplified vrms = ",simplify(vrms)
Returns this:
num = pi*vp**2
den = 2*pi
vrms = sqrt(2)*vp/2
simplified vrms = sqrt(2)*vp/2
How can I get it to take the last step? I'd like it return this:
vrms = vp/sqrt(2)
SymPy automatically canonicalizes rational power of rational numbers to a form with positive exponents and reduced powers. Because this happens automatically, it will happen with every such number that appears in any expression, meaning there is no way to make sqrt(2)/2 result in 1/sqrt(2).
So it looks like sqrt(2)/2 is simpler than 1/sqrt(2).
Thank you, sandwich.
Indeed, much of the code in the example is superfluous. I was worried that how the symbols were defined and calculated could be relevant.

Formatting floats so they all have the same total digits (ex 1.234, 456.7) [duplicate]

I need to round a float to be displayed in a UI. e.g, to one significant figure:
1234 -> 1000
0.12 -> 0.1
0.012 -> 0.01
0.062 -> 0.06
6253 -> 6000
1999 -> 2000
Is there a nice way to do this using the Python library, or do I have to write it myself?
You can use negative numbers to round integers:
>>> round(1234, -3)
1000.0
Thus if you need only most significant digit:
>>> from math import log10, floor
>>> def round_to_1(x):
... return round(x, -int(floor(log10(abs(x)))))
...
>>> round_to_1(0.0232)
0.02
>>> round_to_1(1234243)
1000000.0
>>> round_to_1(13)
10.0
>>> round_to_1(4)
4.0
>>> round_to_1(19)
20.0
You'll probably have to take care of turning float to integer if it's bigger than 1.
%g in string formatting will format a float rounded to some number of significant figures. It will sometimes use 'e' scientific notation, so convert the rounded string back to a float then through %s string formatting.
>>> '%s' % float('%.1g' % 1234)
'1000'
>>> '%s' % float('%.1g' % 0.12)
'0.1'
>>> '%s' % float('%.1g' % 0.012)
'0.01'
>>> '%s' % float('%.1g' % 0.062)
'0.06'
>>> '%s' % float('%.1g' % 6253)
'6000.0'
>>> '%s' % float('%.1g' % 1999)
'2000.0'
If you want to have other than 1 significant decimal (otherwise the same as Evgeny):
>>> from math import log10, floor
>>> def round_sig(x, sig=2):
... return round(x, sig-int(floor(log10(abs(x))))-1)
...
>>> round_sig(0.0232)
0.023
>>> round_sig(0.0232, 1)
0.02
>>> round_sig(1234243, 3)
1230000.0
f'{float(f"{i:.1g}"):g}'
# Or with Python <3.6,
'{:g}'.format(float('{:.1g}'.format(i)))
This solution is different from all of the others because:
it exactly solves the OP question
it does not need any extra package
it does not need any user-defined auxiliary function or mathematical operation
For an arbitrary number n of significant figures, you can use:
print('{:g}'.format(float('{:.{p}g}'.format(i, p=n))))
Test:
a = [1234, 0.12, 0.012, 0.062, 6253, 1999, -3.14, 0., -48.01, 0.75]
b = ['{:g}'.format(float('{:.1g}'.format(i))) for i in a]
# b == ['1000', '0.1', '0.01', '0.06', '6000', '2000', '-3', '0', '-50', '0.8']
Note: with this solution, it is not possible to adapt the number of significant figures dynamically from the input because there is no standard way to distinguish numbers with different numbers of trailing zeros (3.14 == 3.1400). If you need to do so, then non-standard functions like the ones provided in the to-precision package are needed.
To directly answer the question, here's my version using naming from the R function:
import math
def signif(x, digits=6):
if x == 0 or not math.isfinite(x):
return x
digits -= math.ceil(math.log10(abs(x)))
return round(x, digits)
My main reason for posting this answer are the comments complaining that "0.075" rounds to 0.07 rather than 0.08. This is due, as pointed out by "Novice C", to a combination of floating point arithmetic having both finite precision and a base-2 representation. The nearest number to 0.075 that can actually be represented is slightly smaller, hence rounding comes out differently than you might naively expect.
Also note that this applies to any use of non-decimal floating point arithmetic, e.g. C and Java both have the same issue.
To show in more detail, we ask Python to format the number in "hex" format:
0.075.hex()
which gives us: 0x1.3333333333333p-4. The reason for doing this is that the normal decimal representation often involves rounding and hence is not how the computer actually "sees" the number. If you're not used to this format, a couple of useful references are the Python docs and the C standard.
To show how these numbers work a bit, we can get back to our starting point by doing:
0x13333333333333 / 16**13 * 2**-4
which should should print out 0.075. 16**13 is because there are 13 hexadecimal digits after the decimal point, and 2**-4 is because hex exponents are base-2.
Now we have some idea of how floats are represented we can use the decimal module to give us some more precision, showing us what's going on:
from decimal import Decimal
Decimal(0x13333333333333) / 16**13 / 2**4
giving: 0.07499999999999999722444243844 and hopefully explaining why round(0.075, 2) evaluates to 0.07
I have created the package to-precision that does what you want. It allows you to give your numbers more or less significant figures.
It also outputs standard, scientific, and engineering notation with a specified number of significant figures.
In the accepted answer there is the line
>>> round_to_1(1234243)
1000000.0
That actually specifies 8 sig figs. For the number 1234243 my library only displays one significant figure:
>>> from to_precision import to_precision
>>> to_precision(1234243, 1, 'std')
'1000000'
>>> to_precision(1234243, 1, 'sci')
'1e6'
>>> to_precision(1234243, 1, 'eng')
'1e6'
It will also round the last significant figure and can automatically choose what notation to use if a notation isn't specified:
>>> to_precision(599, 2)
'600'
>>> to_precision(1164, 2)
'1.2e3'
To round an integer to 1 significant figure the basic idea is to convert it to a floating point with 1 digit before the point and round that, then convert it back to its original integer size.
To do this we need to know the largest power of 10 less than the integer. We can use floor of the log 10 function for this.
from math import log10, floor
def round_int(i,places):
if i == 0:
return 0
isign = i/abs(i)
i = abs(i)
if i < 1:
return 0
max10exp = floor(log10(i))
if max10exp+1 < places:
return i
sig10pow = 10**(max10exp-places+1)
floated = i*1.0/sig10pow
defloated = round(floated)*sig10pow
return int(defloated*isign)
def round_to_n(x, n):
if not x: return 0
power = -int(math.floor(math.log10(abs(x)))) + (n - 1)
factor = (10 ** power)
return round(x * factor) / factor
round_to_n(0.075, 1) # 0.08
round_to_n(0, 1) # 0
round_to_n(-1e15 - 1, 16) # 1000000000000001.0
Hopefully taking the best of all the answers above (minus being able to put it as a one line lambda ;) ). Haven't explored yet, feel free to edit this answer:
round_to_n(1e15 + 1, 11) # 999999999999999.9
I modified indgar's solution to handle negative numbers and small numbers (including zero).
from math import log10, floor
def round_sig(x, sig=6, small_value=1.0e-9):
return round(x, sig - int(floor(log10(max(abs(x), abs(small_value))))) - 1)
The posted answer was the best available when given, but it has a number of limitations and does not produce technically correct significant figures.
numpy.format_float_positional supports the desired behaviour directly. The following fragment returns the float x formatted to 4 significant figures, with scientific notation suppressed.
import numpy as np
x=12345.6
np.format_float_positional(x, precision=4, unique=False, fractional=False, trim='k')
> 12340.
If you want to round without involving strings, the link I found buried in the comments above:
http://code.activestate.com/lists/python-tutor/70739/
strikes me as best. Then when you print with any string formatting descriptors, you get a reasonable output, and you can use the numeric representation for other calculation purposes.
The code at the link is a three liner: def, doc, and return. It has a bug: you need to check for exploding logarithms. That is easy. Compare the input to sys.float_info.min. The complete solution is:
import sys,math
def tidy(x, n):
"""Return 'x' rounded to 'n' significant digits."""
y=abs(x)
if y <= sys.float_info.min: return 0.0
return round( x, int( n-math.ceil(math.log10(y)) ) )
It works for any scalar numeric value, and n can be a float if you need to shift the response for some reason. You can actually push the limit to:
sys.float_info.min*sys.float_info.epsilon
without provoking an error, if for some reason you are working with miniscule values.
The sigfig package/library covers this. After installing you can do the following:
>>> from sigfig import round
>>> round(1234, 1)
1000
>>> round(0.12, 1)
0.1
>>> round(0.012, 1)
0.01
>>> round(0.062, 1)
0.06
>>> round(6253, 1)
6000
>>> round(1999, 1)
2000
I can't think of anything that would be able to handle this out of the box. But it's fairly well handled for floating point numbers.
>>> round(1.2322, 2)
1.23
Integers are trickier. They're not stored as base 10 in memory, so significant places isn't a natural thing to do. It's fairly trivial to implement once they're a string though.
Or for integers:
def intround(n, sigfigs):
n = str(n)
return n[:sigfigs] + ('0' * (len(n)-sigfigs))
>>> intround(1234, 1)
'1000'
>>> intround(1234, 2)
'1200'
If you would like to create a function that handles any number, my preference would be to convert them both to strings and look for a decimal place to decide what to do:
def roundall1(n, sigfigs):
n = str(n)
try:
sigfigs = n.index('.')
except ValueError:
pass
return intround(n, sigfigs)
Another option is to check for type. This will be far less flexible, and will probably not play nicely with other numbers such as Decimal objects:
def roundall2(n, sigfigs):
if type(n) is int:
return intround(n, sigfigs)
else:
return round(n, sigfigs)
Using python 2.6+ new-style formatting (as %-style is deprecated):
>>> "{0}".format(float("{0:.1g}".format(1216)))
'1000.0'
>>> "{0}".format(float("{0:.1g}".format(0.00356)))
'0.004'
In python 2.7+ you can omit the leading 0s.
I adapted one of the answers. I like this:
def sigfiground(number:float, ndigits=3)->float:
return float(f"{number:.{ndigits}g}")
I use it when I still want a float (I do formatting elsewhere).
I ran into this as well but I needed control over the rounding type. Thus, I wrote a quick function (see code below) that can take value, rounding type, and desired significant digits into account.
import decimal
from math import log10, floor
def myrounding(value , roundstyle='ROUND_HALF_UP',sig = 3):
roundstyles = [ 'ROUND_05UP','ROUND_DOWN','ROUND_HALF_DOWN','ROUND_HALF_UP','ROUND_CEILING','ROUND_FLOOR','ROUND_HALF_EVEN','ROUND_UP']
power = -1 * floor(log10(abs(value)))
value = '{0:f}'.format(value) #format value to string to prevent float conversion issues
divided = Decimal(value) * (Decimal('10.0')**power)
roundto = Decimal('10.0')**(-sig+1)
if roundstyle not in roundstyles:
print('roundstyle must be in list:', roundstyles) ## Could thrown an exception here if you want.
return_val = decimal.Decimal(divided).quantize(roundto,rounding=roundstyle)*(decimal.Decimal(10.0)**-power)
nozero = ('{0:f}'.format(return_val)).rstrip('0').rstrip('.') # strips out trailing 0 and .
return decimal.Decimal(nozero)
for x in list(map(float, '-1.234 1.2345 0.03 -90.25 90.34543 9123.3 111'.split())):
print (x, 'rounded UP: ',myrounding(x,'ROUND_UP',3))
print (x, 'rounded normal: ',myrounding(x,sig=3))
This function does a normal round if the number is bigger than 10**(-decimal_positions), otherwise adds more decimal until the number of meaningful decimal positions is reached:
def smart_round(x, decimal_positions):
dp = - int(math.log10(abs(x))) if x != 0.0 else int(0)
return round(float(x), decimal_positions + dp if dp > 0 else decimal_positions)
Hope it helps.
https://stackoverflow.com/users/1391441/gabriel, does the following address your concern about rnd(.075, 1)?
Caveat: returns value as a float
def round_to_n(x, n):
fmt = '{:1.' + str(n) + 'e}' # gives 1.n figures
p = fmt.format(x).split('e') # get mantissa and exponent
# round "extra" figure off mantissa
p[0] = str(round(float(p[0]) * 10**(n-1)) / 10**(n-1))
return float(p[0] + 'e' + p[1]) # convert str to float
>>> round_to_n(750, 2)
750.0
>>> round_to_n(750, 1)
800.0
>>> round_to_n(.0750, 2)
0.075
>>> round_to_n(.0750, 1)
0.08
>>> math.pi
3.141592653589793
>>> round_to_n(math.pi, 7)
3.141593
This returns a string, so that results without fractional parts, and small values which would otherwise appear in E notation are shown correctly:
def sigfig(x, num_sigfig):
num_decplace = num_sigfig - int(math.floor(math.log10(abs(x)))) - 1
return '%.*f' % (num_decplace, round(x, num_decplace))
Given a question so thoroughly answered why not add another
This suits my aesthetic a little better, though many of the above are comparable
import numpy as np
number=-456.789
significantFigures=4
roundingFactor=significantFigures - int(np.floor(np.log10(np.abs(number)))) - 1
rounded=np.round(number, roundingFactor)
string=rounded.astype(str)
print(string)
This works for individual numbers and numpy arrays, and should function fine for negative numbers.
There's one additional step we might add - np.round() returns a decimal number even if rounded is an integer (i.e. for significantFigures=2 we might expect to get back -460 but instead we get -460.0). We can add this step to correct for that:
if roundingFactor<=0:
rounded=rounded.astype(int)
Unfortunately, this final step won't work for an array of numbers - I'll leave that to you dear reader to figure out if you need.
import math
def sig_dig(x, n_sig_dig):
num_of_digits = len(str(x).replace(".", ""))
if n_sig_dig >= num_of_digits:
return x
n = math.floor(math.log10(x) + 1 - n_sig_dig)
result = round(10 ** -n * x) * 10 ** n
return float(str(result)[: n_sig_dig + 1])
>>> sig_dig(1234243, 3)
>>> sig_dig(243.3576, 5)
1230.0
243.36
Most of these answers involve the math, decimal and/or numpy imports or output values as strings. Here is a simple solution in base python that handles both large and small numbers and outputs a float:
def sig_fig_round(number, digits=3):
power = "{:e}".format(number).split('e')[1]
return round(number, -(int(power) - digits))
A simple variant using the standard decimal library
from decimal import Decimal
def to_significant_figures(v: float, n_figures: int) -> str:
d = Decimal(v)
d = d.quantize(Decimal((0, (), d.adjusted() - n_figures + 1)))
return str(d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize())
Testing it
>>> to_significant_figures(1.234567, 3)
'1.23'
>>> to_significant_figures(1234567, 3)
'1230000'
>>> to_significant_figures(1.23, 7)
'1.23'
>>> to_significant_figures(123, 7)
'123'
This function takes both positive and negative numbers and does the proper significant digit rounding.
from math import floor
def significant_arithmetic_rounding(n, d):
'''
This function takes a floating point number and the no. of significant digit d, perform significant digits
arithmetic rounding and returns the floating point number after rounding
'''
if n == 0:
return 0
else:
# Checking whether the no. is negative or positive. If it is negative we will take the absolute value of it and proceed
neg_flag = 0
if n < 0:
neg_flag = 1
n = abs(n)
n1 = n
# Counting the no. of digits to the left of the decimal point in the no.
ld = 0
while(n1 >= 1):
n1 /= 10
ld += 1
n1 = n
# Counting the no. of zeros to the right of the decimal point and before the first significant digit in the no.
z = 0
if ld == 0:
while(n1 <= 0.1):
n1 *= 10
z += 1
n1 = n
# No. of digits to be considered after decimal for rounding
rd = (d - ld) + z
n1 *= 10**rd
# Increase by 0.5 and take the floor value for rounding
n1 = floor(n1+0.5)
# Placing the decimal point at proper position
n1 /= 10 ** rd
# If the original number is negative then make it negative
if neg_flag == 1:
n1 = 0 - n1
return n1
Testing:
>>> significant_arithmetic_rounding(1234, 3)
1230.0
>>> significant_arithmetic_rounding(123.4, 3)
123.0
>>> significant_arithmetic_rounding(0.0012345, 3)
0.00123
>>> significant_arithmetic_rounding(-0.12345, 3)
-0.123
>>> significant_arithmetic_rounding(-30.15345, 3)
-30.2
Easier to know an answer works for your needs when it includes examples. The following is built on previous solutions, but offers a more general function which can round to 1, 2, 3, 4, or any number of significant digits.
import math
# Given x as float or decimal, returns as string a number rounded to "sig" significant digts
# Return as string in order to control significant digits, could be a float or decimal
def round_sig(x, sig=2):
r = round(x, sig-int(math.floor(math.log10(abs(x))))-1)
floatsig = "%." + str(sig) + "g"
return "%d"%r if abs(r) >= 10**(sig-1) else '%s'%float(floatsig % r)
>>> a = [1234, 123.4, 12.34, 1.234, 0.1234, 0.01234, 0.25, 1999, -3.14, -48.01, 0.75]
>>> [print(i, "->", round_sig(i,1), round_sig(i), round_sig(i,3), round_sig(i,4)) for i in a]
1234 -> 1000 1200 1230 1234
123.4 -> 100 120 123 123.4
12.34 -> 10 12 12.3 12.34
1.234 -> 1 1.2 1.23 1.234
0.1234 -> 0.1 0.12 0.123 0.1234
0.01234 -> 0.01 0.012 0.0123 0.01234
0.25 -> 0.2 0.25 0.25 0.25
1999 -> 2000 2000 2000 1999
-3.14 -> -3 -3.1 -3.14 -3.14
-48.01 -> -50 -48 -48.0 -48.01
0.75 -> 0.8 0.75 0.75 0.75
in very cases, the number of significant is depend on to the evaluated process, e.g. error. I wrote the some codes which returns a number according to it's error (or with some desired digits) and also in string form (which doesn't eliminate right side significant zeros)
import numpy as np
def Sig_Digit(x, *N,):
if abs(x) < 1.0e-15:
return(1)
N = 1 if N ==() else N[0]
k = int(round(abs(N)-1))-int(np.floor(np.log10(abs(x))))
return(k);
def Sig_Format(x, *Error,):
if abs(x) < 1.0e-15:
return('{}')
Error = 1 if Error ==() else abs(Error[0])
k = int(np.floor(np.log10(abs(x))))
z = x/10**k
k = -Sig_Digit(Error, 1)
m = 10**k
y = round(x*m)/m
if k < 0:
k = abs(k)
if z >= 9.5:
FMT = '{:'+'{}'.format(1+k)+'.'+'{}'.format(k-1)+'f}'
else:
FMT = '{:'+'{}'.format(2+k)+'.'+'{}'.format(k)+'f}'
elif k == 0:
if z >= 9.5:
FMT = '{:'+'{}'.format(1+k)+'.0e}'
else:
FMT = '{:'+'{}'.format(2+k)+'.0f}'
else:
FMT = '{:'+'{}'.format(2+k)+'.'+'{}'.format(k)+'e}'
return(FMT)
def Sci_Format(x, *N):
if abs(x) < 1.0e-15:
return('{}')
N = 1 if N ==() else N[0]
N = int(round(abs(N)-1))
y = abs(x)
k = int(np.floor(np.log10(y)))
z = x/10**k
k = k-N
m = 10**k
y = round(x/m)*m
if k < 0:
k = abs(k)
if z >= 9.5:
FMT = '{:'+'{}'.format(1+k)+'.'+'{}'.format(k-1)+'f}'
else:
FMT = '{:'+'{}'.format(2+k)+'.'+'{}'.format(k)+'f}'
elif k == 0:
if z >= 9.5:
FMT = '{:'+'{}'.format(1+k)+'.0e}'
else:
FMT = '{:'+'{}'.format(2+k)+'.0f}'
else:
FMT = '{:'+'{}'.format(2+N)+'.'+'{}'.format(N)+'e}'
return(FMT)
def Significant(x, *Error):
N = 0 if Error ==() else Sig_Digit(abs(Error[0]), 1)
m = 10**N
y = round(x*m)/m
return(y)
def Scientific(x, *N):
m = 10**Sig_Digit(x, *N)
y = round(x*m)/m
return(y)
def Scientific_Str(x, *N,):
FMT = Sci_Format(x, *N)
return(FMT.format(x))
def Significant_Str(x, *Error,):
FMT = Sig_Format(x, *Error)
return(FMT.format(x))
test code:
X = [19.03345607, 12.075, 360.108321344, 4325.007605343]
Error = [1.245, 0.1245, 0.0563, 0.01245, 0.001563, 0.0004603]
for x in X:
for error in Error:
print(x,'+/-',error, end=' \t==> ')
print(' (',Significant_Str(x, error), '+/-', Scientific_Str(error),')')
print out:
19.03345607 +/- 1.245 ==> ( 19 +/- 1 )
19.03345607 +/- 0.1245 ==> ( 19.0 +/- 0.1 )
19.03345607 +/- 0.0563 ==> ( 19.03 +/- 0.06 )
19.03345607 +/- 0.01245 ==> ( 19.03 +/- 0.01 )
19.03345607 +/- 0.001563 ==> ( 19.033 +/- 0.002 )
19.03345607 +/- 0.0004603 ==> ( 19.0335 +/- 0.0005 )
12.075 +/- 1.245 ==> ( 12 +/- 1 )
12.075 +/- 0.1245 ==> ( 12.1 +/- 0.1 )
12.075 +/- 0.0563 ==> ( 12.07 +/- 0.06 )
12.075 +/- 0.01245 ==> ( 12.07 +/- 0.01 )
12.075 +/- 0.001563 ==> ( 12.075 +/- 0.002 )
12.075 +/- 0.0004603 ==> ( 12.0750 +/- 0.0005 )
360.108321344 +/- 1.245 ==> ( 360 +/- 1 )
360.108321344 +/- 0.1245 ==> ( 360.1 +/- 0.1 )
360.108321344 +/- 0.0563 ==> ( 360.11 +/- 0.06 )
360.108321344 +/- 0.01245 ==> ( 360.11 +/- 0.01 )
360.108321344 +/- 0.001563 ==> ( 360.108 +/- 0.002 )
360.108321344 +/- 0.0004603 ==> ( 360.1083 +/- 0.0005 )
4325.007605343 +/- 1.245 ==> ( 4325 +/- 1 )
4325.007605343 +/- 0.1245 ==> ( 4325.0 +/- 0.1 )
4325.007605343 +/- 0.0563 ==> ( 4325.01 +/- 0.06 )
4325.007605343 +/- 0.01245 ==> ( 4325.01 +/- 0.01 )
4325.007605343 +/- 0.001563 ==> ( 4325.008 +/- 0.002 )
4325.007605343 +/- 0.0004603 ==> ( 4325.0076 +/- 0.0005 )

Quadratic Equations Factored Form

I'm a beginner with python as my first language trying to factor a
quadratic where the equation provides the result in
factor form for example:
x^2+5x+4
Output to be (or any factors in parenthesis)
(x+4)(x+1)
So far this only gives me x but not a correct value either
CODE
def quadratic(a,b,c):
x = -b+(((b**2)-(4*a*c))**(1/2))/(2*a)
return x
print quadratic(1,5,4)
Your parentheses are in the wrong places, you're only calculating and returning one root, and (most importantly), you're using **(1/2) to calculate the square root. In Python 2, this will evaluate to 0 (integer arithmetic). To get 0.5, use (1./2) (or 0.5 directly).
This is (slightly) better:
def quadratic(a,b,c):
x1 = (-b+(b**2 - 4*a*c)**(1./2))/(2*a)
x2 = (-b-(b**2 - 4*a*c)**(1./2))/(2*a)
return x1, x2
print quadratic(1,5,4)
and returns (-1.0, -4.0).
To get your parentheses, put the negative of the roots in an appropriate string:
def quadratic(a,b,c):
x1 = (-b+(b**2 - 4*a*c)**(1./2))/(2*a)
x2 = (-b-(b**2 - 4*a*c)**(1./2))/(2*a)
return '(x{:+f})(x{:+f})'.format(-x1,-x2)
print quadratic(1,5,4)
Returns:
(x+1.000000)(x+4.000000)
This will help you:
from __future__ import division
def quadratic(a,b,c):
x = (-b+((b**2)-(4*a*c))**(1/2))/(2*a)
y = (-b-((b**2)-(4*a*c))**(1/2))/(2*a)
return x,y
m,n = quadratic(1,5,4)
sign_of_m = '-' if m > 0 else '+'
sign_of_n = '-' if n > 0 else '+'
print '(x'+sign_of_m+str(abs(m))+')(x'+sign_of_n+str(abs(n))+')'
Output
(x+1.0)(x+4.0)
Let me know if it helps.

TypeError: 'list' object is not callable- Python

I write this code
def evaluate_poly(poly, x):
"""
Computes the value of a polynomial function at given value x. Returns that
value as a float.
Example:
>>> poly = [0.0, 0.0, 5.0, 9.3, 7.0] # f(x) = 5x^2 + 9.3x^3 + 7x^4
>>> x = -13
>>> print evaluate_poly(poly, x) # f(-13) = 5(-13)^2 + 9.3(-13)^3 + 7(-13)^4
180339.9
poly: list of numbers, length > 0
x: number
returns: float
"""
# FILL IN YOUR CODE HERE ...
answer = 0.0
for i in range(0, len(poly)):
answer +=poly[i]*(x**i)
return float(answer)
and consistently get the response
Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
evaluate_poly( [0.0, 0.0, 5.0, 9.3, 7.0], -13)
File "/Users/katharinaross/Downloads/ps2/ps2_bisection.py", line 28, in evaluate_poly
answer +=poly[i]*(x**i)
TypeError: 'list' object is not callable
All of the """ are notes from my professor on examples of how the code should run. what does this mean?
That error message is the exact one I get when I use the line:
answer += poly(i)*(x**i)
(using parentheses rather than square brackets). When I use square brackets, I get the right answer, as specified in the comments:
$ cat qq.py
def evaluate_poly(poly, x):
"""
Computes the value of a polynomial function at given value x. Returns that
value as a float.
Example:
>>> poly = [0.0, 0.0, 5.0, 9.3, 7.0] # f(x) = 5x^2 + 9.3x^3 + 7x^4
>>> x = -13
>>> print evaluate_poly(poly, x) # f(-13) = 5(-13)^2 + 9.3(-13)^3 + 7(-13)^4
180339.9
poly: list of numbers, length > 0
x: number
returns: float
"""
# FILL IN YOUR CODE HERE ...
answer = 0.0
for i in range(0, len(poly)):
answer +=poly[i]*(x**i)
return float(answer)
print evaluate_poly ([0.0,0.0,5.0,9.3,7],-13)
$ python qq.py
180339.9
Hence either you've gone out of your way to doctor the code and output (unlikely) or you have a problem with the way your Python interpreter is handling the indexing operator.
Since that works fine in other environments, it's unlikely to be that code itself, so you'll need to search for some other cause.
As a first step, you should create a file containing absolutely nothing except the contents of my qq.py file above and run it to see if it exhibits a similar problem.
Secondly, I would check that the file your stack trace is being raised in (/Users/katharinaross/Downloads/ps2/ps2_bisection.py) is actually the one you think it is.
Also show us the entire file since there may be stuff at the top affecting your given code.
I mention all that since that exception is not on the 28th line in your sample code (as per the stack trace), it's actually around line 19, so there's probably something above it which you haven't shown us.