Commit 02782cd5e58e7106693ce84449a31ece0799c5e1

Authored by Miguel Barao
1 parent 9f66ec18
Exists in master and in 1 other branch dev

- messages from initdb.py in english

- documentation improvements
1 -# Perguntations 1 +# Perguntations user manual
2 2
3 -### Requirements and instalation 3 +## Quick start
4 4
5 -Install python 3.4 and the following packages from pip: 5 +After installing python and the required packages as described in the `README.md` you can run a demonstration:
  6 +
  7 +```
  8 +$ cd PATH/TO/perguntations
  9 +$ ./initdb.py
  10 +New database created: students.db
  11 +10 users inserted:
  12 + 0 - Professor (administrator)
  13 + 1465 - Gil Vicente
  14 + .
  15 + .
  16 + .
  17 + 1924 - Alexandre O'Neill
  18 +$ mv students.db demo/
  19 +$ ./serve.py demo/test.yaml
  20 +2016-07-13 15:19:21,718 | INFO | app | ============= Running perguntations =============
  21 +2016-07-13 15:19:21,740 | INFO | questions | Loaded 9 questions from "questions.yaml".
  22 +2016-07-13 15:19:21,740 | INFO | test | Test factory ready for "demo".
  23 +2016-07-13 15:19:21,756 | INFO | app | Database has 9 students registered.
  24 +...
  25 +2016-07-13 15:19:21,919 | INFO | cherrypy.error | [13/Jul/2016:15:19:21] ENGINE Serving on http://0.0.0.0:8080
  26 +2016-07-13 15:19:21,919 | INFO | cherrypy.error | [13/Jul/2016:15:19:21] ENGINE Bus STARTED
  27 +```
  28 +
  29 +You can now open a browser and point it to the server address, e.g. `http://127.0.0.1:8080`.
  30 +
  31 +Enter `0` for the number and any password. This will be your password from now on.
  32 +
  33 +After login, you will see an administrator page. This page allows you to:
  34 +
  35 +- Generate a sample test just for you to see if it looks right.
  36 +- Allow students to login to the test. This can be done one at a time using the checkboxes on the left of each student, or allow all students by clicking the button in the bottom of the page.
  37 +- Review a test done by a student by clicking the grade colorbar on the right. If a student has multiple tests, then several bars will be shown. A tooltip shows the date/time for each test.
  38 +- Reset student passwords. Students that already have a password will have a label `PW` next to the student name. To reset the password, go to the bottom of the page and insert the student number in the box and press the button to reset the password. The label `PW` will disappear.
  39 +- Online students will be marked and the table on the top of the page will show some more information (login time, ip address, etc)
  40 +- If a student moves away from the browser (e.g. for cheating), a red bar appears along with the status `unfocus`. Screen saver is also reported as unfocus, so some care should be taken...
  41 +- It is also possible to add new students by clicking the button on the bottom of the page.
  42 +
  43 +## Answering a test
  44 +
  45 +Students are redirected to a test as soon as they login.
  46 +
  47 +Just answer the questions. If the answer is unknown, the question should be disabled on the top right corner. This avoids penalties in some questions.
  48 +
  49 +After answering all the questions, the test is submited by clicking the button on the bottom of the page. A new page is shown with the grade obtained.
  50 +
  51 +## Creating a new test
  52 +
  53 +A test is just a yaml file with the configuration for that test. Look at `demo/test.yaml` for an example.
  54 +
  55 +## Creating questions
  56 +
  57 +Questions are defined in yaml files. Each yaml file contains a list of questions
6 58
7 -- CherryPy (3.7.0)  
8 -- Mako (1.0.1)  
9 -- Markdown (2.6.2)  
10 -- PyYAML (3.11)  
11 -- bcrypt (2.0.0)  
12 59
13 Before using the program you need to 60 Before using the program you need to
14 61
demo/questions/questions.yaml
@@ -28,13 +28,14 @@ @@ -28,13 +28,14 @@
28 solar_system_planets: images/planets.png 28 solar_system_planets: images/planets.png
29 text: Qual é o maior planeta do Sistema Solar? <img src="solar_system_planets" width="100%"/> 29 text: Qual é o maior planeta do Sistema Solar? <img src="solar_system_planets" width="100%"/>
30 options: 30 options:
31 - - Júpiter  
32 - Mercúrio 31 - Mercúrio
33 - Marte 32 - Marte
  33 + - Júpiter
  34 + - Têm todos o mesmo tamanho
34 # opcional 35 # opcional
35 - correct: 0  
36 title: Sistema solar 36 title: Sistema solar
37 - shuffle: True 37 + correct: 2
  38 + shuffle: False
38 discount: True 39 discount: True
39 hint: Se usar o markdown `!(text)[imagem]` a imagem fica com tamanho fixo. É preferível usar a tag html `<img with="100%" src="...">` para ter sempre a largura correcta. 40 hint: Se usar o markdown `!(text)[imagem]` a imagem fica com tamanho fixo. É preferível usar a tag html `<img with="100%" src="...">` para ter sempre a largura correcta.
40 # --------------------------------------------------------------------------- 41 # ---------------------------------------------------------------------------
demo/test.yaml
1 #============================================================================= 1 #=============================================================================
  2 +# The test reference should be a unique identifier. It is saved in the database
  3 +# so that queries for the results can be done in the terminal with
  4 +# $ sqlite3 students.db "select * from tests where ref='demo'"
2 ref: demo 5 ref: demo
  6 +
  7 +# (optional, default: '') You may wish to refer the course, year or kind of test
3 title: Exame de Demonstração 8 title: Exame de Demonstração
4 9
5 # Database with student credentials and grades of all questions and tests done 10 # Database with student credentials and grades of all questions and tests done
6 -# The database is an sqlite3 file generate with the script initdb_from_csv.py 11 +# The database is an sqlite3 file generate with the script initdb.py
7 database: demo/students.db 12 database: demo/students.db
8 13
9 # (optional) Generate a file for each test done by a student. 14 # (optional) Generate a file for each test done by a student.
10 # It includes the questions, answers and grades. 15 # It includes the questions, answers and grades.
11 -# If undefined, then no tests are saved (useful for debug and training) 16 +# If undefined, then no tests are saved (useful for debug and training).
12 save_answers: yes 17 save_answers: yes
13 answers_dir: demo/ans 18 answers_dir: demo/ans
14 19
15 -# Show points for each question, scale 0-20 (default: False) 20 +# (optional, default: False) Show points for each question, scale 0-20.
16 show_points: True 21 show_points: True
17 22
18 -# Show question's hint if available (default: False) 23 +# (optional, default: False) Show hints if available
19 show_hints: True 24 show_hints: True
20 25
21 -# Show lots of information for debugging (default: False) 26 +# (optional, default: False) Show lots of information for debugging
22 # debug: True 27 # debug: True
23 28
24 #----------------------------------------------------------------------------- 29 #-----------------------------------------------------------------------------
25 # Base path applied to the questions files and all the scripts 30 # Base path applied to the questions files and all the scripts
26 # including question generators and correctors. 31 # including question generators and correctors.
27 -# Either absolute path or relative to current directory. 32 +# Either absolute path or relative to current directory can be used.
28 questions_dir: demo/questions 33 questions_dir: demo/questions
29 34
30 # (optional) List of files containing questions in yaml format. 35 # (optional) List of files containing questions in yaml format.
31 # Selected questions will be obtained from these files. 36 # Selected questions will be obtained from these files.
32 -# If undefined, all files in questions_dir are loaded. 37 +# If undefined, all yaml files in questions_dir are loaded (not recommended).
33 files: 38 files:
34 - questions.yaml 39 - questions.yaml
35 40
36 -# This is the list of questions. If a "ref:" has a list of keys, then  
37 -# one question is selected from the list.  
38 -# The following example will generate a test with 3 questions. 41 +# This is the list of questions that will make up the test.
  42 +# The order is preserved.
  43 +# There are several ways to define each question (explained below).
39 questions: 44 questions:
40 - - instructions 45 + # show question where ref=instructions
  46 + - ref: instructions
  47 +
  48 + # show question where ref=flags and assigns 0.5 points (unnormalized)
41 - ref: flags 49 - ref: flags
42 points: 0.5 50 points: 0.5
  51 +
  52 + # idem
43 - ref: math-expressions 53 - ref: math-expressions
44 points: 2.0 54 points: 2.0
  55 +
  56 + # show question where ref=solar-system and assign the default of 1.0 point (unnormalized)
45 - ref: solar-system 57 - ref: solar-system
46 - # points: 1.0 is the default, if omitted  
47 - - ref: # choose one of the following list of questions 58 +
  59 + # select one questions from the list [our_planet1, our_planet2]
  60 + # and assign 0.75 points (unnormalized)
  61 + - ref:
48 - our_planet1 62 - our_planet1
49 - our_planet2 63 - our_planet2
50 points: 0.75 64 points: 0.75
51 - - basic-colors # same as `ref: basic-colors` 65 +
  66 + # the key 'ref:' can be omitted, a default of 1.0 points is assigned
  67 + - basic-colors
  68 +
52 - question-whatever 69 - question-whatever
  70 +
53 - markdown_instructions 71 - markdown_instructions
@@ -49,23 +49,37 @@ try: @@ -49,23 +49,37 @@ try:
49 session.add_all([Student(id=r['N.º'], name=fix(r['Nome']), password='') for r in csvreader]) 49 session.add_all([Student(id=r['N.º'], name=fix(r['Nome']), password='') for r in csvreader])
50 else: 50 else:
51 # otherwise add 5 fake students 51 # otherwise add 5 fake students
52 - session.add_all([  
53 - Student(id='student1', name='Student1', password=''),  
54 - Student(id='student2', name='Student2', password=''),  
55 - Student(id='student3', name='Student3', password=''),  
56 - Student(id='student4', name='Student4', password=''),  
57 - Student(id='student5', name='Student5', password=''),  
58 - ]) 52 + fakes = [
  53 + ['1888', 'Fernando Pessoa'],
  54 + ['1799', 'Almeida Garrett'],
  55 + ['1845', 'José Maria Eça de Queirós'],
  56 + ['1465', 'Gil Vicente'],
  57 + ['1825', 'Camilo Castelo Branco'],
  58 + ['1842', 'Antero de Quental'],
  59 + ['1907', 'Miguel Torga'],
  60 + ['1810', 'Alexandre Herculano'],
  61 + ['1924', 'Alexandre O\'Neill'],
  62 + ]
  63 + session.add_all([Student(id=i, name=name, password='') for i,name in fakes])
59 64
60 session.commit() 65 session.commit()
61 66
62 except Exception: 67 except Exception:
63 session.rollback() 68 session.rollback()
64 - print('Erro: Dados já existentes na base de dados?') 69 + print('Error: Database already exists.')
65 sys.exit(1) 70 sys.exit(1)
66 71
67 else: 72 else:
68 n = session.query(Student).count() 73 n = session.query(Student).count()
69 - print('Base de dados inicializada com {} utilizadores.'.format(n)) 74 + print('New database created: {0}\n{1} users inserted:'.format(args.db, n))
  75 +
  76 + users = session.query(Student).order_by(Student.id).all()
  77 + print(' {0:8} - {1} (administrator)'.format(users[0].id, users[0].name))
  78 + if n > 1:
  79 + print(' {0:8} - {1}'.format(users[1].id, users[1].name))
  80 + if n > 3:
  81 + print(' .\n .\n .')
  82 + if n > 2:
  83 + print(' {0:8} - {1}'.format(users[-1].id, users[-1].name))
70 84
71 # --- end session --- 85 # --- end session ---