Skip to content

Commit 7aa703e

Browse files
committed
add management command to link current and previous questions
Defaults to matching question numbers across sessions but allows overrides for where there is not a direct match Fixes #142
1 parent 852be83 commit 7aa703e

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from collections import defaultdict
2+
3+
from django.core.management.base import BaseCommand
4+
5+
import pandas as pd
6+
7+
from crowdsourcer.models import MarkingSession, Question, Section
8+
9+
10+
class Command(BaseCommand):
11+
help = "set up question links to previous session"
12+
13+
overrides = {}
14+
15+
def add_arguments(self, parser):
16+
parser.add_argument(
17+
"--current",
18+
action="store",
19+
required=True,
20+
help="The current session",
21+
)
22+
23+
parser.add_argument(
24+
"--previous",
25+
action="store",
26+
required=True,
27+
help="The previous session",
28+
)
29+
30+
parser.add_argument(
31+
"--overrides", action="store", help="CSV file with list of link overrides"
32+
)
33+
34+
def get_overrides(self, file):
35+
df = pd.read_csv(file)
36+
37+
overrides = defaultdict(dict)
38+
for _, row in df.iterrows():
39+
overrides[row["section"]][str(row["current_question"])] = str(
40+
row["previous_question"]
41+
)
42+
43+
self.overrides = overrides
44+
45+
def get_session(self, session_label):
46+
try:
47+
ms = MarkingSession.objects.get(label=session_label)
48+
except MarkingSession.DoesNotExist:
49+
ms = None
50+
51+
return ms
52+
53+
def setup_sessions(self, *args, **kwargs):
54+
setup = True
55+
56+
for session in ("current", "previous"):
57+
ms = self.get_session(kwargs[session])
58+
if ms is not None:
59+
setattr(self, session, ms)
60+
else:
61+
setup = False
62+
self.stderr.write(
63+
f"Could not find {session} session: {kwargs[session]}"
64+
)
65+
66+
return setup
67+
68+
def get_questions(self, session):
69+
questions = defaultdict(dict)
70+
71+
for section in Section.objects.filter(marking_session=session):
72+
for question in Question.objects.filter(section=section):
73+
questions[section.title][question.number_and_part] = question
74+
75+
return questions
76+
77+
def handle(self, *args, **kwargs):
78+
sessions_exist = self.setup_sessions(*args, **kwargs)
79+
if not sessions_exist:
80+
return
81+
82+
if kwargs.get("overrides") is not None:
83+
self.get_overrides(kwargs["overrides"])
84+
85+
current_questions = self.get_questions(self.current)
86+
previous_questions = self.get_questions(self.previous)
87+
88+
for section, questions in current_questions.items():
89+
for q_no, question in questions.items():
90+
overrides = self.overrides.get(section, None)
91+
if overrides is not None and overrides.get(q_no) is not None:
92+
prev_question_no = overrides.get(q_no, q_no)
93+
self.stdout.write(
94+
f"Using previous question {prev_question_no} for {question} in {section}"
95+
)
96+
else:
97+
prev_question_no = q_no
98+
99+
if previous_questions[section].get(prev_question_no) is None:
100+
self.stderr.write(f"No matching question for {q_no} in {section}")
101+
continue
102+
else:
103+
prev_question = previous_questions[section][prev_question_no]
104+
105+
question.previous_question = prev_question
106+
question.save()

0 commit comments

Comments
 (0)