Commit bd2ad2b73a8a0f4de7b7e1dbb42af531712b2680
1 parent
eeb28a09
Exists in
master
and in
1 other branch
- fix references to python3.6/3.7 in README.
- fix and update demo. - fix striping <p></p> tags in certain cases in the md_to_html function.
Showing
8 changed files
with
69 additions
and
44 deletions
Show diff stats
BUGS.md
... | ... | @@ -3,7 +3,6 @@ |
3 | 3 | |
4 | 4 | - click numa opcao checkbox fora da checkbox+label não está a funcionar. |
5 | 5 | - shift-enter não está a funcionar |
6 | -- nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido. | |
7 | 6 | - mathjax, formulas $$f(x)$$ nas opções de escolha multipla, não ficam centradas em toda a coluna mas apenas na largura do parágrafo. |
8 | 7 | - default prefix should be obtained from each course (yaml conf)? |
9 | 8 | - tabelas nas perguntas radio/checkbox não ocupam todo o espaço como em question. |
... | ... | @@ -29,6 +28,8 @@ |
29 | 28 | |
30 | 29 | # FIXED |
31 | 30 | |
31 | +- nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido. | |
32 | +- não esta a fazer render correcto de tabelas nas opcoes checkbox. e.g. information-theory/source-coding-theory/block-codes | |
32 | 33 | - max tries nas perguntas. |
33 | 34 | - mostrar feedback/solucoes quando acerta, ou excede max tries. |
34 | 35 | - quando se pressiona "responde" rapido (enquanto a animacao dura), a pergunta passa para a seguinte sem haver o correspondente redraw, ou seja a proxima resposta nao é a da pergunta mostrada. | ... | ... |
README.md
... | ... | @@ -37,7 +37,7 @@ python3.7 -m ensurepip --user |
37 | 37 | ``` |
38 | 38 | |
39 | 39 | This will install pip in your user account under `~/.local/bin`. |
40 | -In the end you should be able to run `pip3 --version` and `python3 -c "import sqlite3"` without errors (sometimes `pip3` is `pip`, `pip3.6` or `pip-3.6`). | |
40 | +In the end you should be able to run `pip3 --version` and `python3 -c "import sqlite3"` without errors (sometimes `pip3` is `pip`, `pip3.7` or `pip-3.7`). | |
41 | 41 | |
42 | 42 | If you want to always install python modules on the user account (recommended), edit the pip configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or `Library/Application Support/pip/pip.conf` (MacOS) and add the lines |
43 | 43 | |
... | ... | @@ -93,7 +93,7 @@ cd aprendizations |
93 | 93 | |
94 | 94 | We need certificates for https. Certificates can be self-signed or validated by a trusted authority. |
95 | 95 | |
96 | -Self-signed can be used locally for development and testing, but browsers will complain. | |
96 | +Self-signed can be used locally for development and testing, but browsers will complain. | |
97 | 97 | LetsEncrypt issues trusted and free certificates, but the server must have a registered publicly accessible domain name. |
98 | 98 | |
99 | 99 | #### Selfsigned | ... | ... |
demo/demo.yaml
1 | +--- | |
2 | + | |
1 | 3 | title: Example |
2 | 4 | database: students.db |
3 | -# path: ./demo | |
5 | + | |
4 | 6 | |
5 | 7 | # values applie to each topic, if undefined there |
6 | 8 | # default values are: file=question.yaml, shuffle=True, choose: all |
7 | 9 | file: questions.yaml |
8 | -shuffle: True | |
10 | +shuffle: false | |
9 | 11 | choose: 6 |
12 | +max_tries: 2 | |
10 | 13 | forgetting_factor: 0.99 |
11 | 14 | |
12 | -# Representation of the edges of the dependency graph. | |
13 | -# Example: A depends on B and C | |
14 | -# A: | |
15 | -# name: Topic A | |
16 | -# deps: | |
17 | -# - B | |
18 | -# - C | |
15 | +# ---------------------------------------------------------------------------- | |
19 | 16 | topics: |
20 | 17 | # topic without dependencies |
21 | 18 | math: |
22 | 19 | name: Matemática |
23 | 20 | file: questions.yaml |
24 | 21 | choose: 6 |
25 | - shuffle: True | |
22 | + shuffle: true | |
26 | 23 | |
27 | 24 | # topic with one dependency |
28 | 25 | solar_system: | ... | ... |
demo/solar_system/questions.yaml
1 | 1 | --- |
2 | 2 | |
3 | 3 | # --------------------------------------------------------------------------- |
4 | -- ref: solar-system | |
5 | - type: radio | |
4 | +- type: checkbox | |
5 | + ref: teste-debug | |
6 | + title: tabelas em opcoes | |
7 | + text: ve la se as tabelas estao bem... | |
8 | + options: | |
9 | + - | | |
10 | + x | y | |
11 | + --|-- | |
12 | + 1 | 2 | |
13 | + - | | |
14 | + x | y | |
15 | + --|-- | |
16 | + 1 | 2 | |
17 | + correct: [1, 1] | |
18 | + | |
19 | +# --------------------------------------------------------------------------- | |
20 | +- type: radio | |
21 | + ref: teste-debug2 | |
22 | + title: formuolas em opcoes | |
23 | + text: ve la se as tabelas estao bem... | |
24 | + options: | |
25 | + - A | |
26 | + - B | |
27 | +# --------------------------------------------------------------------------- | |
28 | +- type: text | |
29 | + ref: home-planet | |
30 | + title: Sistema solar | |
31 | + text: O nosso planeta chama-se planeta... | |
32 | + correct: ['Terra', 'terra'] | |
33 | + # opcional | |
34 | + answer: Não é Marte... | |
35 | + | |
36 | +# --------------------------------------------------------------------------- | |
37 | +- type: radio | |
38 | + ref: solar-system | |
6 | 39 | title: Sistema solar |
7 | 40 | text: | |
8 | 41 |  |
... | ... | @@ -16,30 +49,20 @@ |
16 | 49 | - Têm todos o mesmo tamanho |
17 | 50 | # opcional |
18 | 51 | correct: 2 |
19 | - shuffle: False | |
20 | - discount: True | |
52 | + shuffle: false | |
53 | + discount: true | |
21 | 54 | |
22 | -# --------------------------------------------------------------------------- | |
23 | -- | |
24 | - ref: home-planet | |
25 | - type: text | |
26 | - title: Sistema solar | |
27 | - text: O nosso planeta chama-se planeta... | |
28 | - correct: ['Terra', 'terra'] | |
29 | - # opcional | |
30 | - answer: Não é Marte... | |
31 | 55 | |
32 | 56 | # --------------------------------------------------------------------------- |
33 | -- | |
34 | - ref: saturn | |
35 | - type: text-regex | |
36 | - title: Sistema solar | |
37 | - text: O planeta do sistema solar conhecido por ter aneis é o planeta... | |
38 | - correct: !regex '[Ss]aturno' | |
57 | +- type: text-regex | |
58 | + ref: saturn | |
59 | + title: Sistema solar | |
60 | + text: O planeta do sistema solar conhecido por ter aneis é o planeta... | |
61 | + correct: !regex '[Ss]aturno' | |
39 | 62 | |
40 | 63 | # --------------------------------------------------------------------------- |
41 | -- ref: first_3_planets | |
42 | - type: textarea | |
64 | +- type: textarea | |
65 | + ref: first_3_planets | |
43 | 66 | title: Sistema solar |
44 | 67 | text: Escreva o nome dos três planetas mais próximos do Sol. (Exemplo `A, B e C`) |
45 | 68 | correct: correct-first_3_planets.py | ... | ... |
serve.py
... | ... | @@ -23,7 +23,7 @@ from learnapp import LearnApp |
23 | 23 | from tools import load_yaml, md_to_html |
24 | 24 | |
25 | 25 | # ---------------------------------------------------------------------------- |
26 | -# Decorator used to restrict access to the administrator | |
26 | +# Decorator used to restrict access to the administrator only | |
27 | 27 | # ---------------------------------------------------------------------------- |
28 | 28 | def admin_only(func): |
29 | 29 | @functools.wraps(func) |
... | ... | @@ -96,7 +96,7 @@ class LoginHandler(BaseHandler): |
96 | 96 | login_ok = await self.learn.login(uid, pw) |
97 | 97 | |
98 | 98 | if login_ok: |
99 | - self.set_secure_cookie('user', uid) # expires_days=30 | |
99 | + self.set_secure_cookie('user', uid) | |
100 | 100 | self.set_secure_cookie('counter', str(self.learn.get_login_counter(uid))) |
101 | 101 | self.redirect('/') |
102 | 102 | else: |
... | ... | @@ -198,7 +198,6 @@ class FileHandler(BaseHandler): |
198 | 198 | self.set_header("Content-Type", content_type) |
199 | 199 | self.write(data) |
200 | 200 | await self.flush() |
201 | - # self.flush() | |
202 | 201 | |
203 | 202 | |
204 | 203 | # ---------------------------------------------------------------------------- |
... | ... | @@ -216,8 +215,9 @@ class QuestionHandler(BaseHandler): |
216 | 215 | 'textarea': 'question-textarea.html', |
217 | 216 | # -- information panels -- |
218 | 217 | 'information': 'question-information.html', |
219 | - 'info': 'question-information.html', | |
220 | 218 | 'success': 'question-success.html', |
219 | + 'warning': 'question-information.html', | |
220 | + 'alert': 'question-information.html', | |
221 | 221 | } |
222 | 222 | |
223 | 223 | # --- get question to render | ... | ... |
templates/question-checkbox.html
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <div class="custom-control custom-checkbox"> |
10 | 10 | <input type="checkbox" class="custom-control-input" |
11 | 11 | id="{{ n }}" accesskey="{{ n+1 }}" name="answer" value="{{ n }}"> |
12 | - <label for="{{ n }}" class="custom-control-label">{{ md(opt)[3:-5] }}</label> | |
12 | + <label for="{{ n }}" class="custom-control-label">{{ md(opt, strip_p_tag=True) }}</label> | |
13 | 13 | </div> |
14 | 14 | </a> |
15 | 15 | {% end %} | ... | ... |
templates/question-radio.html
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <div class="custom-control custom-radio"> |
10 | 10 | <input type="radio" class="custom-control-input" |
11 | 11 | id="{{ n }}" accesskey="{{ n+1 }}" name="answer" value="{{ n }}"> |
12 | - <label for="{{ n }}" class="custom-control-label">{{ md(opt)[3:-5] }}</label> | |
12 | + <label for="{{ n }}" class="custom-control-label">{{ md(opt, strip_p_tag=True) }}</label> | |
13 | 13 | </div> |
14 | 14 | </a> |
15 | 15 | {% end %} | ... | ... |
tools.py
1 | 1 | |
2 | -# builtin | |
2 | +# python standard library | |
3 | 3 | from os import path |
4 | 4 | import subprocess |
5 | 5 | import logging |
6 | 6 | import re |
7 | 7 | |
8 | -# packages | |
8 | +# user installed libraries | |
9 | 9 | import yaml |
10 | 10 | import mistune |
11 | 11 | from pygments import highlight |
... | ... | @@ -117,8 +117,12 @@ class HighlightRenderer(mistune.Renderer): |
117 | 117 | |
118 | 118 | markdown = MarkdownWithMath(HighlightRenderer(escape=True)) # hard_wrap=True to insert <br> on newline |
119 | 119 | |
120 | -def md_to_html(text, q=None): | |
121 | - return markdown(text) | |
120 | +def md_to_html(text, strip_p_tag=False, q=None): | |
121 | + md = markdown(text) | |
122 | + if strip_p_tag and md.startswith('<p>') and md.endswith('</p>'): | |
123 | + return md[3:-5] | |
124 | + else: | |
125 | + return md | |
122 | 126 | |
123 | 127 | # --------------------------------------------------------------------------- |
124 | 128 | # load data from yaml file | ... | ... |