-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First draft materials for debugging workshop #75
Merged
Merged
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
cc957f8
First draft materials for debugging workshop
robmoss f1043c3
Add a video of an R debugger session
robmoss f821979
Reorder some content in "Using a debugger"
robmoss 3a8d500
Add a link to the asciinema-scripted tool
robmoss 4ae5f26
Add a link to VS Code's debugger page
robmoss 9545af6
Separate the debugger overview from the example
robmoss 3b7fe77
Begin revising the "Building your skills" page
robmoss 0d55f6a
Hide exercise solutions by default
robmoss 589d561
Add a page about interpreting error messages
robmoss cfa162c
Explain how to create manual breakpoints
robmoss c7ebe72
Correct Julia Evans' first name
robmoss 69b45cb
Remove link to course materials
robmoss 89edd68
Update to asciinema-player 3.8.0
robmoss 49a9035
Add a link to the RStudio Cheatsheet
robmoss 8c3147a
Add an example of a very long stack trace
robmoss c1282c5
Highlight relevant lines in the long stack trace
robmoss 31507c4
Make the first demo a hands-on activity
robmoss 3e6de50
Add a tip about enabling stack traces in R
robmoss ff11cc4
Move the debugging manifesto poster to the end
robmoss 1e3757d
Add examples of breaking on errors
robmoss 36fe530
Minor improvements to example code
robmoss 4b004fe
Break each debugging action into a short list
robmoss 5079109
Add a debugging story I experienced this week
robmoss 688a339
Continue line numbering for R example
robmoss 7ba1573
Move real-world examples to a separate page
robmoss 9517570
Fix a copy-and-paste error in example stack trace
robmoss 0a7e3fe
Add filenames to each pypfilt code block
robmoss 26548ea
Add Michael's story of debugging ORCID works in R
robmoss f8280d8
Thank people who helped shape this workshop
robmoss File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Training events | ||
|
||
We will be running an [Introduction to Debugging](debugging/README.md) workshop at the [SPECTRUM](https://spectrum.edu.au/) Annual Meeting 2024 (23-25 September). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Introduction to Debugging | ||
|
||
This workshop was prepared for the [SPECTRUM](https://spectrum.edu.au/) Annual Meeting 2024 (23-25 September). | ||
|
||
!!! tip | ||
|
||
**We all make mistakes** when writing code and introduce errors. | ||
|
||
Having good debugging skills means that you can spend **less time fixing your code**. | ||
|
||
See the discussion in our [August 2024 meeting](../../meetings/2024-08-08.md#debugging) for further background. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions
45
docs/community/training/debugging/example-perfect-numbers.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Perfect numbers | ||
|
||
=== "Overview" | ||
|
||
[Perfect numbers](https://en.wikipedia.org/wiki/Perfect_number) are positive integers that are equal to the sum of their divisors. | ||
Here we have provided example Python and R scripts that should print all of the perfect numbers up to 1,000. | ||
|
||
You can download each script to debug on your own computer: | ||
|
||
- [perfect_numbers.py](perfect_numbers.py) | ||
- [perfect_numbers.R](perfect_numbers.R) | ||
|
||
=== "Python" | ||
|
||
```py title="perfect_numbers.py" linenums="1" | ||
--8<-- "perfect_numbers.py" | ||
``` | ||
|
||
=== "R" | ||
|
||
```R title="perfect_numbers.R" linenums="1" | ||
--8<-- "perfect_numbers.R" | ||
``` | ||
|
||
??? bug "But there's a problem ..." | ||
|
||
If we run these scripts, we see that **they don't print anything**: | ||
|
||
<div id="demo" data-cast-file="../perfect-numbers-first-run.cast"></div> | ||
|
||
How should we begin investigating? | ||
|
||
??? note "Some initial thoughts ..." | ||
|
||
- Are we actually running the `main()` function at all? | ||
|
||
- The `main()` function is almost certainly not the cause of this error. | ||
|
||
- The `is_perfect()` function is very simple, so it's unlikely to be the cause of this error. | ||
|
||
- The `divisors_of()` function doesn't look obviously wrong. | ||
|
||
- But there must be a mistake **somewhere**! | ||
|
||
- Let's **use a debugger** to investigate. |
112 changes: 112 additions & 0 deletions
112
docs/community/training/debugging/example-python-vs-r.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Example: Python vs R | ||
|
||
=== "Overview" | ||
|
||
Here we have provided SIR ODE model implementations in Python and in R. | ||
Each script runs several scenarios and produces a plot of infection prevalence for each scenario. | ||
|
||
You can download each script to debug on your computer: | ||
|
||
- [sir_ode.py](sir_ode.py) | ||
- [sir_ode.R](sir_ode.R) | ||
|
||
=== "Python" | ||
|
||
```py title="sir_ode.py" linenums="1" | ||
--8<-- "sir_ode.py" | ||
``` | ||
|
||
=== "R" | ||
|
||
```R title="sir_ode.R" linenums="1" | ||
--8<-- "sir_ode.R" | ||
``` | ||
|
||
??? bug "The model outputs differ!" | ||
|
||
Here are prevalence time-series plots produced by each script: | ||
|
||
=== "Python plot" | ||
|
||
<figure markdown="span"> | ||
![Python outputs](sir_ode_python.png) | ||
<figcaption>Model outputs for the Python script.</figcaption> | ||
</figure> | ||
|
||
=== "R plot" | ||
|
||
<figure markdown="span"> | ||
![R outputs](sir_ode_r.png) | ||
<figcaption>Model outputs for the R script.</figcaption> | ||
</figure> | ||
|
||
??? note "Some initial thoughts ..." | ||
|
||
- Is it obvious whether one of the figures is correct and the other is wrong? | ||
|
||
- The `sir_rhs()` functions in the two scripts appear to be equivalent — but are they? | ||
|
||
- The `default_settings()` functions appear to be equivalent — but are they? | ||
|
||
- The `run_model_scaled_beta()` and `run_model_scaled_gamma()` functions also appear to be equivalent. | ||
|
||
- Where might you begin looking? | ||
|
||
??? info "Commentary" | ||
|
||
> I've heard that dicts (and other mutable data types) are passed by reference, as such a function could change the “local” value of a variable, which causes an error when using the “global” variable in another function. | ||
> | ||
> This would also be good for showing that your test cases aren’t perfect. | ||
> | ||
> You can run function 1 tests and get good answers, and then run function 2 test and get good answers, but this is because they are not sharing the state of the mutable variable. | ||
> Sounds like a great inclusion as a mini chapter. | ||
|
||
These are great ideas! The one drawback of the mutable data example is that it won't work in R, because it's copy-on-write. But that's no big deal. In fact, now that I think about, this difference us surely worth highlighting! People who are familiar with only one of these two languages need to be aware of this important difference if they begin using the other language. | ||
|
||
I've come up with an example of shared mutable state resulting in incorrect model outputs. | ||
|
||
!!! quote "The R Language Definition" | ||
|
||
The semantics of invoking a function in R argument are **call-by-value**. | ||
In general, supplied arguments behave as if they are **local variables** initialized with the value supplied and the name of the corresponding formal argument. | ||
Changing the value of a supplied argument within a function **will not affect** the value of the variable in the calling frame. | ||
|
||
— [Argument Evaluation](https://cran.r-project.org/doc/manuals/r-patched/R-lang.html#Argument-evaluation) | ||
|
||
!!! quote "Python Programming FAQ" | ||
|
||
Remember that arguments are **passed by assignment** in Python. | ||
Since assignment just **creates references** to objects, there's no alias between an argument name in the caller and callee, and so no call-by-reference per se. | ||
|
||
— [How do I write a function with output parameters (call by reference)?](https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference) | ||
|
||
??? info "Output messages" | ||
|
||
Here are the output messages printed by each script: | ||
|
||
=== "Python" | ||
|
||
```text | ||
beta = 1.0 gamma = 0.5 | ||
beta = 1.5 gamma = 0.5 | ||
beta = 1.5 gamma = 0.35 | ||
``` | ||
|
||
=== "R" | ||
|
||
```text | ||
beta = 1.0 gamma = 0.5 | ||
beta = 1.5 gamma = 0.5 | ||
beta = 1.0 gamma = 0.35 | ||
``` | ||
|
||
??? bug "Parameters differ!" | ||
|
||
There's a difference in the parameter values for the third scenario: | ||
|
||
```diff | ||
beta = 1.0 gamma = 0.5 | ||
beta = 1.5 gamma = 0.5 | ||
- beta = 1.5 gamma = 0.35 | ||
+ beta = 1.0 gamma = 0.35 | ||
``` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Learning objectives | ||
|
||
In this workshop, we will introduce the concept of "debugging", and demonstrate techniques and tools that can help us efficiently identify and remove errors from our code. | ||
|
||
After completing this workshop, participants will: | ||
|
||
+ Understand that debugging can be divided into a sequence of actions; | ||
|
||
+ Understand the purpose of each of these actions; | ||
|
||
+ Be familiar with techniques and tools that can help perform these actions; | ||
|
||
+ Be able to apply these techniques and tools to their own code. | ||
|
||
!!! info | ||
|
||
By achieving these learning objectives, participants should be able to find and correct errors in their code more quickly and with greater confidence. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Debugging manifesto | ||
|
||
<figure markdown="span"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could consider listing a few errors that we have found ourselves around here? |
||
![A debugging manifesto poster.](debugging-manifesto-poster.jpg){ align=left, width="50%" } | ||
<figcaption markdown="span"> | ||
[Julia Evans](https://jvns.ca/) and [Tanya Brassie](https://tanyabrassie.com/): [Debugging Manifesto Poster](https://store.wizardzines.com/products/poster-debugging-manifesto), 2024. | ||
</figcaption> | ||
</figure> | ||
|
||
!!! info | ||
|
||
See the [Resources](resources.md) page for links to more of Julia Evans' articles, stories, and zines about debugging. |
48 changes: 48 additions & 0 deletions
48
docs/community/training/debugging/perfect-numbers-first-run.cast
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{"version": 2, "width": 80, "height": 4, "timestamp": 1723508323, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} | ||
[0.106254, "o", "\u001b[?2004h\u001b]2;(x1::debugging)\u0007\u001b[32;1m(x1::debugging)\u001b[0m "] | ||
[1.439464, "o", "."] | ||
[1.511348, "o", "/"] | ||
[1.735208, "o", "p"] | ||
[1.815337, "o", "e"] | ||
[1.879152, "o", "r"] | ||
[2.063205, "o", "f"] | ||
[2.151301, "o", "e"] | ||
[2.271034, "o", "c"] | ||
[2.46335, "o", "t"] | ||
[2.663166, "o", "_"] | ||
[2.823218, "o", "n"] | ||
[3.007567, "o", "u"] | ||
[3.199264, "o", "m"] | ||
[3.271363, "o", "b"] | ||
[3.439513, "o", "e"] | ||
[3.487438, "o", "r"] | ||
[3.607177, "o", "s"] | ||
[3.687383, "o", "."] | ||
[3.847072, "o", "p"] | ||
[3.991135, "o", "y"] | ||
[4.967213, "o", "\r\n"] | ||
[4.967292, "o", "\u001b[?2004l\r"] | ||
[5.065072, "o", "\u001b[?2004h\u001b]2;(x1::debugging)\u0007\u001b[32;1m(x1::debugging)\u001b[0m "] | ||
[6.879247, "o", "."] | ||
[7.079536, "o", "/"] | ||
[7.319153, "o", "p"] | ||
[7.415356, "o", "e"] | ||
[7.479395, "o", "r"] | ||
[7.639271, "o", "f"] | ||
[7.727076, "o", "e"] | ||
[7.823333, "o", "c"] | ||
[8.00743, "o", "t"] | ||
[8.151241, "o", "_"] | ||
[8.407055, "o", "n"] | ||
[8.527353, "o", "u"] | ||
[8.71911, "o", "m"] | ||
[8.783422, "o", "b"] | ||
[8.967451, "o", "e"] | ||
[9.015325, "o", "r"] | ||
[9.151235, "o", "s"] | ||
[9.247291, "o", "."] | ||
[9.575237, "o", "R"] | ||
[10.167232, "o", "\r\n"] | ||
[10.167313, "o", "\u001b[?2004l\r"] | ||
[10.450741, "o", "\u001b[?2004h\u001b]2;(x1::debugging)\u0007\u001b[32;1m(x1::debugging)\u001b[0m "] | ||
[12.800104, "o", "\u001b[?2004l"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/usr/bin/env -S Rscript --vanilla | ||
# | ||
# This script prints perfect numbers. | ||
# | ||
# Perfect numbers are positive integers that are equal to the sum of their | ||
# divisors. | ||
# | ||
|
||
|
||
main <- function() { | ||
start <- 2 | ||
end <- 1000 | ||
for (value in seq.int(start, end)) { | ||
if (is_perfect(value)) { | ||
print(value) | ||
} | ||
} | ||
} | ||
|
||
|
||
is_perfect <- function(value) { | ||
divisors <- divisors_of(value) | ||
sum(divisors) == value | ||
} | ||
|
||
|
||
divisors_of <- function(value) { | ||
divisors <- c() | ||
candidate <- 2 | ||
while (candidate < value) { | ||
if (value %% candidate == 0) { | ||
divisors <- c(divisors, candidate) | ||
} | ||
candidate <- candidate + 1 | ||
} | ||
divisors | ||
} | ||
|
||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
This script prints perfect numbers. | ||
|
||
Perfect numbers are positive integers that are equal to the sum of their | ||
divisors. | ||
""" | ||
|
||
|
||
def main(): | ||
start = 2 | ||
end = 1_000 | ||
for value in range(start, end + 1): | ||
if is_perfect(value): | ||
print(value) | ||
|
||
|
||
def is_perfect(value): | ||
divisors = divisors_of(value) | ||
return sum(divisors) == value | ||
|
||
|
||
def divisors_of(value): | ||
divisors = [] | ||
candidate = 2 | ||
while candidate < value: | ||
if value % candidate == 0: | ||
divisors.append(candidate) | ||
candidate += 1 | ||
return divisors | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Resources | ||
|
||
- Julie Evans: | ||
- [Debugging articles](https://jvns.ca/#debugging) | ||
- [Debugging stories](https://jvns.ca/#debugging-stories) | ||
- [The Pocket Guide to Debugging](https://jvns.ca/blog/2022/12/21/new-zine--the-pocket-guide-to-debugging/) (see the [table of contents](https://jvns.ca/images/debugging-guide-toc.png)) | ||
- [Notes on building debugging puzzles](https://jvns.ca/blog/2021/04/16/notes-on-debugging-puzzles/) | ||
- [Learn Debugging](https://www.cse.unsw.edu.au/~learn/debugging/) | ||
- [Debug with pdb and breakpoint](https://hamatti.org/posts/debug-with-pdb-and-breakpoint/) | ||
- [Advanced R: Debugging](https://adv-r.hadley.nz/debugging.html) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great. I think it will shock some people to realise that their two favourite languages have drastic different behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks! I'm not sure how much (if any) of the "Commentary" box I should leave in the published materials ... perhaps I should collect explanations for the two exercises in a separate page at the end?