Python point formatting using {}.format and non-English locales

I just stumbled on this so I thought I would post it in case anyone finds it useful.

I have a script that the user will pick a point on an existing curve, later that point needs to be converted into a string so that it can be used in a rs.Command() string in another part of the script. Up to now, I have been using the following to format my 3D points into strings

pt_str="{}".format(my_3d_point)

where my_3d_point is a RhinoCommon Point3d object. I do this because the 3d point is only part of the command string and often there are several replacements made at one time with the format statement, so itā€™s handy.

That has worked fine until now as my OS is in in English and thatā€™s where I testā€¦ To my surprise, the other day, I wanted to demo the script in a class, but I was logged in on a computer that was running a French OS. And it failed.

If I have a 3d point, say, 22.5,11.3,5.0

Running in my English OS the result of the string conversion via {}.format above is the following::

"22.5,11.3,5.0"  #as expected

However running in my French OS, the result is the following:

"22,5;11,3;5,0"  #not at all what I expected

And needless to say that the rs.Command() that contains that string fails, as it does not recognize that as a valid string representing a point.

So, lesson learned, I guess itā€™s best to use the following instead:

pt_str=str(my_3d_point)
#or
pt_str=my_3d_point.ToString()

Note that both of those will truncate trailing 0ā€™s after the decimal point, i.e. 22.0 becomes 22, 22.50 becomes 22.5.

"{},{},{}".format(pt.X,pt.Y,pt.Z)

also seems to work correctly, but slightly differently than the above, for example an input value of 10,5,2 will be formatted to a string 10.0,5.0,2.0.

Anyway, just FYI in case anyone is interested.

1 Like

Iā€™ve too have experienced this issue. Specifically, on Windows between English and Danish. If Iā€™m forced to use a Danish system, I now customise the number formatting to English here:

I donā€™t know for CPython, but since its IronPython you should always care about the culture in use.
You can set the culture app-wide or better for any string formatting operation you specify the culture as an argument. For anything scientific you always provide ā€œCultureInfo.InvariantCultureā€ as an argument in your string formatting operation. This makes floating numbers always separated by dots.

e.g.
myPoint.ToString(CultureInfo.InvariantCulture)
or
String.Format(CultureInfo.InvariantCulture, "{0:0.000}, {1:0.000}", x, y)

(part of the ā€˜System.Globalizationā€™ namespace)

2 Likes