From 23eaa3960eff4acabd6e39f4333d2ed702ee5430 Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Thu, 16 Mar 2017 08:25:23 -0600 Subject: [PATCH] Add @format macro (#251) * Add tests for @format * Correct testset * Add docs for @format * Use @format correctly by generating corresponding setdisplay code * Replace setdisplay -> setformat --- NEWS.md | 8 ++--- docs/decorations.md | 2 +- docs/usage.md | 14 ++++---- src/ValidatedNumerics.jl | 2 +- src/deprecated.jl | 4 +-- src/display.jl | 60 +++++++++++++++++++++++++++++--- test/display_tests/display.jl | 63 ++++++++++++++++++++-------------- test/interval_tests/parsing.jl | 2 +- test/runtests.jl | 2 +- 9 files changed, 111 insertions(+), 46 deletions(-) diff --git a/NEWS.md b/NEWS.md index d66b7f8..3a422b9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,9 +6,9 @@ - v0.7 is the last version to include support for Julia v0.4 ### Breaking API changes -- Deprecate `displaymode`, replacing it with `setdisplay`, with simplified syntax #210: +- Deprecate `displaymode`, replacing it with `setformat`, with simplified syntax #210: ``` -setdisplay(:full) +setformat(:full) ``` ### Added features @@ -53,7 +53,7 @@ or ## v0.4.3 -- Fix display of intervals with different setdisplay options; [#146](https://github.com/dpsanders/ValidatedNumerics.jl/pull/146) +- Fix display of intervals with different setformat options; [#146](https://github.com/dpsanders/ValidatedNumerics.jl/pull/146) - Add emptyinterval(x::IntervalBox); [#145](https://github.com/dpsanders/ValidatedNumerics.jl/pull/145) @@ -68,7 +68,7 @@ or # v0.4 - Added decorated intervals [#112](https://github.com/dpsanders/ValidatedNumerics.jl/pull/112) -- Added `setdisplay` function for modifying how intervals are displayed [#115](https://github.com/dpsanders/ValidatedNumerics.jl/pull/115) +- Added `setformat` function for modifying how intervals are displayed [#115](https://github.com/dpsanders/ValidatedNumerics.jl/pull/115) - Added `±` syntax for creating intervals as e.g. `1.3 ± 0.1` [#116](https://github.com/dpsanders/ValidatedNumerics.jl/pull/116) diff --git a/docs/decorations.md b/docs/decorations.md index 9c3c84a..83ee6cf 100644 --- a/docs/decorations.md +++ b/docs/decorations.md @@ -52,7 +52,7 @@ julia> X = DecoratedInterval(3, 4) By default, decorations are not displayed. The following turns on display of decorations: ``` -julia> setdisplay(decorations=true) +julia> setformat(decorations=true) julia> X [3, 4]_com diff --git a/docs/usage.md b/docs/usage.md index fff00c7..463c276 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -357,8 +357,8 @@ rounding(Interval) ``` ## Display modes -There are several useful output representations for intervals, some of which we have already touched on. The display is controlled globally by the `setdisplay` function, which has -the following options, specified by keyword arguments (type `?setdisplay` to get help at the REPL): +There are several useful output representations for intervals, some of which we have already touched on. The display is controlled globally by the `setformat` function, which has +the following options, specified by keyword arguments (type `?setformat` to get help at the REPL): - `format`: interval output format @@ -377,29 +377,29 @@ the following options, specified by keyword arguments (type `?setdisplay` to get julia> a = @interval(1.1, pi) [1.09999, 3.1416] -julia> setdisplay(sigfigs=10) +julia> setformat(sigfigs=10) 10 julia> a [1.099999999, 3.141592654] -julia> setdisplay(:full) +julia> setformat(:full) julia> a Interval(1.0999999999999999, 3.1415926535897936) -julia> setdisplay(:midpoint) +julia> setformat(:midpoint) julia> a 2.120796327 ± 1.020796327 -julia> setdisplay(:midpoint, sigfigs=4) +julia> setformat(:midpoint, sigfigs=4) 4 julia> a 2.121 ± 1.021 -julia> setdisplay(:standard) +julia> setformat(:standard) julia> a [1.099, 3.142] diff --git a/src/ValidatedNumerics.jl b/src/ValidatedNumerics.jl index 649f77e..96d83bf 100644 --- a/src/ValidatedNumerics.jl +++ b/src/ValidatedNumerics.jl @@ -44,7 +44,7 @@ export cancelminus, cancelplus, isunbounded, .., @I_str, ±, pow, - setdisplay + setformat, @format export setindex # re-export from StaticArrays for IntervalBox diff --git a/src/deprecated.jl b/src/deprecated.jl index 645f97c..c4acca8 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -5,7 +5,7 @@ export displaymode function displaymode(; format = display_params.format, decorations = display_params.decorations, sigfigs::Integer = display_params.sigfigs) - Base.depwarn("`displaymode(format=f)` is deprecated. Use `setdisplay(f)` instead.", :setdisplay) + Base.depwarn("`displaymode(format=f)` is deprecated. Use `setformat(f)` instead.", :setformat) - setdisplay(format; decorations=decorations, sigfigs=sigfigs) + setformat(format; decorations=decorations, sigfigs=sigfigs) end diff --git a/src/display.jl b/src/display.jl index 51aab8f..d157458 100644 --- a/src/display.jl +++ b/src/display.jl @@ -8,9 +8,9 @@ const display_params = DisplayParameters(:standard, false, 6) doc""" - setdisplay(;kw) + setformat(;kw) -`setdisplay` changes how intervals are displayed using keyword arguments. +`setformat` changes how intervals are displayed using keyword arguments. The following options are available: - `format`: interval output format @@ -25,10 +25,10 @@ The following options are available: Example: ``` -julia> setdisplay(:full, decorations=true) +julia> setformat(:full, decorations=true) ``` """ -function setdisplay(format = display_params.format; +function setformat(format = display_params.format; decorations = display_params.decorations, sigfigs::Integer = display_params.sigfigs) if format ∉ (:standard, :full, :midpoint) @@ -49,6 +49,58 @@ function setdisplay(format = display_params.format; display_params.sigfigs = sigfigs end +doc""" + @format [style::Symbol] [decorations::Bool] [sigfigs::Integer] + +The `@format` macro provides a simple interface to control the output format +for intervals. These options are passed to the `setformat` function. + +The arguments may be in any order and of type: + +- `Symbol`: the output format (`:full`, `:standard` or `:midpoint`) +- `Bool`: whether to display decorations +- `Integer`: the number of significant figures + +E.g. +``` +julia> x = 0.1..0.3 +@[0.0999999, 0.300001] + +julia> @format full + +julia> x +Interval(0.09999999999999999, 0.30000000000000004) + +julia> @format standard 3 + +julia> x +[0.0999, 0.301] +``` +""" +macro format(expr...) + + format = Meta.quot(display_params.format) + decorations = display_params.decorations + sigfigs = display_params.sigfigs + + for ex in expr + + if isa(ex, Symbol) + format = Meta.quot(ex) + + elseif isa(ex, Integer) + sigfigs = ex + + elseif isa(ex, Bool) + decorations = ex + end + end + + format_code = :(setformat($format, decorations=$decorations, sigfigs=$sigfigs)) + + return format_code +end + ## Output diff --git a/test/display_tests/display.jl b/test/display_tests/display.jl index 8ce4e78..2e04482 100644 --- a/test/display_tests/display.jl +++ b/test/display_tests/display.jl @@ -3,7 +3,7 @@ using Base.Test setprecision(Interval, Float64) -@testset "setdisplay tests" begin +@testset "setformat tests" begin @testset "Interval" begin @@ -13,7 +13,7 @@ setprecision(Interval, Float64) d = @interval(π) @testset "6 sig figs" begin - setdisplay(:standard, sigfigs=6) + setformat(:standard, sigfigs=6) @test string(a) == "[1, 2]" @test string(b) == "[-1.10001, 1.30001]" @@ -22,7 +22,7 @@ setprecision(Interval, Float64) end @testset "10 sig figs" begin - setdisplay(sigfigs=10) + setformat(sigfigs=10) @test string(a) == "[1, 2]" @test string(b) == "[-1.100000001, 1.300000001]" @@ -31,7 +31,7 @@ setprecision(Interval, Float64) end @testset "20 sig figs" begin - setdisplay(sigfigs=20) + setformat(sigfigs=20) @test string(a) == "[1, 2]" @test string(b) == "[-1.1000000000000000889, 1.3000000000000000445]" @@ -40,7 +40,7 @@ setprecision(Interval, Float64) end @testset "Full" begin - setdisplay(:full) + setformat(:full) @test string(a) == "Interval(1.0, 2.0)" @test string(b) == "Interval(-1.1, 1.3)" @@ -49,7 +49,7 @@ setprecision(Interval, Float64) end @testset "Midpoint" begin - setdisplay(:midpoint, sigfigs=6) + setformat(:midpoint, sigfigs=6) @test string(a) == "1.5 ± 0.5" @test string(b) == "0.1 ± 1.20001" @@ -64,13 +64,13 @@ setprecision(Interval, Float64) @testset "Interval{Rational{T}}" begin a = Interval(1//3, 5//4) @test typeof(a)== Interval{Rational{Int}} - setdisplay(:standard) + setformat(:standard) @test string(a) == "[1//3, 5//4]" - setdisplay(:full) + setformat(:full) @test string(a) == "Interval(1//3, 5//4)" - setdisplay(:midpoint) + setformat(:midpoint) @test string(a) == "19//24 ± 11//24" end @@ -81,28 +81,28 @@ setprecision(Interval, Float64) a = @decorated(1, 2) @test typeof(a)== DecoratedInterval{Float64} - setdisplay(:standard, decorations=false) + setformat(:standard, decorations=false) @test string(a) == "[1, 2]" - setdisplay(:standard, decorations=true) + setformat(:standard, decorations=true) @test string(a) == "[1, 2]_com" # issue 131: a = DecoratedInterval(big(2), big(3), com) - setdisplay(:standard, decorations=false) + setformat(:standard, decorations=false) @test string(a) == "[2, 3]₂₅₆" - setdisplay(decorations=true) + setformat(decorations=true) @test string(a) == "[2, 3]₂₅₆_com" - setdisplay(:full) + setformat(:full) @test string(a) == "DecoratedInterval(Interval(2.000000000000000000000000000000000000000000000000000000000000000000000000000000, 3.000000000000000000000000000000000000000000000000000000000000000000000000000000), com)" - setdisplay(:midpoint) + setformat(:midpoint) @test string(a) == "2.5 ± 0.5_com" - setdisplay(decorations=false) + setformat(decorations=false) @test string(a) == "2.5 ± 0.5" end @@ -111,26 +111,26 @@ setprecision(Interval, Float64) setprecision(Interval, 128) @testset "BigFloat intervals" begin - setdisplay(:standard, decorations=false) + setformat(:standard, decorations=false) a = @interval big(1) @test typeof(a)== Interval{BigFloat} @test string(a) == "[1, 1]₁₂₈" - setdisplay(:full) + setformat(:full) @test string(a) == "Interval(1.000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000)" a = DecoratedInterval(big(2), big(3), com) @test typeof(a)== DecoratedInterval{BigFloat} - setdisplay(:standard, decorations=false) + setformat(:standard, decorations=false) @test string(a) == "[2, 3]₁₂₈" - setdisplay(:standard, decorations=true) + setformat(:standard, decorations=true) @test string(a) == "[2, 3]₁₂₈_com" - setdisplay(:full) + setformat(:full) @test string(a) == "DecoratedInterval(Interval(2.000000000000000000000000000000000000000, 3.000000000000000000000000000000000000000), com)" end @@ -139,7 +139,7 @@ setprecision(Interval, Float64) @testset "IntervalBox" begin - setdisplay(:standard, sigfigs=6) + setformat(:standard, sigfigs=6) X = IntervalBox(1..2, 3..4) @test typeof(X) == IntervalBox{2,Float64} @@ -154,14 +154,14 @@ setprecision(Interval, Float64) X = IntervalBox(-Inf..Inf, -Inf..Inf) @test string(X) == "[-∞, ∞] × [-∞, ∞]" - setdisplay(:full) + setformat(:full) @test string(X) == "IntervalBox(Interval(-Inf, Inf), Interval(-Inf, Inf))" end end @testset "showall" begin - setdisplay(:standard, decorations=false, sigfigs=6) + setformat(:standard, decorations=false, sigfigs=6) setprecision(128) x = 0..1 @@ -180,7 +180,20 @@ end @test string(x) == "[0, 1]₁₂₈" @test sprint(showall, x) == "DecoratedInterval(Interval(0.000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000), def)" - setdisplay(decorations=true) + setformat(decorations=true) @test string(x) == "[0, 1]₁₂₈_def" end + +@testset "@format tests" begin + x = 0.1..0.3 + + @format full + @test string(x) == "Interval(0.09999999999999999, 0.30000000000000004)" + + @format standard 3 + @test string(x) == "[0.0999, 0.301]" + + @format 10 + @test string(x) == "[0.09999999999, 0.3000000001]" +end diff --git a/test/interval_tests/parsing.jl b/test/interval_tests/parsing.jl index 417a5e5..560202b 100644 --- a/test/interval_tests/parsing.jl +++ b/test/interval_tests/parsing.jl @@ -1,7 +1,7 @@ using ValidatedNumerics using Base.Test -setdisplay(:standard, decorations=true, sigfigs=6) +setformat(:standard, decorations=true, sigfigs=6) setprecision(128) diff --git a/test/runtests.jl b/test/runtests.jl index e863665..f02fbcb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ using Base.Test # Interval tests: -setdisplay(:full) +setformat(:full) include("interval_tests/intervals.jl") include("multidim_tests/multidim.jl")