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)
Related
I'm working on a Python script that will read a file and grab a string total_time. Currently, this is what I have.
if("Total time" in data):
total_time=int(filter(str.isdigit, data))
print(total_time)
Output: 419
I'm trying to find the best way to read lots of files, grab this total time, and convert 419 into 4 hours and 19 minutes to allow me to do some statics and analytics with this.
Passing format argument to datetime in Pandas:
t="419"
a = pd.to_datetime(t, format='%H%M')
print(a.hour)
print(a.minute)
The built-in function divmod() seems appropriate here!
>>> a = 5
>>> b = 3
>>> divmod(a,b) # (a // b, a % b)
(1,2)
For your specific situation:
def dataToTime(data):
''' Returns a list of (hour, minute) tuples from
a list of strings '''
total_times = filter(str.isdigit,data)
return [divmod(int(time),100) for time in total_times]
If you would like to parse the data as you are inputting it try the re module which has the method re.sub() for regex substitution
>>> import re
>>> s = '| Total time | 4:19 | | |--------------+--------+------| –'
>>> h = int(re.sub(r':.*$|[^0-9]','',s))
>>> m = int(re.sub(r'^.*:|[^0-9]','',s))
>>> print h,m
(4,19)
Given some string set as
s = '419'
you can get the upper and lower digits by converting to an integer, then using modulo and integer division. The integer conversion can be encapsulated in a try-except block catching ValueError if you have a reasonable response to invalid inputs:
n = int(s)
hours = n // 100 # Truncating integer division
minutes = n % 100 # Modulo removes the upper digits
I've written the python script below to convert hexadecimal to decimal.
It seems to work fine, at least as long as the hexadecimal has less then 8 characters .
What did I do wrong ? Tnx !
""" converts hexidecimal to decimal"""
def HextoDec (string):
ret = 0
for i in string :
hex = "0123456789ABCDEF"
value= hex.index(i) # 0 to 15
index = string.index(i)
power = (len(string) -(index+1)) #power of 16
ret += (value*16**power)
return ret
print(HextoDec("BAABFC7DE"))
The problem is this line:
index = string.index(i)
index() returns the position of the first match. If the hex number contains any duplicate characters, you'll get the wrong index for all the repeats.
Instead of searching for the index, get it directly when you're iterating:
for index, i in enumerate(string):
There is a much easier way to convert hexadecimal to decimal without the use of a custom function - just use the built-in int() function like so:
int("BAABFC7DE", base=16) #replace BAABFC7DE with any hex code you want
But if you do want to use a custom function, then Barmar's answer is the best.
As Barmar pointed out. The issued is with the line
index = string.index(i)
Which returns first match. Try this:
def HextoDec (string):
ret = 0
for i,d in enumerate(string) :
hex = "0123456789ABCDEF"
value= hex.index(d) # 0 to 15
#index = string.index(i)
power = (len(string) -(i+1)) #power of 16
ret += (value*16**power)
return ret
(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}
taking only the lower 3 digits of decimal data? Any python math function library do the job
data = 55554343.345
incoming(data)
def incoming(data)
in_data = data
I need to collect the last 3 bit of my decimal data to be like: in_data = 343.345
Get the reminder of division by 1000
def incoming(data)
in_data = round(data % 1000,3)
Thanks to sammy :)
data = 1411984956.155
incoming(data)
def incoming(incoming_data)
in_da = str(incoming_data)
print 'incoming data', float(in_da[7:])
result:
incoming data 956.155
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)