Skip to content
Snippets Groups Projects
Commit f74ea091 authored by srosse's avatar srosse
Browse files

OO-1593: switch in word export, better statistics of test with manual...

OO-1593: switch in word export, better statistics of test with manual correction, don't count test in author mode
parent daab507c
No related branches found
No related tags found
No related merge requests found
...@@ -87,6 +87,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -87,6 +87,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
} else { } else {
sb.append(" and asession.subIdent is null"); sb.append(" and asession.subIdent is null");
} }
sb.append(" and asession.authorMode=false");
if(finished) { if(finished) {
sb.append(" and asession.finishTime is not null"); sb.append(" and asession.finishTime is not null");
...@@ -126,7 +127,9 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -126,7 +127,9 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
private void decorateRSetQuery(TypedQuery<?> query, QTI21StatisticSearchParams searchParams) { private void decorateRSetQuery(TypedQuery<?> query, QTI21StatisticSearchParams searchParams) {
query.setParameter("testEntryKey", searchParams.getTestEntry().getKey()); query.setParameter("testEntryKey", searchParams.getTestEntry().getKey());
if(searchParams.getCourseEntry() != null) { if(searchParams.getCourseEntry() == null) {
query.setParameter("repositoryEntryKey", searchParams.getTestEntry().getKey());
} else {
query.setParameter("repositoryEntryKey", searchParams.getCourseEntry().getKey()); query.setParameter("repositoryEntryKey", searchParams.getCourseEntry().getKey());
} }
if(searchParams.getNodeIdent() != null ) { if(searchParams.getNodeIdent() != null ) {
...@@ -147,7 +150,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -147,7 +150,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
@Override @Override
public StatisticAssessment getAssessmentStatistics(QTI21StatisticSearchParams searchParams) { public StatisticAssessment getAssessmentStatistics(QTI21StatisticSearchParams searchParams) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("select asession.score, asession.passed, asession.duration from qtiassessmenttestsession asession "); sb.append("select asession.score, asession.manualScore, asession.passed, asession.duration from qtiassessmenttestsession asession ");
decorateRSet(sb, searchParams, true); decorateRSet(sb, searchParams, true);
sb.append(" order by asession.key asc"); sb.append(" order by asession.key asc");
...@@ -170,7 +173,14 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -170,7 +173,14 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
int dataPos = 0; int dataPos = 0;
boolean hasScore = false; boolean hasScore = false;
for(Object[] rawData:rawDatas) { for(Object[] rawData:rawDatas) {
BigDecimal score = (BigDecimal)rawData[0]; int pos = 0;
BigDecimal score = (BigDecimal)rawData[pos++];
BigDecimal manualScore = (BigDecimal)rawData[pos++];
if(score == null) {
score = manualScore;
} else if(manualScore != null) {
score = score.add(manualScore);
}
if(score != null) { if(score != null) {
double scored = score.doubleValue(); double scored = score.doubleValue();
scores[dataPos] = scored; scores[dataPos] = scored;
...@@ -179,7 +189,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -179,7 +189,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
hasScore = true; hasScore = true;
} }
Boolean passed = (Boolean)rawData[1]; Boolean passed = (Boolean)rawData[pos++];
if(passed != null) { if(passed != null) {
if(passed.booleanValue()) { if(passed.booleanValue()) {
numOfPassed++; numOfPassed++;
...@@ -188,7 +198,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -188,7 +198,7 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
} }
} }
Long duration = (Long)rawData[2]; Long duration = (Long)rawData[pos++];
if(duration != null) { if(duration != null) {
double durationd = duration.doubleValue(); double durationd = duration.doubleValue();
double durationSecond = Math.round(durationd / 1000d); double durationSecond = Math.round(durationd / 1000d);
...@@ -232,11 +242,11 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -232,11 +242,11 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
QTI21StatisticSearchParams searchParams) { QTI21StatisticSearchParams searchParams) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("select isession.score, count(isession.key), avg(isession.duration) from qtiassessmentitemsession isession ") sb.append("select isession.score, isession.manualScore, count(isession.key), avg(isession.duration) from qtiassessmentitemsession isession ")
.append(" inner join isession.assessmentTestSession asession"); .append(" inner join isession.assessmentTestSession asession");
decorateRSet(sb, searchParams, true); decorateRSet(sb, searchParams, true);
sb.append(" and isession.assessmentItemIdentifier=:itemIdent and isession.duration > 0") sb.append(" and isession.assessmentItemIdentifier=:itemIdent and isession.duration > 0")
.append(" group by isession.score"); .append(" group by isession.score, isession.manualScore");
TypedQuery<Object[]> query = dbInstance.getCurrentEntityManager() TypedQuery<Object[]> query = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Object[].class) .createQuery(sb.toString(), Object[].class)
...@@ -254,15 +264,23 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager { ...@@ -254,15 +264,23 @@ public class QTI21StatisticsManagerImpl implements QTI21StatisticsManager {
long numOfIncorrectAnswers = 0; long numOfIncorrectAnswers = 0;
for(Object[] result:results) { for(Object[] result:results) {
double score = ((Number)result[0]).doubleValue(); BigDecimal score = (BigDecimal)result[0];
long numOfResults = ((Number)result[1]).longValue(); BigDecimal manualScore = (BigDecimal)result[1];
double averageDuration = ((Number)result[2]).doubleValue(); if(score == null) {
score = manualScore;
} else if(manualScore != null) {
score = score.add(manualScore);
}
long numOfResults = ((Number)result[2]).longValue();
double averageDuration = ((Number)result[3]).doubleValue();
//average //average
totalScore += (score * numOfResults); double dScore = score == null ? 0.0d : score.doubleValue();
totalScore += (dScore * numOfResults);
totalResults += numOfResults; totalResults += numOfResults;
if((maxScore - score) < 0.0001) { if((maxScore - dScore) < 0.0001) {
numOfCorrectAnswers += numOfResults; numOfCorrectAnswers += numOfResults;
} else { } else {
numOfIncorrectAnswers += numOfResults; numOfIncorrectAnswers += numOfResults;
......
...@@ -343,66 +343,76 @@ public class QTI21WordExport implements MediaResource { ...@@ -343,66 +343,76 @@ public class QTI21WordExport implements MediaResource {
@Override @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) { public void startElement(String uri, String localName, String qName, Attributes attributes) {
String tag = localName.toLowerCase(); String tag = localName.toLowerCase();
if("choiceinteraction".equals(tag)) { switch(tag) {
responseIdentifier = attributes.getValue("responseidentifier"); case "choiceinteraction":
} else if("simplechoice".equals(tag)) { responseIdentifier = attributes.getValue("responseidentifier");
if(currentTable == null) { break;
startTable(); case "simplechoice":
} if(currentTable == null) {
currentTable.addRowEl(); startTable();
currentTable.addCellEl(factory.createTableCell("E9EAF2", 4560, Unit.pct), 1); }
simpleChoiceIdentifier = attributes.getValue("identifier"); currentTable.addRowEl();
} else if("textentryinteraction".equals(tag)) { currentTable.addCellEl(factory.createTableCell("E9EAF2", 4560, Unit.pct), 1);
startTextEntryInteraction(tag, attributes); simpleChoiceIdentifier = attributes.getValue("identifier");
} else if("extendedtextinteraction".equals(tag)) { break;
startExtendedTextInteraction(attributes); case "textentryinteraction":
} else if("hotspotinteraction".equals(tag)) { startTextEntryInteraction(tag, attributes);
startHotspotInteraction(attributes); break;
} else if("inlinechoiceinteraction".equals(tag)) { case "extendedtextinteraction":
startExtendedTextInteraction(attributes);
} else if("hottextinteraction".equals(tag)) { break;
case "hotspotinteraction":
} else if("hottext".equals(tag)) { startHotspotInteraction(attributes);
break;
} else if("matchinteraction".equals(tag)) { case "inlinechoiceinteraction":
renderElement = false; case "hottextinteraction":
case "hottext":
Interaction interaction = getInteractionByResponseIdentifier(attributes); break;
if(interaction instanceof MatchInteraction) { case "matchinteraction":
MatchInteraction matchInteraction = (MatchInteraction)interaction; renderElement = false;
QTI21QuestionType type = QTI21QuestionType.getTypeOfMatch(assessmentItem, matchInteraction);
if(type == QTI21QuestionType.kprim) { Interaction interaction = getInteractionByResponseIdentifier(attributes);
startKPrim(matchInteraction); if(interaction instanceof MatchInteraction) {
MatchInteraction matchInteraction = (MatchInteraction)interaction;
QTI21QuestionType type = QTI21QuestionType.getTypeOfMatch(assessmentItem, matchInteraction);
if(type == QTI21QuestionType.kprim) {
startKPrim(matchInteraction);
}
}
break;
case "gapmatchinteraction":
break;
case "selectpointinteraction":
startSelectPointInteraction(attributes);
break;
case "graphicassociateinteraction":
startGraphicAssociateInteraction(attributes);
break;
case "graphicorderinteraction":
startGraphicOrderInteraction(attributes);
break;
case "graphicgapmatchinteraction":
case "associateinteraction":
case "uploadinteraction":
break;
case "positionobjectinteraction":
startPositionObjectInteraction(attributes);
break;
case "sliderinteraction":
break;
case "drawinginteraction":
startDrawingInteraction(attributes);
break;
case "simplematchset":
case "simpleassociablechoice":
//do nothing
break;
default: {
if(renderElement) {
super.startElement(uri, localName, qName, attributes);
} }
} }
} else if("gapmatchinteraction".equals(tag)) {
} else if("selectpointinteraction".equals(tag)) {
startSelectPointInteraction(attributes);
} else if("graphicassociateinteraction".equals(tag)) {
startGraphicAssociateInteraction(attributes);
} else if("graphicorderinteraction".equals(tag)) {
startGraphicOrderInteraction(attributes);
} else if("graphicgapmatchinteraction".equals(tag)) {
//
} else if("associateinteraction".equals(tag)) {
//
} else if("uploadinteraction".equals(tag)) {
//
} else if("positionobjectinteraction".equals(tag)) {
startPositionObjectInteraction(attributes);
} else if("sliderinteraction".equals(tag)) {
//
} else if("drawinginteraction".equals(tag)) {
startDrawingInteraction(attributes);
} else if("simplematchset".equals(tag)) {
//do nothing
} else if("simpleassociablechoice".equals(tag)) {
//do nothing
} else if(renderElement) {
super.startElement(uri, localName, qName, attributes);
} }
} }
...@@ -416,34 +426,42 @@ public class QTI21WordExport implements MediaResource { ...@@ -416,34 +426,42 @@ public class QTI21WordExport implements MediaResource {
@Override @Override
public void endElement(String uri, String localName, String qName) { public void endElement(String uri, String localName, String qName) {
String tag = localName.toLowerCase(); String tag = localName.toLowerCase();
if("choiceinteraction".equals(tag)) { switch(tag) {
endTable(); case "choiceinteraction":
} else if("simplechoice".equals(tag)) { endTable();
Element checkboxCell = factory.createTableCell(null, 369, Unit.pct); break;
Node checkboxNode = currentTable.addCellEl(checkboxCell, 1); case "simplechoice":
Element checkboxCell = factory.createTableCell(null, 369, Unit.pct);
boolean checked = false; Node checkboxNode = currentTable.addCellEl(checkboxCell, 1);
if(withResponses) {
Identifier identifier = Identifier.assumedLegal(simpleChoiceIdentifier); boolean checked = false;
List<Identifier> correctAnswers = CorrectResponsesUtil if(withResponses) {
.getCorrectIdentifierResponses(assessmentItem, Identifier.assumedLegal(responseIdentifier)); Identifier identifier = Identifier.assumedLegal(simpleChoiceIdentifier);
checked = correctAnswers.contains(identifier); List<Identifier> correctAnswers = CorrectResponsesUtil
.getCorrectIdentifierResponses(assessmentItem, Identifier.assumedLegal(responseIdentifier));
checked = correctAnswers.contains(identifier);
}
Node responseEl = factory.createCheckbox(checked);
Node wrapEl = factory.wrapInParagraph(responseEl);
checkboxNode.appendChild(wrapEl);
closeCurrentTableRow();
break;
case "textentryinteraction":
//auto closing tag
case "extendedtextinteraction":
//auto closing tag
case "hotspotinteraction":
//all work done during start
break;
case "matchinteraction":
renderElement = true;
break;
default: {
if(renderElement) {
super.endElement(uri, localName, qName);
}
} }
Node responseEl = factory.createCheckbox(checked);
Node wrapEl = factory.wrapInParagraph(responseEl);
checkboxNode.appendChild(wrapEl);
closeCurrentTableRow();
} else if("textentryinteraction".equals(tag)) {
//auto closing tag
} else if("extendedtextinteraction".equals(tag)) {
//auto closing tag
} else if("hotspotinteraction".equals(tag)) {
//all work done during start
} else if("matchinteraction".equals(tag)) {
renderElement = true;
} else if(renderElement) {
super.endElement(uri, localName, qName);
} }
} }
......
...@@ -73,9 +73,9 @@ public class QTI21RuntimeStatisticsController extends BasicController implements ...@@ -73,9 +73,9 @@ public class QTI21RuntimeStatisticsController extends BasicController implements
public QTI21RuntimeStatisticsController(UserRequest ureq, WindowControl wControl, public QTI21RuntimeStatisticsController(UserRequest ureq, WindowControl wControl,
RepositoryEntry testEntry, AssessmentToolOptions asOptions) { RepositoryEntry testEntry, AssessmentToolOptions asOptions) {
super(ureq, wControl); super(ureq, wControl);
this.options = new ArchiveOptions(); options = new ArchiveOptions();
this.options.setGroup(asOptions.getGroup()); options.setGroup(asOptions.getGroup());
this.options.setIdentities(asOptions.getIdentities()); options.setIdentities(asOptions.getIdentities());
searchParams = new QTI21StatisticSearchParams(testEntry, null, null); searchParams = new QTI21StatisticSearchParams(testEntry, null, null);
if(asOptions.getGroup() != null) { if(asOptions.getGroup() != null) {
......
...@@ -177,13 +177,7 @@ public class QTI21StatisticResourceResult implements StatisticResourceResult { ...@@ -177,13 +177,7 @@ public class QTI21StatisticResourceResult implements StatisticResourceResult {
rootTreeNode.setTitle(test.getTitle()); rootTreeNode.setTitle(test.getTitle());
rootTreeNode.setUserObject(test); rootTreeNode.setUserObject(test);
rootTreeNode.setIconCssClass("o_icon o_icon-lg o_qtiassessment_icon"); rootTreeNode.setIconCssClass("o_icon o_icon-lg o_qtiassessment_icon");
buildRecursively(test, rootTreeNode);
//list all test parts
List<TestPart> parts = test.getChildAbstractParts();
int counter = 0;
for(TestPart part:parts) {
buildRecursively(part, ++counter, rootTreeNode);
}
return treeModel; return treeModel;
} }
...@@ -202,13 +196,29 @@ public class QTI21StatisticResourceResult implements StatisticResourceResult { ...@@ -202,13 +196,29 @@ public class QTI21StatisticResourceResult implements StatisticResourceResult {
resolvedAssessmentTest = qtiService.loadAndResolveAssessmentTest(unzippedDirRoot, false); resolvedAssessmentTest = qtiService.loadAndResolveAssessmentTest(unzippedDirRoot, false);
AssessmentTest test = resolvedAssessmentTest.getTestLookup().getRootNodeHolder().getRootNode(); AssessmentTest test = resolvedAssessmentTest.getTestLookup().getRootNodeHolder().getRootNode();
buildRecursively(test, rootTreeNode);
return subTreeModel;
}
private void buildRecursively(AssessmentTest test, GenericTreeNode rootTreeNode) {
//list all test parts //list all test parts
List<TestPart> parts = test.getChildAbstractParts(); List<TestPart> parts = test.getTestParts();
int counter = 0; if(parts.size() == 1) {
for(TestPart part:parts) { TreeNode firstItem = null;
buildRecursively(part, ++counter, rootTreeNode); List<AssessmentSection> sections = test.getTestParts().get(0).getAssessmentSections();
for(AssessmentSection section:sections) {
TreeNode itemNode = buildRecursively(section, rootTreeNode);
if(firstItem == null) {
firstItem = itemNode;
}
}
rootTreeNode.setDelegate(firstItem);
} else {
int counter = 0;
for(TestPart part:parts) {
buildRecursively(part, ++counter, rootTreeNode);
}
} }
return subTreeModel;
} }
private void buildRecursively(TestPart part, int pos, TreeNode parentNode) { private void buildRecursively(TestPart part, int pos, TreeNode parentNode) {
......
...@@ -30,7 +30,7 @@ public class QTI21StatisticsSecurityCallback { ...@@ -30,7 +30,7 @@ public class QTI21StatisticsSecurityCallback {
private boolean anonymousUsers; private boolean anonymousUsers;
private boolean nonParticipantUsers; private boolean nonParticipantUsers;
public QTI21StatisticsSecurityCallback(boolean anonymousUsers, boolean nonParticipantUsers) { public QTI21StatisticsSecurityCallback(boolean nonParticipantUsers, boolean anonymousUsers) {
this.anonymousUsers = anonymousUsers; this.anonymousUsers = anonymousUsers;
this.nonParticipantUsers = nonParticipantUsers; this.nonParticipantUsers = nonParticipantUsers;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment