I'm working on a project where I have to parse prices. I have to take into account different formats of prices.
Problems:
US citizens write prices this way: 1,000.00
EU this way: 1.000,00
This very problem could be solved splitting string using commas and dots so the last item in the list would be cents. The problem is that sometimes people doesn't write cents at all so somebody could write 1.000 EUR for example.
And there are other problems... sometimes people don't write dots at all.
Do you know some python module or function which could solve this problem and return decimal.Decimal
of the price? I don't care about currency.
EDIT: Assume that I will have thousands of prices in such formats.
A string with digits only (which corresponds to the None style) always parses successfully if it is in the range of the Decimal type. The remaining NumberStyles members control elements that may be but are not required to be present in the input string.
The NumberFormatInfo object that belongs to that CultureInfo object is then passed to the Parse (String, IFormatProvider) method to convert the user's input to a Decimal value.
// Parse a floating point value with thousands separators value = "25,162.1378"; number = Decimal.Parse (value); Console.WriteLine ("' {0}' converted to {1}.", value, number); // Displays: // '25,162.1378' converted to 25162.1378.
The Decimal number equivalent to the number contained in s as specified by style and provider. s is not in the correct format. s represents a number less than Decimal.MinValue or greater than Decimal.MaxValue. s is null. style is not a NumberStyles value. style is the AllowHexSpecifier value.
This code uses this logic:
else if ',' or '.' are the 3rd character from the end, then this is the decimal character:
. strip then non-decimal character, change the decimal char to '.' if necessary, then convert to float
else
. there is no decimal part given, just strip all ',' and '.' and convert to float
This code is very dependent on getting valid strings - invalid strings like "1,2,3.000"
or "1..."
will give erroneous values.
def parse_price(s):
if '.' not in s and ',' not in s:
return float(s)
elif s[-3] in ',.':
dec_char = s[-3]
sep_char = {'.': ',', ',':'.'}[dec_char]
s = s.replace(sep_char, '')
s = s.replace(',', '.')
return float(s)
else:
s = s.replace(',','').replace('.', '')
return float(s)
tests = """\
1.000
1.000,20
23.14
1,234
1.23
3,12
""".splitlines()
for test in tests:
print(test, '->', parse_price(test))
gives
1.000 -> 1000.0
1.000,20 -> 1000.2
23.14 -> 23.14
1,234 -> 1234.0
1.23 -> 1.23
3,12 -> 3.12
Use price-parser:
>>> from price_parser import parse_price
>>> parse_price('1,000.00')
Price(amount=Decimal('1000.00'), currency=None)
>>> parse_price('1.000,00')
Price(amount=Decimal('1000.00'), currency=None)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With