Compact float printing in the REPL


#1

How can I globally change the printing format of the REPL? I would specifically like to change the formatting of floats to a more compact style so that

julia> 10/3
3.3333

instead of

julia> 10/3
3.3333333333333335

I found this issue which was closed without resolution.

Looking at the code I see that

function Base.show(io::IO, x::Union{Float64,Float32})
    if get(io, :compact, false)
        _show(io, x, PRECISION, 6, true, true)
    else
        _show(io, x, SHORTEST, 0, true, false)
    end
end

refers to :compact but I don’t know how to set this. The REPL formatting section of the manual doesn’t mention it either.


#2

Did you ever find a nice answer to this?


#3

from the docs (latest) search IOContext

julia> print(IOContext(stdout, :compact => false), 1.12341234)
1.12341234
julia> print(IOContext(stdout, :compact => true), 1.12341234)
1.12341

This does not change the way the REPL shows all Float64 values.


#4

Thanks.

The reason that I am asking about this now is that I am doing demonstrations in class.
For these, I would like to keep the syntax as simple as possible so that students can easily follow.
But, I would also like to keep the numbers short.
The projector in my classroom can’t handle high resolution!


#5

You can redefine the show method for float. @which show(stdout, 2/3) shows you where it is, @less prints it. This modification might work:

julia> function Base.show(io::IO, x::Union{Float64,Float32})
                 Base.Grisu._show(io, round(x, sigdigits=3), Base.Grisu.SHORTEST, 0, get(io, :typeinfo, Any) !== typeof(x), false)
         end                                                                                                                                                            
                                                                                                                                                                        
julia> 2/3                                                                                                                                                              
0.667                                                                                                                                                                   

julia> rand(10)                                                                                                                                                         
10-element Array{Float64,1}:                                                                                                                                            
 0.684                                                                                                                                                                  
 0.594                                                                                                                                                                  
 0.0643
 0.695                                                                                                                                                                  
 0.524                                                                                                                                                                  
 0.884                                                                                                                                                                  
 0.541                                                                                                                                                                  
 0.49                                                                                                                                                                   
 0.175                                                                                                                                                                  
 0.561                                                                                                                                                                  

(Note, there is a certain danger in redefining Base-methods! But should be ok for show)


#6

Thanks!

That does just what I need.


#7

Redefining show entirely seems a bit dramatic. I quoted the default show code above. Wouldn’t it be more appropriate to somehow change what is returned by this line:

get(io, :compact, false)

Can I can I somehow

set(stdout, :compact, true)

? This doesn’t work btw.


#8

I am almost certain that there are better ways to do it, but I’m entirely certain that I don’t know those ways…


#9
julia> 2/3
0.6666666666666666

julia> struct IOContextDisplay <: AbstractDisplay
           ctx
       end

julia> function Base.Multimedia.display(d::IOContextDisplay, x)
           io = IOBuffer()
           ctx = d.ctx(io)
           show(ctx, "text/plain", x)
           println(stdout, String(take!(io)))
       end

julia> disp = IOContextDisplay(x -> IOContext(x, :compact => true, :limit => true, :color => true))
IOContextDisplay(getfield(Main, Symbol("##3#4"))())

julia> pushdisplay(disp);

julia> 2/3
0.666667

This will probably break in some cases (and won’t work in Juno).