From 729b68db93b52de30ba8472d8ae27b350100ce1f Mon Sep 17 00:00:00 2001
From: Miguel Barão
Date: Wed, 6 May 2020 18:25:19 +0100
Subject: [PATCH] - add button to get detailed grades of questions
---
perguntations/app.py | 33 ++++++++++++++++++++++++++++++++-
perguntations/models.py | 52 +++++++++++++++++++++++++++-------------------------
perguntations/serve.py | 9 +++++++++
perguntations/templates/admin.html | 3 ++-
4 files changed, 70 insertions(+), 27 deletions(-)
diff --git a/perguntations/app.py b/perguntations/app.py
index c4c229e..7623dd4 100644
--- a/perguntations/app.py
+++ b/perguntations/app.py
@@ -281,6 +281,37 @@ class App():
# def get_student_name(self, uid):
# return self.online[uid]['student']['name']
+ def get_questions_csv(self):
+ '''generates a CSV with the grades of the test'''
+ test_id = self.testfactory['ref']
+
+ with self.db_session() as sess:
+ grades = sess.query(Question.student_id, Question.starttime,
+ Question.ref, Question.grade)\
+ .filter(Question.test_id == test_id)\
+ .order_by(Question.student_id)\
+ .all()
+
+ cols = ['Aluno', 'Início'] + \
+ [r for question in self.testfactory['questions']
+ for r in question['ref']]
+
+ tests = {}
+ for q in grades:
+ student, qref, qgrade = q[:2], q[2], q[3]
+ tests.setdefault(student, {})[qref] = qgrade
+
+ rows = [{'Aluno': test[0], 'Início': test[1], **q}
+ for test, q in tests.items()]
+
+ csvstr = io.StringIO()
+ writer = csv.DictWriter(csvstr, fieldnames=cols, restval=None,
+ delimiter=';', quoting=csv.QUOTE_ALL)
+ writer.writeheader()
+ writer.writerows(rows)
+ return test_id, csvstr.getvalue()
+
+
def get_test_csv(self):
'''generates a CSV with the grades of the test'''
with self.db_session() as sess:
@@ -292,7 +323,7 @@ class App():
csvstr = io.StringIO()
writer = csv.writer(csvstr, delimiter=';', quoting=csv.QUOTE_ALL)
- writer.writerow(('Número', 'Nota', 'Início', 'Fim'))
+ writer.writerow(('Aluno', 'Nota', 'Início', 'Fim'))
writer.writerows(grades)
return self.testfactory['ref'], csvstr.getvalue()
diff --git a/perguntations/models.py b/perguntations/models.py
index c02275a..d0191ff 100644
--- a/perguntations/models.py
+++ b/perguntations/models.py
@@ -1,5 +1,7 @@
'''
-Database tables
+SQLAlchemy ORM
+
+The classes below correspond to database tables
'''
@@ -26,10 +28,10 @@ class Student(Base):
questions = relationship('Question', back_populates='student')
def __repr__(self):
- return f'Student:\n\
- id: "{self.id}"\n\
- name: "{self.name}"\n\
- password: "{self.password}"'
+ return (f'Student:\n'
+ f' id: "{self.id}"\n'
+ f' name: "{self.name}"\n'
+ f' password: "{self.password}"\n')
# ----------------------------------------------------------------------------
@@ -38,7 +40,7 @@ class Test(Base):
__tablename__ = 'tests'
id = Column(Integer, primary_key=True) # auto_increment
ref = Column(String)
- title = Column(String) # FIXME depends on ref and should come from another table...
+ title = Column(String)
grade = Column(Float)
state = Column(String) # ACTIVE, FINISHED, QUIT, NULL
comment = Column(String)
@@ -52,17 +54,17 @@ class Test(Base):
questions = relationship('Question', back_populates='test')
def __repr__(self):
- return f'Test:\n\
- id: "{self.id}"\n\
- ref: "{self.ref}"\n\
- title: "{self.title}"\n\
- grade: "{self.grade}"\n\
- state: "{self.state}"\n\
- comment: "{self.comment}"\n\
- starttime: "{self.starttime}"\n\
- finishtime: "{self.finishtime}"\n\
- filename: "{self.filename}"\n\
- student_id: "{self.student_id}"\n'
+ return (f'Test:\n'
+ f' id: "{self.id}"\n'
+ f' ref: "{self.ref}"\n'
+ f' title: "{self.title}"\n'
+ f' grade: "{self.grade}"\n'
+ f' state: "{self.state}"\n'
+ f' comment: "{self.comment}"\n'
+ f' starttime: "{self.starttime}"\n'
+ f' finishtime: "{self.finishtime}"\n'
+ f' filename: "{self.filename}"\n'
+ f' student_id: "{self.student_id}"\n')
# ---------------------------------------------------------------------------
@@ -82,11 +84,11 @@ class Question(Base):
test = relationship('Test', back_populates='questions')
def __repr__(self):
- return f'Question:\n\
- id: "{self.id}"\n\
- ref: "{self.ref}"\n\
- grade: "{self.grade}"\n\
- starttime: "{self.starttime}"\n\
- finishtime: "{self.finishtime}"\n\
- student_id: "{self.student_id}"\n\
- test_id: "{self.test_id}"\n'
+ return (f'Question:\n'
+ f' id: "{self.id}"\n'
+ f' ref: "{self.ref}"\n'
+ f' grade: "{self.grade}"\n'
+ f' starttime: "{self.starttime}"\n'
+ f' finishtime: "{self.finishtime}"\n'
+ f' student_id: "{self.student_id}"\n'
+ f' test_id: "{self.test_id}"\n')
diff --git a/perguntations/serve.py b/perguntations/serve.py
index 2f2e703..c6044ca 100644
--- a/perguntations/serve.py
+++ b/perguntations/serve.py
@@ -191,6 +191,15 @@ class AdminWebservice(BaseHandler):
self.write(data)
await self.flush()
+ if cmd == 'questionscsv':
+ test_ref, data = self.testapp.get_questions_csv()
+ self.set_header('Content-Type', 'text/csv')
+ self.set_header('content-Disposition',
+ f'attachment; filename={test_ref}-detailed.csv')
+ self.write(data)
+ await self.flush()
+
+
# ----------------------------------------------------------------------------
class AdminHandler(BaseHandler):
'''Handle /admin'''
diff --git a/perguntations/templates/admin.html b/perguntations/templates/admin.html
index 1468366..fd09824 100644
--- a/perguntations/templates/admin.html
+++ b/perguntations/templates/admin.html
@@ -76,7 +76,8 @@
Base de dados: --
- Obter CSV com as notas
+ Obter CSV das notas
+ Obter CSV detalhado
--
libgit2 0.21.2