Decimal commas instead of points

Does Julia provide a simple way to use decimal commas instead of the standard point?

Some countries use that standard and working with local data is sometimes a hassle. For example, importing spreadsheets with percentage numbers would require users to import the string, convert commas into dots, then use parse to get the proper float variable.

The biggest issue for me is for making tables and graphs. Other tools allow you to set some localization variable which will write variables as appropriate, so an internally stored ā€œ2.5ā€ can be shown as ā€œ2,5ā€ in such situation.

I donā€™t think thereā€™s a built-in way. You can redefine the method that prints floats if you want

 @eval Base.Ryu begin 
        function Base.show(io::IO, x::T, forceuntyped::Bool=false, fromprint::Bool=false) where {T <: Base.IEEEFloat}
           compact = get(io, :compact, false)::Bool
           buf = Base.StringVector(neededdigits(T))
           typed = !forceuntyped && !compact && get(io, :typeinfo, Any) != typeof(x)
           pos = writeshortest(buf, 1, x, false, false, true, -1,
               (x isa Float32 && !fromprint) ? UInt8('f') : UInt8('e'), false, UInt8(','), typed, compact)
           write(io, resize!(buf, pos - 1))
           return
        end
end

The UInt8(',') above used to be UInt8('.') in the original.

This carries some risk though, since you donā€™t know if anything else depends on the expected/default printing, and will silently (or loudly) break. You could also define your own function for printing decimals with commas, either based on the above or custom, and use it when you need it. I.e. when making labels for graphs and tables, use your new function to create the strings.

If this is a must-have for you, you could open an issue on github. Maybe someone who knows more can figure out if making this possible breaks anything important.

1 Like

use CSV.jl:

https://github.com/JuliaData/CSV.jl/issues/83#issuecomment-328656507

1 Like

I thought I had answered before, but apparently something came up. Iā€™m glad to know a solution exists, but itā€™s a bit sad thereā€™s no simple ā€˜locale flagā€™ to set either as default. That said, there would still need additional work for the Plots side of things.

@jling thanks for pointing out CSV.jl. It can probably solve the problem of writing into files with the appropriate limiter, but it certainly doesnā€™t solve showing in Julia REPL and plotting a graph with decimal commas.

Could you use Printf for some of this?

using Printf
replace(@sprintf("%.4f",Ļ€), "." => ",")
"3,1416"

And for plotting, place the ticks manually.

1 Like

I like the simplicity of this approach for dealing with tables, unless Julia has functionality which takes a matrix of elements and automatically turns them into a LaTeX table (which Iā€™m almost sure it does). This may be solved by first translating an array of an arbitrary type into a properly formatted string.

A similar workaround may be possible with Plots. Maybe I can override the current print function to use decimal commas for my environment.

Julia is intentionally locally-independent: https://github.com/JuliaLang/julia/issues/5928

Thereā€™s however open issue:
https://github.com/JuliaLang/julia/issues/6593

You want something like in Python, a locale module:
https://stackoverflow.com/questions/1823058/how-to-print-number-with-commas-as-thousands-separators

Iā€™m not aware of any such module for Julia, in a package, nor as a stdlib, but there is for dates (in the docs): ā€œcustom locales can be loaded by passing in the locale=>Dict{String,Int} mapping to the MONTHTOVALUEABBR and MONTHTOVALUE dicts for abbreviated and full-name month names, respectively.ā€

1 Like

Fyi, using Masonā€™s ReplMaker.jl we can get an interesting REPL with minimal effort, which accepts as input the decimal comma as decimal separator and the point as thousands separator. (Not exactly the OP requirement, but at least it can help to check the grocery cost-of-living.)

using ReplMaker

comma2point(str) = Meta.parse(replace(str, r"[-?0-9]{1,3}(.[0-9]{3})*(\,[0-9]+)?" => s -> replace(s, "."=>"", ","=>".")))


initrepl(comma2point,
    prompt_text="decimal-commas> ",
    prompt_color=:blue,
    start_key=',',
    mode_name="decimal-comma"
)


# Type comma `,` in the REPL to start (may need backspace first):
decimal-commas> 11.123,337 + 456,5 + 5.400              # 16979.837
decimal-commas> x = [11.123,337,  456,5,  5.400]        # 3-element Vector{Float64}
decimal-commas> using Statistics
decimal-commas> (sum(x), mean(x), std(x))               # (16979.837, 5659.95, 5338.17)
2 Likes