metal slug 3 screenshot
2020 is definitely a year of oddities. My code often includes some weird bugs too. And in this post I want to show you several methods for debugging julia code.
I am by no means a professional at this and that is true of everything I blog about, so just keep that in mind ... well, actually some of you pay to do my work, so technically I I can call myself a professional blogger, right?
, . , , . , - .
, . , :
, . , , .
: 10 000. …
(a,b)
, d(a) = b
d(b) = a
, d
— , d(4) = 1+2 = 3
.
— a = 220
b = 284
.
, , .
function is_amicable(a, b)
sum_divisors(a) == b && sum_divisors(b) == a
end
. ,return
.
sum_divisors
function sum_divisors(a)
result = 0
for i = 1:a
if a % i == 0
result += i
end
end
return result
end
julia> is_amicable(220, 284) false
, , , , , . .
Debugger.jl REPL
, REPL IDE, VSCode.
, REPL. (Debugger.jl)
julia> ] add Debugger
julia> using Debugger
julia> @enter is_amicable(220, 284)
In is_amicable(a, b) at REPL[7]:1
1 function is_amicable(a, b)
>2 sum_divisors(a) == b && sum_divisors(b) == a
3 end
About to run: (sum_divisors)(220)
1|debug>
@enter is_amicable(220, 284)
, . , , , REPL. , amicable.jl
Revise include
(. REPL and Revise.jl).
, , .
...
julia> using Revise
julia> includet("amicable.jl")
julia> using Debugger
julia> @enter is_amicable(220, 284)
In is_amicable(a, b) at /home/ole/Julia/opensources/blog/2020-10-27-basics-debugging/amicable.jl:1
1 function is_amicable(a, b)
>2 sum_divisors(a) == b && sum_divisors(b) == a
3 end
About to run: (sum_divisors)(220)
1|debug>
. , , sum_divisors(220)
.
1|debug>
, , , .
: Debugger.jl commands
?
enter,
n
— .
1|debug> n
In is_amicable(a, b) at /home/ole/Julia/opensources/blog/2020-10-27-basics-debugging/amicable.jl:1
1 function is_amicable(a, b)
>2 sum_divisors(a) == b && sum_divisors(b) == a
3 end
About to run: return false
sum_divisors(220) != 284
. , , sum_divisors(220)
.
q
,
@enter is_amicable(220, 284)
s
1|debug> s
In sum_divisors(a) at /home/ole/Julia/opensources/blog/2020-10-27-basics-debugging/amicable.jl:5
5 function sum_divisors(a)
> 6 result = 0
7 for i = 1:a
8 if a % i == 0
9 result += i
10 end
About to run: 0
1|debug>
n
, , , , .
, , ?
: , , , , , sum_divisors(220)
. , , , . , .
, , , , .
, , .
, , , , .
bp add
, , . ?
.
bp add 12
. c
, continue ( ).
1|debug> c
Hit breakpoint:
In sum_divisors(a) at /home/ole/Julia/opensources/blog/2020-10-27-basics-debugging/amicable.jl:5
8 if a % i == 0
9 result += i
10 end
11 end
>12 return result
13 end
About to run: return 504
, , 504
284
. `
, . ( , , , , 1|julia>
, julia>
, , ...)
504-284
— , julia, , , :
1|debug> `
1|julia> 504-284
220
, . , .
, :
function sum_divisors(a)
result = 0
#for i = 1:a
for i = 1:a-1
if a % i == 0
result += i
end
end
return result
end
.
, , ,
backspace, q
, .
julia> is_amicable(220, 284) true
, .
. c
1|debug> w add i
1] i: 219
1|debug> w add a
1] i: 219
2] a: 220
. c
, ( sum_divisors(284) == 220
).
w
, :
1|debug> w
1] i: 283
2] a: 284
, , , . .
visual studio julialang.
VSCode
, Julia VSCode IDE , , , vim, emacs - … , , ,
VSCode Atom/Juno, Julia VSCode Atom.
IDE, , , .
, .
, , julia.
is_amicable(220, 284)
, VSCode .
, .
, , .
. . , , , "284". a
i
.
, , , .
. Watch
Variables
, . , , .
: , , ? , .
!
Infiltrator.jl
Julia, - . , , . C++, , , , , , .
, , , , .
, - , Infiltrator.jl. , , , .
100 . , , , , .
Infiltrator.jl . , . @infiltrate
. ,
, . , , REPL. , @infiltrate
, , .
. debugging ConstraintSolver.jl.
using Infiltrator
@infiltrate
.
using Infiltrator
function is_amicable(a, b)
sum_divisors(a) == b && sum_divisors(b) == a
end
function sum_divisors(a)
result = 0
for i = 1:a-1
if a % i == 0
result += i
end
end
@infiltrate
return result
end
is_amicable(220, 284)
include("amicable.jl")
:
Hit `@infiltrate` in sum_divisors(::Int64) at amicable.jl:14: debug>
, , , , sum_divisors
. Debugger.jl .
?
debug> ? Code entered is evaluated in the current function's module. Note that you cannot change local variables. The following commands are special cased: - `@trace`: Print the current stack trace. - `@locals`: Print local variables. - `@stop`: Stop infiltrating at this `@infiltrate` spot. Exit this REPL mode with `Ctrl-D`, and clear the effect of `@stop` with `Infiltrator.clear_stop()`.
, :
debug> @trace [1] sum_divisors(::Int64) at amicable.jl:14 [2] is_amicable(::Int64, ::Int64) at amicable.jl:4 [3] top-level scope at amicable.jl:18 [4] include(::String) at client.jl:457
, is_amicable
, , multiple dispatch.
debug> @locals - result::Int64 = 284 - a::Int64 = 220
, , VSCode.
, . Infiltrator.jl `
, .
debug> a == 220 true
@stop
, , Infiltrator.clear_stop()
, .
@stop
, @infiltrate
CTRL-D
:
Hit `@infiltrate` in sum_divisors(::Int64) at amicable.jl:14: debug>
, , . , , , , @locals
, .
.
Debugger. jl, , REPL.
.
, , VSCode Debugger.jl. , , IDE. Debugger.jl , , .
, , . ( , Debugger.jl). , , , . , , , 1000 .
In such a case, Infiltrator.jl is the way to go, at least for me, and so far the compiled mode of Debugger.jl is not working well enough. It has other disadvantages as well, since it does not happen all at once, but I think that it is often superior to use println
, since you can print everything that is currently of interest at a given breakpoint, and see all local variables in one go.
Thanks for reading and special thanks to my 10 patrons!
I'll keep you updated on Twitter OpenSourcES .