[ANN] PrettyNumbers.jl

Hi!

Long time, no see :slight_smile: I am passing through a very big change, I was pretty much off-line in the previous months.

I just want to announce a very simple package called PrettyNumbers.jl. The idea is to format numbers in many back-ends (text, HTML, LaTeX, etc.), allowing, for example, to change the decimal base easily. Currently, only the text back-end exists.

julia> pretty_number(19//86)
¹⁹/₈₆

julia> pretty_number(19//86; compact = false)
19
——
86

julia> pretty_number(1906.1896)
1.90619 · 10³

julia> pretty_number(1906.1896, significand_format = "%.10f")
1.9061896000 · 10³

julia> pretty_number(1906.1896; new_decimal_base = 4)
0.190619 · 10⁴

I create this package to help me constructing reports when designing space missions like this one:

Depending on the size of the satellite, you want to see the results in a different unit (10^-3 Nm, or 10^-5 Nm, and so on). Hence, with PrettyNumbers.jl I can now do this very easily by just using a keyword argument in the function.

58 Likes

Very nice, thanks for the contribution.

Just a minor formatting comment. Let me cite here the section 7.3.3 Multiplication and division from “ISO 80000-1:2009/Cor 1:2011 Quantities and Units — Part 1: General — Technical Corrigendum 1.” ISO, October 2011. ISO 80000-1:2009/Cor 1:2011 - Quantities and units — Part 1: General — Technical Corrigendum 1 :

If the point is used as the decimal sign, the cross and not the half-high dot should be used as the multiplication sign between numbers expressed with digits. If the comma is used as the decimal sign, both the cross and the half-high dot may be used as the multiplication sign between numbers expressed with digits.

Perhaps having at least an option of this

julia> pretty_number(1906.1896)
1.90619 × 10³

will be great. If not even having this format as default.

14 Likes

Thanks for the information! I will definitely implement this feature :slight_smile: Maybe we can have an option but use the X as the default.

9 Likes

I am a simple man.
I see a package by @Ronis_B, it gets added to my startup.jl.

Awesome tool and glad to see you around again!

7 Likes

Thanks!! :slight_smile: I am glad they are being useful for you!

4 Likes

@Ronis_BR, how would you do pretty_matrix() ?

A preliminary attempt combining your two awesome packages:

using PrettyNumbers, PrettyTables
pretty_matrix(M) = pretty_table(pretty_number.(String, M), noheader=true, tf=tf_borderless, alignment=:c)
M = Any[0.001 2e5; 19//86 -1e-3]
pretty_matrix(M)
# result:
  1 ⋅ 10⁻³    2 ⋅ 10⁵
   ¹⁹/₈₆     -1 ⋅ 10⁻³

On a side note, how to keep π pretty?

pretty_number(π)  # result: 3.14159

Grato :slight_smile:

4 Likes

Hi @rafael.guerra !

This proposal is more or less what I would do to pretty print a matrix. If you want something more “mathematical” but a little bit more verbose, you can use tf = tf_matrix:

┌                     ┐
│ 1 ⋅ 10⁻³   2 ⋅ 10⁵  │
│  ¹⁹/₈₆    -1 ⋅ 10⁻³ │
└                     ┘

Good point! This should be very easy. I just need to add a new renderer for Irrational{:π}. I will try :slight_smile:

4 Likes

@zdenek_hurak done!

If you use the latest version (0.2.0) the default multiplication sign is \times but you can change using the keyword multiplication_sign.

@rafael.guerra

Using latest PrettyTables (due to a bug), I think most matrices can be rendered good enough using this:

julia> using PrettyNumbers, PrettyTables

julia> ft(v, i, j) = pretty_number(String, v);

julia> pretty_matrix(M) = pretty_table(
           M;
           noheader = true,
           formatters = ft,
           alignment_anchor_regex = Dict(0 => [r"\.", r"/"]),
           alignment = :c,
           alignment_anchor_fallback = :r,
           tf = tf_matrix
       );

julia> M = hcat([(randn())^i for i = -5:5 ], [rand(Any[π, ℯ, randn() * 100]) for i = 0:10], [rand(0:50)//rand(0:50) for i = 0:10]);

julia> pretty_matrix(M)
┌                                        ┐
│  1.20536 × 10³    π               ⁸/₄₁ │
│  5.51494 × 10²    ℯ              ⁴¹/₁₇ │
│ -4.43545 × 10⁻¹   π               ⁷/₆  │
│  4.77558 × 10⁻¹   π              ³⁷/₂₁ │
│  9.69893          5.99425 × 10¹  ⁴⁸/₁₇ │
│  1                ℯ              ⁴⁶/₃₃ │
│ -1.5696           π               ⁷/₃  │
│  1.89858          π               ⁷/₃₉ │
│ -5.55123 × 10⁻²   ℯ              ³⁸/₄₅ │
│  1.95432 × 10⁻¹  -7.89276 × 10¹   ³/₇  │
│ -1.57892 × 10⁻³  -9.1711 × 10¹   ⁴⁸/₅  │
└                                        ┘
5 Likes

I assume that e in the matrix stands for the Euler’s number. Then I cannot help bothering you once again with a reference to (another) standard: ISO 80000-2:2019 - Quantities and units — Part 2: Mathematics. In section 3 it reads

2 Likes

That is the Julia default:

help?> ℯ
"ℯ" can be typed by \euler<tab>
2 Likes

I see. Then… I don’t know :grinning:

Yes! It used to be just e, I think, but changed at some point.

1 Like

Here’s the old discussion of this.

https://github.com/JuliaLang/julia/pull/10612

It looks like Julia adopted the unicode character which is recommended as the natural exponent. And that’s inconsistent with the ISO standard. From https://unicode.org/charts/PDF/U2100.pdf :

212F ℯ SCRIPT SMALL E
= error
= natural exponent
≈ 0065 e latin small letter e

5 Likes