diff --git a/MANUAL.md b/MANUAL.md
index d0de72e..f867ebf 100644
--- a/MANUAL.md
+++ b/MANUAL.md
@@ -1,14 +1,61 @@
-# Perguntations
+# Perguntations user manual
-### Requirements and instalation
+## Quick start
-Install python 3.4 and the following packages from pip:
+After installing python and the required packages as described in the `README.md` you can run a demonstration:
+
+```
+$ cd PATH/TO/perguntations
+$ ./initdb.py
+New database created: students.db
+10 users inserted:
+ 0 - Professor (administrator)
+ 1465 - Gil Vicente
+ .
+ .
+ .
+ 1924 - Alexandre O'Neill
+$ mv students.db demo/
+$ ./serve.py demo/test.yaml
+2016-07-13 15:19:21,718 | INFO | app | ============= Running perguntations =============
+2016-07-13 15:19:21,740 | INFO | questions | Loaded 9 questions from "questions.yaml".
+2016-07-13 15:19:21,740 | INFO | test | Test factory ready for "demo".
+2016-07-13 15:19:21,756 | INFO | app | Database has 9 students registered.
+...
+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
+2016-07-13 15:19:21,919 | INFO | cherrypy.error | [13/Jul/2016:15:19:21] ENGINE Bus STARTED
+```
+
+You can now open a browser and point it to the server address, e.g. `http://127.0.0.1:8080`.
+
+Enter `0` for the number and any password. This will be your password from now on.
+
+After login, you will see an administrator page. This page allows you to:
+
+- Generate a sample test just for you to see if it looks right.
+- 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.
+- 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.
+- 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.
+- Online students will be marked and the table on the top of the page will show some more information (login time, ip address, etc)
+- 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...
+- It is also possible to add new students by clicking the button on the bottom of the page.
+
+## Answering a test
+
+Students are redirected to a test as soon as they login.
+
+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.
+
+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.
+
+## Creating a new test
+
+A test is just a yaml file with the configuration for that test. Look at `demo/test.yaml` for an example.
+
+## Creating questions
+
+Questions are defined in yaml files. Each yaml file contains a list of questions
-- CherryPy (3.7.0)
-- Mako (1.0.1)
-- Markdown (2.6.2)
-- PyYAML (3.11)
-- bcrypt (2.0.0)
Before using the program you need to
diff --git a/demo/questions/questions.yaml b/demo/questions/questions.yaml
index 89acf84..38a69ac 100644
--- a/demo/questions/questions.yaml
+++ b/demo/questions/questions.yaml
@@ -28,13 +28,14 @@
solar_system_planets: images/planets.png
text: Qual é o maior planeta do Sistema Solar?
options:
- - Júpiter
- Mercúrio
- Marte
+ - Júpiter
+ - Têm todos o mesmo tamanho
# opcional
- correct: 0
title: Sistema solar
- shuffle: True
+ correct: 2
+ shuffle: False
discount: True
hint: Se usar o markdown `!(text)[imagem]` a imagem fica com tamanho fixo. É preferível usar a tag html `
` para ter sempre a largura correcta.
# ---------------------------------------------------------------------------
diff --git a/demo/test.yaml b/demo/test.yaml
index 34953fb..2bdc689 100644
--- a/demo/test.yaml
+++ b/demo/test.yaml
@@ -1,53 +1,71 @@
#=============================================================================
+# The test reference should be a unique identifier. It is saved in the database
+# so that queries for the results can be done in the terminal with
+# $ sqlite3 students.db "select * from tests where ref='demo'"
ref: demo
+
+# (optional, default: '') You may wish to refer the course, year or kind of test
title: Exame de Demonstração
# Database with student credentials and grades of all questions and tests done
-# The database is an sqlite3 file generate with the script initdb_from_csv.py
+# The database is an sqlite3 file generate with the script initdb.py
database: demo/students.db
# (optional) Generate a file for each test done by a student.
# It includes the questions, answers and grades.
-# If undefined, then no tests are saved (useful for debug and training)
+# If undefined, then no tests are saved (useful for debug and training).
save_answers: yes
answers_dir: demo/ans
-# Show points for each question, scale 0-20 (default: False)
+# (optional, default: False) Show points for each question, scale 0-20.
show_points: True
-# Show question's hint if available (default: False)
+# (optional, default: False) Show hints if available
show_hints: True
-# Show lots of information for debugging (default: False)
+# (optional, default: False) Show lots of information for debugging
# debug: True
#-----------------------------------------------------------------------------
# Base path applied to the questions files and all the scripts
# including question generators and correctors.
-# Either absolute path or relative to current directory.
+# Either absolute path or relative to current directory can be used.
questions_dir: demo/questions
# (optional) List of files containing questions in yaml format.
# Selected questions will be obtained from these files.
-# If undefined, all files in questions_dir are loaded.
+# If undefined, all yaml files in questions_dir are loaded (not recommended).
files:
- questions.yaml
-# This is the list of questions. If a "ref:" has a list of keys, then
-# one question is selected from the list.
-# The following example will generate a test with 3 questions.
+# This is the list of questions that will make up the test.
+# The order is preserved.
+# There are several ways to define each question (explained below).
questions:
- - instructions
+ # show question where ref=instructions
+ - ref: instructions
+
+ # show question where ref=flags and assigns 0.5 points (unnormalized)
- ref: flags
points: 0.5
+
+ # idem
- ref: math-expressions
points: 2.0
+
+ # show question where ref=solar-system and assign the default of 1.0 point (unnormalized)
- ref: solar-system
- # points: 1.0 is the default, if omitted
- - ref: # choose one of the following list of questions
+
+ # select one questions from the list [our_planet1, our_planet2]
+ # and assign 0.75 points (unnormalized)
+ - ref:
- our_planet1
- our_planet2
points: 0.75
- - basic-colors # same as `ref: basic-colors`
+
+ # the key 'ref:' can be omitted, a default of 1.0 points is assigned
+ - basic-colors
+
- question-whatever
+
- markdown_instructions
diff --git a/initdb.py b/initdb.py
index 82c1348..85bde8f 100755
--- a/initdb.py
+++ b/initdb.py
@@ -49,23 +49,37 @@ try:
session.add_all([Student(id=r['N.º'], name=fix(r['Nome']), password='') for r in csvreader])
else:
# otherwise add 5 fake students
- session.add_all([
- Student(id='student1', name='Student1', password=''),
- Student(id='student2', name='Student2', password=''),
- Student(id='student3', name='Student3', password=''),
- Student(id='student4', name='Student4', password=''),
- Student(id='student5', name='Student5', password=''),
- ])
+ fakes = [
+ ['1888', 'Fernando Pessoa'],
+ ['1799', 'Almeida Garrett'],
+ ['1845', 'José Maria Eça de Queirós'],
+ ['1465', 'Gil Vicente'],
+ ['1825', 'Camilo Castelo Branco'],
+ ['1842', 'Antero de Quental'],
+ ['1907', 'Miguel Torga'],
+ ['1810', 'Alexandre Herculano'],
+ ['1924', 'Alexandre O\'Neill'],
+ ]
+ session.add_all([Student(id=i, name=name, password='') for i,name in fakes])
session.commit()
except Exception:
session.rollback()
- print('Erro: Dados já existentes na base de dados?')
+ print('Error: Database already exists.')
sys.exit(1)
else:
n = session.query(Student).count()
- print('Base de dados inicializada com {} utilizadores.'.format(n))
+ print('New database created: {0}\n{1} users inserted:'.format(args.db, n))
+
+ users = session.query(Student).order_by(Student.id).all()
+ print(' {0:8} - {1} (administrator)'.format(users[0].id, users[0].name))
+ if n > 1:
+ print(' {0:8} - {1}'.format(users[1].id, users[1].name))
+ if n > 3:
+ print(' .\n .\n .')
+ if n > 2:
+ print(' {0:8} - {1}'.format(users[-1].id, users[-1].name))
# --- end session ---
--
libgit2 0.21.2