text:
# this needs to be defined outside of the module to make
# Julia print type name without module name when displaying it
struct ⛵⛵⛵⛵⛵
end
Base.show(io::IO, ::⛵⛵⛵⛵⛵) = show(io, "⛵")

struct F<:AbstractFloat
    i::Int
end

Base.show(io::IO, f::F) = show(io, f.i)

module TestShow

using DataFrames, Dates, Random, Test, CategoricalArrays

import Main: ⛵⛵⛵⛵⛵, F

function capture_stdout(f::Function)
    oldstdout = stdout
    rd, wr = redirect_stdout()
    f()
    redirect_stdout(oldstdout)
    size = displaysize(rd)
    close(wr)
    str = read(rd, String)
    close(rd)
    str, size
end

@testset "Basic show test with allrows and allcols" begin
    df = DataFrame(A = Int64[1:4;], B = ["x\"", "∀ε>0: x+ε>x", "z\$", "A\nC"],
                   C = Float32[1.0, 2.0, 3.0, 4.0], D = ['\'', '∀', '\$', '\n'])

    refstr = """
    4×4 DataFrame
     Row │ A      B            C        D
         │ Int64  String       Float32  Char
    ─────┼───────────────────────────────────
       1 │     1  x"               1.0  '
       2 │     2  ∀ε>0: x+ε>x      2.0  ∀
       3 │     3  z\$               3.0  \$
       4 │     4  A\\nC             4.0  \\n"""

    for allrows in [true, false], allcols in [true, false]
        io = IOBuffer()
        show(io, df, allcols=allcols, allrows=allrows)
        str = String(take!(io))
        @test str == refstr
        io = IOBuffer()
        show(io, MIME("text/plain"), df, allcols=allcols, allrows=allrows)
        str = String(take!(io))
        @test str == refstr
    end

    df = DataFrame(A = Vector{String}(undef, 3))
    @test sprint(show, df) == """
        3×1 DataFrame
         Row │ A
             │ String
        ─────┼────────
           1 │ #undef
           2 │ #undef
           3 │ #undef"""
end

@testset "displaysize test" begin
    df_big = DataFrame(reshape(Int64(10000001):Int64(10000000+25*5), 25, 5),
                       :auto)

    io = IOContext(IOBuffer(), :displaysize=>(11, 40), :limit=>true)
    show(io, df_big)
    str = String(take!(io.io))
    @test str == """
        25×5 DataFrame
         Row │ x1        x2        x3        x ⋯
             │ Int64     Int64     Int64     I ⋯
        ─────┼──────────────────────────────────
           1 │ 10000001  10000026  10000051  1 ⋯
          ⋮  │    ⋮         ⋮         ⋮        ⋱
          25 │ 10000025  10000050  10000075  1
                   2 columns and 23 rows omitted"""

    io = IOContext(IOBuffer(), :displaysize=>(11, 40), :limit=>true)
    show(io, df_big, allcols=true)
    str = String(take!(io.io))
    @test str == """
        25×5 DataFrame
         Row │ x1        x2        x3        x4        x5
             │ Int64     Int64     Int64     Int64     Int64
        ─────┼──────────────────────────────────────────────────
           1 │ 10000001  10000026  10000051  10000076  10000101
          ⋮  │    ⋮         ⋮         ⋮         ⋮         ⋮
          25 │ 10000025  10000050  10000075  10000100  10000125
                                                 23 rows omitted"""

    io = IOContext(IOBuffer(), :displaysize=>(11, 40), :limit=>true)
    show(io, df_big, allrows=true, allcols=true)
    str = String(take!(io.io))
    @test str == """
        25×5 DataFrame
         Row │ x1        x2        x3        x4        x5
             │ Int64     Int64     Int64     Int64     Int64
        ─────┼──────────────────────────────────────────────────
           1 │ 10000001  10000026  10000051  10000076  10000101
           2 │ 10000002  10000027  10000052  10000077  10000102
           3 │ 10000003  10000028  10000053  10000078  10000103
           4 │ 10000004  10000029  10000054  10000079  10000104
           5 │ 10000005  10000030  10000055  10000080  10000105
           6 │ 10000006  10000031  10000056  10000081  10000106
           7 │ 10000007  10000032  10000057  10000082  10000107
           8 │ 10000008  10000033  10000058  10000083  10000108
           9 │ 10000009  10000034  10000059  10000084  10000109
          10 │ 10000010  10000035  10000060  10000085  10000110
          11 │ 10000011  10000036  10000061  10000086  10000111
          12 │ 10000012  10000037  10000062  10000087  10000112
          13 │ 10000013  10000038  10000063  10000088  10000113
          14 │ 10000014  10000039  10000064  10000089  10000114
          15 │ 10000015  10000040  10000065  10000090  10000115
          16 │ 10000016  10000041  10000066  10000091  10000116
          17 │ 10000017  10000042  10000067  10000092  10000117
          18 │ 10000018  10000043  10000068  10000093  10000118
          19 │ 10000019  10000044  10000069  10000094  10000119
          20 │ 10000020  10000045  10000070  10000095  10000120
          21 │ 10000021  10000046  10000071  10000096  10000121
          22 │ 10000022  10000047  10000072  10000097  10000122
          23 │ 10000023  10000048  10000073  10000098  10000123
          24 │ 10000024  10000049  10000074  10000099  10000124
          25 │ 10000025  10000050  10000075  10000100  10000125"""

    io = IOContext(IOBuffer(), :displaysize=>(11, 40), :limit=>true)
    show(io, df_big, allrows=true, allcols=false)
    str = String(take!(io.io))
    @test str == """
        25×5 DataFrame
         Row │ x1        x2        x3        x ⋯
             │ Int64     Int64     Int64     I ⋯
        ─────┼──────────────────────────────────
           1 │ 10000001  10000026  10000051  1 ⋯
           2 │ 10000002  10000027  10000052  1
           3 │ 10000003  10000028  10000053  1
           4 │ 10000004  10000029  10000054  1
           5 │ 10000005  10000030  10000055  1 ⋯
           6 │ 10000006  10000031  10000056  1
           7 │ 10000007  10000032  10000057  1
           8 │ 10000008  10000033  10000058  1
           9 │ 10000009  10000034  10000059  1 ⋯
          10 │ 10000010  10000035  10000060  1
          11 │ 10000011  10000036  10000061  1
          12 │ 10000012  10000037  10000062  1
          13 │ 10000013  10000038  10000063  1 ⋯
          14 │ 10000014  10000039  10000064  1
          15 │ 10000015  10000040  10000065  1
          16 │ 10000016  10000041  10000066  1
          17 │ 10000017  10000042  10000067  1 ⋯
          18 │ 10000018  10000043  10000068  1
          19 │ 10000019  10000044  10000069  1
          20 │ 10000020  10000045  10000070  1
          21 │ 10000021  10000046  10000071  1 ⋯
          22 │ 10000022  10000047  10000072  1
          23 │ 10000023  10000048  10000073  1
          24 │ 10000024  10000049  10000074  1
          25 │ 10000025  10000050  10000075  1 ⋯
                               2 columns omitted"""
end

@testset "IOContext parameters test" begin
    df = DataFrame(A = Int64[1:4;], B = ["x\"", "∀ε>0: x+ε>x", "z\$", "A\nC"],
                   C = Float32[1.0, 2.0, 3.0, 4.0])
    str1, size = capture_stdout() do
        show(df)
    end
    io = IOContext(IOBuffer(), :limit=>true, :displaysize=>size)
    show(io, df)
    str2 = String(take!(io.io))
    @test str1 == str2

    Random.seed!(1)
    df_big = DataFrame(rand(25, 5), :auto)
    str1, size = capture_stdout() do
        show(df_big)
    end
    io = IOContext(IOBuffer(), :limit=>true, :displaysize=>size)
    show(io, df_big)
    str2 = String(take!(io.io))
    @test str1 == str2
end

@testset "SubDataFrame show test" begin
    df = DataFrame(A = Int64[1:4;], B = ["x\"", "∀ε>0: x+ε>x", "z\$", "A\nC"],
                   C = Float32[1.0, 2.0, 3.0, 4.0])
    subdf = view(df, [2, 3], :)
    io = IOBuffer()
    show(io, subdf, allrows=true, allcols=false)
    str = String(take!(io))
    @test str == """
        2×3 SubDataFrame
         Row │ A      B            C
             │ Int64  String       Float32
        ─────┼─────────────────────────────
           1 │     2  ∀ε>0: x+ε>x      2.0
           2 │     3  z\$               3.0"""
    show(io, subdf, allrows=true)
    show(io, subdf, allcols=true)
    show(io, subdf, allcols=true, allrows=true)
end

@testset "Test showing StackedVector and RepeatedVector" begin
    A = DataFrames.StackedVector(Any[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    @test sprint(show, A) == "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
    A = DataFrames.RepeatedVector([1, 2, 3], 5, 1)
    @test sprint(show, A) == "[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]"
    A = DataFrames.RepeatedVector([1, 2, 3], 1, 5)
    @test sprint(show, A) == "[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]"
end

@testset "Test colors and non-standard values: missing and nothing" begin
    df = DataFrame(Fish = ["Suzy", "Amir"], Mass = [1.5, missing])
    @test sprint(show, df, context=:color=>true) == """
        \e[1m2×2 DataFrame\e[0m
        \e[1m Row \e[0m│\e[1m Fish   \e[0m\e[1m Mass      \e[0m
        \e[1m     \e[0m│\e[90m String \e[0m\e[90m Float64?  \e[0m
        ─────┼───────────────────
           1 │ Suzy          1.5
           2 │ Amir   \e[90m missing   \e[0m"""

    df = DataFrame(A = [:Symbol, missing, :missing],
                   B = [missing, "String", "missing"],
                   C = [:missing, "missing", missing])
    @test sprint(show, df, context=:color=>true) == """
        \e[1m3×3 DataFrame\e[0m
        \e[1m Row \e[0m│\e[1m A       \e[0m\e[1m B       \e[0m\e[1m C       \e[0m
        \e[1m     \e[0m│\e[90m Symbol? \e[0m\e[90m String? \e[0m\e[90m Any     \e[0m
        ─────┼───────────────────────────
           1 │ Symbol  \e[90m missing \e[0m missing
           2 │\e[90m missing \e[0m String   missing
           3 │ missing  missing \e[90m missing \e[0m"""

    df_nothing = DataFrame(A = [1.0, 2.0, 3.0], B = ["g", "g", nothing])
    @test sprint(show, df_nothing) == """
        3×2 DataFrame
         Row │ A        B
             │ Float64  Union…
        ─────┼─────────────────
           1 │     1.0  g
           2 │     2.0  g
           3 │     3.0"""
end

@testset "Test correct width computation" begin
    df = DataFrame([["a"]], [:x])
    @test sprint(show, df) == """
        1×1 DataFrame
         Row │ x
             │ String
        ─────┼────────
           1 │ a"""
end

@testset "Test showing special types" begin
    # strings with escapes
    df = DataFrame(a = ["1\n1", "2\t2", "3\r3", "4\$4", "5\"5", "6\\6"])
    @test sprint(show, df) == """
        6×1 DataFrame
         Row │ a
             │ String
        ─────┼────────
           1 │ 1\\n1
           2 │ 2\\t2
           3 │ 3\\r3
           4 │ 4\$4
           5 │ 5"5
           6 │ 6\\\\6"""

    # categorical
    df = DataFrame(a = categorical([1, 2, 3]), b = categorical(["a", "b", missing]))
    @test sprint(show, df) == """
        3×2 DataFrame
         Row │ a     b
             │ Cat…  Cat…?
        ─────┼───────────────
           1 │ 1     a
           2 │ 2     b
           3 │ 3     missing"""

    # BigFloat
    df = DataFrame(a = [big(1.0), missing])
    @test sprint(show, df) == """
        2×1 DataFrame
         Row │ a
             │ BigFloat?
        ─────┼───────────
           1 │       1.0
           2 │ missing"""

    # date types
    df = DataFrame(a = Date(2020, 2, 11), b = DateTime(2020, 2, 11, 15), c = Day(1))
    @test sprint(show, df) == """
        1×3 DataFrame
         Row │ a           b                    c
             │ Date        DateTime             Day
        ─────┼────────────────────────────────────────
           1 │ 2020-02-11  2020-02-11T15:00:00  1 day"""

    # Irrational
    df = DataFrame(a = π)
    if VERSION < v"1.2.0-DEV.276"
        @test sprint(show, df) == """
            1×1 DataFrame
             Row │ a
                 │ Irration…
            ─────┼────────────────────────
               1 │ π = 3.1415926535897..."""
    else
        @test sprint(show, df) == """
            1×1 DataFrame
             Row │ a
                 │ Irration…
            ─────┼───────────
               1 │         π"""
    end
end

@testset "Test using :compact parameter of IOContext" begin
    df = DataFrame(x = [float(pi)])
    @test sprint(show, df) == """
        1×1 DataFrame
         Row │ x
             │ Float64
        ─────┼─────────
           1 │ 3.14159"""

    @test sprint(show, df, context=:compact=>false) == """
        1×1 DataFrame
         Row │ x
             │ Float64
        ─────┼───────────────────
           1 │ 3.141592653589793"""
end

@testset "Test of DataFrameRows and DataFrameColumns" begin
    df = DataFrame(x = [float(pi)])
    @test sprint(show, eachrow(df)) == """
        1×1 DataFrameRows
         Row │ x
             │ Float64
        ─────┼─────────
           1 │ 3.14159"""

    @test sprint((io, x) -> show(io, x, summary=false), eachrow(df)) == """
         Row │ x
             │ Float64
        ─────┼─────────
           1 │ 3.14159"""

    @test sprint(show, eachcol(df)) == """
        1×1 DataFrameColumns
         Row │ x
             │ Float64
        ─────┼─────────
           1 │ 3.14159"""

    @test sprint((io, x) -> show(io, x, summary=false), eachcol(df)) == """
         Row │ x
             │ Float64
        ─────┼─────────
           1 │ 3.14159"""
end

@testset "Test empty data frame and DataFrameRow" begin
    df = DataFrame(x = [float(pi)])
    @test sprint(show, df[:, 2:1]) == "0×0 DataFrame"
    @test sprint(show, @view df[:, 2:1]) == "0×0 SubDataFrame"
    @test sprint(show, df[1, 2:1]) == "DataFrameRow"
end

@testset "consistency" begin
    df = DataFrame(a = [1, 1, 2, 2], b = [5, 6, 7, 8], c = 1:4)
    push!(df.c, 5)
    @test_throws AssertionError sprint(show, df)

    df = DataFrame(a = [1, 1, 2, 2], b = [5, 6, 7, 8], c = 1:4)
    push!(DataFrames._columns(df), df[:, :a])
    @test_throws AssertionError sprint(show, df)
end

@testset "wide type name" begin
    @test sprint(show, DataFrame(a=⛵⛵⛵⛵⛵())) == """
        1×1 DataFrame
         Row │ a
             │ ⛵⛵⛵⛵…
        ─────┼───────────
           1 │ "⛵\""""

    @test sprint(show, DataFrame(a=categorical([Int64(2)^54]))) == """
        1×1 DataFrame
         Row │ a
             │ Cat…
        ─────┼───────────────────
           1 │ 18014398509481984"""

    @test sprint(show, DataFrame(a=categorical([Int64(2)^53]))) == """
        1×1 DataFrame
         Row │ a
             │ Cat…
        ─────┼──────────────────
           1 │ 9007199254740992"""

    @test sprint(show, DataFrame(a=categorical([Int64(2)^37]))) == """
        1×1 DataFrame
         Row │ a
             │ Cat…
        ─────┼──────────────
           1 │ 137438953472"""

    @test sprint(show, DataFrame(a=categorical([Int64(2)^36]))) == """
        1×1 DataFrame
         Row │ a
             │ Cat…
        ─────┼─────────────
           1 │ 68719476736"""

    @test sprint(show, DataFrame(a=Union{Function, Missing}[missing])) == """
        1×1 DataFrame
         Row │ a
             │ Function?
        ─────┼───────────
           1 │ missing"""
end

@testset "wide type name" begin
    df = DataFrame(A = Int32.(1:3), B = ["x", "y", "z"])

    io = IOBuffer()
    show(io, df, eltypes=true)
    str = String(take!(io))
    @test str == """
        3×2 DataFrame
         Row │ A      B
             │ Int32  String
        ─────┼───────────────
           1 │     1  x
           2 │     2  y
           3 │     3  z"""

    io = IOBuffer()
    show(io, df, eltypes=false)
    str = String(take!(io))
    @test str == """
        3×2 DataFrame
         Row │ A  B
        ─────┼──────
           1 │ 1  x
           2 │ 2  y
           3 │ 3  z"""
end

@testset "UnionAll" begin
    df = DataFrame(x=AbstractVector[1:2])

    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        1×1 DataFrame
         Row │ x
             │ Abstract…
        ─────┼───────────
           1 │ 1:2"""
end

@testset "wide output and column trimming" begin
    df = DataFrame(x = "0123456789"^4)
    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        1×1 DataFrame
         Row │ x
             │ String
        ─────┼───────────────────────────────────
           1 │ 01234567890123456789012345678901…"""

    io = IOContext(IOBuffer(), :displaysize=>(10, 10), :limit=>true)
    show(io, df)
    str = String(take!(io.io))
    @test str === """
        1×1 DataF…
         Row │ x ⋯
             │ S ⋯
        ─────┼────
           1 │ 0 ⋯
        1 column omitted"""

    df = DataFrame(x = "😄"^20)
    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str === """
        1×1 DataFrame
         Row │ x
             │ String
        ─────┼───────────────────────────────────
           1 │ 😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄…"""
end

@testset "Floating point alignment" begin
    df = DataFrame(a = [i == 2 ? missing : 10^i for i = -7:1.0:7],
                   b = Int64.(1:1:15),
                   c = [i % 2 == 0 for i = 1:15],
                   d = [i == 2 ? "test" : 10^i for i = -7:1.0:7],
                   e = [i == 2 ? -0.0 : i == 3 ? +0.0 : 10^i for i = -7:1.0:7])

    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        15×5 DataFrame
         Row │ a             b      c      d         e
             │ Float64?      Int64  Bool   Any       Float64
        ─────┼───────────────────────────────────────────────────
           1 │       1.0e-7      1  false  1.0e-7         1.0e-7
           2 │       1.0e-6      2   true  1.0e-6         1.0e-6
           3 │       1.0e-5      3  false  1.0e-5         1.0e-5
           4 │       0.0001      4   true  0.0001         0.0001
           5 │       0.001       5  false  0.001          0.001
           6 │       0.01        6   true  0.01           0.01
           7 │       0.1         7  false  0.1            0.1
           8 │       1.0         8   true  1.0            1.0
           9 │      10.0         9  false  10.0          10.0
          10 │ missing          10   true  test          -0.0
          11 │    1000.0        11  false  1000.0         0.0
          12 │   10000.0        12   true  10000.0    10000.0
          13 │  100000.0        13  false  100000.0  100000.0
          14 │       1.0e6      14   true  1.0e6          1.0e6
          15 │       1.0e7      15  false  1.0e7          1.0e7"""

    io = IOBuffer()
    show(io, df, eltypes = false)
    str = String(take!(io))
    @test str == """
        15×5 DataFrame
         Row │ a             b   c      d         e
        ─────┼────────────────────────────────────────────────
           1 │       1.0e-7   1  false  1.0e-7         1.0e-7
           2 │       1.0e-6   2   true  1.0e-6         1.0e-6
           3 │       1.0e-5   3  false  1.0e-5         1.0e-5
           4 │       0.0001   4   true  0.0001         0.0001
           5 │       0.001    5  false  0.001          0.001
           6 │       0.01     6   true  0.01           0.01
           7 │       0.1      7  false  0.1            0.1
           8 │       1.0      8   true  1.0            1.0
           9 │      10.0      9  false  10.0          10.0
          10 │ missing       10   true  test          -0.0
          11 │    1000.0     11  false  1000.0         0.0
          12 │   10000.0     12   true  10000.0    10000.0
          13 │  100000.0     13  false  100000.0  100000.0
          14 │       1.0e6   14   true  1.0e6          1.0e6
          15 │       1.0e7   15  false  1.0e7          1.0e7"""

    df = DataFrame(This_is_a_very_big_name = 1.0, b = 2.0, c = 3.0)

    io = IOBuffer()
    show(io, df, eltypes = false)
    str = String(take!(io))
    @test str == """
        1×3 DataFrame
         Row │ This_is_a_very_big_name  b    c
        ─────┼───────────────────────────────────
           1 │                     1.0  2.0  3.0"""

    df = DataFrame(This_is_a_very_big_name = [10.0^i for i = -5:1:5],
                   This_is_smaller = 1.0:2:22,
                   T = 100001:1.0:100011)

    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        11×3 DataFrame
         Row │ This_is_a_very_big_name  This_is_smaller  T
             │ Float64                  Float64          Float64
        ─────┼────────────────────────────────────────────────────
           1 │                  1.0e-5              1.0  100001.0
           2 │                  0.0001              3.0  100002.0
           3 │                  0.001               5.0  100003.0
           4 │                  0.01                7.0  100004.0
           5 │                  0.1                 9.0  100005.0
           6 │                  1.0                11.0  100006.0
           7 │                 10.0                13.0  100007.0
           8 │                100.0                15.0  100008.0
           9 │               1000.0                17.0  100009.0
          10 │              10000.0                19.0  100010.0
          11 │             100000.0                21.0  100011.0"""

    df = DataFrame(😄😄😄😄😄😄😄 = [10.0^i for i = -5:1:5],
                   🚀🚀🚀🚀🚀 = 1.0:2:22)

    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        11×2 DataFrame
         Row │ 😄😄😄😄😄😄😄  🚀🚀🚀🚀🚀
             │ Float64         Float64
        ─────┼────────────────────────────
           1 │         1.0e-5         1.0
           2 │         0.0001         3.0
           3 │         0.001          5.0
           4 │         0.01           7.0
           5 │         0.1            9.0
           6 │         1.0           11.0
           7 │        10.0           13.0
           8 │       100.0           15.0
           9 │      1000.0           17.0
          10 │     10000.0           19.0
          11 │    100000.0           21.0"""

    df = DataFrame(😄😄😄😄😄😄😄😄😄 = [10.0^i + pi for i = -5:1:5],
                   🚀🚀🚀🚀🚀🚀🚀 = collect(1.0:2:22) .+ pi)

    io = IOBuffer()
    show(io, df)
    str = String(take!(io))
    @test str == """
        11×2 DataFrame
         Row │ 😄😄😄😄😄😄😄😄😄  🚀🚀🚀🚀🚀🚀🚀
             │ Float64             Float64
        ─────┼────────────────────────────────────
           1 │          3.1416            4.14159
           2 │          3.14169           6.14159
           3 │          3.14259           8.14159
           4 │          3.15159          10.1416
           5 │          3.24159          12.1416
           6 │          4.14159          14.1416
           7 │         13.1416           16.1416
           8 │        103.142            18.1416
           9 │       1003.14             20.1416
          10 │      10003.1              22.1416
          11 │          1.00003e5        24.1416"""

    io = IOContext(IOBuffer(), :compact => false)
    show(io, df)
    str = String(take!(io.io))
    @test str == """
        11×2 DataFrame
         Row │ 😄😄😄😄😄😄😄😄😄       🚀🚀🚀🚀🚀🚀🚀
             │ Float64                  Float64
        ─────┼─────────────────────────────────────────────
           1 │      3.141602653589793    4.141592653589793
           2 │      3.1416926535897933   6.141592653589793
           3 │      3.142592653589793    8.141592653589793
           4 │      3.151592653589793   10.141592653589793
           5 │      3.241592653589793   12.141592653589793
           6 │      4.141592653589793   14.141592653589793
           7 │     13.141592653589793   16.141592653589793
           8 │    103.1415926535898     18.141592653589793
           9 │   1003.1415926535898     20.141592653589793
          10 │  10003.14159265359       22.141592653589793
          11 │ 100003.14159265358       24.141592653589793"""

    df = DataFrame(This_is_a_very_long_header =
                   Union{F, Float64, Missing}[i == 6 ? F(1234567) : i == 4 ? missing : 10.0^i for i = -6:1:6])

    io = IOContext(IOBuffer())
    show(io, df)
    str = String(take!(io.io))
    @test str == """
        13×1 DataFrame
         Row │ This_is_a_very_long_header
             │ Union{Missing, Float64, F}
        ─────┼────────────────────────────
           1 │                     1.0e-6
           2 │                     1.0e-5
           3 │                     0.0001
           4 │                     0.001
           5 │                     0.01
           6 │                     0.1
           7 │                     1.0
           8 │                    10.0
           9 │                   100.0
          10 │                  1000.0
          11 │               missing
          12 │                100000.0
          13 │               1234567"""

end

@testset "Issue #2673 - Vertical line when not showing row numbers" begin
    df = DataFrame(a = Int64[10, 20], b = Int64[30, 40], c = Int64[50, 60])

    io = IOContext(IOBuffer())
    show(io, df)
    str = String(take!(io.io))
    @test str == """
        2×3 DataFrame
         Row │ a      b      c
             │ Int64  Int64  Int64
        ─────┼─────────────────────
           1 │    10     30     50
           2 │    20     40     60"""

    io = IOContext(IOBuffer())
    show(io, df, show_row_number=false)
    str = String(take!(io.io))
    @test str == """
        2×3 DataFrame
         a      b      c
         Int64  Int64  Int64
        ─────────────────────
            10     30     50
            20     40     60"""

    io = IOContext(IOBuffer())
    show(io, df[2, :])
    str = String(take!(io.io))
    @test str == """
        DataFrameRow
         Row │ a      b      c
             │ Int64  Int64  Int64
        ─────┼─────────────────────
           2 │    20     40     60"""

    io = IOContext(IOBuffer())
    show(io, df[2, :], show_row_number=false)
    str = String(take!(io.io))
    @test str == """
        DataFrameRow
         a      b      c
         Int64  Int64  Int64
        ─────────────────────
            20     40     60"""
end

end # module


text:
# Recursive zygote update method, this is the general recursion case:
function update!(opt, model, updates)
	# If this `model` node has no fields, then just return it
    if nfields(model) == 0
        return model
    end

	# If it does have fields, recurse into them:
    for field_idx in 1:nfields(model)
        update!(opt, getfield(model, field_idx), getfield(updates, field_idx))
    end

    # In the end, return the `model`
    return model
end

# If the `updates` is set to `Nothing`, then just return `model`; this means
# that there were no changes to be applied to this piece of the model.
update!(opt, model, updates::Nothing) = model

# If the `updates` are set as a `Ref`, then we need to peel it:
update!(opt, model, updates::Base.RefValue) = update!(opt, model, updates[])

# If `model` is an `AbstractArray` and `updates` is too, then apply our Flux
# optimizer to the incoming gradients and apply them to the model!
function update!(opt, model::AbstractArray, updates::AbstractArray)
    # Sub off to our RMSProp optimizer
    Flux.Optimise.apply!(opt, model, updates)
    return model .-= updates
end

ext: jl

max_stars_repo_name: MikeInnes/zygote-paper

max_issues_repo_name: MikeInnes/zygote-paper

max_forks_repo_name: MikeInnes/zygote-paper


text:
#!/usr/bin/env julia

using Catlab, Catlab.Doctrines, Catlab.WiringDiagrams, Catlab.Graphics
using Catlab.Graphics: Graphviz

W, X, Y, Z = Ob(FreeCartesianCategory, :W, :X, :Y, :Z)
I = munit(FreeCartesianCategory.Ob)
f = Hom(:f, otimes(X,Y), Z)
g = Hom(:g, Z, Z)
h = Hom(:h, I, W)

diagram = to_wiring_diagram(otimes(compose(f,g),h))
write_json_graph(diagram, "simple_graph.json", indent=2)

graph = to_graphviz(diagram,
  direction = :horizontal,
  labels = false, node_labels = false,
  port_size = "0",
  cell_attrs = Graphviz.Attributes(
    :width => "40",
    :height => "40",
  )
)

open("simple_graph.dot", "w") do io
  Graphviz.pprint(io, graph)
end
open("simple_graph.dot.json", "w") do io
  print(io, Graphviz.run_graphviz(graph, format="json0"))
end

max_stars_repo_name: epatters/wiring-diagram-canvas

max_issues_repo_name: epatters/wiring-diagram-canvas

max_forks_repo_name: epatters/wiring-diagram-canvas


text:
#####
##### Script to replicate the mysterious OOM errors
#####

# NUM_FILTERS=64 julia --project scripts/profile/debug_oom.jl
# NUM_FILTERS=128 julia --project scripts/profile/debug_oom.jl

using AlphaZero
using Setfield

if !haskey(ENV, "NUM_FILTERS")
  error("You should set the NUM_FILTERS env variable.")
end

num_filters = parse(Int, ENV["NUM_FILTERS"])

println("Number of filters: $num_filters")

exp = Examples.experiments["connect-four"]

exp = @set exp.netparams.num_filters = num_filters

Scripts.test_grad_updates(exp, num_games=5000)


text:
export load_rule_file

immutable Variable{T}
    name::Symbol
    desc::String
    deps::Vector{Symbol}
    func::Expr
end

immutable Filter
    desc::String
    deps::Vector{Symbol}
    func::Expr
end

immutable Rule
    name::String
    bymut::Bool # read or mut
    soft::Bool  # hard or soft
    desc::String
    init::Vector{Expr}
    var::Vector{Variable}
    filt::Vector{Filter}
    stat::Vector{Vector{Symbol}}
    anno::Vector{Symbol}
end

vartype{T}(::Variable{T}) = T

function load_rule_file(filename)
    λ"""
    l(code (parse (* "module X\n" (open readstring filename) "\nend")))
    return*(=(rules ref(Rule)))
    local(rule)
    ∀(line ∈ (getfield ref(code.args 3) :args))
    switch(line.head
      *:line $(continue)
      *:macrocall >(
        l('(doc def) ?((isa ref(line.args 1) GlobalRef)
                     '(ref(line.args 2) (getfield ref(line.args 3) :args))
                     '("" line.args)))
        switch((car def)
          *(Symbol "@rule") (push! rules =(rule (Rule ref(def 2) (== ref(def 3) :bymut) (== ref(def 4) :soft) doc
                                                      ref(Expr) ref(Variable) ref(Filter) ref(Symbol) ref(Symbol))))
          *(Symbol "@init") (push! rule.init (cadr def))
          *(Symbol "@var") (push! rule.var (Variable{(eval (cadr (getfield (cadr def) :args)))}
                                 (car (getfield (cadr def) :args)) doc
                                 switch((car (getfield ref(def 3) :args))
                                   (isa . Symbol) ref(Symbol .)
                                   (isa . Expr) (collect ..args))
                                 (cadr (getfield ref(def 3) :args))))
          *(Symbol "@filt") (push! rule.filt (Filter doc
                                   switch((car (getfield (cadr def) :args))
                                     (isa . Symbol) ref(Symbol .)
                                     (isa . Expr) (collect ..args))
                                   (cadr (getfield (cadr def) :args))))
          *(Symbol "@stat") (push! rule.stat (cdr def))
          *(Symbol "@anno") (push! rule.anno (cadr def)))))
    """
end

function gen_var_factory(f, vars)
    new = Set(keys(vars))
    gen_var(v) = if v in new
        foreach(gen_var, vars[v].deps)
        push!(f, :(
            $v = $(reduce((x,y)->Expr(:||, :($y == nothing), x), false, vars[v].deps)) ? nothing : $(vars[v].func)
        ))
        delete!(new, v)
    end
end

function build_rule_func(bymut, rules, writeline, plotstat=nothing; debug=false)
    f = []
    vars = try # julia panics if rules is empty, It is a bug of Julia v0.5
        Dict(v.name => v for r in rules for v in r.var)
    catch
        Dict()
    end
    gen_var = gen_var_factory(f, vars)
    stats = try # the same bug
        unique(s for rule in rules for stats in rule.stat for s in stats)
    catch
        x = []
        for rule in rules
            for stats in rule.stat
                for s in stats
                    push!(x, s)
                end
            end
        end
        unique(x)
    end

    for rule in rules
        p = nothing
        for filt in rule.filt
            foreach(gen_var, filt.deps)
            p = :(
                !$(reduce((x,y)->Expr(:||, :($y == nothing), x), false, filt.deps)) && !$(filt.func) ?
                    $(rule.soft ? bymut ? :( push!(filters, $(rule.name)) ) : :( pass=false ) :
                                 :(continue)) : $p
            )
        end
        push!(f, p)

        plotstat != nothing && for stat in stats
            gen_var(stat)
            push!(f, :( $stat != nothing && push!($(Symbol("stat_", stat)), $stat) ))
        end

        for anno in rule.anno
            gen_var(anno)
            push!(f, :( $anno != nothing && $( bymut ? anno_info(:info, vars[anno]) :
                                                     :(read[$(Meta.quot(anno))] = $anno) ) ))
        end
    end

    f = quote function(x)
        $((init for rule in rules for init in rule.init)...)
        $((plotstat != nothing ? (:( $(Symbol("stat_", s)) = $(vartype(vars[s]))[] ) for s in stats) : ())...)
        $(bymut ? :(for (reads, chr, mut) in x
            info = IOBuffer()
            filters = String[]
            $(f...)
            $writeline(reads, chr, mut, String(info.data[1:end-1]), filters)
        end) : :(for read in x
            pass = true
            $(f...)
            $writeline(read, pass)
        end))
        $((plotstat != nothing ? (:( $plotstat($((vars[s] for s in stats)...), $((Symbol("stat_", s) for s in stats)...)) ) for r in rules for stats in r.stat) : ())...)
    end end

    debug && println(STDERR, f)

    eval(Main, f)
end


text:
struct Bitmap{I, B <: AbstractMatrix{Bool}} <: AbstractShape
    position::Point{I}
    bitmap::B
end

get_i_min(shape::Bitmap) = shape.position.i
get_i_max(shape::Bitmap) = shape.position.i + size(shape.bitmap, 1) - one(shape.position.i)

get_j_min(shape::Bitmap) = shape.position.j
get_j_max(shape::Bitmap) = shape.position.j + size(shape.bitmap, 2) - one(shape.position.j)

function clip(image::AbstractMatrix, shape::Bitmap)
    position = shape.position
    bitmap = shape.bitmap

    i_min_shape, i_max_shape = get_i_extrema(shape)
    i_min_image, i_max_image = get_i_extrema(image)

    I = typeof(i_min_shape)

    j_min_shape, j_max_shape = get_j_extrema(shape)
    j_min_image, j_max_image = get_j_extrema(image)

    clipped_height = min(i_max_shape, i_max_image) - max(i_min_shape, i_min_image) + one(I)
    clipped_width = min(j_max_shape, j_max_image) - max(j_min_shape, j_min_image) + one(I)

    clipped_bitmap = @view bitmap[begin:clipped_height, begin:clipped_width]

    return Bitmap(position, clipped_bitmap)
end

get_drawing_optimization_style(::Bitmap) = CLIP

function draw!(f::F, image::AbstractMatrix, shape::Bitmap, color) where {F <: Function}
    position = shape.position
    bitmap = shape.bitmap

    i_position = position.i
    j_position = position.j

    I = typeof(i_position)

    i_min, i_max = get_i_extrema(shape)
    j_min, j_max = get_j_extrema(shape)

    for j in j_min:j_max
        for i in i_min:i_max
            i_bitmap = i - i_position + one(I)
            j_bitmap = j - j_position + one(I)
            if bitmap[i_bitmap, j_bitmap]
                f(image, i, j, color)
            end
        end
    end

    return nothing
end


text:
function AICtest(m0,m1)
    exp((aic(m0) − aic(m1))/2)
end


text:
module DoubleDicts

import MathOptInterface

const MOI = MathOptInterface
const MOIU = MOI.Utilities
const CI = MOI.ConstraintIndex
const AD = AbstractDict

const DataTypePair = Tuple{DataType,DataType}

abstract type AbstractDoubleDict{K,V,IK,DI<:AD{IK},DO<:AD{K,DI}} <: AD{CI,V} end

"""
    DoubleDict{V}

Optimized dictionary to map `ConstraintIndex` (`CI`) to values of type `V`.
Works as a `AbstractDict{CI, V}` with minimal differences.
Note that `CI` is not a concrete type, opposed to `CI{MOI.SingleVariable, MOI.Integers}`,
which is a concrete type.

When optimal performance or type stability is required it is possible to obtain a
fully type stable dictionary with values of type `V` and keys of type
`CI{MOI.SingleVariable, MOI.Integers}` from the dictionary `dict`, for instance:

    ``inner = dict[MOI.SingleVariable, MOI.Integers]``
"""
struct DoubleDict{V,DI,DO} <: AbstractDoubleDict{DataTypePair,V,Int64,DI,DO}
    dict::DO
    function DoubleDict{V}() where {V}
        return new{V,Dict{Int64,V},Dict{DataTypePair,Dict{Int64,V}}}(
            Dict{DataTypePair,Dict{Int64,V}}(),
        )
    end
end

"""
    IndexDoubleDict

Specialized version of `DoubleDict` in which keys and values are of type
`ConstraintIndex` (`CI`).

This is an optimized dictionary to map `ConstraintIndex` (`CI`) to values of type `CI`.
Works as a `AbstractDict{CI, V}` with minimal differences.
Note that `CI` is not a concrete type, opposed to `CI{MOI.SingleVariable, MOI.Integers}`,
which is a concrete type.

When optimal performance or type stability is required its possible to obtain a
fully type stable dictionary with values of type
`CI{MOI.SingleVariable, MOI.Integers}` and keys of type
`CI{MOI.SingleVariable, MOI.Integers}` from the dictionary `dict`, for instance:

    ``inner = dict[MOI.SingleVariable, MOI.Integers]``
"""
struct IndexDoubleDict{DI,DO} <: AbstractDoubleDict{DataTypePair,CI,Int64,DI,DO}
    dict::DO
    function IndexDoubleDict()
        return new{Dict{Int64,Int64},Dict{DataTypePair,Dict{Int64,Int64}}}(
            Dict{DataTypePair,Dict{Int64,Int64}}(),
        )
    end
end

struct FunctionSetDoubleDict{DI,DO} <:
       AbstractDoubleDict{DataTypePair,Tuple,Int64,DI,DO}
    dict::DO
    function FunctionSetDoubleDict()
        return new{Dict{Int64},Dict{DataTypePair,Dict{Int64}}}(
            Dict{DataTypePair,Dict{Int64}}(),
        )
    end
end

const MainIndexDoubleDict = IndexDoubleDict{
    Dict{Int64,Int64},
    Dict{Tuple{DataType,DataType},Dict{Int64,Int64}},
}

@inline function typed_value(
    ::DoubleDict{V},
    v::V,
    ::Type{F},
    ::Type{S},
)::V where {V,F,S}
    return v
end
@inline function typed_value(
    ::IndexDoubleDict,
    v::Int64,
    ::Type{F},
    ::Type{S},
)::CI{F,S} where {F,S}
    return CI{F,S}(v)
end
@inline function typed_value(
    ::FunctionSetDoubleDict,
    v::Tuple{F,S},
    ::Type{F},
    ::Type{S},
)::Tuple{F,S} where {F,S}
    return v
end

# reversing IndexDoubleDict is ok because they map CI to CI
function MOIU._reverse_dict(
    dest::IndexDoubleDict{DI},
    src::IndexDoubleDict{DI},
) where {DI}
    for (k, v) in src.dict
        dest.dict[k] = MOIU._reverse_dict(v)
    end
end
# reversing other double dict types is not ok because the map CI fo K
# so it wont be a double dict anymore, double dict keys are always CIs.
# We keep the default fallback

function Base.sizehint!(::AbstractDoubleDict, ::Integer)
    return throw(
        ErrorException(
            "sizehint!(d::DoubleDict, ::Integer) has no proper" *
            " meaning for DoubleDict, use sizehint!(d[F,S], n::Integer) " *
            "instead.",
        ),
    )
end

function Base.length(d::AbstractDoubleDict)
    len = 0
    for inner in values(d.dict)
        len += length(inner)
    end
    return len
end

function Base.haskey(dict::AbstractDoubleDict, key::CI{F,S}) where {F,S}
    inner = get(dict.dict, (F, S), nothing)
    return inner !== nothing ? haskey(inner, key.value) : false
end

function Base.get(dict::AbstractDoubleDict, key::CI{F,S}, default) where {F,S}
    inner = get(dict.dict, (F, S), nothing)
    if inner !== nothing && haskey(inner, key.value)
        return typed_value(dict, inner[key.value], F, S)
    end
    return default
end

function Base.getindex(dict::AbstractDoubleDict, key::CI{F,S}) where {F,S}
    inner = dict.dict[(F, S)]
    k_value = key.value::Int64
    return typed_value(dict, inner[k_value], F, S)
end

function init_inner_dict(
    ::AbstractDoubleDict{K,V},
    ::Type{F},
    ::Type{S},
) where {K,V,F,S}
    return Dict{Int64,V}()
end
function init_inner_dict(
    ::FunctionSetDoubleDict,
    ::Type{F},
    ::Type{S},
) where {F,S}
    return Dict{Int64,Tuple{F,S}}()
end
function init_inner_dict(::IndexDoubleDict, ::Type{F}, ::Type{S}) where {F,S}
    return Dict{Int64,Int64}()
end

"""
    lazy_get(dict::DoubleDict, ::Type{F}, ::Type{S})

description
"""
function lazy_get(
    dict::AbstractDoubleDict{K,V},
    ::Type{F},
    ::Type{S},
) where {K,V,F,S}
    inner = get(dict.dict, (F, S), nothing)
    if inner === nothing
        return dict.dict[(F, S)] = init_inner_dict(dict, F, S)
    end
    return inner
end

function Base.setindex!(
    dict::AbstractDoubleDict{K,V},
    value::V,
    key::CI{F,S},
) where {K,V,F,S}
    v_value = value
    k_value = key.value::Int64
    inner = lazy_get(dict, F, S)
    inner[k_value] = v_value
    return value
end
function Base.setindex!(
    dict::DoubleDict{V},
    value::V,
    key::CI{F,S},
) where {V,F,S}
    v_value = value
    k_value = key.value::Int64
    inner = lazy_get(dict, F, S)::Dict{Int64,V}
    inner[k_value] = v_value
    return value
end
function Base.setindex!(
    dict::IndexDoubleDict,
    value::CI{F,S},
    key::CI{F,S},
) where {F,S}
    v_value = value.value::Int64
    k_value = key.value::Int64
    inner = lazy_get(dict, F, S)::Dict{Int64,Int64}
    inner[k_value] = v_value
    return value
end

function Base.empty!(d::AbstractDoubleDict)::Nothing
    Base.empty!(d.dict)
    return
end

function Base.delete!(d::AbstractDoubleDict, key::CI{F,S}) where {F,S}
    k_value = key.value::Int64
    inner = lazy_get(d, F, S)
    delete!(inner, k_value)
    return d
end

function Base.isempty(d::AbstractDoubleDict)
    if isempty(d.dict)
        return true
    end
    for val in values(d.dict)
        if !isempty(val)
            return false
        end
    end
    return true
end

function Base.values(d::IndexDoubleDict)::Vector{CI}
    out = CI[]
    for ((F, S), inner) in d.dict
        append!(out, CI{F,S}.(values(inner)))
    end
    return out
end
function Base.values(d::AbstractDoubleDict{K,V})::Vector{V} where {K,V}
    out = V[]
    for ((F, S), inner) in d.dict
        append!(out, values(inner))
    end
    return out
end

function Base.keys(d::AbstractDoubleDict)
    out = CI[]
    for ((F, S), inner) in d.dict
        append!(out, CI{F,S}.(keys(inner)))
    end
    return out
end

function Base.iterate(d::AbstractDoubleDict)
    o_next = iterate(d.dict)
    if o_next === nothing
        return nothing
    end
    (o_i, o_state) = o_next
    ((F, S), inner) = o_i
    i_next = iterate(inner)
    while i_next === nothing
        o_next = iterate(d.dict, o_state)
        if o_next === nothing
            return nothing
        end
        (o_i, o_state) = o_next
        ((F, S), inner) = o_i
        i_next = iterate(inner)
    end
    (i_i, i_state) = i_next
    return CI{F,S}(i_i[1]) => typed_value(d, i_i[2], F, S),
    (i_state, (o_i, o_state))
end
function Base.iterate(d::AbstractDoubleDict, state)
    (i_state, (o_i, o_state)) = state
    ((F, S), inner) = o_i
    i_next = iterate(inner, i_state)
    while i_next === nothing
        o_next = iterate(d.dict, o_state)
        if o_next === nothing
            return nothing
        end
        (o_i, o_state) = o_next
        ((F, S), inner) = o_i
        i_next = iterate(inner)
    end
    (i_i, i_state) = i_next
    return CI{F,S}(i_i[1]) => typed_value(d, i_i[2], F, S),
    (i_state, (o_i, o_state))
end

abstract type AbstractWithType{F,S,V,DI,DD} <: AD{CI{F,S},V} end

"""
    WithType{D<:DoubleDict, F<:MOI.AbstractFunction, S<:MOI.AbstractSet}

Used to specialize methods and iterators for a given contraint type CI{F,S}.
"""
mutable struct WithType{F,S,V,DI,DD} <: AbstractWithType{F,S,V,DI,DD}
    dict::DD
    inner::Union{DI,Nothing}
    function WithType{F,S}(
        d::DD,
    ) where {
        V,
        DI<:AD{Int64,V},
        DO<:AD{DataTypePair,DI},
        DD<:DoubleDict{V,DI,DO},
        F,
        S,
    }
        inner = get(d.dict, (F, S), nothing)
        return new{F,S,V,DI,DD}(d, inner)
    end
end
mutable struct IndexWithType{F,S,V,DI,DD} <: AbstractWithType{F,S,CI{F,S},DI,DD}
    dict::DD
    inner::Union{DI,Nothing}
    function IndexWithType{F,S}(
        d::DD,
    ) where {
        DI<:AD{Int64,Int64},
        DO<:AD{DataTypePair,DI},
        DD<:IndexDoubleDict{DI,DO},
        F,
        S,
    }
        inner = get(d.dict, (F, S), nothing)::Union{DI,Nothing}
        return new{F,S,CI{F,S},DI,DD}(d, inner)
    end
end
mutable struct FunctionSetWithType{F,S,V,DI,DD} <:
               AbstractWithType{F,S,Tuple{F,S},DI,DD}
    dict::DD
    inner::Union{DI,Nothing}
    function FunctionSetWithType{F,S}(
        d::DD,
    ) where {
        F,
        S,
        DI<:AD{Int64},
        DO<:AD{DataTypePair,DI},
        DD<:FunctionSetDoubleDict{DI,DO},
    }
        inner = get(d.dict, (F, S), nothing)::Union{DI{Tuple{F,S}},Nothing}
        return new{F,S,Tuple{F,S},DI{Tuple{F,S}},DD}(d, inner)
    end
end

function with_type(
    d::DoubleDict,
    ::Type{F},
    ::Type{S},
)::WithType{F,S} where {F,S}
    return WithType{F,S}(d)::WithType{F,S}
end
function with_type(
    d::IndexDoubleDict,
    ::Type{F},
    ::Type{S},
)::IndexWithType{F,S} where {F,S}
    return IndexWithType{F,S}(d)::IndexWithType{F,S}
end
function with_type(
    d::FunctionSetDoubleDict,
    ::Type{F},
    ::Type{S},
)::FunctionSetWithType{F,S} where {F,S}
    return FunctionSetWithType{F,S}(d)::FunctionSetWithType{F,S}
end

function Base.getindex(d::DoubleDict, ::Type{F}, ::Type{S}) where {F,S}
    return WithType{F,S}(d)
end
function Base.getindex(d::IndexDoubleDict, ::Type{F}, ::Type{S}) where {F,S}
    return IndexWithType{F,S}(d)
end
function Base.getindex(
    d::FunctionSetDoubleDict,
    ::Type{F},
    ::Type{S},
) where {F,S}
    return FunctionSetWithType{F,S}(d)
end

@inline function typed_value(::WithType{F,S,V}, v::V)::V where {V,F,S}
    return v
end
@inline function typed_value(
    ::IndexWithType{F,S},
    v::Int64,
)::CI{F,S} where {F,S}
    return CI{F,S}(v)
end
@inline function typed_value(
    ::FunctionSetWithType{F,S,V},
    v::Tuple{F,S},
)::Tuple{F,S} where {V,F,S}
    return v
end

function initialize_inner!(d::AbstractWithType{F,S,V,D}) where {F,S,V,D}
    return d.inner = D()
end

inner_is_empty(d::AbstractWithType)::Bool = d.inner === nothing
function inner(d::AbstractWithType{F,S,V,D})::D where {F,S,V,D}
    return d.inner::D
end

function Base.sizehint!(d::AbstractWithType{F,S}, n::Integer) where {F,S}
    if inner_is_empty(d)
        initialize_inner!(d)
    end
    return sizehint!(inner(d), n)
end

function Base.length(d::AbstractWithType{F,S}) where {F,S}
    if inner_is_empty(d)
        return 0
    end
    return length(inner(d))
end

function Base.haskey(d::AbstractWithType{F,S}, key::CI{F,S}) where {F,S}
    if inner_is_empty(d)
        return false
    end
    return haskey(inner(d), key.value)
end

function Base.getindex(d::AbstractWithType{F,S}, key::CI{F,S}) where {F,S}
    if inner_is_empty(d)
        throw(KeyError(key))
    end
    k_value = key.value::Int64
    return typed_value(d, inner(d)[k_value])
end

function Base.setindex!(
    d::WithType{F,S,V},
    value::V,
    key::CI{F,S},
)::V where {F,S,V}
    if inner_is_empty(d)
        initialize_inner!(d)
    end
    v_value = value
    k_value = key.value::Int64
    inner(d)[k_value] = v_value
    return value
end
function Base.setindex!(
    d::IndexWithType{F,S,V},
    value::CI{F,S},
    key::CI{F,S},
)::CI{F,S} where {F,S,V}
    if inner_is_empty(d)
        initialize_inner!(d)
    end
    _inner = inner(d)::Dict{Int64,Int64}
    v_value = value.value::Int64
    k_value = key.value::Int64
    _inner[k_value] = v_value
    return value
end
function Base.setindex!(
    d::FunctionSetWithType{F,S,V},
    value::Tuple{F,S},
    key::CI{F,S},
)::Tuple{F,S} where {F,S,V}
    if inner_is_empty(d)
        initialize_inner!(d)
    end
    _inner = inner(d)::Dict{Int64,Tuple{F,S}}
    v_value = value
    k_value = key.value::Int64
    _inner[k_value] = v_value
    return value
end

function Base.empty!(d::AbstractWithType{F,S}) where {F,S}
    if inner_is_empty(d)
        return d
    end
    return empty!(inner(d))
end

function Base.delete!(d::AbstractWithType{F,S}, key::CI{F,S}) where {F,S}
    if inner_is_empty(d)
        return d
    end
    k_value = key.value::Int64
    delete!(inner(d), k_value)
    return d
end

function Base.isempty(d::AbstractWithType{F,S}) where {F,S}
    if inner_is_empty(d)
        return true
    end
    return isempty(inner(d))
end

function Base.values(d::WithType{F,S,V})::Vector{V} where {F,S,V}
    if inner_is_empty(d)
        return V[]
    end
    return collect(values(inner(d)))
end
function Base.values(d::IndexWithType{F,S})::Vector{CI{F,S}} where {F,S}
    if inner_is_empty(d)
        return CI{F,S}[]
    end
    return CI{F,S}.(values(inner(d)))
end
function Base.values(
    d::FunctionSetWithType{F,S},
)::Vector{Tuple{F,S}} where {F,S}
    if inner_is_empty(d)
        return Tuple{F,S}[]
    end
    return collect(values(inner(d)))
end

function Base.keys(d::AbstractWithType{F,S}) where {F,S}
    if inner_is_empty(d)
        return CI{F,S}[]
    end
    return CI{F,S}.(keys(inner(d)))
end

function Base.iterate(d::AbstractWithType{F,S}) where {F,S}
    inner = d.inner
    if inner === nothing
        return nothing
    else
        next = iterate(inner)
        if next === nothing
            return nothing
        end
        (i, state) = next
        return CI{F,S}(i[1]) => typed_value(d, i[2]), (state, inner)
    end
end
function Base.iterate(d::AbstractWithType{F,S}, state) where {F,S}
    (istate, inner) = state
    next = iterate(inner, istate)
    if next === nothing
        return nothing
    end
    (i, state) = next
    return CI{F,S}(i[1]) => typed_value(d, i[2]), (state, inner)
end

end


text:
# Test constructing empty future
function test_construct_empty_future()
    fut = Banyan.Future()
    @test fut.value == nothing
    @test fut.mutated == false
    @test Banyan.get_src_name(fut) == "None"
    fut = Banyan.Future(source=Client())
    @test fut.value == nothing
    @test fut.mutated = true
    @test Banyan.get_dst_name(fut) == "None"
end

# Test constructing future from value
function test_construct_future_from_value()
    fut = Banyan.Future([1, 2, 3, 4, 5])
    @test fut.value == [1, 2, 3, 4, 5]
    @test fut.mutated == false
    @test fut.stale == false
    @test Banyan.get_src_name(fut) == "Value"
    @test Banyan.get_dst_name(fut) == "None"
end

# Test constructing future from existing future
function test_construct_future_from_future()
    fut = Banyan.Future([1, 2, 3, 4, 5])
    new_fut = Banyan.Future(fut)
    @test new_fut.value == fut.value
    @test fut.value_id != new_fut.value_id
    # Test when fut is stale
    fut.stale = true
    new_fut = Banyan.Future(fut)
    @test new_fut.value == nothing
end

# Test getting future from value id
function test_get_future_from_value_id()
    data = [1, 2, 3, 4, 5]
    fut = Banyan.Future(data)
    @test_throws KeyError Banyan.get_future(fut.value_id).value
    Banyan.sourced(fut, Client(data))
    @test Banyan.get_future(fut.value_id).value == data
end

# @testset "Test constructing futures" begin
#     job = Banyan.create_job(
#         username = get(ENV, "BANYAN_USERNAME", nothing),
# 	user_id = get(ENV, "BANYAN_USER_ID", nothing),
# 	api_key = get(ENV, "BANYAN_API_KEY", nothing),
# 	cluster_name = get(ENV, "BANYAN_CLUSTER_NAME", nothing),
# 	nworkers = 2,
# 	banyanfile_path = "file://res/Banyanfile.json",
#     )
#     run("construct future") do
#         with_job(job=job) do j
#             test_construct_empty_future()
#             test_construct_future_from_value()
#             test_construct_future_from_future()
#             test_get_future_from_value_id()
#         end
#     end
# end

max_stars_repo_name: banyan-team/banyan-julia

max_issues_repo_name: banyan-team/banyan-julia

max_forks_repo_name: banyan-team/banyan-julia


text:
empty!(server._documents)

LanguageServer.textDocument_didOpen_notification(LanguageServer.DidOpenTextDocumentParams(LanguageServer.TextDocumentItem("none", "julia", 0, "")), server, server.jr_endpoint)
@test LanguageServer.hasdocument(server, LanguageServer.URI2("none"))

LanguageServer.textDocument_didOpen_notification(LanguageServer.DidOpenTextDocumentParams(LanguageServer.TextDocumentItem("none", "julia", 0, "")), server, server.jr_endpoint)
@test LanguageServer.hasdocument(server, LanguageServer.URI2("none"))

LanguageServer.textDocument_didSave_notification(LanguageServer.DidSaveTextDocumentParams(LanguageServer.TextDocumentIdentifier("none"), ""), server, server.jr_endpoint)

LanguageServer.textDocument_didChange_notification(LanguageServer.DidChangeTextDocumentParams(LanguageServer.VersionedTextDocumentIdentifier("none", 0), [LanguageServer.TextDocumentContentChangeEvent(missing, missing, "ran")]), server, server.jr_endpoint)

LanguageServer.textDocument_didClose_notification(LanguageServer.DidCloseTextDocumentParams(LanguageServer.TextDocumentIdentifier("none")), server, server.jr_endpoint)
@test !LanguageServer.hasdocument(server, LanguageServer.URI2("none"))


text:
using Random, Plots
using ForwardDiff
using OrdinaryDiffEq, DiffEqSensitivity
using LinearAlgebra
using Statistics
using ProgressBars, Printf
using Flux
using Flux.Optimise:update!
using Flux.Losses: mae, mse
using BSON: @save, @load
using DelimitedFiles
using YAML
using XLSX
using StatsBase

ENV["GKSwstype"] = "100"

conf = YAML.load_file("./config.yaml")

fuel_name = conf["fuel_name"]
expr_name = conf["expr_name"]
fig_path = string("./results/$fuel_name/$expr_name/figs")
ckpt_path = string("./results/$fuel_name/$expr_name/checkpoint")
config_path = "./results/$fuel_name/$expr_name/config.yaml"

is_restart = Bool(conf["is_restart"])
ns = Int64(conf["ns"])
nr = Int64(conf["nr"])
lb = Float64(conf["lb"])
n_epoch = Int64(conf["n_epoch"])
n_plot = Int64(conf["n_plot"])
grad_max = Float64(conf["grad_max"])
maxiters = Int64(conf["maxiters"])
n_train = Int64(conf["n_train"])
batchsize = Int64(conf["batchsize"])

lr_max = Float64(conf["lr_max"])
lr_min = Float64(conf["lr_min"])
lr_decay = Float64(conf["lr_decay"])
lr_decay_step = Int64(conf["lr_decay_step"])
w_decay = Float64(conf["w_decay"])

llb = lb;
global p_cutoff = -1.0

opt = Flux.Optimiser(
    ExpDecay(lr_max, lr_decay, n_train * lr_decay_step, lr_min),
    ADAMW(0.005, (0.9, 0.999), w_decay),
);

if !is_restart
    if ispath(fig_path)
        rm(fig_path, recursive=true)
    end
    if ispath(ckpt_path)
        rm(ckpt_path, recursive=true)
    end
end

if ispath("./results/$fuel_name") == false
    mkdir("./results/$fuel_name")
end

if ispath("./results/$fuel_name/$expr_name") == false
    mkdir("./results/$fuel_name/$expr_name")
end

if ispath(fig_path) == false
    mkdir(fig_path)
    mkdir(string(fig_path, "/conditions"))
end

if ispath(ckpt_path) == false
    mkdir(ckpt_path)
end

cp("./config.yaml", config_path; force=true)

max_stars_repo_name: DENG-MIT/CRNN-Pyrolysis

max_issues_repo_name: DENG-MIT/CRNN-Pyrolysis

max_forks_repo_name: DENG-MIT/CRNN-Pyrolysis


text:
using GLVisualize, GeometryTypes, GLAbstraction, Colors, FileIO

window = glscreen()

mesh = GLNormalMesh(loadasset("./resources/quadrotor.obj")

view(visualize(mesh), window)

renderloop(window)

max_stars_repo_name: umd-agrc/SimpleControlSim

max_issues_repo_name: umd-agrc/SimpleControlSim

max_forks_repo_name: umd-agrc/SimpleControlSim


text:
## Simulation function
# dispatch the simulate method to be problem specific

function AutomotiveDrivingModels.simulate!{S,D,I,A,M<:AutomotiveDrivingModels.DriverModel, C<:Tuple{Vararg{Any}}}(
    ::Type{A},
    rec::EntityQueueRecord{S, D, I},
    scene::EntityFrame{S, D, I},
    env::CrosswalkEnv,
    models::Dict{I, M},
    nticks::Int,
    rng::AbstractRNG,
    n_ped::Int64,
    callbacks::C
    )

    empty!(rec)
    update!(rec, scene)

    # potential early out right off the bat
    if _run_callbacks(callbacks, rec, env, models, 0)
        return rec
    end

    actions = Array{A}(length(scene))

    # next_time = -log(rand(rng))/env.params.ped_rate
    # time_precision = Int(abs(log10(1/rec.timestep)))
    # next_time = round(next_time, time_precision)
    # println("First pedestrian Spawning time: $next_time")
    for tick in 1 : nticks
        # time = tick*rec.timestep
        # # println("time: $time")
        # if time ≈ next_time && scene.n < n_ped + 1
        #     # println("Spawning new pedestrians")
        #     next_time = time + max(-log(rand(rng))/env.params.ped_rate, rec.timestep)
        #     next_time = round(next_time, time_precision)
        #     # println("Next pedestrian at $(next_time)")
        #     new_ped = initial_pedestrian(scene, env, rng)
        #     models[new_ped.id] = ConstantPedestrian(dt = config.sim_dt)#TODO parameterized
        #     push!(scene, new_ped)
        #     actions = Array{A}(length(scene))
        # end
        if rand(config.rng) < env.params.ped_rate
            # println("Spawning new pedestrians")
            new_ped = initial_pedestrian(scene, env, config.rng)
            models[new_ped.id] = ConstantPedestrian(dt = config.sim_dt)#TODO parameterized
            push!(scene, new_ped)
            actions = Array{Any}(length(scene))
        end

        get_actions!(actions, scene, env.roadway, models)
        tick!(scene, env.roadway, actions, rec.timestep)
        update!(rec, scene)

        if _run_callbacks(callbacks, rec, env, models, tick)
            break
        end
    end
    return rec
end

function AutomotiveDrivingModels.simulate!{S,D,I,M<:AutomotiveDrivingModels.DriverModel, C<:Tuple{Vararg{Any}}}(
    rec::EntityQueueRecord{S, D, I},
    scene::EntityFrame{S, D, I},
    env::CrosswalkEnv,
    models::Dict{I, M},
    nticks::Int,
    rng::AbstractRNG,
    n_ped::Int64,
    callbacks::C
    )

    return simulate!(Any, rec, scene, env, models, nticks, rng, n_ped, callbacks)
end

function _run_callbacks{S,D,I,M<:DriverModel,C<:Tuple{Vararg{Any}}}(callbacks::C, rec::EntityQueueRecord{S,D,I}, env::CrosswalkEnv, models::Dict{I,M}, tick::Int)
    isdone = false
    for callback in callbacks
        isdone |= run_callback(callback, rec, env, models, tick)
    end
    return isdone
end

"""
    initial_pedestrian(scene::Scene, env::CrosswalkEnv, scene::Scene, rng::AbstractRNG)
Create a new pedestrian entity at its initial state
"""
function initial_pedestrian(scene::Scene, env::CrosswalkEnv, rng::AbstractRNG)
    # lateral position
    d_lat = Distributions.Uniform(env.params.roadway_length - env.params.crosswalk_width + 2, env.params.roadway_length + env.params.crosswalk_width-1)
    x0 = 0.5*rand(rng, d_lat)
    # x0 =  0.5*env.params.roadway_length

    # vertical position
    y0 = -env.params.crosswalk_length/4

    # orientation
    θ = π/2

    #velocity
    v0 = rand(rng, Distributions.Uniform(0., env.params.ped_max_speed))
    cw_roadway = Roadway([RoadSegment(2, [env.crosswalk])]);
    ped_initialstate = VehicleState(VecSE2(x0, y0, θ), env.crosswalk, cw_roadway, v0);
    # ped_initialstate = VehicleState(VecSE2(x0, y0, θ), env.crosswalk, env.roadway, v0)

    # new id, increment last id
    id = scene.n + 2

    return Vehicle(ped_initialstate,  VehicleDef(AgentClass.PEDESTRIAN, 1.0, 1.0), id)
end

function initial_scene(models::Dict{Int64, DriverModel}, env::CrosswalkEnv, config::EvalConfig)
    scene = Scene()
    n_ped = rand(config.rng, 0:10)
    n_ped = 0
    ego = models[1].ego.state
    pomdp = models[1].updater.problem
    b0 = initialstate(pomdp, ego)
    for i = 1:n_ped
        ped_state = rand(config.rng, b0).ped
        d_lat = Distributions.Uniform(env.params.roadway_length - env.params.crosswalk_width + 2, env.params.roadway_length + env.params.crosswalk_width-1)
        x0 = 0.5*rand(config.rng, d_lat)
        y0 = ped_state.posG.y
        cw_roadway = Roadway([RoadSegment(2, [env.crosswalk])])
        ped_state = VehicleState(VecSE2(x0, y0, ped_state.posG.θ), env.crosswalk, cw_roadway, ped_state.v)

        if !off_the_grid(pomdp, ped_state)
            id = scene.n + 2
            new_ped = Vehicle(ped_state, PEDESTRIAN_DEF, id)
            models[new_ped.id] = ConstantPedestrian(dt = config.sim_dt)
            push!(scene, new_ped)
        end
    end
    # println("Starting with ", scene.n, " pedestrians on the scene")
    return scene
end

# function initial_scene(models::Dict{Int64, DriverModel}, env::CrosswalkEnv,
#                        config::EvalConfig)
#
#     nticks = rand(config.rng, 0:200)
#     rec = SceneRecord(nticks+1, config.sim_dt)
#     scene = Scene()
#     empty!(rec)
#     update!(rec, scene)
#     actions = Array{Any}(length(scene))
#
#     for tick in 1 : nticks
#         time = tick*rec.timestep
#         # println("time: $time")
#         if rand(config.rng) < env.params.ped_rate
#             # println("Spawning new pedestrians")
#             new_ped = initial_pedestrian(scene, env, config.rng)
#             models[new_ped.id] = ConstantPedestrian(dt = config.sim_dt)#TODO parameterized
#             push!(scene, new_ped)
#             actions = Array{Any}(length(scene))
#         end
#
#         get_actions!(actions, scene, env.roadway, models)
#         tick!(scene, env.roadway, actions, rec.timestep)
#         update!(rec, scene)
#     end
#     @assert findfirst(EGO_ID, scene) == nothing
#     return rec[0]
# end


text:
using Test

using MPI
using LinearAlgebra, DoubleFloats

MPI.Init()

comm = MPI.COMM_WORLD
sz = MPI.Comm_size(comm)
rank = MPI.Comm_rank(comm)

root = sz-1
val = rank == root ? sum(0:sz-1) : nothing
@test MPI.Reduce(rank, MPI.SUM, root, comm) == val

val = rank == root ? sz-1 : nothing
@test MPI.Reduce(rank, MPI.MAX, root, comm) == val

val = rank == root ? 0 : nothing
@test MPI.Reduce(rank, MPI.MIN, root, comm) == val

val = rank == root ? sz : nothing
@test MPI.Reduce(1, +, root, comm) == val

mesg = collect(1.0:5.0)
sum_mesg = MPI.Reduce(mesg, MPI.SUM, root, comm)
sum_mesg = rank == root ? sum_mesg : sz*mesg
@test isapprox(norm(sum_mesg-sz*mesg), 0.0)

comm_size = MPI.Comm_size(MPI.COMM_WORLD)

send_arr = Int[1, 2, 3]

if Sys.iswindows() && Sys.WORD_SIZE == 32
    operators = [MPI.SUM, +]
else
    operators = [MPI.SUM, +, (x,y) -> 2x+y-x]
end

for typ=[Int]
    for dims = [1, 2, 3]
        send_arr = zeros(typ, Tuple(3 for i in 1:dims))
        send_arr[:] .= 1:length(send_arr)

        for op in operators

            # Non allocating version
            recv_arr = zeros(typ, size(send_arr))
            MPI.Reduce!(send_arr, recv_arr, op, root, MPI.COMM_WORLD)
            for i=1:length(recv_arr)
                @test rank == root ? recv_arr[i] == comm_size*send_arr[i] : true
            end

            # Assertions when output buffer too small
            recv_arr = zeros(typ, size(send_arr).-1)
            rank == root && @test_throws AssertionError MPI.Reduce!(send_arr,
                                                                recv_arr,
                                                                length(send_arr),
                                                                op, root,
                                                                MPI.COMM_WORLD)

            # IN_PLACE
            recv_arr = deepcopy(send_arr)
            MPI.Reduce_in_place!(recv_arr, length(recv_arr), op, root, MPI.COMM_WORLD)
            for i=1:length(recv_arr)
                @test rank == root ? recv_arr[i] == comm_size*send_arr[i] : true
            end

            # Allocating version
            val = MPI.Reduce(2, op, root, MPI.COMM_WORLD)
            @test rank == root ? val == comm_size*2 : true

            # Allocating, Subarray
            A = typ[1,2]
            val = MPI.Reduce(view(A, 2:2), op, root, MPI.COMM_WORLD)
            @test rank == root ? val[1] == comm_size*2 : true

            vals = MPI.Reduce(send_arr, op, root, MPI.COMM_WORLD)
            for i=1:length(recv_arr)
                @test rank == root ? vals[i] == comm_size*send_arr[i] : true
                @test rank == root ? length(vals) == length(send_arr) : true
                @test rank == root ? eltype(vals) == typ : true
            end
        end
    end
end

MPI.Barrier( MPI.COMM_WORLD )

if !(Sys.iswindows() && Sys.WORD_SIZE == 32)

    send_arr = [Double64(i)/10 for i = 1:10]

    if rank == root
        @test MPI.Reduce(send_arr, +, root, MPI.COMM_WORLD) ≈ [Double64(sz*i)/10 for i = 1:10] rtol=sz*eps(Double64)
    else
        @test MPI.Reduce(send_arr, +, root, MPI.COMM_WORLD) === nothing
    end

    MPI.Barrier( MPI.COMM_WORLD )
end

GC.gc()
MPI.Finalize()
@test MPI.Finalized()


text:
# Script for producing an animation
# Requires Plots.jl, PyPlot (matplotlib~1.5), and Linux (Windows confirmed not to work as of 5/9/2016)

using Plots
pyplot(reuse=true)
sr() = sort(2rand(100)-1)
@gif for i=0:0.2:5
    x, y = sr(), sr()
    z = map((x,y) -> sin(x+i)+cos(y), x, y)
    surface(x, y, z)
end


text:
function pause(cur_player::AbstractPlayer)
  cur_player.game.in_focus || return

  cur_state = cur_player.state

  cur_state.is_done && return

  is_paused = !cur_state.is_playing

  cur_state.is_playing = !cur_state.is_playing

  is_paused && drop_clock(cur_player)

  cur_js_func = is_paused ? "removeClass" : "addClass"

  cur_js = """
    \$(".js-pause-button").closest("a").$(cur_js_func)("cs-active");
  """

  tetris_js(
    cur_player.game.scope,
    JSString(cur_js)
  )

  return
end


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

##### mean #####

"""
    mean(f::Function, v)

Apply the function `f` to each element of `v` and take the mean.

```jldoctest
julia> mean(√, [1, 2, 3])
1.3820881233139908

julia> mean([√1, √2, √3])
1.3820881233139908
```
"""
function mean(f::Callable, iterable)
    y = iterate(iterable)
    if y == nothing
        throw(ArgumentError("mean of empty collection undefined: $(repr(iterable))"))
    end
    count = 1
    value, state = y
    f_value = f(value)
    total = reduce_first(add_sum, f_value)
    y = iterate(iterable, state)
    while y !== nothing
        value, state = y
        total += f(value)
        count += 1
        y = iterate(iterable, state)
    end
    return total/count
end
mean(iterable) = mean(identity, iterable)
mean(f::Callable, A::AbstractArray) = sum(f, A) / _length(A)

"""
    mean!(r, v)

Compute the mean of `v` over the singleton dimensions of `r`, and write results to `r`.

# Examples
```jldoctest
julia> v = [1 2; 3 4]
2×2 Array{Int64,2}:
 1  2
 3  4

julia> mean!([1., 1.], v)
2-element Array{Float64,1}:
 1.5
 3.5

julia> mean!([1. 1.], v)
1×2 Array{Float64,2}:
 2.0  3.0
```
"""
function mean!(R::AbstractArray, A::AbstractArray)
    sum!(R, A; init=true)
    x = max(1, _length(R)) // _length(A)
    R .= R .* x
    return R
end

"""
    mean(v; dims)

Compute the mean of whole array `v`, or optionally along the given dimensions.

!!! note
    Julia does not ignore `NaN` values in the computation. Use the [`missing`](@ref) type
    to represent missing values, and the [`skipmissing`](@ref) function to omit them.
"""
mean(A::AbstractArray; dims=:) = _mean(A, dims)

_mean(A::AbstractArray{T}, region) where {T} = mean!(reducedim_init(t -> t/2, +, A, region), A)
_mean(A::AbstractArray, ::Colon) = sum(A) / _length(A)

##### median & quantiles #####

"""
    middle(x)

Compute the middle of a scalar value, which is equivalent to `x` itself, but of the type of `middle(x, x)` for consistency.
"""
middle(x::Union{Bool,Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128}) = Float64(x)
# Specialized functions for real types allow for improved performance
middle(x::AbstractFloat) = x
middle(x::Real) = (x + zero(x)) / 1

"""
    middle(x, y)

Compute the middle of two reals `x` and `y`, which is
equivalent in both value and type to computing their mean (`(x + y) / 2`).
"""
middle(x::Real, y::Real) = x/2 + y/2

"""
    middle(range)

Compute the middle of a range, which consists of computing the mean of its extrema.
Since a range is sorted, the mean is performed with the first and last element.

```jldoctest
julia> middle(1:10)
5.5
```
"""
middle(a::AbstractRange) = middle(a[1], a[end])

"""
    middle(a)

Compute the middle of an array `a`, which consists of finding its
extrema and then computing their mean.

```jldoctest
julia> a = [1,2,3.6,10.9]
4-element Array{Float64,1}:
  1.0
  2.0
  3.6
 10.9

julia> middle(a)
5.95
```
"""
middle(a::AbstractArray) = ((v1, v2) = extrema(a); middle(v1, v2))

"""
    median!(v)

Like [`median`](@ref), but may overwrite the input vector.
"""
function median!(v::AbstractVector)
    isempty(v) && throw(ArgumentError("median of an empty array is undefined, $(repr(v))"))
    if eltype(v)<:AbstractFloat
        @inbounds for x in v
            isnan(x) && return x
        end
    end
    inds = axes(v, 1)
    n = _length(inds)
    mid = div(first(inds)+last(inds),2)
    if isodd(n)
        return middle(partialsort!(v,mid))
    else
        m = partialsort!(v, mid:mid+1)
        return middle(m[1], m[2])
    end
end
median!(v::AbstractArray) = median!(vec(v))

"""
    median(v; dims)

Compute the median of an entire array `v`, or, optionally,
along the given dimensions. For an even number of
elements no exact median element exists, so the result is
equivalent to calculating mean of two median elements.

!!! note
    Julia does not ignore `NaN` values in the computation. Use the [`missing`](@ref) type
    to represent missing values, and the [`skipmissing`](@ref) function to omit them.
"""
median(v::AbstractArray; dims=:) = _median(v, dims)

_median(v::AbstractArray, dims) = mapslices(median!, v, dims)

_median(v::AbstractArray{T}, ::Colon) where {T} = median!(copyto!(Array{T,1}(undef, _length(v)), v))

# for now, use the R/S definition of quantile; may want variants later
# see ?quantile in R -- this is type 7
"""
    quantile!([q, ] v, p; sorted=false)

Compute the quantile(s) of a vector `v` at the probability or probabilities `p`, which
can be given as a single value, a vector, or a tuple. If `p` is a vector, an optional
output array `q` may also be specified. (If not provided, a new output array is created.)
The keyword argument `sorted` indicates whether `v` can be assumed to be sorted; if
`false` (the default), then the elements of `v` may be partially sorted.

The elements of `p` should be on the interval [0,1], and `v` should not have any `NaN`
values.

Quantiles are computed via linear interpolation between the points `((k-1)/(n-1), v[k])`,
for `k = 1:n` where `n = length(v)`. This corresponds to Definition 7 of Hyndman and Fan
(1996), and is the same as the R default.

!!! note
    Julia does not ignore `NaN` values in the computation: `quantile!` will
    throw an `ArgumentError` in the presence of `NaN` values in the data array.
    Use the [`missing`](@ref) type to represent missing values, and the
    [`skipmissing`](@ref) function to omit them.

* Hyndman, R.J and Fan, Y. (1996) "Sample Quantiles in Statistical Packages",
  *The American Statistician*, Vol. 50, No. 4, pp. 361-365
"""
function quantile!(q::AbstractArray, v::AbstractVector, p::AbstractArray;
                   sorted::Bool=false)
    if size(p) != size(q)
        throw(DimensionMismatch("size of p, $(size(p)), must equal size of q, $(size(q))"))
    end
    isempty(q) && return q

    minp, maxp = extrema(p)
    _quantilesort!(v, sorted, minp, maxp)

    for (i, j) in zip(eachindex(p), eachindex(q))
        @inbounds q[j] = _quantile(v,p[i])
    end
    return q
end

quantile!(v::AbstractVector, p::AbstractArray; sorted::Bool=false) =
    quantile!(similar(p,float(eltype(v))), v, p; sorted=sorted)

quantile!(v::AbstractVector, p::Real; sorted::Bool=false) =
    _quantile(_quantilesort!(v, sorted, p, p), p)

function quantile!(v::AbstractVector, p::Tuple{Vararg{Real}}; sorted::Bool=false)
    isempty(p) && return ()
    minp, maxp = extrema(p)
    _quantilesort!(v, sorted, minp, maxp)
    return map(x->_quantile(v, x), p)
end

# Function to perform partial sort of v for quantiles in given range
function _quantilesort!(v::AbstractArray, sorted::Bool, minp::Real, maxp::Real)
    isempty(v) && throw(ArgumentError("empty data vector"))

    if !sorted
        lv = length(v)
        lo = floor(Int,1+minp*(lv-1))
        hi = ceil(Int,1+maxp*(lv-1))

        # only need to perform partial sort
        sort!(v, 1, lv, Sort.PartialQuickSort(lo:hi), Base.Sort.Forward)
    end
    isnan(v[end]) && throw(ArgumentError("quantiles are undefined in presence of NaNs"))
    return v
end

# Core quantile lookup function: assumes `v` sorted
@inline function _quantile(v::AbstractVector, p::Real)
    0 <= p <= 1 || throw(ArgumentError("input probability out of [0,1] range"))

    lv = length(v)
    f0 = (lv - 1)*p # 0-based interpolated index
    t0 = trunc(f0)
    h  = f0 - t0
    i  = trunc(Int,t0) + 1

    T  = promote_type(eltype(v), typeof(v[1]*h))

    if h == 0
        return convert(T, v[i])
    else
        a = v[i]
        b = v[i+1]
        if isfinite(a) && isfinite(b)
            return convert(T, a + h*(b-a))
        else
            return convert(T, (1-h)*a + h*b)
        end
    end
end

"""
    quantile(v, p; sorted=false)

Compute the quantile(s) of a vector `v` at a specified probability or vector or tuple of
probabilities `p`. The keyword argument `sorted` indicates whether `v` can be assumed to
be sorted.

The `p` should be on the interval [0,1], and `v` should not have any `NaN` values.

Quantiles are computed via linear interpolation between the points `((k-1)/(n-1), v[k])`,
for `k = 1:n` where `n = length(v)`. This corresponds to Definition 7 of Hyndman and Fan
(1996), and is the same as the R default.

!!! note
    Julia does not ignore `NaN` values in the computation: `quantile` will
    throw an `ArgumentError` in the presence of `NaN` values in the data array.
    Use the [`missing`](@ref) type to represent missing values, and the
    [`skipmissing`](@ref) function to omit them.

- Hyndman, R.J and Fan, Y. (1996) "Sample Quantiles in Statistical Packages",
  *The American Statistician*, Vol. 50, No. 4, pp. 361-365
"""
quantile(v::AbstractVector, p; sorted::Bool=false) =
    quantile!(sorted ? v : copymutable(v), p; sorted=sorted)

max_stars_repo_name: ninjin/julia

max_issues_repo_name: ninjin/julia

max_forks_repo_name: ninjin/julia


text:
include("C:\\Users\\darien.shannon\\Documents\\Code\\Julia\\JuliaSE\\src\\2DBeam.jl")

COORD = [Node(0,0)
         Node(120, 0)
         Node(360, 0)
         Node(480, 0)]

MSUP = [Support(1, 1, 0)
        Support(2, 1, 0)
        Support(3, 1, 0)
        Support(4, 1, 1)]

EM = Dict( 1 => Material(29e3))

CP = Dict( 1 => Section(350),
           2 => Section(500))

MPRP = [Element(1, 2, 1, 1)
        Element(2, 3, 1, 1)
        Element(3, 4, 1, 2)]

memberLoads = [(2, DLoad(0.1667, 0.1667, 0, 120))
               (2, CLoad(25, 180))
               (3, DLoad(0.25, 0, 0, 120))]

nodeLoads = [(1, NLoad((0, -480)))]

forces, reactions = run_analysis(COORD, MSUP, EM, CP, MPRP, memberLoads, nodeLoads)
println(forces)
println(reactions)

max_stars_repo_name: Julia-SE/matrix-analysis

max_issues_repo_name: Julia-SE/matrix-analysis

max_forks_repo_name: Julia-SE/matrix-analysis


text:
#
# BlockOffsets
#

const Blocks{N} = Vector{Block{N}}
const BlockOffset{N} = Pair{Block{N},Int}
# Use Dictionary from Dictionaries.jl (faster
# iteration than Base.Dict)
const BlockOffsets{N} = Dictionary{Block{N},Int}

BlockOffset(block::Block{N}, offset::Int) where {N} = BlockOffset{N}(block, offset)

nzblock(bof::BlockOffset) = first(bof)

offset(bof::BlockOffset) = last(bof)

nzblock(block::Block) = block

# Get the offset if the nth block in the block-offsets
# list
offset(bofs::BlockOffsets, n) = offset(bofs[n])

nnzblocks(bofs::BlockOffsets) = length(bofs)
nnzblocks(bs::Blocks) = length(bs)

eachnzblock(bofs::BlockOffsets) = keys(bofs)

nzblocks(bofs::BlockOffsets) = collect(eachnzblock(bofs))

# define block ordering with reverse lexographical order
function isblockless(b1::Block{N}, b2::Block{N}) where {N}
  return CartesianIndex(b1) < CartesianIndex(b2)
end

function isblockless(bof1::BlockOffset{N}, bof2::BlockOffset{N}) where {N}
  return isblockless(nzblock(bof1), nzblock(bof2))
end

function isblockless(bof1::BlockOffset{N}, b2::Block{N}) where {N}
  return isblockless(nzblock(bof1), b2)
end

function isblockless(b1::Block{N}, bof2::BlockOffset{N}) where {N}
  return isblockless(b1, nzblock(bof2))
end

function offset(bofs::BlockOffsets{N}, block::Block{N}) where {N}
  if !isassigned(bofs, block)
    return nothing
  end
  return bofs[block]
end

function nnz(bofs::BlockOffsets, inds)
  _nnz = 0
  nnzblocks(bofs) == 0 && return _nnz
  for block in eachnzblock(bofs)
    _nnz += blockdim(inds, block)
  end
  return _nnz
end

blockoffsets(blocks::Vector{<:NTuple}, inds) = blockoffsets(Block.(blocks), inds)

# TODO: should this be a constructor?
function blockoffsets(blocks::Vector{<:Block{N}}, inds) where {N}
  blockoffsets = BlockOffsets{N}()
  nnz = 0
  for block in blocks
    insert!(blockoffsets, block, nnz)
    current_block_dim = blockdim(inds, block)
    nnz += current_block_dim
  end
  return blockoffsets, nnz
end

"""
    diagblockoffsets(blocks::Blocks,inds)

Get the blockoffsets only along the diagonal.
The offsets are along the diagonal.

Assumes the blocks are allong the diagonal.
"""
function diagblockoffsets(
  blocks::Vector{BlockT}, inds
) where {BlockT<:Union{Block{N},Tuple{Vararg{<:Any,N}}}} where {N}
  blockoffsets = BlockOffsets{N}()
  nnzdiag = 0
  for (i, block) in enumerate(blocks)
    insert!(blockoffsets, Block(block), nnzdiag)
    current_block_diaglength = blockdiaglength(inds, block)
    nnzdiag += current_block_diaglength
  end
  return blockoffsets, nnzdiag
end

# Permute the blockoffsets and indices
function permutedims(boffs::BlockOffsets{N}, inds, perm::NTuple{N,Int}) where {N}
  blocksR = Blocks{N}(undef, nnzblocks(boffs))
  for (i, block) in enumerate(keys(boffs))
    blocksR[i] = permute(block, perm)
  end
  indsR = permute(inds, perm)
  blockoffsetsR, _ = blockoffsets(blocksR, indsR)
  return blockoffsetsR, indsR
end

function permutedims(blocks::Vector{Block{N}}, perm::NTuple{N,Int}) where {N}
  blocks_perm = Vector{Block{N}}(undef, length(blocks))
  for (i, block) in enumerate(blocks)
    blocks_perm[i] = permute(block, perm)
  end
  return blocks_perm
end

"""
blockdim(T::BlockOffsets,nnz::Int,pos::Int)

Get the block dimension of the block at position pos.
"""
function blockdim(boffs::BlockOffsets, nnz::Int, pos::Int)
  if nnzblocks(boffs) == 0
    return 0
  elseif pos == nnzblocks(boffs)
    return nnz - offset(boffs, pos)
  end
  return offset(boffs, pos + 1) - offset(boffs, pos)
end

function Base.union(
  boffs1::BlockOffsets{N}, nnz1::Int, boffs2::BlockOffsets{N}, nnz2::Int
) where {N}
  n1, n2 = 1, 1
  boffsR = BlockOffset{N}[]
  current_offset = 0
  while n1 <= length(boffs1) && n2 <= length(boffs2)
    if isblockless(boffs1[n1], boffs2[n2])
      push!(boffsR, BlockOffset(nzblock(boffs1[n1]), current_offset))
      current_offset += blockdim(boffs1, nnz1, n1)
      n1 += 1
    elseif isblockless(boffs2[n2], boffs1[n1])
      push!(boffsR, BlockOffset(nzblock(boffs2[n2]), current_offset))
      current_offset += blockdim(boffs2, nnz2, n2)
      n2 += 1
    else
      push!(boffsR, BlockOffset(nzblock(boffs1[n1]), current_offset))
      current_offset += blockdim(boffs1, nnz1, n1)
      n1 += 1
      n2 += 1
    end
  end
  if n1 <= length(boffs1)
    for n in n1:length(boffs1)
      push!(boffsR, BlockOffset(nzblock(boffs1[n]), current_offset))
      current_offset += blockdim(boffs1, nnz1, n)
    end
  elseif n2 <= length(boffs2)
    for n in n2:length(bofss2)
      push!(boffsR, BlockOffset(nzblock(boffs2[n]), current_offset))
      current_offset += blockdim(boffs2, nnz2, n)
    end
  end
  return boffsR, current_offset
end


text:
module LinearWrapper

using JavaCall

const AbstractKalmanFilter = @jimport org.hipparchus.filtering.kalman.AbstractKalmanFilter
const Class = @jimport java.lang.Class
const JString = @jimport java.lang.String
const LinearEvolution = @jimport org.hipparchus.filtering.kalman.linear.LinearEvolution
const LinearKalmanFilter = @jimport org.hipparchus.filtering.kalman.linear.LinearKalmanFilter
const LinearProcess = @jimport org.hipparchus.filtering.kalman.linear.LinearProcess
const MatrixDecomposer = @jimport org.hipparchus.linear.MatrixDecomposer
const Measurement = @jimport org.hipparchus.filtering.kalman.Measurement
const Object = @jimport java.lang.Object
const ProcessEstimate = @jimport org.hipparchus.filtering.kalman.ProcessEstimate
const RealMatrix = @jimport org.hipparchus.linear.RealMatrix
const RealVector = @jimport org.hipparchus.linear.RealVector

export LinearEvolution
export LinearKalmanFilter
export LinearProcess
export equals
export estimation_step
export get_class
export get_command
export get_control_matrix
export get_corrected
export get_evolution
export get_measurement_jacobian
export get_predicted
export get_process_noise_matrix
export get_state_transition_matrix
export hash_code
export notify
export notify_all
export to_string
export wait

include("linear_evolution.jl")
include("linear_kalman_filter.jl")
include("linear_process.jl")

end


text:
function test_adjtrans()
  @testset ExtendedTestSet "Adjoint/Transpose/Conjugate" begin
    A = rand(5, 3) + im * rand(5, 3)
    opA = LinearOperator(A)

    aopA = AdjointLinearOperator(opA)
    copA = ConjugateLinearOperator(opA)
    topA = TransposeLinearOperator(opA)

    for (foo, fop) in [(adjoint, aopA), (conj, copA), (transpose, topA)]
      @test foo(opA) === fop
      @test Matrix(fop) == foo(A)
      @test foo(fop) === opA

      @test Matrix(-fop) == foo(-A)
      @test Matrix((2 + 3im) * fop) == (2 + 3im) * foo(A)
      @test Matrix(fop * (2 + 3im)) == foo(A) * (2 + 3im)
    end

    @test adjoint(topA) === copA
    @test adjoint(copA) === topA
    @test conj(aopA) === topA
    @test conj(topA) === aopA
    @test transpose(copA) === aopA
    @test transpose(aopA) === copA

    v = rand(5) + im * rand(5)
    @test aopA * v == adjoint(A) * v
    @test topA * v == transpose(A) * v

    v = rand(3) + im * rand(3)
    @test copA * v == conj(A) * v
  end
end

test_adjtrans()


text:
import ..SamplingConstraints:
    StartToEnd,
    StrictlyDecreasing,
    sequence_exists,
    constrain,
    TruncateMaximum,
    TruncateRange,
    TruncateQuantiles

import IntervalArithmetic:
    interval

function _draw!(s, x, c::StrictlyDecreasing{<:StartToEnd}, mins, maxs)
    L = length(x)

    # TODO: add slight margin?
    for i = 1:L
        if i == 1
            lo = maximum(mins[2:end])
            truncated_distribution = truncate(x[i], TruncateMinimum(lo))
            s[1] = resample(truncated_distribution)
        end

        if 1 < i < L
            hi = min(s[i - 1], maxs[i])
            lo = max(mins[i], maximum(mins[i+1:end]))

            lo <= hi || error("Truncation range invalid for point $i. Got lo < hi ($lo < $hi), which should be impossible.")

            truncated_distribution = truncate(x[i], TruncateRange(lo, hi))
            s[i] = resample(truncated_distribution)
        end

        if i == L
            hi = min(s[i - 1], maxs[i])
            truncated_distribution = truncate(x[i], TruncateMaximum(hi))
            s[end] = resample(truncated_distribution)

        end
    end

    return s
end

"""
    _draw(x, c::StrictlyDecreasing{StartToEnd}, mins, maxs)

Sample `x` in a strictly decreasing manner, given pre-computed minimum and maximum
values for each distribution in `c`.

Implicitly assumes a strictly decreasing sequence exists, but does not check that condition.
"""
function _draw(x, c::StrictlyDecreasing{<:StartToEnd}, mins, maxs)
    L = length(x)
    samples = zeros(Float64, L) # a vector to hold the element-wise samples

    _draw!(samples, x, c, mins, maxs)
end


text:
"""
   Wrapper for Sundials `N_Vector` that
   uses Julia `Vector{realtype}` as the data container.

   Implements `DenseVector` interface and
   manages automatic destruction of the referenced `N_Vector` when it is
   no longer in use.
"""
struct NVector <: DenseVector{realtype}
    ref_nv::Ref{N_Vector}   # reference to N_Vector
    v::Vector{realtype}     # array that is referenced by N_Vector

    function NVector(v::Vector{realtype})
        # note that N_VMake_Serial() creates N_Vector doesn't own the data,
        # so calling N_VDestroy_Serial() would not deallocate v
        nv = new(Ref{N_Vector}(N_VMake_Serial(length(v), v)), v)
        finalizer(release_handle, nv.ref_nv)
        return nv
    end

    function NVector(nv::N_Vector)
        # wrap N_Vector into NVector and get non-owning access to `nv` data
        # via `v`, but don't register finalizer for `nv`
        return new(Ref{N_Vector}(nv), asarray(nv))
    end
end

N_Vector(x::NVector) = convert(N_Vector,x)

release_handle(ref_nv::Ref{N_Vector}) = N_VDestroy_Serial(ref_nv[])

Base.size(nv::NVector, d...) = size(nv.v, d...)
Base.stride(nv::NVector, d::Integer) = stride(nv.v, d)

Base.getindex(nv::NVector, i::Real) = getindex(nv.v, i)
Base.getindex(nv::NVector, i::AbstractArray) = getindex(nv.v, i)
Base.getindex(nv::NVector, inds...) = getindex(nv.v, inds...)

Base.setindex!(nv::NVector, X, i::Real) = setindex!(nv.v, X, i)
Base.setindex!(nv::NVector, X, i::AbstractArray) = setindex!(nv.v, X, i)
Base.setindex!(nv::NVector, X, inds...) = setindex!(nv.v, X, inds...)

Base.pointer(nv::NVector) = Sundials.__N_VGetArrayPointer_Serial(nv.ref_nv[])

##################################################################
#
# Methods to convert between Julia Vectors and Sundials N_Vectors.
#
##################################################################

Base.convert(::Type{NVector}, v::Vector{realtype}) = NVector(v)
Base.convert(::Type{NVector}, v::Vector{T}) where {T<:Real} = NVector(copy!(similar(v, realtype), v))
Base.convert(::Type{NVector}, nv::NVector) = nv
Base.convert(::Type{NVector}, nv::N_Vector) = NVector(nv)
Base.convert(::Type{N_Vector}, nv::NVector) = nv.ref_nv[]
Base.convert(::Type{Vector{realtype}}, nv::NVector)= nv.v
Base.convert(::Type{Vector}, nv::NVector)= nv.v

""" `N_Vector(v::Vector{T})`

    Converts Julia `Vector` to `N_Vector`.

    Implicitly creates `NVector` object that manages automatic
    destruction of `N_Vector` object when no longer in use.
"""
Base.convert(::Type{N_Vector}, v::Vector{realtype}) = N_Vector(NVector(v))
Base.convert(::Type{N_Vector}, v::Vector{T}) where {T<:Real} = N_Vector(NVector(v))

Base.similar(nv::NVector) = NVector(similar(nv.v))

nvlength(x::N_Vector) = unsafe_load(unsafe_load(convert(Ptr{Ptr{Clong}}, x)))
# asarray() creates an array pointing to N_Vector data, but does not take the ownership
@inline asarray(x::N_Vector) = unsafe_wrap(Array, __N_VGetArrayPointer_Serial(x), (nvlength(x),), own=false)
@inline asarray(x::N_Vector, dims::Tuple) = unsafe_wrap(Array, __N_VGetArrayPointer_Serial(x), dims, own=false)
asarray(x::Vector{realtype}) = x
asarray(x::Ptr{realtype}, dims::Tuple) = unsafe_wrap(Array, x, dims, own=false)
@inline Base.convert(::Type{Vector{realtype}}, x::N_Vector) = asarray(x)
@inline Base.convert(::Type{Vector}, x::N_Vector) = asarray(x)

nvector(x::Vector{realtype}) = NVector(x)
#nvector(x::N_Vector) = x


text:
using Revise, Debugger

using Images
image = Images.load("./examples/cat_posing.jpg"); # Check current working directory with pwd()

using CausticsEngineering
mesh, image_caustics = engineer_caustics(image);


text:
function pointmin(I::AbstractArray{T}) where {T}
    Fx = zeros(T, size(I))
    Fy = zeros(T, size(I))
    J = zeros(T, size(I) .+ 2)
    return pointmin!(I, Fx, Fy, J)
end

function pointmin!(I::AbstractArray{T}, Fx, Fy) where {T}
    J = zeros(T, size(I) .+ 2)
    return pointmin!(I, Fx, Fy, J)
end

function pointmin!(I::AbstractArray{T}, Fx, Fy, J) where {T}
    @views J .= maximum(I)

    @views J[2:(end - 1), 2:(end - 1)] .= I
    Ne = [-1 -1; -1 0; -1 1; 0 -1; 0 1; 1 -1; 1 0; 1 1]
    for i in 1:maximum(size(Ne))
        @views In = J[
            (2 + Ne[i, 1]):(end - 1 + Ne[i, 1]), (2 + Ne[i, 2]):(end - 1 + Ne[i, 2])
        ]
        check = In .< I
        I[check] .= In[check]
        @views D = Ne[i, :]
        D = D ./ sqrt(sum(D .^ 2))
        Fx[check] .= D[1]
        Fy[check] .= D[2]
    end
    return (Fx, Fy)
end


text:
import ..UncertainDatasets.AbstractUncertainValueDataset
import ..UncertainDatasets.UncertainDataset
import ..UncertainValues.UncertainScalarKDE

abstract type SamplingConstraint end

"""
    NoConstraint

A (non)constraint indicating that the distribution furnishing an uncertain value
should be sampled its entire support.
"""
struct NoConstraint <: SamplingConstraint end

#########################################################################
# Sampling constraints for regular data (i.e. not age/depth/time index...,
# but the values associated to those indices).
#########################################################################

abstract type ValueSamplingConstraint <: SamplingConstraint end

"""
    TruncateLowerQuantile(lower_quantile::Float64)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated below at some quantile.
"""
struct TruncateLowerQuantile <: ValueSamplingConstraint
    lower_quantile::Float64
end

"""
    TruncateUpperQuantile(upper_quantile::Float64)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated above at some quantile.
"""
struct TruncateUpperQuantile <: ValueSamplingConstraint
    upper_quantile::Float64
end

"""
    TruncateQuantiles(lower_quantile::Float64, upper_quantile::Float64)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated at some quantile quantile
`(lower_quantile, upper_quantile)`.
"""
struct TruncateQuantiles{T1<:Real, T2<:Real} <: ValueSamplingConstraint
    lower_quantile::T1
    upper_quantile::T2

    function TruncateQuantiles(lower_quantile::T1, upper_quantile::T2) where {T1, T2}
        err_msg = "Need 0 <= lower_quantile < upper_quantile <= 1"

        if !(lower_quantile < upper_quantile && 0.0 <= lower_quantile < upper_quantile <= 1.0)
            throw(DomainError(err_msg * " (got lo = $lower_quantile, hi = $upper_quantile)"))
        else
            new{T1, T2}(lower_quantile, upper_quantile)
        end
    end
end

"""
    TruncateStd(nσ::Number)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated at the mean ± `nσ` (`n` standard deviations).

## Notes

- Beware when you apply the `TruncateStd` constraint to a (usually a numeric)
    population with a small value range. With `nσ` small, you might end up with
    a population mean *between* the actual values, so that the range
    `[mean(pop) - nσ*std(pop), mean(pop) + nσ*std(pop)]` returns `nothing`.
"""
struct TruncateStd{T<:Number} <: ValueSamplingConstraint
    nσ::T

    function TruncateStd(nσ::T) where T

        if nσ <= 0
            err_str = "TruncateStd must be initialised with nσ strictly positive"
            throw(DomainError(err_str *  " (got nσ = $nσ)"))
        else
            new{T}(nσ)
        end
    end
end

"""
    TruncateMinimum(min::Number)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated below at some specified minimum value.
"""
struct TruncateMinimum{T<:Number} <: ValueSamplingConstraint
    min::T
end

"""
    TruncateMaximum(max::Number)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated above at some specified maximum value.
"""
struct TruncateMaximum{T<:Number} <: ValueSamplingConstraint
    max::T
end

"""
    TruncateRange(min::Number, max::Number)

A constraint indicating that the distribution furnishing an uncertain value
should be truncated at some range `[min, max]`.
"""
struct TruncateRange{T1, T2} <: ValueSamplingConstraint
    min::T1
    max::T2

    function TruncateRange(min::T1, max::T2) where {T1, T2}
        if min <= max # <= ties are allowed, because we may encounter CertainValue instances
            return new{T1, T2}(min, max)
        else
            err_msg = "Cannot create TruncateRange instance. Need min < max"
            throw(DomainError(err_msg * " (got min = $min, max = $max)"))
        end
    end
end

export
SamplingConstraint,
NoConstraint,

ValueSamplingConstraint,
TruncateLowerQuantile,
TruncateUpperQuantile,
TruncateQuantiles,
TruncateMinimum,
TruncateMaximum,
TruncateRange,
TruncateStd

#########################################################################
# Sampling constraints for sample indices (time index, age, depth, etc...)
# Often, these need to be sampled to obey some physical criteria (i.e.,
# observations are from physical samples lying above each other, so the order
# of the observations cannot be mixed).
#########################################################################
include("ordered_sequences/ordered_sequence_algorithms.jl")

"""
    IndexSamplingConstraint

An abstract type for sampling constraints valid only for indices.
"""
abstract type IndexSamplingConstraint <: SamplingConstraint end

#########################################################################
# Sequential sampling constraints
#########################################################################

abstract type SequentialSamplingConstraint{OA} end

# Add the ordered sampling scheme to the seqential sampling constraints,
# because that's all they affect. Defaults to `StartToEnd`.
#(::Type{SSC})(args...; kwargs...) where SSC<:SequentialSamplingConstraint = SSC(StartToEnd(), args...; kwargs...)

"""
    StrictlyIncreasing(algorithm::OrderedSamplingAlgorithm;
        n::Int = 50000, lq = 0.05, uq = 0.95)

Sampling scheme indicating element-wise sampling such that the resulting values
are strictly increasing in magnitude.

Increasing sequential sampling is only guaranteed when distributions have finite support.
Therefore, distributions are element-wise truncated to the lower and upper quantiles
`lq` and `uq`. For each distribution, this is done by drawing `n` values from it, then
finding the quantiles for that sample, and finally truncating the distribution to the empirical
quantile range.

`algorithm` is an instance of some `OrderedSamplingAlgorithm` (e.g. `StartToEnd`).
`n` is the number of samples to draw when computing quantiles.

Typically used when there are known, physical constraints on the measurements.
For example, geochemical measurements of sediments at different depths of a sediment core
are taken at physically separate depths in the core. Thus, the order of the indices cannot
be flipped, and must be strictly decreasing/increasing.

See also: [`StartToEnd`](@ref)
"""
struct StrictlyIncreasing{OA <: OrderedSamplingAlgorithm} <: SequentialSamplingConstraint{OA}
    ordered_sampling_algorithm::OA
    n::Int # number of samples to draw from samples
    lq::Float64 # lower quantile
    uq::Float64 # upper quantile

    function StrictlyIncreasing(algorithm::OA = StartToEnd(); n::Int = 10000, lq = 0.05, uq = 0.95) where OA
        if lq >= uq
            throw(ArgumentError("Need lq < uq. Got lq=$(lq) > uq=$(uq)."))
        end
        new{OA}(algorithm, n, lq, uq)
    end
end

"""
    StrictlyIncreasing(algorithm::OrderedSamplingAlgorithm; n::Int = 50000)

Sampling scheme indicating element-wise sampling such that the resulting values
are strictly decreasing in magnitude.

Decreasing sequential sampling is only guaranteed when distributions have finite support.
Therefore, distributions are element-wise truncated to the lower and upper quantiles
`lq` and `uq`. For each distribution, this is done by drawing `n` values from it, then
finding the quantiles for that sample, and finally truncating the distribution to the empirical
quantile range.

`algorithm` is an instance of some `OrderedSamplingAlgorithm` (e.g. `StartToEnd`).
`n` is the number of samples to draw when computing quantiles.

Typically used when there are known, physical constraints on the measurements.
For example, geochemical measurements of sediments at different depths of a sediment core
are taken at physically separate depths in the core. Thus, the order of the indices cannot
be flipped, and must be strictly decreasing/increasing.

See also: [`StartToEnd`](@ref)
"""
struct StrictlyDecreasing{OA <: OrderedSamplingAlgorithm} <: SequentialSamplingConstraint{OA}
    ordered_sampling_algorithm::OA
    n::Int # number of samples to draw from samples
    lq::Float64 # lower quantile
    uq::Float64 # upper quantile

    function StrictlyDecreasing(algorithm::OA = StartToEnd(); n::Int = 10000, lq = 0.05, uq = 0.95) where OA
        if lq >= uq
            throw(ArgumentError("Need lq < uq. Got lq=$(lq) > uq=$(uq)."))
        end
        new{OA}(algorithm, n, lq, uq)
    end
end

export
IndexSamplingConstraint,
SequentialSamplingConstraint,
StrictlyIncreasing,
StrictlyDecreasing


text:
include("../src/BlockCiphers.jl")

importall BlockCiphers

print("benching AES ")

plain = zeros(Uint8, 16)
k1 = AES(zeros(Uint8, int32(128/8)))

buff = zeros(Uint8, 16 * 1000000)

function gigs(len :: Int64)
    for i=0:(len - 1)
        s = slice(buff, ((i*16)+1) : ((i+1) * 16))
        encrypt!(k1, s, s)
    end
    show(buff[1:16])
    println()
end

gigs(1000)

@time gigs(100000)
@time gigs(1000000)
@time gigs(1000000)

println()


text:
ALL_TASK_OFFSETS[("linux-x86", v"1.6.1")] = Dict(
    :END => 216,
    :_isexception => 30,
    :_state => 28,
    :bufsz => 204,
    :copy_stack => 208,
    :ctx => 44,
    :donenotify => 12,
    :eh => 40,
    :excstack => 36,
    :gcstack => 212,
    :logstate => 20,
    :next => 0,
    :prio => 34,
    :queue => 4,
    :result => 16,
    :sizeof_ctx => 156,
    :start => 24,
    :sticky => 29,
    :stkbuf => 200,
    :tid => 32,
    :tls => 8,
    :tls_base_context => 3412,
)


text:
# Define Order, OrderQueue objects and relavant methods.

"Orders as an immutable container type"
struct Order
    orderid::Int64
    side::Symbol
    size::Int64
    price::Float32
    acctid::Union{Int64,Nothing}
end

# Orderbook State Saving Methods

_order_to_csv(o::Order) = "LMT,$(o.orderid),$(string(o.side)),$(o.size),$(o.price),$(o.acctid)"

"Return new order with size modified"
copy_modify_size(o::Order,size) = Order(o.orderid,o.side,size,o.price,o.acctid)

""""
OrderQueue is a queue of orders at a fixed price, implemented as a Deque/Vector.

OrderQueue.queue is a Vector (interpreted as double ended queue). Orders are added and removed via FIFO logic.
OrderQueue also keeps track of its contained volume in shares and orders

OrderQueue(price) Initializes an empty order queue at price
"""
@kwdef struct OrderQueue
    price::Float32
    queue::Vector{Order} = Vector{Order}()
    total_volume::Base.RefValue{Int64} = Base.RefValue{Int64}(0)
    num_orders::Base.RefValue{Int64} = Base.RefValue{Int64}(0)
end

# Insert, delete, push, pop orders into/out of OrderQueue
function Base.push!(oq::OrderQueue,ord::Order)
    push!(oq.queue,ord)
    oq.total_volume[] += ord.size
    oq.num_orders[] += 1
end

function Base.pushfirst!(oq::OrderQueue,ord::Order)
    pushfirst!(oq.queue,ord)
    oq.total_volume[] += ord.size
    oq.num_orders[] += 1
end

@inline function _popat_orderid!(oq::OrderQueue,pop_id::Int64)
    ret_ix = Int64(0)
    for i in 1:length(oq.queue)
        @inbounds if oq.queue[i].orderid == pop_id
            ret_ix = i
            break
        end
    end
    return popat!(oq.queue,ret_ix)
end

function Base.delete!(oq::OrderQueue,orderid::Int64)
    ord = _popat_orderid!(oq,orderid)
    oq.total_volume[] -= ord.size
    oq.num_orders[] -= 1
end

function Base.popfirst!(oq::OrderQueue)
    ord = popfirst!(oq.queue)
    oq.total_volume[] -= ord.size
    oq.num_orders[] -= 1
    return ord
end

Base.isempty(oq::OrderQueue) = Base.isempty(oq.queue)

function Base.print(io::IO,oq::OrderQueue)
    write(io::IO,"OrderQueue @ price=$(oq.price):","\n")
    # write(io," ","TRD,ID,SIDE,SIZE,PX,ACCT",'\n')
    for ord in oq.queue
        write(io::IO," ")
        print(io::IO,ord)
        write(io::IO,"\n")
        # write(io::IO," ",_order_to_csv(ord),"\n")
    end
end