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

OO-1593: convert FIB from QTI 1.2, create FIB in question pool

parent 16ad045c
No related branches found
No related tags found
No related merge requests found
...@@ -31,7 +31,7 @@ public enum QTI21QuestionType { ...@@ -31,7 +31,7 @@ public enum QTI21QuestionType {
sc(true, "sc", QuestionType.SC), sc(true, "sc", QuestionType.SC),
mc(true, "mc", QuestionType.MC), mc(true, "mc", QuestionType.MC),
kprim(true, "kprim", QuestionType.KPRIM), kprim(true, "kprim", QuestionType.KPRIM),
fib(false, "fib", QuestionType.FIB), fib(true, "fib", QuestionType.FIB),
essay(true, "essay", QuestionType.ESSAY), essay(true, "essay", QuestionType.ESSAY),
unkown(false, null, null); unkown(false, null, null);
......
...@@ -143,6 +143,7 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder { ...@@ -143,6 +143,7 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder {
private void extractTextEntrySettingsFromResponseDeclaration() { private void extractTextEntrySettingsFromResponseDeclaration() {
double mappedScore = 0.0d; double mappedScore = 0.0d;
int countAlternatives = 0;
for(Map.Entry<String, TextEntry> textEntryEntry:responseIdentifierToTextEntry.entrySet()) { for(Map.Entry<String, TextEntry> textEntryEntry:responseIdentifierToTextEntry.entrySet()) {
TextEntry textEntry = textEntryEntry.getValue(); TextEntry textEntry = textEntryEntry.getValue();
...@@ -187,10 +188,11 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder { ...@@ -187,10 +188,11 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder {
alternative.setAlternative(alt); alternative.setAlternative(alt);
alternative.setScore(mapEntry.getMappedValue()); alternative.setScore(mapEntry.getMappedValue());
alternatives.add(alternative); alternatives.add(alternative);
mappedScore += mapEntry.getMappedValue();
} else if(alt.equals(solution)) { } else if(alt.equals(solution)) {
textEntry.setScore(mapEntry.getMappedValue()); textEntry.setScore(mapEntry.getMappedValue());
} }
countAlternatives++;
mappedScore += mapEntry.getMappedValue();
} }
caseSensitive &= mapEntry.getCaseSensitive(); caseSensitive &= mapEntry.getCaseSensitive();
...@@ -202,7 +204,7 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder { ...@@ -202,7 +204,7 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder {
} }
} }
boolean hasMapping = mappedScore > (-1.0 * responseIdentifierToTextEntry.size()); boolean hasMapping = Math.abs(mappedScore - (-1.0 * countAlternatives)) > 0.0001;
scoreEvaluation = hasMapping ? ScoreEvaluation.perAnswer : ScoreEvaluation.allCorrectAnswers; scoreEvaluation = hasMapping ? ScoreEvaluation.perAnswer : ScoreEvaluation.allCorrectAnswers;
} }
......
...@@ -37,7 +37,9 @@ import org.olat.ims.qti.editor.beecom.objects.Control; ...@@ -37,7 +37,9 @@ import org.olat.ims.qti.editor.beecom.objects.Control;
import org.olat.ims.qti.editor.beecom.objects.Duration; import org.olat.ims.qti.editor.beecom.objects.Duration;
import org.olat.ims.qti.editor.beecom.objects.EssayQuestion; import org.olat.ims.qti.editor.beecom.objects.EssayQuestion;
import org.olat.ims.qti.editor.beecom.objects.EssayResponse; import org.olat.ims.qti.editor.beecom.objects.EssayResponse;
import org.olat.ims.qti.editor.beecom.objects.FIBResponse;
import org.olat.ims.qti.editor.beecom.objects.Item; import org.olat.ims.qti.editor.beecom.objects.Item;
import org.olat.ims.qti.editor.beecom.objects.Material;
import org.olat.ims.qti.editor.beecom.objects.OutcomesProcessing; import org.olat.ims.qti.editor.beecom.objects.OutcomesProcessing;
import org.olat.ims.qti.editor.beecom.objects.QTIDocument; import org.olat.ims.qti.editor.beecom.objects.QTIDocument;
import org.olat.ims.qti.editor.beecom.objects.Question; import org.olat.ims.qti.editor.beecom.objects.Question;
...@@ -57,6 +59,7 @@ import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder; ...@@ -57,6 +59,7 @@ import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder;
import org.olat.ims.qti21.model.xml.interactions.ChoiceAssessmentItemBuilder.ScoreEvaluation; import org.olat.ims.qti21.model.xml.interactions.ChoiceAssessmentItemBuilder.ScoreEvaluation;
import org.olat.ims.qti21.model.xml.interactions.EssayAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.EssayAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.FIBAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.FIBAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.FIBAssessmentItemBuilder.TextEntry;
import org.olat.ims.qti21.model.xml.interactions.KPrimAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.KPrimAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder;
...@@ -133,6 +136,14 @@ public class QTI12To21Converter { ...@@ -133,6 +136,14 @@ public class QTI12To21Converter {
} }
AssessmentTestBuilder assessmentTestBuilder = new AssessmentTestBuilder(assessmentTest); AssessmentTestBuilder assessmentTestBuilder = new AssessmentTestBuilder(assessmentTest);
assessmentTestBuilder.setExportScore(true);
//root
List<Section> sections = assessment.getSections();
for(Section section:sections) {
convert(section, testPart);
}
//this are lost in QTI 2.1 //this are lost in QTI 2.1
//assessment.getSelection_ordering().getOrderType(); //assessment.getSelection_ordering().getOrderType();
//assessment.getSelection_ordering().getSelectionNumber(); //assessment.getSelection_ordering().getSelectionNumber();
...@@ -148,12 +159,6 @@ public class QTI12To21Converter { ...@@ -148,12 +159,6 @@ public class QTI12To21Converter {
} }
} }
//root
List<Section> sections = assessment.getSections();
for(Section section:sections) {
convert(section, testPart);
}
assessmentTest = assessmentTestBuilder.build(); assessmentTest = assessmentTestBuilder.build();
persistAssessmentObject(testFile, assessmentTest); persistAssessmentObject(testFile, assessmentTest);
manifest.write(new File(unzippedDirRoot, "imsmanifest.xml")); manifest.write(new File(unzippedDirRoot, "imsmanifest.xml"));
...@@ -193,10 +198,10 @@ public class QTI12To21Converter { ...@@ -193,10 +198,10 @@ public class QTI12To21Converter {
break; break;
case Question.TYPE_KPRIM: case Question.TYPE_KPRIM:
itemBuilder = convertKPrim(item); itemBuilder = convertKPrim(item);
break;/* break;
case Question.TYPE_FIB: case Question.TYPE_FIB:
itemBuilder = convertFIB(item); itemBuilder = convertFIB(item);
break;*/ break;
case Question.TYPE_ESSAY: case Question.TYPE_ESSAY:
itemBuilder = convertEssay(item); itemBuilder = convertEssay(item);
break; break;
...@@ -210,6 +215,7 @@ public class QTI12To21Converter { ...@@ -210,6 +215,7 @@ public class QTI12To21Converter {
AssessmentItemRef itemRef = new AssessmentItemRef(assessmentSection); AssessmentItemRef itemRef = new AssessmentItemRef(assessmentSection);
String itemId = IdentifierGenerator.newAsString(itemBuilder.getQuestionType().getPrefix()); String itemId = IdentifierGenerator.newAsString(itemBuilder.getQuestionType().getPrefix());
itemRef.setIdentifier(Identifier.parseString(itemId)); itemRef.setIdentifier(Identifier.parseString(itemId));
convertItemBasics(item, itemRef);
File itemFile = new File(unzippedDirRoot, itemId + ".xml"); File itemFile = new File(unzippedDirRoot, itemId + ".xml");
itemRef.setHref(new URI(itemFile.getName())); itemRef.setHref(new URI(itemFile.getName()));
assessmentSection.getSectionParts().add(itemRef); assessmentSection.getSectionParts().add(itemRef);
...@@ -219,6 +225,36 @@ public class QTI12To21Converter { ...@@ -219,6 +225,36 @@ public class QTI12To21Converter {
} }
} }
private void convertItemBasics(Item item, AssessmentItemRef itemRef) {
if(item.getMaxattempts() > 0) {
ItemSessionControl itemSessionControl = itemRef.getItemSessionControl();
if(itemSessionControl == null) {
itemSessionControl = new ItemSessionControl(itemRef);
itemRef.setItemSessionControl(itemSessionControl);
}
itemSessionControl.setMaxAttempts(item.getMaxattempts());
}
if(item.getDuration() != null && item.getDuration().isSet()) {
TimeLimits timeLimits = itemRef.getTimeLimits();
if(timeLimits == null) {
timeLimits = new TimeLimits(itemRef);
itemRef.setTimeLimits(timeLimits);
}
timeLimits.setMinimum(0.0d);
double max = 0.0d;
if(item.getDuration().getMin() > 0) {
max += item.getDuration().getMin() * 60d;
}
if(item.getDuration().getSec() > 0) {
max += item.getDuration().getSec();
}
timeLimits.setMaximum(max);
}
}
private void appendResourceAndMetadata(Item item, AssessmentItemBuilder itemBuilder, File itemFile) { private void appendResourceAndMetadata(Item item, AssessmentItemBuilder itemBuilder, File itemFile) {
manifest.appendAssessmentItem(itemFile.getName()); manifest.appendAssessmentItem(itemFile.getName());
ManifestMetadataBuilder metadata = manifest.getResourceBuilderByHref(itemFile.getName()); ManifestMetadataBuilder metadata = manifest.getResourceBuilderByHref(itemFile.getName());
...@@ -344,12 +380,67 @@ public class QTI12To21Converter { ...@@ -344,12 +380,67 @@ public class QTI12To21Converter {
private AssessmentItemBuilder convertFIB(Item item) { private AssessmentItemBuilder convertFIB(Item item) {
FIBAssessmentItemBuilder itemBuilder = new FIBAssessmentItemBuilder(qtiSerializer); FIBAssessmentItemBuilder itemBuilder = new FIBAssessmentItemBuilder(qtiSerializer);
itemBuilder.setQuestion("");
itemBuilder.clearTextEntries();
convertItemBasics(item, itemBuilder); convertItemBasics(item, itemBuilder);
Question question = item.getQuestion();
boolean singleCorrect = question.isSingleCorrect();
if(singleCorrect) {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.allCorrectAnswers);
} else {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.perAnswer);
}
itemBuilder.getMinScoreBuilder().setScore(new Double(question.getMinValue()));
itemBuilder.getMaxScoreBuilder().setScore(new Double(question.getMaxValue()));
List<Response> responses = question.getResponses();
StringBuilder sb = new StringBuilder();
for(Response response:responses) {
if(response instanceof FIBResponse) {
FIBResponse gap = (FIBResponse)response;
if(FIBResponse.TYPE_BLANK.equals(gap.getType())) {
String responseId = itemBuilder.generateResponseIdentifier();
TextEntry entry = itemBuilder.createTextEntry(responseId);
entry.setCaseSensitive("Yes".equals(gap.getCaseSensitive()));
if(gap.getMaxLength() > 0) {
entry.setExpectedLength(gap.getMaxLength());
} else if(gap.getSize() > 0) {
entry.setExpectedLength(gap.getSize());
}
parseAlternatives(gap.getCorrectBlank(), gap.getPoints(), entry);
String entryString = " <textEntryInteraction responseIdentifier=\"" + responseId + "\"/>";
sb.append(entryString);
} else if(FIBResponse.TYPE_CONTENT.equals(gap.getType())) {
Material text = gap.getContent();
String htmltext = text.renderAsHtmlForEditor();
sb.append(htmltext);
}
}
}
String fib = sb.toString();
if(!fib.startsWith("<p") && !fib.startsWith("<div")) {
fib = "<p>" + fib + "</p>";
}
itemBuilder.setQuestion(fib);
return itemBuilder; return itemBuilder;
} }
private void parseAlternatives(String value, double score, TextEntry textEntry) {
String[] values = value.split(";");
if(values.length > 0) {
textEntry.setSolution(values[0]);
textEntry.setScore(score);
}
if(values.length > 1) {
for(int i=1; i<values.length; i++) {
textEntry.addAlterantive(values[i], score);
}
}
}
private AssessmentItemBuilder convertEssay(Item item) { private AssessmentItemBuilder convertEssay(Item item) {
EssayAssessmentItemBuilder itemBuilder = new EssayAssessmentItemBuilder(qtiSerializer); EssayAssessmentItemBuilder itemBuilder = new EssayAssessmentItemBuilder(qtiSerializer);
convertItemBasics(item, itemBuilder); convertItemBasics(item, itemBuilder);
...@@ -376,14 +467,6 @@ public class QTI12To21Converter { ...@@ -376,14 +467,6 @@ public class QTI12To21Converter {
if(StringHelper.containsNonWhitespace(item.getLabel())) { if(StringHelper.containsNonWhitespace(item.getLabel())) {
assessmentItem.setLabel(item.getLabel()); assessmentItem.setLabel(item.getLabel());
} }
if(StringHelper.containsNonWhitespace(item.getObjectives())) {
//metadata description item.getObjectives()
}
if(item.getMaxattempts() > 0
|| (item.getDuration() != null && item.getDuration().isSet())) {
//not supported
}
Question question = item.getQuestion(); Question question = item.getQuestion();
String questionText = question.getQuestion().renderAsHtmlForEditor(); String questionText = question.getQuestion().renderAsHtmlForEditor();
......
...@@ -53,7 +53,7 @@ public class QTI21AssessmentItemFactory implements QItemFactory { ...@@ -53,7 +53,7 @@ public class QTI21AssessmentItemFactory implements QItemFactory {
case sc: return "QTI 2.1 " + trans.translate("new.sc"); case sc: return "QTI 2.1 " + trans.translate("new.sc");
case mc: return "QTI 2.1 " + trans.translate("new.mc"); case mc: return "QTI 2.1 " + trans.translate("new.mc");
case kprim: return "QTI 2.1 " + trans.translate("new.kprim"); case kprim: return "QTI 2.1 " + trans.translate("new.kprim");
//case fib: return "QTI 2.1 " + trans.translate("item.type.fib"); case fib: return "QTI 2.1 " + trans.translate("new.fib");
case essay: return "QTI 2.1 " + trans.translate("new.essay"); case essay: return "QTI 2.1 " + trans.translate("new.essay");
default: return type.name(); default: return type.name();
} }
......
...@@ -30,7 +30,6 @@ import java.util.Locale; ...@@ -30,7 +30,6 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import org.olat.core.commons.persistence.DB;
import org.olat.core.gui.UserRequest; import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.WindowControl;
...@@ -54,6 +53,7 @@ import org.olat.ims.qti21.model.xml.AssessmentItemBuilder; ...@@ -54,6 +53,7 @@ import org.olat.ims.qti21.model.xml.AssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.AssessmentItemMetadata; import org.olat.ims.qti21.model.xml.AssessmentItemMetadata;
import org.olat.ims.qti21.model.xml.ManifestBuilder; import org.olat.ims.qti21.model.xml.ManifestBuilder;
import org.olat.ims.qti21.model.xml.interactions.EssayAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.EssayAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.FIBAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.KPrimAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.KPrimAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder;
...@@ -95,8 +95,6 @@ public class QTI21QPoolServiceProvider implements QPoolSPI { ...@@ -95,8 +95,6 @@ public class QTI21QPoolServiceProvider implements QPoolSPI {
public static final String QTI_12_OO_TEST = "OpenOLAT Test"; public static final String QTI_12_OO_TEST = "OpenOLAT Test";
@Autowired
private DB dbInstance;
@Autowired @Autowired
private QTI21Service qtiService; private QTI21Service qtiService;
...@@ -240,7 +238,7 @@ public class QTI21QPoolServiceProvider implements QPoolSPI { ...@@ -240,7 +238,7 @@ public class QTI21QPoolServiceProvider implements QPoolSPI {
case sc: itemBuilder = new SingleChoiceAssessmentItemBuilder(qtiService.qtiSerializer()); break; case sc: itemBuilder = new SingleChoiceAssessmentItemBuilder(qtiService.qtiSerializer()); break;
case mc: itemBuilder = new MultipleChoiceAssessmentItemBuilder(qtiService.qtiSerializer()); break; case mc: itemBuilder = new MultipleChoiceAssessmentItemBuilder(qtiService.qtiSerializer()); break;
case kprim: itemBuilder = new KPrimAssessmentItemBuilder(qtiService.qtiSerializer()); break; case kprim: itemBuilder = new KPrimAssessmentItemBuilder(qtiService.qtiSerializer()); break;
//case fib: item = QTIEditHelper.createFIBItem(trans); break; case fib: itemBuilder = new FIBAssessmentItemBuilder(qtiService.qtiSerializer()); break;
case essay: itemBuilder = new EssayAssessmentItemBuilder(qtiService.qtiSerializer()); break; case essay: itemBuilder = new EssayAssessmentItemBuilder(qtiService.qtiSerializer()); break;
default: return null; default: return null;
} }
......
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