This package offers Python-style general formatting and c-style numerical formatting (for speed).
PackageEvaluator | Build Status |
---|---|
This package is pure Julia. Setting up this package is like setting up other Julia packages:
Pkg.add("Formatting")
To start using the package, you can simply write
using Formatting
This package depends on Julia of version 0.7 or above. It has no other dependencies. The package is MIT-licensed.
This package has two types FormatSpec
and FormatExpr
to represent a format specification.
In particular, FormatSpec
is used to capture the specification of a single entry. One can compile a format specification string into a FormatSpec
instance as
fspec = FormatSpec("d")
fspec = FormatSpec("<8.4f")
Please refer to Python's format specification language for details.
FormatExpr
captures a formatting expression that may involve multiple items. One can compile a formatting string into a FormatExpr
instance as
fe = FormatExpr("{1} + {2}")
fe = FormatExpr("{1:d} + {2:08.4e} + {3|>abs2}")
Please refer to Python's format string syntax for details.
Note: If the same format is going to be applied for multiple times. It is more efficient to first compile it.
One can use printfmt
and printfmtln
for formatted printing:
-
printfmt(io, fe, args...)
-
printfmt(fe, args...)
Print given arguments using given format
fe
. Herefe
can be a formatting string, an instance ofFormatSpec
orFormatExpr
.Examples
printfmt("{1:>4s} + {2:.2f}", "abc", 12) # --> print(" abc + 12.00") printfmt("{} = {:#04x}", "abc", 12) # --> print("abc = 0x0c") fs = FormatSpec("#04x") printfmt(fs, 12) # --> print("0x0c") fe = FormatExpr("{} = {:#04x}") printfmt(fe, "abc", 12) # --> print("abc = 0x0c")
Notes
If the first argument is a string, it will be first compiled into a
FormatExpr
, which implies that you can not use specification-only string in the first argument.printfmt("{1:d}", 10) # OK, "{1:d}" can be compiled into a FormatExpr instance printfmt("d", 10) # Error, "d" can not be compiled into a FormatExpr instance # such a string to specify a format specification for single argument printfmt(FormatSpec("d"), 10) # OK printfmt(FormatExpr("{1:d}", 10)) # OK
-
printfmtln(io, fe, args...)
-
printfmtln(fe, args...)
Similar to
printfmt
except that this function print a newline at the end.
One can use fmt
to format a single value into a string, or format
to format one to multiple arguments into a string using an format expression.
-
fmt(fspec, a)
Format a single value using a format specification given by
fspec
, wherefspec
can be either a string or an instance ofFormatSpec
. -
format(fe, args...)
Format arguments using a format expression given by
fe
, wherefe
can be either a string or an instance ofFormatSpec
.
At this point, this package implements a subset of Python's formatting language (with slight modification). Here is a summary of the differences:
-
g
andG
for floating point formatting have not been supported yet. Please usef
,e
, orE
instead. -
The package currently provides default alignment, left alignment
<
and right alignment>
. Other form of alignment such as centered alignment^
has not been supported yet. -
In terms of argument specification, it supports natural ordering (e.g.
{} + {}
), explicit position (e.g.{1} + {2}
). It hasn't supported named arguments or fields extraction yet. Note that mixing these two modes is not allowed (e.g.{1} + {}
). -
The package provides support for filtering (for explicitly positioned arguments), such as
{1|>lowercase}
by allowing one to embed the|>
operator, which the Python counter part does not support.
The c-style part of this package aims to get around the limitation that
@sprintf
has to take a literal string argument.
The core part is basically a c-style print formatter using the standard
@sprintf
macro.
It also adds functionalities such as commas separator (thousands), parenthesis for negatives,
stripping trailing zeros, and mixed fractions.
The idea here is that the package compiles a function only once for each unique
format string within the Formatting.*
name space, so repeated use is faster.
Unrelated parts of a session using the same format string would reuse the same
function, avoiding redundant compilation. To avoid the proliferation of
functions, we limit the usage to only 1 argument. Practical consideration
would suggest that only dozens of functions would be created in a session, which
seems manageable.
Usage
using Formatting
fmt = "%10.3f"
s = sprintf1( fmt, 3.14159 ) # usage 1. Quite performant. Easiest to switch to.
fmtrfunc = generate_formatter( fmt ) # usage 2. This bypass repeated lookup of cached function. Most performant.
s = fmtrfunc( 3.14159 )
s = format( 3.14159, precision=3 ) # usage 3. Most flexible, with some non-printf options. Least performant.
sprintf1
: Speed penalty is about 20% for floating point and 30% for integers.
If the formatter is stored and used instead (see the example using generate_formatter
above),
the speed penalty reduces to 10% for floating point and 15% for integers.
This package also supplements the lack of thousand separator e.g. "%'d"
, "%'f"
, "%'s"
.
Note: "%'s"
behavior is that for small enough floating point (but not too small),
thousand separator would be used. If the number needs to be represented by "%e"
, no
separator is used.
This package contains a run-time number formatter format
function, which goes beyond
the standard sprintf
functionality.
An example:
s = format( 1234, commas=true ) # 1,234
s = format( -1234, commas=true, parens=true ) # (1,234)
The keyword arguments are (Bold keywards are not printf standard)
- width. Integer. Try to fit the output into this many characters. May not be successful. Sacrifice space first, then commas.
- precision. Integer. How many decimal places.
- leftjustified. Boolean
- zeropadding. Boolean
- commas. Boolean. Thousands-group separator.
- signed. Boolean. Always show +/- sign?
- positivespace. Boolean. Prepend an extra space for positive numbers? (so they align nicely with negative numbers)
- parens. Boolean. Use parenthesis instead of "-". e.g.
(1.01)
instead of-1.01
. Useful in finance. Note that you cannot usesigned
andparens
option at the same time. - stripzeros. Boolean. Strip trailing '0' to the right of the decimal (and to the left of 'e', if any ).
- It may strip the decimal point itself if all trailing places are zeros.
- This is true by default if precision is not given, and vice versa.
- alternative. Boolean. See
#
alternative form explanation in standard printf documentation - conversion. length=1 string. Default is type dependent. It can be one of
aAeEfFoxX
. See standard printf documentation. - mixedfraction. Boolean. If the number is rational, format it in mixed fraction e.g.
1_1/2
instead of3/2
- mixedfractionsep. Default
_
- fractionsep. Default
/
- fractionwidth. Integer. Try to pad zeros to the numerator until the fractional part has this width
- tryden. Integer. Try to use this denominator instead of a smaller one. No-op if it'd lose precision.
- suffix. String. This strings will be appended to the output. Useful for units/%
- autoscale. Symbol, default
:none
. It could be:metric
,:binary
, or:finance
.:metric
implements common SI symbols for large and small numbers e.g.M
,k
,μ
,n
:binary
implements common ISQ symbols for large numbers e.g.Ti
,Gi
,Mi
,Ki
:finance
implements common finance/news symbols for large numbers e.g.b
(billion),m
(millions)
See the test script for more examples.