Approach, fast and dirty - "str.replace":
Python's string manipulation facilities allow you to transform the number into a string, and replace the "." character. through the ",".
Just do something like: print(str(1234.56).replace(".", ","))
Appropriate approach: "locale"
However, although this technique is simple and works well from the end-user's point of view, it is not considered a good practice - because semantically you no longer have a number - you are exchanging characters in a string. The biggest problem however is that this ties your code into specific formatting. It's one thing to be doing a little program of some 300 lines for personal use. Another is to be programming a complex system, which will have to serve users in several different languages and countries, always "doing the right thing". And this is the reality of both who codifies Open Source projects and who is in any company that wants to grow a little.
Well, of course in so many decades of computing there are standardized and correct ways to write a generic code that can format numbers (and write things like names of months and days of the week, word order with accent, etc ... ) that work for different countries and languages, simply by changing the configuration. These forms serve the name of "locale" - and in Python they are usable through the package of the same name as the default library:
locale
.
To format numbers like we used in Brazil you need the following steps:
- import the package locale
- change the locale setting to numbers to use Brazilian Portuguese with a call to
locale.setlocale
- convert your number to string using the function
locale.format
So, in fact, if the program is going to be fixed in Brazilian Portuguese, it's very simple. Ah, to read back a number entered by the user you can use the locale.atof
function to convert the number correctly, according to the country of the program.
Below is a small program that performs a print and input using the Brazilian locale (pt_BR) and the American (en_US) in sequence:
import locale
def body():
suggestion = 3500
str_value = input(
"Digite a pretenção salarial (exemplo: R${}): ".format(
locale.format("%.2f", suggestion)
)
)
value = locale.atof(str_value)
print(
"Valor numérico interno: {}. Valor formatado: {}".format(
value,
locale.format("%.2f", value, grouping=True, monetary=True)
)
)
def main():
for locale_name in ("pt_BR", "en_US"):
locale.setlocale(locale.LC_ALL, (locale_name, ""))
print("\n\nExemplo usando o locale {}: \n".format(locale_name))
body()
if __name__ == "__main__":
main()
Some details: locale.format
and locale.format_string
functions use Python's "old" numeric formatting syntax - the one that uses the %
string-formatting operator - which inherits from the printf
of the C language. you can see the details of this formatting in the documentation, but the important thing is to know that you must provide a formatting string starting with the character "%", of the desired total size of the number, followed by a "." followed by the number of boxes after the desired comma and finally the character "f" - that is, our "% .02f" indicates that we are going to format a decimal number of a size that does not matter, but always with two boxes after the comma .
Another detail is that in this example I used the "format" method which was the one recommended for formatting strings in the last years in Python - before leaving Python 3.6 - with Python 3.6 you can use fstrings - strings in which quotes are prefixed with the letter "f" instead of calling the "format" method - and inserting Python expressions directly between braces ({}) within the string itself. The final print line in Python 3.6 would be: print(f"Valor numérico interno: {value}. Valor formatado: {locale.format("%.2f", value, grouping=True, monetary=True)}")
Please note that the program more or less follows the good practice of "being tolerant of incoming entries and being strict with what prints back" - it does not matter if the user types the thousands separator (the "." in the case of numbers as we used in Brazil) - it formats back with this tab, using the optional "grouping" parameter of the locale.format
function.
See the locale's full documentation at link . And - in order to leave the answer complete - if the program is to be "internationalized" only the locale is not enough - it is necessary to use a framework that allows the translation of all the strings that go to the interface of the program. The locale module only takes care of the formatting of numbers and names of months and days of the week. For translations, you need to use the gettext library: link