(update)
Here's the actual problem I'm seeing. Note that round() doesn't seem to be doing the trick.
Here's my code:
t0=time.time()
# stuff
t1=time.time()
perfdat={'et1' : round(t1-t0,6), 'et2': '%.6f'%(t1-t0)}
And the dict and json output, respectively:
{'et2': '0.010214', 'et1': 0.010214000000000001}
{"et2":"0.010214","et1":0.010214000000000001}
(end update)
I've got a floating point value that has a lot of extra digits of precision that I don't need. Is there a way to truncate those digits when formatting a json string?
I can get the truncation I need if I format the value as a string, but I would like to transmit the value as a (truncated) number.
import json
v=2.030000002
json.dumps({'x':v}) # would like to just have 2.030
'{"x": 2.030000002}'
s= '%.3f' % (v) # like this, but not as a string
json.dumps({'x' : s})
'{"x": "2.030"}'
Wrap the number into a float:
>>> s = float('%.3f' % (v))
>>> json.dumps({'x' : s})
{"x": 2.03}
Builtin function round can help
In [16]: v=2.030000002
In [17]: json.dumps({'x': round(v, 3)})
Out[17]: '{"x": 2.03}'
This is something I found from from the Python Standard library:
"Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem:
>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')
"
A better import statement would be:
from decimal import getcontext, Decimal
Then you could apply those same functions to specify an arbitrary precision. Hope this helps! I haven't actually used this before.
For your case: (still has the trailing zero issue)
getcontext().prec = 3
s = '2.030'
var = float(Decimal(s))
var returns 2.03
This following approach seems promising:
import json
v = 2.030000002
result = []
for part in json.JSONEncoder().iterencode({'x': v}):
try:
tmp = round(float(part), 3)
except ValueError:
pass
else:
part = '{:.3f}'.format(tmp)
result.append(part)
result = ''.join(result)
print result # -> {"x": 2.030}
Related
I have a simple math formula that results in a decimal number (0.97745) that I want to round to 4 numbers.
When I do that from my evaluated variable I get (0.9774), but when I hardcode that number into function round(), I get 0.9775
Here is the code
zero = 0.9700
effective_beta = 0.00745
loan = {}
loan['beta2'] = 0.0
loan['beta3'] = 0.0
mrktdiff_2 =0.08880400
mrktdiff_3 = 0.026463592000
forecasted_pt = (float(zero) + float(effective_beta) + float(loan['beta2'] or 0.) * float(mrktdiff_2) +
float(loan['beta3'] or 0.) * float(mrktdiff_3))
print("before rounding forecastedpt is ")
print(forecasted_pt)
print("after rounding")
print(round(forecasted_pt,4))
print("Dont get this part")
print(round(0.97745,4))
The reason why I use the float operators is due to the that these variables are dynamic and sometimes can result in string / null values.
Also when I run the same code in php I get the 0.9775 value for this.
Edit:
I ran the code in katacoda.com editor, and got the following:
before rounding forecastedpt is
0.97745
after rounding
0.9774
Dont get this part
0.9775
But running it in repl.com I get the first value as: 0.97744999999999 so I guess it could be in the precision of the expression itself
try it :
zero = 0.9700
effective_beta = 0.00745
loan = {}
loan['beta2'] = 0.0
loan['beta3'] = 0.0
mrktdiff_2 =0.08880400
mrktdiff_3 = 0.026463592000
forecasted_pt = (float(zero) + float(effective_beta) + float(loan['beta2'] or 0.) * float(mrktdiff_2) + float(loan['beta3'] or 0.) * float(mrktdiff_3))
print("before rounding forecastedpt is ")
print(forecasted_pt)
print("after rounding")
print(round(forecasted_pt,5))
numb = round(forecasted_pt,5)
print(round(numb,4))
print("Dont get this part")
print(round(0.97745,4))
the output:
before rounding forecastedpt is
0.9774499999999999
after rounding
0.97745
0.9775
Dont get this part
0.9775
the round function in any language dont round all entire number its strip the numbers to round only the last number of it.
From the python documentation:
Note: The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
Try this:
I remember on my statistics class 10 years ago. My Professor has always been advising us to round the calculation up to 6 decimal points as statistics is all about estimation, it counts alot.
zero = 0.9700
effective_beta = 0.00745
loan = {}
loan['beta2'] = 0.0
loan['beta3'] = 0.0
mrktdiff_2 =0.08880400
mrktdiff_3 = 0.026463592000
forecasted_pt = round((float(zero) + float(effective_beta) + float(loan['beta2'] or 0.) * float(mrktdiff_2) + float(loan['beta3'] or 0.) * float(mrktdiff_3)),6)
print(round(forecasted_pt,4))
I would like to know how to convert a sympy value with a physical unit into the same unit with another prefix. For example:
>>> import sympy.physics.units as u
>>> x = 0.001 * u.kilogram
0.001kg
should be converted to grams. The approach I have taken so far is very bloated and delivers a wrong result.
>>> x / u.kilogram * u.gram
1.0^-6kg
It should be 1g instead.
If you can accept printing 1 instead of 1g, you could just use division:
>>> x / u.g
1.0
Otherwise, you'd better switch to sympy.physics.unitsystems.
>>> from sympy.physics.unitsystems import Quantity
>>> from sympy.physics.unitsystems.systems import mks
>>> Quantity(0.001, mks['kg'])
0.001kg
>>> _.convert_to(mks['g'])
1g
>>> u.convert_to(x, u.gram)
1.0*gram
I have a program that is a converter for times in minutes and seconds and returns a float value with a decimal, for example:
6.57312
I would like to extract the .57312 part in order to convert it to seconds.
How can I get python to take only the value after the decimal point and put it into a variable that I can then use for the conversion?
You can do just a simple operation
dec = 6.57312 % 1
math.modf does that. It also has the advantage that you get the whole part in the same operation.
import math
f,i = math.modf(6.57312)
# f == .57312, i==6.0
Example program:
import math
def dec_to_ms(value):
frac,whole = math.modf(value)
return "%d:%02d"%(whole, frac*60)
print dec_to_ms(6.57312)
You can do this also
num = 6.57312
dec = num - int(num)
Encountered a problem whereby my JSON data gets printed as a scientific notation instead of a float.
import urllib2
import json
import sys
url = 'https://bittrex.com/api/v1.1/public/getmarketsummary?market=btc-quid'
json_obj = urllib2.urlopen(url)
QUID_data = json.load(json_obj)
QUID_MarketName_Trex = QUID_data["result"][0]["MarketName"][4:9]
QUID_Last_Trex = QUID_data["result"][0]["Last"]
QUID_High_Trex = QUID_data["result"][0]["High"]
QUID_Low_Trex = QUID_data["result"][0]["Low"]
QUID_Volume_Trex = QUID_data["result"][0]["Volume"]
QUID_BaseVolume_Trex = QUID_data["result"][0]["BaseVolume"]
QUID_TimeStamp_Trex = QUID_data["result"][0]["TimeStamp"]
QUID_Bid_Trex = QUID_data["result"][0]["Bid"]
QUID_Ask_Trex = QUID_data["result"][0]["Ask"]
QUID_OpenBuyOrders_Trex = QUID_data["result"][0]["OpenBuyOrders"]
QUID_OpenSellOrders_Trex = QUID_data["result"][0]["OpenSellOrders"]
QUID_PrevDay_Trex = QUID_data["result"][0]["PrevDay"]
QUID_Created_Trex = QUID_data["result"][0]["Created"]
QUID_Change_Trex = ((QUID_Last_Trex - QUID_PrevDay_Trex)/ QUID_PrevDay_Trex)*100
QUID_Change_Var = str(QUID_Change_Trex)
QUID_Change_Final = QUID_Change_Var[0:5] + '%'
print QUID_Last_Trex
It prints the following value; 1.357e-05.
I need this to be a float with 8 chars behind the decimal (0.00001370)
As you can see here --> http://i.imgur.com/FCVM1UN.jpg, my GUI displays the first row correct (using the exact same code).
You are looking at the default str() formatting of floating point numbers, where scientific notation is used for sufficiently small or large numbers.
You don't need to convert this, the value itself is a proper float. If you need to display this in a different format, format it explicitly:
>>> print(0.00001357)
1.357e-05
>>> print(format(0.00001357, 'f'))
0.000014
>>> print(format(0.00001357, '.8f'))
0.00001357
Here the f format always uses fixed point notation for the value. The default precision is 6 digits; the .8 instructs the f formatter to show 8 digits instead.
In Python 3, the default string format is essentially the same as format(fpvalue, '.16g'); the g format uses either a scientific or fixed point presentation depending on the exponent of the number. Python 2 used '.12g'.
You can use print formatting:
x = 1.357e-05
print('%f' % x)
Edit:
print('%.08f' % x)
There are some approaches:
#1 float(...) + optionally round() or .format()
x = float(1.357e-05)
round(x, 6)
"{:.8f}".format(x)
#2 with decimal class
import decimal
tmp = decimal.Decimal('1.357e-05')
print('[0]', tmp)
# [0] 0.00001357
tmp = decimal.Decimal(1.357e-05)
print('[1]', tmp)
# [1] 0.0000135700000000000005188384444299032338676624931395053863525390625
decimal.getcontext().prec = 6
tmp = decimal.getcontext().create_decimal(1.357e-05)
print('[2]', tmp)
# [2] 0.0000135700
#3 with .rstrip(...)
x = ("%.17f" % n).rstrip('0').rstrip('.')
Note: there are counterparts to %f:
%f shows standard notation
%e shows scientific notation
%g shows default (scientific if 5 or more zeroes)
For a project in one of my classes we have to output numbers up to five decimal places.It is possible that the output will be a complex number and I am unable to figure out how to output a complex number with five decimal places. For floats I know it is just:
print "%0.5f"%variable_name
Is there something similar for complex numbers?
You could do it as is shown below using the str.format() method:
>>> n = 3.4+2.3j
>>> n
(3.4+2.3j)
>>> '({0.real:.2f} + {0.imag:.2f}i)'.format(n)
'(3.40 + 2.30i)'
>>> '({c.real:.2f} + {c.imag:.2f}i)'.format(c=n)
'(3.40 + 2.30i)'
To make it handle both positive and negative imaginary portions properly, you would need a (even more) complicated formatting operation:
>>> n = 3.4-2.3j
>>> n
(3.4-2.3j)
>>> '({0:.2f} {1} {2:.2f}i)'.format(n.real, '+-'[n.imag < 0], abs(n.imag))
'(3.40 - 2.30i)'
Update - Easier Way
Although you cannot use f as a presentation type for complex numbers using the string formatting operator %:
n1 = 3.4+2.3j
n2 = 3.4-2.3j
try:
print('test: %.2f' % n1)
except Exception as exc:
print('{}: {}'.format(type(exc).__name__, exc))
Output:
TypeError: float argument required, not complex
You can however use it with complex numbers via the str.format() method. This isn't explicitly documented, but is implied by the Format Specification Mini-Language documentation which just says:
'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
. . .so it's easy to overlook.
In concrete terms, the following works in both Python 2.7.14 and 3.4.6:
print('n1: {:.2f}'.format(n1))
print('n2: {:.2f}'.format(n2))
Output:
n1: 3.10+4.20j
n2: 3.10-4.20j
This doesn't give you quite the control the code in my original answer does, but it's certainly much more concise (and handles both positive and negative imaginary parts automatically).
Update 2 - f-strings
Formatted string literals (aka f-strings) were added in Python 3.6, which means it could also be done like this in that version or later:
print(f'n1: {n1:.2f}') # -> n1: 3.40+2.30j
print(f'n2: {n2:.3f}') # -> n2: 3.400-2.300j
In Python 3.8.0, support for an = specifier was added to f-strings, allowing you to write:
print(f'{n1=:.2f}') # -> n1=3.40+2.30j
print(f'{n2=:.3f}') # -> n2=3.400-2.300j
Neither String Formatting Operations - i.e. the modulo (%) operator) -
nor the newer str.format() Format String Syntax support complex types.
However it is possible to call the __format__ method of all built in numeric types directly.
Here is an example:
>>> i = -3 # int
>>> l = -33L # long (only Python 2.X)
>>> f = -10./3 # float
>>> c = - 1./9 - 2.j/9 # complex
>>> [ x.__format__('.3f') for x in (i, l, f, c)]
['-3.000', '-33.000', '-3.333', '-0.111-0.222j']
Note, that this works well with negative imaginary parts too.
For questions like this, the Python documentation should be your first stop. Specifically, have a look at the section on string formatting. It lists all the string format codes; there isn't one for complex numbers.
What you can do is format the real and imaginary parts of the number separately, using x.real and x.imag, and print it out in a + bi form.
>>> n = 3.4 + 2.3j
>>> print '%05f %05fi' % (n.real, n.imag)
3.400000 2.300000i
As of Python 2.6 you can define how objects of your own classes respond to format strings. So, you can define a subclass of complex that can be formatted. Here's an example:
>>> class Complex_formatted(complex):
... def __format__(self, fmt):
... cfmt = "({:" + fmt + "}{:+" + fmt + "}j)"
... return cfmt.format(self.real, self.imag)
...
>>> z1 = Complex_formatted(.123456789 + 123.456789j)
>>> z2 = Complex_formatted(.123456789 - 123.456789j)
>>> "My complex numbers are {:0.5f} and {:0.5f}.".format(z1, z2)
'My complex numbers are (0.12346+123.45679j) and (0.12346-123.45679j).'
>>> "My complex numbers are {:0.6f} and {:0.6f}.".format(z1, z2)
'My complex numbers are (0.123457+123.456789j) and (0.123457-123.456789j).'
Objects of this class behave exactly like complex numbers except they take more space and operate more slowly; reader beware.
Check this out:
np.set_printoptions(precision=2) # Rounds up to 2 decimals all float expressions
I've successfully printed my complexfloat's expressions:
# Show poles and zeros
print( "zeros = ", zeros_H , "\n")
print( "poles = ", poles_H )
out before:
zeros = [-0.8 +0.6j -0.8 -0.6j -0.66666667+0.j ]
poles = [-0.81542318+0.60991027j -0.81542318-0.60991027j -0.8358203 +0.j ]
out after:
zeros = [-0.8 +0.6j -0.8 -0.6j -0.67+0.j ]
poles = [-0.82+0.61j -0.82-0.61j -0.84+0.j ]