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 | ... | ... |