-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate the debugger overview from the example
We now present the example (square numbers) on the next page, followed by the two example exercises. Solutions to these exercises have been added at the end of the workshop.
- Loading branch information
Showing
8 changed files
with
268 additions
and
218 deletions.
There are no files selected for viewing
112 changes: 0 additions & 112 deletions
112
docs/community/training/debugging/example-python-vs-r.md
This file was deleted.
Oops, something went wrong.
97 changes: 97 additions & 0 deletions
97
docs/community/training/debugging/example-square-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,97 @@ | ||
# Example: Square numbers | ||
|
||
[Square numbers](https://en.wikipedia.org/wiki/Square_number) are positive integers that are equal to the square of an integer. | ||
Here we have provided example Python and R scripts that print all of the square numbers between 1 and 100: | ||
|
||
<div id="square-numbers-demo" data-cast-file="../square-numbers-demo.cast"></div> | ||
|
||
You can download these scripts to run on your own computer: | ||
|
||
- [square_numbers.py](square_numbers.py) | ||
- [square_numbers.R](square_numbers.R) | ||
|
||
Each script contains three functions: | ||
|
||
- `main()` | ||
- `find_squares(lower_bound, upper_bound)` | ||
- `is_square(value)` | ||
|
||
The diagram below shows how `main()` calls `find_squares()`, which in turn calls `is_square()` many times. | ||
|
||
```mermaid | ||
sequenceDiagram | ||
participant M as main() | ||
participant F as find_squares() | ||
participant I as is_square() | ||
activate M | ||
M ->>+ F: lower_bound = 1, upper_bound = 100 | ||
Note over F: squares = [ ] | ||
F ->>+ I: value = 1 | ||
I ->>- F: True/False | ||
F ->>+ I: value = 2 | ||
I ->>- F: True/False | ||
F -->>+ I: ... | ||
I -->>- F: ... | ||
F ->>+ I: value = 100 | ||
I ->>- F: True/False | ||
F ->>- M: squares = [...] | ||
Note over M: print(squares) | ||
deactivate M | ||
``` | ||
|
||
??? info "Source code" | ||
|
||
=== "Python" | ||
|
||
```py title="square_numbers.py" linenums="1" | ||
--8<-- "square_numbers.py" | ||
``` | ||
|
||
=== "R" | ||
|
||
```R title="square_numbers.R" linenums="1" | ||
--8<-- "square_numbers.R" | ||
``` | ||
|
||
## Stepping through the code | ||
|
||
These recorded terminal sessions demonstrate how to use Python and R debuggers from the command line. | ||
They cover: | ||
|
||
- How to define breakpoints; | ||
- How to inspect the current values of variables; and | ||
- How to step through, and over, lines of code. | ||
|
||
!!! tip "Interactive debugger sessions" | ||
|
||
If your editor supports running a debugger, **use this feature!** | ||
See these examples for [RStudio](https://support.posit.co/hc/en-us/articles/205612627-Debugging-with-the-RStudio-IDE), [PyCharm](https://www.jetbrains.com/pycharm/features/debugger.html), [Spyder](https://docs.spyder-ide.org/current/panes/debugging.html), and [VS Code](https://code.visualstudio.com/docs/editor/debugging). | ||
|
||
=== "Python debugger" | ||
|
||
<div id="pdb-demo" data-cast-file="../square-numbers-pdb.cast"></div> | ||
|
||
Video timeline: | ||
|
||
1. <a data-video="pdb-demo" data-seek-to="4.7" href="javascript:;">Set a breakpoint</a> | ||
2. <a data-video="pdb-demo" data-seek-to="9.081" href="javascript:;">Show current location</a> | ||
3. <a data-video="pdb-demo" data-seek-to="16.146" href="javascript:;">Step into `is_square()`</a> | ||
4. <a data-video="pdb-demo" data-seek-to="36.744" href="javascript:;">Return from `is_square()`</a> | ||
5. <a data-video="pdb-demo" data-seek-to="40.021" href="javascript:;">Show updated `squares` list</a> | ||
6. <a data-video="pdb-demo" data-seek-to="57.947" href="javascript:;">Add a conditional breakpoint</a> | ||
7. <a data-video="pdb-demo" data-seek-to="69.697" href="javascript:;">Stop at the conditional breakpoint</a> | ||
8. <a data-video="pdb-demo" data-seek-to="76.202" href="javascript:;">Continue until the script ends</a> | ||
|
||
=== "R debugger" | ||
|
||
<div id="r-debug-demo" data-cast-file="../square-numbers-r-debug.cast"></div> | ||
|
||
Video timeline: | ||
|
||
1. <a data-video="r-debug-demo" data-seek-to="6.568" href="javascript:;">Set a breakpoint</a> | ||
2. <a data-video="r-debug-demo" data-seek-to="23.548" href="javascript:;">Step into `is_square()`</a> | ||
3. <a data-video="r-debug-demo" data-seek-to="29.654" href="javascript:;">Return from `is_square()`</a> | ||
4. <a data-video="r-debug-demo" data-seek-to="33.505" href="javascript:;">Show updated `squares` list</a> | ||
5. <a data-video="r-debug-demo" data-seek-to="47.751" href="javascript:;">Add a conditional breakpoint</a> | ||
6. <a data-video="r-debug-demo" data-seek-to="67.77" href="javascript:;">Stop at the conditional breakpoint</a> | ||
7. <a data-video="r-debug-demo" data-seek-to="74.546" href="javascript:;">Continue until the script ends</a> |
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,58 @@ | ||
# Exercise: 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> | ||
|
||
!!! tip "Interactive debugger sessions" | ||
|
||
If your editor supports running a debugger, **use this feature!** | ||
See these examples for [RStudio](https://support.posit.co/hc/en-us/articles/205612627-Debugging-with-the-RStudio-IDE), [PyCharm](https://www.jetbrains.com/pycharm/features/debugger.html), [Spyder](https://docs.spyder-ide.org/current/panes/debugging.html), and [VS Code](https://code.visualstudio.com/docs/editor/debugging). | ||
|
||
??? 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? |
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,50 @@ | ||
# Exercise solutions | ||
|
||
## Perfect numbers | ||
|
||
Perfect numbers are equal to the sum of their proper divisors — all divisors except the number itself. | ||
|
||
For example, 6 is a perfect number. | ||
Its proper divisors are 1, 2, and 3, and 1 + 2 + 3 = 6. | ||
|
||
The mistake here is that the `divisors_of()` function only returns divisors **greater than one**, and so the code fails to identify any of the true perfect numbers. | ||
|
||
Interestingly, this mistake did not result in the code mistakenly identifying any other numbers as perfect numbers. | ||
|
||
## Python vs R | ||
|
||
If you're only familiar with one of these two languages, you may be surprised to discover that they have some fundamental differences. | ||
In this exercise we demonstrated one consequence of the ways that these languages handle function arguments. | ||
|
||
!!! 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) | ||
|
||
- In R the `run_model_scaled_beta()` and `run_model_scaled_gamma()` functions **do not modify** the value of `settings` in the `demonstration()` function. | ||
This produces model outputs for the following parameter combinations: | ||
|
||
- β = 1.0 and γ = 0.5; | ||
- β = 1.5 and γ = 0.5; and | ||
- **β = 1.0 and γ = 0.35**. | ||
|
||
- In Python the `run_model_scaled_beta()` and `run_model_scaled_gamma()` functions **do modify** the value of `settings` in the `demonstration()` function. | ||
This produces model outputs for the following parameter combinations: | ||
|
||
- β = 1.0 and γ = 0.5; | ||
- β = 1.5 and γ = 0.5; and | ||
- **β = 1.5 and γ = 0.35**. | ||
|
||
!!! success "Answer" | ||
|
||
The value of β is different in the third combination. |
Oops, something went wrong.