To be able to edit code and run cells, you need to run the notebook yourself. Where would you like to run the notebook?

This notebook takes about 20 seconds to run.

In the cloud (experimental)

Binder is a free, open source service that runs scientific notebooks in the cloud! It will take a while, usually 2-7 minutes to get a session.

On your computer

(Recommended if you want to store your changes.)

  1. Copy the notebook URL:
  2. Run Pluto

    (Also see: How to install Julia and Pluto)

  3. Paste URL in the Open box

Frontmatter

If you are publishing this notebook on the web, you can set the parameters below to provide HTML metadata. This is useful for search engines and social media.

Author 1

Testing

👀 Reading hidden code
189 μs
👀 Reading hidden code
abstract type TestResult end
322 μs
Any
👀 Reading hidden code
const Code = Any
108 μs
👀 Reading hidden code
struct Pass <: TestResult
expr::Code
end
1.1 ms
👀 Reading hidden code
abstract type Fail <: TestResult end
334 μs
👀 Reading hidden code
struct Wrong <: Fail
expr::Code
result
arg_results
end
1.2 ms
👀 Reading hidden code
struct Error <: Fail
expr::Code
error
end
1.1 ms
👀 Reading hidden code
function Base.show(io::IO, mime::MIME"text/html", value::Pass)
show(io, mime, HTML("""
<div
style="
display: flex;
flex-direction: row;
align-items: center;
/*background-color: rgb(208, 255, 209)*/
"
>
<div
style="
width: 12px;
height: 12px;
border-radius: 50%;
background-color: green;
"
></div>
<div style="min-width: 12px"></div>
<code
class="language-julia"
style="
flex: 1;
background-color: transparent;
filter: grayscale(1) brightness(0.8);
"
>$(value.expr)</code>
</div>
"""))
end
538 μs
function Base.show(io::IO, mime::MIME"text/html", value::Wrong)
show(io, mime, HTML("""
<div
style="
display: flex;
flex-direction: row;
align-items: center;
/*background-color: rgb(208, 255, 209)*/
"
>
<div
style="
width: 12px;
height: 12px;
border-radius: 50%;
background-color: red;
"
></div>
<div style="min-width: 12px"></div>
<code
class="language-julia"
style="
flex: 1;
background-color: transparent;
filter: grayscale(1) brightness(0.8);
"
>$(value.expr)</code>
<div style="
font-family: monospace;
font-size: 12px;
color: red;
padding-left: 8px;
">Evaluated: $(string(Expr(value.expr.head, value.arg_results...)))</div>
</div>
"""))
end
👀 Reading hidden code
3.2 ms
function Base.show(io::IO, mime::MIME"text/html", value::Error)
show(io, mime, HTML("""
<div
style="
display: flex;
flex-direction: row;
align-items: center;
/*background-color: rgb(208, 255, 209)*/
"
>
<div
style="
width: 12px;
height: 12px;
border-radius: 50%;
background-color: red;
"
></div>
<div style="width: 12px"></div>
<div>
<code
class="language-julia"
style="
background-color: transparent;
filter: grayscale(1) brightness(0.8);
"
>$(value.expr)</code>
<div style="
font-family: monospace;
font-size: 12px;
color: red;
padding-left: 8px;
">Error: $(sprint(showerror, value.error))</div>
</div>
</div>
"""))
end
👀 Reading hidden code
538 μs
# Only define this in Pluto - assume we are `using Test` otherwise
begin
@skip_as_script macro test(expr)
quote
expr_raw = $(expr |> QuoteNode)
try
arg_results = $([esc(a) for a in expr.args])
# result = eval(Expr($(expr.head |> QuoteNode), arg_results...))
# if result == true
# Pass(expr_raw)
# else
# Wrong(expr_raw, result)
# end
catch e
Error(expr_raw, e)
end
# Base.@locals()
end
end
# Do nothing inside pluto (so we don't need to have Test as dependency)
# test/Firebasey is `using Test` before including this file
@only_as_script ((@isdefined Test) ? nothing : macro test(expr) quote nothing end end)
end
👀 Reading hidden code
3.9 ms
Expr
  head: Symbol block
  args: Array{Any}((2,))
    1: LineNumberNode
      line: Int64 2
      file: Symbol /home/runner/work/disorganised-mess/disorganised-mess/testing and debugging 1.jl#==#7c35f88d-7740-4bc3-9ab6-855cc78223e2
    2: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol ==
        2: Symbol a
        3: QuoteNode
          value: Symbol a
quote
a == :a
end |> Dump
👀 Reading hidden code
3.5 ms
Error message

UndefVarError: to_eval#452 not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. macro expansion
    				Pass(expr_raw)			else				Wrong(expr_raw, result, to_eval)			end		catch e
  2. Show more...
@test3 sqrt.([1])
👀 Reading hidden code
---

👀 Reading hidden code
67.4 μs
Error message

UndefVarError: to_eval#438 not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. macro expansion
    				Pass(expr_raw)			else				Wrong(expr_raw, result, to_eval)			end		catch e
  2. Show more...
@test3 a .== a
👀 Reading hidden code
---
a == [1, 2, 3]
@test3 a == [1,2,3]
👀 Reading hidden code
17.6 ms
Error message

UndefVarError: to_eval#445 not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. macro expansion
    				Pass(expr_raw)			else				Wrong(expr_raw, result, to_eval)			end		catch e
  2. Show more...
@test3 a == :a
👀 Reading hidden code
---
iseven(234)
@test3 iseven(234)
👀 Reading hidden code
9.7 ms
Error message

MethodError: no method matching getproperty(::typeof(sqrt), ::Tuple{Vector{Int64}})

Closest candidates are:

getproperty(::Any, ::Symbol) at /opt/hostedtoolcache/julia/1.7.3/x64/share/julia/base/Base.jl:42

getproperty(::Any, ::Symbol, ::Symbol) at /opt/hostedtoolcache/julia/1.7.3/x64/share/julia/base/Base.jl:54

Stack trace

Here is what happened, the most recent locations are first:

  1. eval
  2. eval(x::Expr)
  3. 		eval(Expr(e.head, arg_results...))end
Maybe time for a break? ☕️
let
e = :(sqrt.([5]))
arg_results = [eval(a) for a in e.args]
eval(Expr(e.head, arg_results...))
end
👀 Reading hidden code
---
staged_eval (generic function with 1 method)
staged_eval(e) = eval(e)
👀 Reading hidden code
375 μs
staged_eval (generic function with 2 methods)
function staged_eval(e::Expr)
if e.head == :call
arg_results = Any[
if a isa QuoteNode
QuoteNode(a)
elseif i == 1
a
else
eval(a)
end
for (i,a) in enumerate(e.args)]
arg_results[1] = e.args[1]
printable_arg_results = [
if a isa QuoteNode
a.value
else
a
end
for a in arg_results]
eval(Expr(e.head, arg_results...)), arg_results, Expr(e.head, printable_arg_results...)
else
eval(e), nothing
end
end
👀 Reading hidden code
2.6 ms
eval_args (generic function with 1 method)
eval_args(x) = x
👀 Reading hidden code
324 μs
quote_again (generic function with 1 method)
quote_again(x) = x
👀 Reading hidden code
363 μs
quote_again (generic function with 2 methods)
quote_again(x::QuoteNode) = QuoteNode(x)
👀 Reading hidden code
366 μs
eval_args (generic function with 2 methods)
function eval_args(e::Expr)
if e.head == :call
arg_results = Any[
if a isa QuoteNode
QuoteNode(a)
elseif i == 1
a
else
eval(a)
end
for (i,a) in enumerate(e.args)]
arg_results[1] = e.args[1]
printable_arg_results = [
if a isa QuoteNode
a.value
else
a
end
for a in arg_results]
Expr(e.head, printable_arg_results...)
else
eval(e)
end
end
👀 Reading hidden code
2.9 ms
onestep (generic function with 1 method)
onestep(x; m) = []
👀 Reading hidden code
1.3 ms
onestep (generic function with 2 methods)
function onestep(e::Expr; m=Module())
results = Any[]
# push!(results, e)
arg_results = Any[a for a in e.args]
for (i,a) in enumerate(e.args)
arg_results[i] = if a isa QuoteNode
a
elseif (e.head === :call || e.head === :let) && i == 1
a
elseif a isa Expr
inner_results = onestep(a; m=m)
for ir in inner_results
arg_results[i] = ir
push!(results, Expr(e.head, arg_results...))
end
inner_results[end]
else
a
end
# push!(results, Expr(e.head, arg_results...))
end
push!(results, Core.eval(m, Expr(e.head, arg_results...)))
results
end
👀 Reading hidden code
3.6 ms
expr_debug (generic function with 1 method)
function expr_debug(x)
e = Base.remove_linenums!(deepcopy(x))
Any[e, onestep(e)...]
end
👀 Reading hidden code
565 μs
expr_debug(quote
let
end
end)
👀 Reading hidden code
5.9 ms
eval(Expr(:let, Expr(:block), nothing))
👀 Reading hidden code
253 μs
debug_result = expr_debug(:(
let
r = if rand(Bool)
20
else
16
end
y = sqrt(4)
y == sqrt(sqrt(r))
end
));
👀 Reading hidden code
14.0 ms
👀 Reading hidden code
359 ms
let
    r = if rand(Bool)
            20
        else
            16
        end
    y = sqrt(4)
    y == sqrt(sqrt(r))
end
debug_result[step] |> prettycolors
👀 Reading hidden code
53.3 ms

















👀 Reading hidden code
122 μs
prettycolors (generic function with 1 method)
prettycolors(e) = Markdown.MD([Markdown.Code("julia", string(e))])
👀 Reading hidden code
475 μs
Expr
  head: Symbol let
  args: Array{Any}((2,))
    1: Expr
      head: Symbol block
      args: Array{Any}((0,))
    2: Expr
      head: Symbol block
      args: Array{Any}((3,))
        1: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol r
            2: Expr
              head: Symbol if
              args: Array{Any}((3,))
                1: Expr
                  head: Symbol call
                  args: Array{Any}((2,))
                    1: Symbol rand
                    2: Symbol Bool
                2: Expr
                  head: Symbol block
                  args: Array{Any}((1,))
                    1: Int64 20
                3: Expr
                  head: Symbol block
                  args: Array{Any}((1,))
                    1: Int64 16
        2: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol y
            2: Expr
              head: Symbol call
              args: Array{Any}((2,))
                1: Symbol sqrt
                2: Int64 4
        3: Expr
          head: Symbol call
          args: Array{Any}((3,))
            1: Symbol ==
            2: Symbol y
            3: Expr
              head: Symbol call
              args: Array{Any}((2,))
                1: Symbol sqrt
                2: Expr
                  head: Symbol call
                  args: Array{Any}((2,))
                    1: Symbol sqrt
                    2: Symbol r
Dump(debug_result[step]; maxdepth=999)
👀 Reading hidden code
4.3 ms
using PlutoUI
👀 Reading hidden code
162 ms
Error message

UndefVarError: a not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. from :0
  2. eval
  3. eval
  4. staged_eval
    				a			else				eval(a)			end 				for (i,a) in enumerate(e.args)]
  5. Show more...
Be patient :)
staged_eval(:(a == :a))
👀 Reading hidden code
---
Error message

UndefVarError: a not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. from :0
  2. eval
  3. eval
  4. staged_eval
    				a			else				eval(a)			end 				for (i,a) in enumerate(e.args)]
  5. Show more...
Computers are hard!
staged_eval(:(a == a))
👀 Reading hidden code
---
Error message

UndefVarError: a not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. from :0
  2. eval
  3. eval
  4. staged_eval
    				a			else				eval(a)			end 				for (i,a) in enumerate(e.args)]
  5. Show more...
staged_eval(:(a .== a))
👀 Reading hidden code
---
staged_eval(:(sqrt(sqrt(4))))
👀 Reading hidden code
39.7 ms
staged_eval(:(sqrt.(5)))
👀 Reading hidden code
13.8 ms
:(sqrt.(5))
e = :(sqrt.(5))
👀 Reading hidden code
22.8 μs
Expr
  head: Symbol .
  args: Array{Any}((2,))
    1: Symbol sqrt
    2: Expr
      head: Symbol tuple
      args: Array{Any}((1,))
        1: Int64 5
Dump(e)
👀 Reading hidden code
12.0 μs
Base.Broadcast.BroadcastFunction(==)
.==
👀 Reading hidden code
232 μs
Base.Broadcast.BroadcastFunction(==)
eval(Meta.parse(".=="))
👀 Reading hidden code
281 μs
Error message

UndefVarError: .== not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. from :0
  2. eval
  3. eval(x::Symbol)
  4. eval(Symbol(".=="))
this suckz 💣
eval(Symbol(".=="))
👀 Reading hidden code
---
2.23606797749979
eval(e)
👀 Reading hidden code
203 μs
Error message

UndefVarError: a not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. eval
  2. eval(x::Expr)
  3. eval(Expr(:call, Symbol(".=="), :a, :a))
eval(Expr(:call, Symbol(".=="), :a, :a))
👀 Reading hidden code
---
@test3 (macro with 1 method)
@skip_as_script macro test3(expr)
quote
expr_raw = $(expr |> QuoteNode)
try
result, arg_results = staged_eval(expr_raw)
if result === true
Pass(expr_raw)
else
Wrong(expr_raw, result, to_eval)
end
catch e
rethrow(e)
Error(expr_raw, e)
end

# Base.@locals()
end
end

👀 Reading hidden code
6.6 ms
quote
    var"#491#expr_raw" = $(QuoteNode(:(a .== :a)))
    try
        (var"#492#result", var"#493#arg_results") = Main.workspace#4.staged_eval(var"#491#expr_raw")
        if var"#492#result" === true
            Main.workspace#4.Pass(var"#491#expr_raw")
        else
            Main.workspace#4.Wrong(var"#491#expr_raw", var"#492#result", Main.workspace#4.to_eval)
        end
    catch var"#496#e"
        Main.workspace#4.rethrow(var"#496#e")
        Main.workspace#4.Error(var"#491#expr_raw", var"#496#e")
    end
end
(@macroexpand @test3 a .== :a) |> Base.remove_linenums!
👀 Reading hidden code
1.8 ms
true
eval(Expr(:call, QuoteNode(.<), 1, 2))
👀 Reading hidden code
54.0 ms
quote_if_needed (generic function with 1 method)
quote_if_needed(x) = x
👀 Reading hidden code
337 μs
quote_if_needed (generic function with 2 methods)
quote_if_needed(x::Union{Expr,Symbol}) = QuoteNode(x)
👀 Reading hidden code
393 μs
a = [1,2,3]
👀 Reading hidden code
12.8 μs

👀 Reading hidden code
66.2 μs

👀 Reading hidden code
67.0 μs
@test2 (macro with 1 method)
macro test2(expr)
quote nothing end
end
👀 Reading hidden code
427 μs
@skip_as_script @test notebook1 == deepcopy(notebook1)
👀 Reading hidden code
118 μs

DisplayOnly

👀 Reading hidden code
167 μs
skip_as_script (generic function with 1 method)
function skip_as_script(m::Module)
if isdefined(m, :PlutoForceDisplay)
return m.PlutoForceDisplay
else
isdefined(m, :PlutoRunner) && parentmodule(m) == Main
end
end
👀 Reading hidden code
565 μs
@skip_as_script
@displayonly expression

Marks a expression as Pluto-only, which means that it won't be executed when running outside Pluto. Do not use this for your own projects.

"""
@displayonly expression

Marks a expression as Pluto-only, which means that it won't be executed when running outside Pluto. Do not use this for your own projects.
"""
macro skip_as_script(ex) skip_as_script(__module__) ? esc(ex) : nothing end
👀 Reading hidden code
783 μs
@only_as_script

The opposite of @skip_as_script

"The opposite of `@skip_as_script`"
macro only_as_script(ex) skip_as_script(__module__) ? nothing : esc(ex) end
👀 Reading hidden code
788 μs
2
@skip_as_script x = 2
👀 Reading hidden code
13.6 μs
@skip_as_script @test 1 + 1 == x
👀 Reading hidden code
110 μs
@skip_as_script @test 1 + 1 + 1 == x
👀 Reading hidden code
107 μs
@skip_as_script @test error("Oh my god") == x
👀 Reading hidden code
28.3 ms

Track

👀 Reading hidden code
164 μs
sleep(0.1)
101.0 ms
20 frames in @code_typed
@skip_as_script @track sleep(0.1)
👀 Reading hidden code
366 ms
Tracked
begin
Base.@kwdef struct Tracked
expr
value
time
bytes
times_ran = 1
which = nothing
code_info = nothing
end
function Base.show(io::IO, mime::MIME"text/html", value::Tracked)
times_ran = if value.times_ran === 1
""
else
"""<span style="opacity: 0.5"> ($(value.times_ran)×)</span>"""
end
# method = sprint(show, MIME("text/plain"), value.which)
code_info = if value.code_info ≠ nothing
codelength = length(value.code_info.first.code)
"$(codelength) frames in @code_typed"
else
""
end
color = if value.time > 1
"red"
elseif value.time > 0.001
"orange"
elseif value.time > 0.0001
"blue"
else
"green"
end
show(io, mime, HTML("""
<div
style="
display: flex;
flex-direction: row;
align-items: center;
"
>
<div
style="
width: 12px;
height: 12px;
border-radius: 50%;
background-color: $(color);
"
></div>
<div style="width: 12px"></div>
<div>
<code
class="language-julia"
style="
background-color: transparent;
filter: grayscale(1) brightness(0.8);
"
>$(value.expr)</code>
<div style="
font-family: monospace;
font-size: 12px;
color: $(color);
">
$(prettytime(value.time * 1e9 / value.times_ran))
$(times_ran)
</div>
<div style="
font-family: monospace;
font-size: 12px;
color: gray;
">$(code_info)</div>

</div>
</div>
"""))
end
Tracked
end
👀 Reading hidden code
34.6 ms
@track (macro with 1 method)
macro track(expr)
times_ran_expr = :(1)
expr_to_show = expr
if expr.head == :for
@assert expr.args[1].head == :(=)
times_ran_expr = expr.args[1].args[2]
expr_to_show = expr.args[2].args[2]
end

Tracked # reference so that baby Pluto understands
quote
local times_ran = length($(esc(times_ran_expr)))
local value, time, bytes = @timed $(esc(expr))
local method = nothing
local code_info = nothing
try
# Uhhh
method = @which $(expr_to_show)
code_info = @code_typed $(expr_to_show)
catch nothing end
Tracked(
expr=$(QuoteNode(expr_to_show)),
value=value,
time=time,
bytes=bytes,
times_ran=times_ran,
which=method,
code_info=code_info
)
end
end
👀 Reading hidden code
1.8 ms
prettytime (generic function with 1 method)
function prettytime(time_ns::Number)
suffices = ["ns", "μs", "ms", "s"]
current_amount = time_ns
suffix = ""
for current_suffix in suffices
if current_amount >= 1000.0
current_amount = current_amount / 1000.0
else
suffix = current_suffix
break
end
end
# const roundedtime = time_ns.toFixed(time_ns >= 100.0 ? 0 : 1)
roundedtime = if current_amount >= 100.0
round(current_amount; digits=0)
else
round(current_amount; digits=1)
end
return "$(roundedtime) $(suffix)"
end
👀 Reading hidden code
1.3 ms