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