Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to set REPL output format to engineering notation #46267

Open
tgross35 opened this issue Aug 6, 2022 · 3 comments
Open

Add a way to set REPL output format to engineering notation #46267

tgross35 opened this issue Aug 6, 2022 · 3 comments
Labels
display and printing Aesthetics and correctness of printed representations of objects.

Comments

@tgross35
Copy link

tgross35 commented Aug 6, 2022

Hello all,

I would like to suggest adding a simple way to configure the output format to use engineering notation - that is, scientific notation that is restricted to powers of three. This sort of formatting is very useful for easy conversion to SI units.

For example, after enabling this feature, something like the following would be expected:

julia> 1200
1.2e3

julia> 10000
10e3

julia> 0.0001
100e-6

julia> [10 1000 100000 10000000]
1×4 Matrix{Int64}:
 10  1e3  100e3  10e6

With this formatting, the outputs are quick to read as 1.2k, 10M, 100µ, etc.

The package NumericIO (link here) implements this functionality via functions, and this StackOverflow question includes a solution. However, both options come with overhead (a package or a lengthy function), and requires putting the output through a separate function, rather than native display (though this could likely be changed by overriding Base.show, which is another step).

Matlab/Octave allows this with format short eng (link to the relevant MatLab docs here).

octave:1> format compact
octave:2> format short eng
octave:3> 1200
ans = 1.2000e+003
octave:4> 10000
ans = 10.0000e+003
octave:5> 0.0001
ans = 100.0000e-006
octave:6> [10 1000 100000 10000000]
ans =
    10.0000e+00     1.0000e+03   100.0000e+03    10.0000e+06

A bonus feature would be some way to do something like format compact to not add new lines between interpreter entries (though there may be a way to do this that I just haven't found).

A bonus bonus feature would be a way to enable SI prefixes natively, like in NumericIO. So typing e.g. 1.5k expands to 1500.0, or 2e-8 displays as 20n. (I realize that this is likely out of the scope of what the REPL intends to do, but it is an extremely helpful feature when working with science/engineering documentation)

@mgkuhn
Copy link
Contributor

mgkuhn commented Aug 8, 2022

Julia Base has already the dictionary type IOContext to configure how functions like show display values. And you can already use Base.active_repl.options.iocontext to configure the IOContext that the REPL uses to show the return value of functions.

So I guess what is missing is in IOContext support for a bit more control over the format used for floating-point numbers.

At the moment there is already:

julia> Base.active_repl.options.iocontext[:compact] = true; pi*1e4
31415.9

julia> Base.active_repl.options.iocontext[:compact] = false; pi*1e4
31415.926535897932

But that single Boolean parameter obviously offers fewer options than MATLAB's format command.

In the form of an extended IOContext docstring, what would a nice suitable interface for the desired functionality look like?

@mgkuhn mgkuhn added the display and printing Aesthetics and correctness of printed representations of objects. label Aug 8, 2022
@mgkuhn
Copy link
Contributor

mgkuhn commented Aug 8, 2022

See also previous discussion: #6493

@tgross35
Copy link
Author

tgross35 commented Aug 8, 2022

@mgkuhn thank you for the response, I will drop a quick mention to #6493 as well.

An API related to what you suggest sounds very viable. Off the top of my head, I would suggest mimicing NumericIO, something like:

:numfmt: String value that specifies how Julia should attempt to display numbers. Options are ":DEFAULT"
(use float notation where possible, switch to scientific notation for large values) ":SCI" (always use
scientific notation), ":ENG" (engineering notation, i.e., scientific notation restricted to powers of 3) or
":SI" (add SI prefixes to the end of the words, e.g., 1e7 becomes "10M", 5e-6 becomes "5μ")

Example:
Base.active_repl.options.iocontext[:numfmt] = :ENG

The :SI option is of course not needed, but would be welcome. Something like an enum or struct might be usable to pass instead of a string to help hint values (e.g. ..[:numfmt] = NumFmt.eng) but I am unsure whether there is a precedent for this.

I would also like to make the suggestion that there is also a function or macro added that allows a more terse way of configuring this, and the other IO context options. The current version is a bit lengthy and doesn't validate the given arguments against valid values in the dictionary (I could imagine this may be desired in some cases though)

# This does not complain
julia> Base.active_repl.options.iocontext[:nothing] = true;

# Could something like this be possible? It would complain here
julia> set_iocontext(compact=true, nothing=true)

Also - you might already be aware but just to clarify, Julia's :compact is more akin to Matlab's format short..., Matlab's format compact just gets rid of empty lines in the interpreter, which is useful for fitting more on the screen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

No branches or pull requests

2 participants