I am trying to make a Python function that takes a float number, and converts it to a string with its binary (considering the fractional part too, separated by a dot), but for some values -such as 0.5, 0.25, 0.10, 0.05 , 0.05, ...- it gives the following error:
line 7, in floatToBinary integerPart, fractionalPart = str((convertDecimal(fractional))*2).split(".")
ValueError: Not enough values to unpack (expected 2, got 1)
Functions:
def floatToBinary(floatNumber, decimalPlaces):
integerPart, fractionalPart = str(floatNumber).split(".")
integerPart = int(integerPart)
fractionalPart = int(fractionalPart)
result = bin(integerPart).lstrip("0b") + "."
for i in range(decimalPlaces):
integerPart, fractionalPart = str((convertDecimal(fractionalPart))*2).split(".")
fractionalPart = int(fractionalPart)
result += integerPart
return result
def convertDecimal(n):
while n > 1:
n /= 10
return n
Hope you can help me.
The function convertDecimal returns 0 when n = 0. So there is no '.' to split.
You can fix that by casting the return value as float
def convertDecimal(n):
while n > 1:
n /= 10
return float(n)
Related
I have a float variable with a value of 0.9533. How can I convert it to an int variable so that the value becomes 9553?
a = ((i.left + i.right) / 2)
a = ("{:.4f}".format(a)) //get a: float = 0.9533
print(f"Result 1: {a}")
b = int(a * 10000) //get b: int
print(f"Result 2: {b}")
I get an error:
Result 1: 0.9533
ValueError: invalid literal for int() with base 10: '0.95330.95330...95330'
This should work!
a: float = 0.9533 # Get the number here.
b: int = int(str(a).split('.')[1])
This converts the float to a string, then uses Python's split method for string to split it by the '.' character, then gets the second element of the returned array (index 1), and converts that back into an int, super simple! Hope this helps!
Here is a more general solution that will work with any number.
import decimal
def to_int(num):
d = decimal.Decimal(str(num))
exponent = d.as_tuple().exponent * -1
return int(num * (10 ** (exponent)))
to_int(0.9553) # 9553
Initially, the number was 0.953381023.. . It was necessary to round to 4 digits after the dot, so I used formatting.
This solution helped me:
b = int((a * 10000)[2:6])
a = .0004251
b,c = map(str,map(int,str(a).split('.',1)))
print(int(b+c))
Output:
4251
Here's the code that i'm using:
pie = []
start = 102
stop = 1
step = 1
for i in range(stop,start):
result = (i - step) / 100
pie.append(result)
print(pie)
for i in pie:
result = pie[i] * pie[i-1]
pie.append(result)
print(pie)
and here's the error that i'm getting:
TypeError: list indices must be integers or slices, not float
You have added float numbers in pie list:
result = (i - step) / 100
pie.append(result) # [0.0, 0.01, 0.02, ...]
Then you used those numbers here as index:
for i in pie:
result = pie[1] * pie[i - 1]
pie.append(result)
Error is also saying same thing: list indices must be integers or slices, not float
I need to calculate values of type float, so, in python, 0.01 is not 0.01 but 0.10000000000000001 + some digits (referenced by python documentation Floating).
Ok, my function needs to calculate the number of coins for each value.
def calcula_moedas(resto):
moedas = [0.5, 0.1, 0.05, 0.01]
cont_moeda = {'0.5': 0, '0.1': 0, '0.05': 0, '0.01': 0}
if resto > 0.00:
for valor in moedas:
while resto >= valor:
str_valor = str(valor)
cont_moeda[str_valor] += 1
resto = round(resto, 2) - valor
break
return cont_moeda
return cont_moeda
I tried to use round(resto, 2), round(resto, 10) and Decimal(resto), but the result is wrong yet.
Using resto = round(resto, 2) - valor the result is 0.04999999999999999 when I pass a values 0.15.
Using Decimal the result is:
Image for Decimal module
How can I around this number so that the rounded number is 0.05?
you can use:
resto = round(resto - valor, 2)
I want to split a decimal number into a random table where the sum of the elements in the array equals the original number
# Call a function which receives a decimal number
from decimal import Decimal
from something import split_random_decimal
split_decimal = split_random_decimal(Decimal('10.00'))
print(split_decimal)
# Output: [1.3, 0.7, 1.2, 0.8, 1.0, 1.5, 0.5, 1.9, 0.1, 1.0]
print(sum(split_decimal))
# Output: Decimal('10.00') - The original decimal value
Has anyone an idea how I could do this in pure Python without using a library?
Solved!
Thks for all who have help me, the final beautiful code who saved my life is this:
import random
def random_by_number(number, min_random, max_random, spaces=1, precision=2):
if spaces <= 0:
return number
random_numbers = [random.uniform(min_random, max_random) for i in range(0, spaces)]
increment_number = (number - sum(random_numbers)) / spaces
return [round(n + increment_number, precision) for n in random_numbers]
number = 2500.50
spaces = 30
max_random = number / spaces
min_random = max_random * 0.6
random_numbers = random_by_number(number, min_random, max_random, spaces=spaces, precision=2)
print(random_numbers)
print(len(random_numbers))
print(sum(random_numbers))
You could start with something like:
numberLeft = 10.0
decList = list()
while numberLeft > 0:
cur = random.uniform(0, numberLeft)
decList.append(cur)
numberLeft -= cur
This implementation would choose higher random numbers at first which wouldn't be that hard to logically change.
numberLeft will never hit exactly 0 so you could do something with rounding. You could also wait for numberLeft to get low enough and that would be your last random number in the list.
The problem is a little under defined: into how many pieces should it be split and how large may any piece be? Should the values only be positive? An approximate solution from what you've said would be to pick a random number of pieces (defaulting to 10) and making the values be distributed normally about the average size of the pieces with a standard deviation of 1/10 of the average:
from decimal import Decimal
def split_random_decimal(x, n=10):
assert n > 0
if n == 1:
return [x]
from random import gauss
mu = float(x)/n
s = mu/10
if '.' in str(x):
p = len(str(x)) - str(x).find('.') - 1
else:
p = 0
rv = [Decimal(str(round(gauss(mu, s), p))) for i in range(n-1)]
rv.append(x - sum(rv))
return rv
>>> splited_decimal = split_random_decimal(Decimal('10.00'))
>>> print(splited_decimal)
[Decimal('0.84'), Decimal('1.08'), Decimal('0.85'), Decimal('1.04'),
Decimal('0.96'), Decimal('1.2'), Decimal('0.9'), Decimal('1.09'),
Decimal('1.08'), Decimal('0.96')]
I think this is what you're looking for:
import random as r
def random_sum_to(n, num_terms = None):
n = n*100
num_terms = (num_terms or r.randint(2, n)) - 1
a = r.sample(range(1, n), num_terms) + [0, n]
list.sort(a)
return [(a[i+1] - a[i])/100.00 for i in range(len(a) - 1)]
print(random_sum_to(20, 3)) # [8.11, 3.21, 8.68] example
print(random_sum_to(20, 5)) # [5.21, 7.57, 0.43, 3.83, 2.96] example
print(random_sum_to(20)) # [1 ,2 ,1 ,4, 4, 2, 2, 1, 3] example
n is the number in which you are summing to, and num_terms is the length of the string you would like as a result. Also if you look at the last example you can see that if you don't want to specify a "num_terms" you don't have to and it will do that for you!
The R ppoints function is described as:
Ordinates for Probability Plotting
Description:
Generates the sequence of probability points ‘(1:m - a)/(m +
(1-a)-a)’ where ‘m’ is either ‘n’, if ‘length(n)==1’, or
‘length(n)’.
Usage:
ppoints(n, a = ifelse(n <= 10, 3/8, 1/2))
...
I've been trying to replicate this function in python and I have a couple of doubts.
1- The first m in (1:m - a)/(m + (1-a)-a) is always an integer: int(n) (ie: the integer of n) if length(n)==1 and length(n) otherwise.
2- The second m in the same equation is NOT an integer if length(n)==1 (it assumes the real value of n) and it IS an integer (length(n)) otherwise.
3- The n in a = ifelse(n <= 10, 3/8, 1/2) is the real number n if length(n)==1 and the integer length(n) otherwise.
This points are not made clear at all in the description and I'd very much appreciate if someone could confirm that this is the case.
Add
Well this was initially posted at https://stats.stackexchange.com/ because I was hoping to get the input of staticians who work with the ppoints function. Since it has been migrated here, I'll paste below the function I wrote to replicate ppoints in python. I've tested it and both seem to give back the same results, but I'd be great if someone could clarify the points made above because they are not made at all clear by the function's description.
def ppoints(vector):
'''
Mimics R's function 'ppoints'.
'''
m_range = int(vector[0]) if len(vector)==1 else len(vector)
n = vector[0] if len(vector)==1 else len(vector)
a = 3./8. if n <= 10 else 1./2
m_value = n if len(vector)==1 else m_range
pp_list = [((m+1)-a)/(m_value+(1-a)-a) for m in range(m_range)]
return pp_list
I would implement this with numpy:
import numpy as np
def ppoints(n, a):
""" numpy analogue or `R`'s `ppoints` function
see details at http://stat.ethz.ch/R-manual/R-patched/library/stats/html/ppoints.html
:param n: array type or number"""
try:
n = np.float(len(n))
except TypeError:
n = np.float(n)
return (np.arange(n) + 1 - a)/(n + 1 - 2*a)
Sample output:
>>> ppoints(5, 1./2)
array([ 0.1, 0.3, 0.5, 0.7, 0.9])
>>> ppoints(5, 1./4)
array([ 0.13636364, 0.31818182, 0.5 , 0.68181818, 0.86363636])
>>> n = 10
>>> a = 3./8. if n <= 10 else 1./2
>>> ppoints(n, a)
array([ 0.06097561, 0.15853659, 0.25609756, 0.35365854, 0.45121951,
0.54878049, 0.64634146, 0.74390244, 0.84146341, 0.93902439])
One can use R fiddle to test implementation.