Skip to content

Commit

Permalink
Explain and illustrate # allowed
Browse files Browse the repository at this point in the history
  • Loading branch information
mwermelinger committed Jan 23, 2024
1 parent b3298b5 commit 61c5862
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 37 deletions.
38 changes: 9 additions & 29 deletions Deepnote/example-jewels.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"source": [
"# Jewels and Stones\n",
"\n",
"*Michel Wermelinger*, 21 January 2024"
"*Michel Wermelinger*, 23 January 2024"
]
},
{
Expand Down Expand Up @@ -477,7 +477,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the linter reports that I haven't taught my students the `chr` function.\n",
"Note that the `allowed` tool reports that I haven't taught my students the `chr` function.\n",
"That's why I explained it before presenting the code.\n",
"\n",
"Moving on, I write some tests, to check that `best_case` is generating the right strings."
Expand Down Expand Up @@ -530,17 +530,6 @@
"Testing worst_case:\n",
"Tests finished.\n"
]
},
{
"data": {
"text/markdown": [
"**allowed** found issues:\n",
"- 14: chr()\n",
"- 18: chr()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
Expand All @@ -557,11 +546,11 @@
" # create a string with j different characters (Unicode 32 onwards)\n",
" jewels = \"\"\n",
" for code in range(32, 32 + j):\n",
" jewels = jewels + chr(code)\n",
" jewels = jewels + chr(code) # allowed\n",
" # create a string with s different characters (Unicode 32+j onwards)\n",
" stones = \"\"\n",
" for code in range(32 + j, 32 + j + s):\n",
" stones = stones + chr(code)\n",
" stones = stones + chr(code) # allowed\n",
" return (jewels, stones)\n",
"\n",
"\n",
Expand All @@ -580,6 +569,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The `# allowed` comment in lines 14 and 18 tells the tool that `chr()` is allowed,\n",
"because it was explained, and hence should not be reported.\n",
"\n",
"Finally I generate random typical cases in which not all stones are jewels and not all jewels occur in the stones."
]
},
Expand All @@ -595,18 +587,6 @@
"Some stones are jewels: True\n",
"Some stones aren't jewels: True\n"
]
},
{
"data": {
"text/markdown": [
"**allowed** found issues:\n",
"- 18: chr()\n",
"- 22: chr()\n",
"- 22: random.randint"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
Expand All @@ -627,11 +607,11 @@
" # create a string with j different characters (Unicode 32 onwards)\n",
" jewels = \"\"\n",
" for code in range(32, 32 + j):\n",
" jewels = jewels + chr(code)\n",
" jewels = jewels + chr(code) # allowed\n",
" # create a string with s random characters from Unicode 33 to 33 + 2j\n",
" stones = \"\"\n",
" for _ in range(s):\n",
" stones = stones + chr(random.randint(33, 33 + 2 * j))\n",
" stones = stones + chr(random.randint(33, 33 + 2 * j)) # allowed\n",
" return (jewels, stones)\n",
"\n",
"\n",
Expand Down
23 changes: 15 additions & 8 deletions docs/writing.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: default
title: Feedback guide
title: Writing guide
nav_order: 5
---

Expand Down Expand Up @@ -278,6 +278,7 @@ The formatter has already automatically enforced simple formatting conventions,
4 spaces for indentation and 2 empty lines between functions,
so you will see fewer warnings from the linter.

#### Code style
The Deepnote essay project you copied already has a linter installed:
`ruff`, the fastest Python linter. To turn it on, write the following after
importing `algoesup`.
Expand Down Expand Up @@ -325,13 +326,13 @@ won't be flagged. But again, some linting is better than none.
If you get errors that you think are pointless,
please let us know so that we can change `ruff`'s configuration.

### Basic constructs
#### Language subset
The Deepnote project you copied also includes the `allowed` linter, created by ourselves.
It checks whether your code only uses certain Python constructs. This gives you
some reassurance that your code will be understood by a wide audience.
It checks whether your code only uses a certain subset of the Python language.
This gives you some reassurance that your code will be understood by a wide audience.

By default, `allowed` uses the configuration for our
algorithms and data structures course. It is already included in this project.
By default, `allowed` checks against the Python subset used in our
algorithms and data structures course. It is already included in the project.
So, if you're an M269 student, to check that your essay is easily understood
by your peers in terms of Python constructs, just add a cell:
```python
Expand All @@ -354,13 +355,19 @@ print(f"π is approximately {pi:.5f}.")
We haven't taught the `math.sin()` function nor f-strings, and `allowed` reports these.

Any line that ends with the comment `# allowed` is ignored. This is useful when
you don't want the linter to flag a construct that you explain in your essay.
For example, adding the comment after `print(...)` would not report the f-string.
Note that the comment makes the tool skip the *whole* line:
if it has several constructs that weren't taught, none of them is reported.

We also include the configuration for TM112, our introductory Computing course,
in case you want to use even fewer constructs in your essay.
To use that configuration, write `%allowed on -c tm112.json`.

You can configure the linter with a JSON file that lists the allowed constructs.
You can [duplicate and rename]({{site.baseurl}}/deepnote-how-to#rename-duplicate-download-or-delete-a-notebook-or-file)
one of the JSON configurations in the **Files** section of the left panel,
one of the JSON configurations in the **Files** section of your project,
and adapt it to your course.
See the `allowed` [website](https://dsa-ou.github.io/allowed) for instructions.

Expand Down Expand Up @@ -412,7 +419,7 @@ def descending(n: int) -> tuple[list[int]]:
We should of course test these functions, to make sure they produce the expected lists,
but we will skip that in this explanation because we're focusing on how to measure run-times.

### Comparing different cases
### Comparing cases
To measure the run-times of a function `f` on best, average and worst case inputs, use
library function `time_cases(f, [case1, case2, ...], s, d)`.
The second argument can be a list (or tuple) of up to 6 input-generating functions.
Expand Down

0 comments on commit 61c5862

Please sign in to comment.