Home > Back-end >  ValueError: could not convert string to float: '$50.50'
ValueError: could not convert string to float: '$50.50'

Time:10-12

I have this python function here. However when running I'm getting an error "could not convert string to float: '$50.50'". I need to add the input as a string including the "$" sign and then convert it to a float number in the backend. The function seems to work adding only "50.50" as input.

def main():
    dollars = dollars_to_float(input("How much was the meal? "))
    percent = percent_to_float(input("What percentage would you like to tip? "))
    tip = dollars * percent/100
    print(f"Leave $" , str(tip) )

def dollars_to_float(d):
    str.lstrip(d)
    return float(d)

def percent_to_float(p):
    str.rstrip(p)
    return float(p)
    
main()

Error:

File "/Users/nelsonlamounier/indoor/indoor.py", line 13, in <module>
main()

File "/Users/nelsonlamounier/indoor/indoor.py", line 9, in dollars_to_float
return float(d)

File "/Users/nelsonlamounier/indoor/indoor.py", line 9, in dollars_to_float
return float(d)

ValueError: could not convert string to float: '$50.50'

CodePudding user response:

For a more general case, update dollars_to_float with the following:

def dollars_to_float(d):
    d = ''.join([ch for ch in d if ch.isnumeric() or ch == '.'])
    return float(d)

CodePudding user response:

Just remove $ before number like:

def dollars_to_float(d):
  str.lstrip(d)
  return float(d.replace("$",""))

CodePudding user response:

Your code is error prone, as a single space character would already be able to break it. A more robust version of the currency to float conversion can be found here Remove currency symbols and literals from a string with a price universal solution

You use locale to see what is the decimal point character (, or .), and regex to remove all characters other than numerals and the decimal point.

import re
import locale

def dollars_to_float(price_string: str) -> float:
  decimal_point_char = locale.localeconv()['decimal_point']
  clean = re.sub(r'[^0-9' decimal_point_char r'] ', '', str(price_string))
  return float(clean)

CodePudding user response:

If you want to remove specific characters from the beginning or end of a string then use strip()

In this case your dollars_to_float and percent_to_float could be generalised to:

def to_float(d):
  return float(d.strip('$%'))

This has the advantage of supporting the $ and % characters at either the beginning or end of the string.

However, say the input is like this '$1,200'

That's going to fail due to the thousands separator. Also, why limit functionality to just dollars. Why not allow for an arbitrary preamble to the input string - e.g., USD1,200 or £1,234,50

Here's a reasonably robust approach to this problem.

import re
from locale import LC_NUMERIC, setlocale, localeconv

class CC:
    dp = None
    def __init__(self):
        if CC.dp is None:
            setlocale(LC_NUMERIC, '')
            dp = localeconv()['decimal_point']
            CC.dp = f'[^0-9{dp} -] '
    def conv(self, s):
        return float(re.sub(CC.dp, '', s))

print(CC().conv('$1,200.5'))
print(CC().conv('£1,200'))
print(CC().conv('EUR1234.5'))
print(CC().conv('6543.21'))

Output:

1200.5
1200.0
1234.5
6543.21
  • Related