Skip to content

Commit 4eadc5c

Browse files
authored
Support Hints (#71)
1 parent 9bfa331 commit 4eadc5c

File tree

18 files changed

+217
-24
lines changed

18 files changed

+217
-24
lines changed

challenges/basic-any/hints.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Check out [Any](https://docs.python.org/3/library/typing.html#the-any-type).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Check out [TypeVar](https://docs.python.org/3/library/typing.html#typing.TypeVar), the `constraints` argument might be a good fit for this challenge.

docs/Contribute.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
For example, say you want to add a new challenge about [Protocols](https://mypy.readthedocs.io/en/stable/protocols.html). Since this is an advanced topic, you may name the directory `advanced-protocol`.
1010

1111
4. Put a `question.py` and a `solution.py` in the new directory. Here's an example `question.py`:
12+
1213
```python
1314
"""
1415
TODO:
@@ -34,4 +35,9 @@
3435

3536
5. Test with [`pyright`](https://microsoft.github.io/pyright/#/installation?id=command-line) to make sure your new challenge works as expected.
3637

37-
6. Create a Pull Request.
38+
6. *(Optional)* Add a hint message for the challenge,
39+
A well-written *HINT* sometimes makes the challenge even better. Steps:
40+
- Create a file named `hints.md` in the same directory.
41+
- Write hint message in markdown format, e.g: `Check out TypeVar, the constraints argument might be a good fit for this challenge.`.
42+
43+
7. Create a Pull Request.

docs/Development.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
```
3131
pdm format
3232
```
33+
3334
Note: The project uses [djhtml](https://github.com/rtts/djhtml) to format HTML, which may conflicts with your editor's default formatter.
3435

3536
- Start a development server
@@ -40,4 +41,16 @@
4041

4142
Then visit http://127.0.0.1:5000/ to access the app in your local browser.
4243

44+
- Update dependencies
45+
46+
```
47+
# Use pdm to manage dependencies
48+
pdm add markdown
49+
50+
# Sync changes with requirements.txt after update
51+
pdm export --prod --without-hashes > requirements.txt
52+
```
53+
54+
You may also want to use [pdm-autoexport](https://github.com/pdm-project/pdm-autoexport) extension, it sync the dependencies to other formats automatically.
55+
4356
If you encounter any issues in the above steps, please file a bug and I'll fix it as soon as I can.

pdm.lock

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ dependencies = [
1010
"typing-extensions>=4.8.0",
1111
"pyright>=1.1.338",
1212
"flask-sitemapper>=1.7.0",
13+
"markdown>=3.5.1",
1314
]
1415
requires-python = ">=3.12"
1516
readme = "README.md"

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ flask==3.0.0
77
flask-sitemapper==1.7.0
88
itsdangerous==2.1.2
99
jinja2==3.1.2
10+
markdown==3.5.1
1011
MarkupSafe==2.1.3
1112
nodeenv==1.8.0
1213
pyright==1.1.338
1314
setuptools==68.2.2
1415
typing-extensions==4.8.0
1516
Werkzeug==3.0.0
17+

templates/challenge.html

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,39 @@
6666
}
6767

6868
.challenge-header__exerpt {
69-
margin-bottom: 1.5rem;
69+
margin-bottom: 0.2rem;
7070
line-height: 1.5;
7171
}
7272

73+
/* Hints styles */
74+
.hints-container {
75+
margin-bottom: 1.5rem;
76+
font-size: 13px;
77+
}
78+
.hints-container #read-hints {
79+
padding: 0.2em 0.8em;
80+
font-size: 13px;
81+
}
82+
.hints-container #hints-missing {
83+
margin-top: 0.8em;
84+
/* The "secondary" style comes from https://picocss.com/docs/buttons.html */
85+
color: var(--secondary);
86+
}
87+
.hints-container .hints-message {
88+
display: none;
89+
margin-top: 0.5em;
90+
margin-bottom: 0;
91+
padding: 0.75em 1em;
92+
font-size: 13px;
93+
}
94+
html[data-theme='light'] .hints-container .hints-message {
95+
box-shadow: none;
96+
background-color: #f4f4f4;
97+
}
98+
.hints-container .hints-message * {
99+
font-size: 13px;
100+
}
101+
73102
.challenge-main {
74103
display: flex;
75104
justify-content: space-between;
@@ -243,6 +272,14 @@
243272
fail type check, while others can pass.<br>
244273
Hit the "▶️ Run" button to see result.
245274
</p>
275+
<div class="hints-container">
276+
{% if hints_for_display %}
277+
<a id="read-hints" role="button" class="secondary outline" href="javascript:void(0);">💡 Read Hints</a>
278+
{% else %}
279+
<div id="hints-missing" href="javascript:void(0);">💡 No Hints Available</div>
280+
{% endif %}
281+
<article class="hints-message">{{hints_for_display | safe}}</article>
282+
</div>
246283
</div>
247284

248285
<div class="challenge-main">
@@ -355,6 +392,22 @@
355392
myCodeMirror.setValue(code_under_test);
356393
};
357394

395+
// Set up hints events and functions
396+
let hintBtn = document.getElementById('read-hints')
397+
hintBtn.onclick = function () {
398+
// Toggle the display of the hints message.
399+
let msgElem = document.getElementsByClassName('hints-message')[0];
400+
if (msgElem.style.display === 'block') {
401+
msgElem.style.display = 'none';
402+
} else {
403+
msgElem.style.display = 'block';
404+
}
405+
};
406+
// Make sure to open links in hints in new tab.
407+
document.querySelectorAll('.hints-message a').forEach(function(elem) {
408+
elem.setAttribute('target', '_blank');
409+
})
410+
358411
// Make sure the current challenge is visible to user.
359412
activeChallengeInList = document.getElementById("{{level}}-{{name}}");
360413
activeChallengeInList.scrollIntoView({block: 'center'});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Should contain some hint messages, but there is really nothing to add.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""A simple question with hints, only for running tests.
2+
"""
3+
4+
5+
def foo():
6+
pass
7+
8+
9+
## End of your code ##
10+
foo(1)
11+
foo(1, 2) # expect-type-error

0 commit comments

Comments
 (0)