use of org.olat.ims.qti.container.Output in project OpenOLAT by OpenOLAT.
the class SequentialSectionNavigator method submitItems.
/**
* @see org.olat.qti.process.Navigator#submitItem(org.olat.qti.process.ItemsInput)
*/
public void submitItems(ItemsInput curitsinp) {
clearInfo();
int st = submitMultipleItems(curitsinp);
SectionContext sc = getAssessmentContext().getCurrentSectionContext();
if (st != QTIConstants.SECTION_SUBMITTED) {
// we could not submit the section (out of time is the only reason),
// display a error msg above the next section or assessment-finished-text
getInfo().setError(st);
getInfo().setRenderItems(true);
} else {
// section was successfully submitted
// increase times answered of section
sc.sectionWasSubmitted();
// calculate any section feedback
sc.eval();
if (sc.isFeedbackavailable()) {
Output outp = sc.getOutput();
getInfo().setCurrentOutput(outp);
getInfo().setFeedback(true);
}
getInfo().setMessage(QTIConstants.MESSAGE_SECTION_SUBMITTED);
getInfo().setRenderItems(true);
}
// find next section
AssessmentContext ac = getAssessmentContext();
int secPos = ac.getCurrentSectionContextPos();
int secPosMax = ac.getSectionContextCount() - 1;
if (!ac.isOpen()) {
getInfo().setError(QTIConstants.ERROR_ASSESSMENT_OUTOFTIME);
getInfo().setRenderItems(false);
submitAssessment();
} else if (secPos == secPosMax)
submitAssessment();
else {
while (secPos < secPosMax) {
// there are still further section(s)
secPos++;
if (ac.getSectionContext(secPos).getItemContextCount() != 0)
break;
}
if (secPos == secPosMax && ac.getSectionContext(secPos).getItemContextCount() == 0) {
// reached last section but section is empty -> finish assessment
submitAssessment();
} else {
ac.setCurrentSectionContextPos(secPos);
startSection(ac.getCurrentSectionContext());
}
}
getAssessmentInstance().persist();
}
use of org.olat.ims.qti.container.Output in project OpenOLAT by OpenOLAT.
the class MenuItemNavigator method submitItems.
/**
* @see org.olat.qti.process.Navigator#submitItems(org.olat.qti.container.ItemsInput)
*/
public void submitItems(ItemsInput curitsinp) {
clearInfo();
int st = submitOneItem(curitsinp);
if (st != QTIConstants.ITEM_SUBMITTED) {
// time expired or too many attempts-> display a message above the next item or assessment-finished-text
getInfo().setError(st);
getInfo().setRenderItems(false);
} else {
// ok, eval the whole assessment here each time (so after a submitted item, one sees overall progress)
// getAssessmentContext().eval();
getInfo().setMessage(QTIConstants.MESSAGE_ITEM_SUBMITTED);
getInfo().setRenderItems(false);
ItemContext itc = getAssessmentContext().getCurrentSectionContext().getCurrentItemContext();
// check on section feedbacks
Output outp = itc.getOutput();
if (outp != null)
getInfo().setCurrentOutput(outp);
// check on item feedback
if (itc.isFeedback()) {
// feedback allowed
getInfo().setFeedback(itc.getOutput().hasItem_Responses());
}
if (itc.isHints()) {
// hints allowed
if (itc.getOutput().getHint() != null) {
// feedback existing on item
getInfo().setHint(true);
}
}
if (itc.isSolutions()) {
// solution allowed
if (itc.getOutput().getSolution() != null) {
// solution existing on item
getInfo().setSolution(true);
}
}
}
getAssessmentInstance().persist();
}
use of org.olat.ims.qti.container.Output in project OpenOLAT by OpenOLAT.
the class SequentialItemNavigator method submitItems.
/**
* @see org.olat.ims.qti.navigator.Navigator#submitItems(org.olat.ims.qti.container.ItemsInput)
*/
public void submitItems(ItemsInput curitsinp) {
clearInfo();
AssessmentContext ac = getAssessmentContext();
SectionContext sc = ac.getCurrentSectionContext();
int st = submitOneItem(curitsinp);
if (st != QTIConstants.ITEM_SUBMITTED) {
// item or assessment-finished-text
if (st == QTIConstants.ERROR_SUBMITTEDITEM_TOOMANYATTEMPTS) {
throw new RuntimeException("import check failed: there was a maxattempts in a item, but mode is sequential/item");
} else if (st == QTIConstants.ERROR_ASSESSMENT_OUTOFTIME) {
getInfo().setError(st);
getInfo().setRenderItems(false);
} else if (st == QTIConstants.ERROR_SUBMITTEDITEM_OUTOFTIME) {
getInfo().setError(st);
// still continue to next item
getInfo().setRenderItems(true);
}
} else {
// ok, display feedback
ItemContext itc = getAssessmentContext().getCurrentSectionContext().getCurrentItemContext();
Output outp = itc.getOutput();
if (outp != null)
getInfo().setCurrentOutput(outp);
// check on item feedback
if (itc.isFeedback()) {
// feedback allowed
getInfo().setFeedback(itc.getOutput().hasItem_Responses());
}
getInfo().setMessage(QTIConstants.MESSAGE_ITEM_SUBMITTED);
getInfo().setRenderItems(true);
}
// find next item
int itpos = sc.getCurrentItemContextPos();
if (itpos < sc.getItemContextCount() - 1 && sc.isOpen()) {
// there are still further items in the current section
sc.setCurrentItemContextPos(++itpos);
sc.getCurrentItemContext().start();
} else {
// fetch next section
if (!sc.isOpen()) {
getInfo().setError(QTIConstants.ERROR_SECTION_OUTOFTIME);
getInfo().setRenderItems(true);
}
ac.getCurrentSectionContext().sectionWasSubmitted();
int secPos = ac.getCurrentSectionContextPos();
int secPosMax = ac.getSectionContextCount() - 1;
if (!ac.isOpen()) {
getInfo().setError(QTIConstants.ERROR_ASSESSMENT_OUTOFTIME);
getInfo().setRenderItems(false);
submitAssessment();
} else if (secPos == secPosMax)
submitAssessment();
else {
while (secPos < secPosMax) {
// there are still further section(s)
secPos++;
if (ac.getSectionContext(secPos).getItemContextCount() != 0)
break;
}
if (secPos == secPosMax && ac.getSectionContext(secPos).getItemContextCount() == 0) {
// reached last section but section is empty -> finish assessment
submitAssessment();
} else {
ac.setCurrentSectionContextPos(secPos);
ac.getCurrentSectionContext().setCurrentItemContextPos(0);
ac.getCurrentSectionContext().start();
ac.getCurrentSectionContext().getCurrentItemContext().start();
// since new section starts, show next the section title and description
getInfo().setRenderItems(false);
}
}
}
getAssessmentInstance().persist();
}
use of org.olat.ims.qti.container.Output in project OpenOLAT by OpenOLAT.
the class QTI_respcondition method process.
/**
* Response Condition
*
* ims qti 1.2.1 respcondition
* <!ELEMENT respcondition (qticomment? , conditionvar , setvar* , displayfeedback*)>
* <!ELEMENT conditionvar (not | and | or | unanswered | other | varequal | varlt | varlte |
* vargt | vargte | varsubset | varinside | varsubstring | durequal | durlt | durlte | durgt | durgte)+>
*
* <!ELEMENT setvar (#PCDATA)>
* <!ATTLIST setvar %I_VarName; action (Set | Add | Subtract | Multiply | Divide ) 'Set' >
* mit I_VarName = varname CDATA 'SCORE'
* <setvar action="Set" varname="SCORE">10</setvar>
*
* <!ELEMENT displayfeedback (#PCDATA)>
* <!ATTLIST displayfeedback feedbacktype (Response | Solution | Hint ) 'Response'
* %I_LinkRefId; >
* mit I_LinkRefId = linkrefid CDATA #REQUIRED"
* e.g. <displayfeedback feedbacktype = "Solution" linkrefid = "CorrectSoln"/>
*
* ??? should be ? ? <conditionvar><or>...</or><varequal>...</varequal></conditionvar> does not make sense
* but <conditionvar>
* <varequal respident = "Word-1">KITTENS</varequal>
* <varequal respident = "Word-2">HATS</varequal>
* </conditionvar> makes sense, so treat members of conditionvar as children of an "and" element
* @param node_respcond
*/
public boolean process(Element el_respcond, ItemContext itc, EvalContext ect) {
// 1. evaluate conditionvar
// 2. if true, set variables
// and setCurrentDisplayFeedback (TODO: assuming there is only one displayfeedback in a respcondition)
Variables vars;
Element el_condVar = (Element) el_respcond.selectSingleNode("conditionvar");
String respcondtitle = el_respcond.attributeValue("title");
QTI_and qtiAnd = QTIHelper.getQTI_and();
boolean fulfilled = qtiAnd.eval(el_condVar, itc, ect);
// continue to set variables and display feedback if question was answered correctly
if (fulfilled) {
vars = itc.getVariables();
List setvars = el_respcond.selectNodes("setvar");
for (Iterator iter = setvars.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
String action = element.attributeValue("action");
String varName = element.attributeValue("varname");
if (varName == null)
varName = "SCORE";
varName.trim();
String varVal = element.getText();
Variable var = vars.getVariable(varName);
if (var == null)
throw new RuntimeException("var " + varName + " is in setvar, but was not declared ");
if (action.equals("Set")) {
var.setValue(varVal);
} else {
// Add | Subtract | Multiply | Divide
if (action.equals("Add")) {
var.add(varVal);
} else if (action.equals("Subtract")) {
var.subtract(varVal);
} else if (action.equals("Multiply")) {
var.multiply(varVal);
} else if (action.equals("Divide")) {
var.divide(varVal);
}
}
}
// set displayfeedback
// <displayfeedback feedbacktype = "Response" linkrefid = "Correct"/>
// <!ATTLIST displayfeedback feedbacktype (Response | Solution | Hint ) 'Response' %I_LinkRefId; >
Output output = itc.getOutput();
List fbs = el_respcond.selectNodes("displayfeedback");
for (Iterator it_fbs = fbs.iterator(); it_fbs.hasNext(); ) {
Element el_dispfb = (Element) it_fbs.next();
// must exist (dtd)
String linkRefId = el_dispfb.attributeValue("linkrefid");
// must exist (dtd)
String feedbacktype = el_dispfb.attributeValue("feedbacktype");
Element el_resolved = (Element) itc.getEl_item().selectSingleNode(".//itemfeedback[@ident='" + linkRefId + "']");
if (el_resolved == null)
continue;
if (feedbacktype.equals("Response")) {
// additional (olat) rule:
// we want to render the original answer again in the simple case where the respcondition was generated
// by the olat export and contains only one varequal.
/*
<response_label ident = "2">
<flow_mat>
<material>
<mattext texttype="text/html">...</mattext>
</material>
</flow_mat>
</response_label>
...
<respcondition title="_olat_resp_feedback" continue="Yes">
<conditionvar>
<varequal respident="Frage6549" case="Yes">2</varequal>
</conditionvar>
<displayfeedback linkrefid="2"/>
</respcondition>
In this case, it is possible (and wished) to trace the feedback back to the answer which triggered this feedback.
Such a respcondition is identified by the title which is exactly "_olat_resp_feedback".
*/
Element el_chosenanswer = null;
if (respcondtitle != null && respcondtitle.equals("_olat_resp_feedback")) {
Element el_vareq = (Element) el_respcond.selectSingleNode(".//varequal");
String answerident = el_vareq.getText();
el_chosenanswer = (Element) itc.getEl_item().selectSingleNode(".//response_label[@ident='" + answerident + "']//material");
}
// give the whole itemfeedback to render
output.addItem_El_response(el_chosenanswer, el_resolved);
} else if (feedbacktype.equals("Solution")) {
Element el_solution = (Element) el_resolved.selectSingleNode(".//solution");
if (el_solution != null)
output.setSolution(new Solution(el_solution));
} else if (feedbacktype.equals("Hint")) {
// <!ENTITY % I_FeedbackStyle " feedbackstyle (Complete | Incremental | Multilevel | Proprietary ) 'Complete'">
Element el_hint = (Element) el_resolved.selectSingleNode(".//hint");
output.setHint(new Hint(el_hint));
}
}
}
return fulfilled;
}
use of org.olat.ims.qti.container.Output in project openolat by klemens.
the class QTI_respcondition method process.
/**
* Response Condition
*
* ims qti 1.2.1 respcondition
* <!ELEMENT respcondition (qticomment? , conditionvar , setvar* , displayfeedback*)>
* <!ELEMENT conditionvar (not | and | or | unanswered | other | varequal | varlt | varlte |
* vargt | vargte | varsubset | varinside | varsubstring | durequal | durlt | durlte | durgt | durgte)+>
*
* <!ELEMENT setvar (#PCDATA)>
* <!ATTLIST setvar %I_VarName; action (Set | Add | Subtract | Multiply | Divide ) 'Set' >
* mit I_VarName = varname CDATA 'SCORE'
* <setvar action="Set" varname="SCORE">10</setvar>
*
* <!ELEMENT displayfeedback (#PCDATA)>
* <!ATTLIST displayfeedback feedbacktype (Response | Solution | Hint ) 'Response'
* %I_LinkRefId; >
* mit I_LinkRefId = linkrefid CDATA #REQUIRED"
* e.g. <displayfeedback feedbacktype = "Solution" linkrefid = "CorrectSoln"/>
*
* ??? should be ? ? <conditionvar><or>...</or><varequal>...</varequal></conditionvar> does not make sense
* but <conditionvar>
* <varequal respident = "Word-1">KITTENS</varequal>
* <varequal respident = "Word-2">HATS</varequal>
* </conditionvar> makes sense, so treat members of conditionvar as children of an "and" element
* @param node_respcond
*/
public boolean process(Element el_respcond, ItemContext itc, EvalContext ect) {
// 1. evaluate conditionvar
// 2. if true, set variables
// and setCurrentDisplayFeedback (TODO: assuming there is only one displayfeedback in a respcondition)
Variables vars;
Element el_condVar = (Element) el_respcond.selectSingleNode("conditionvar");
String respcondtitle = el_respcond.attributeValue("title");
QTI_and qtiAnd = QTIHelper.getQTI_and();
boolean fulfilled = qtiAnd.eval(el_condVar, itc, ect);
// continue to set variables and display feedback if question was answered correctly
if (fulfilled) {
vars = itc.getVariables();
List setvars = el_respcond.selectNodes("setvar");
for (Iterator iter = setvars.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
String action = element.attributeValue("action");
String varName = element.attributeValue("varname");
if (varName == null)
varName = "SCORE";
varName.trim();
String varVal = element.getText();
Variable var = vars.getVariable(varName);
if (var == null)
throw new RuntimeException("var " + varName + " is in setvar, but was not declared ");
if (action.equals("Set")) {
var.setValue(varVal);
} else {
// Add | Subtract | Multiply | Divide
if (action.equals("Add")) {
var.add(varVal);
} else if (action.equals("Subtract")) {
var.subtract(varVal);
} else if (action.equals("Multiply")) {
var.multiply(varVal);
} else if (action.equals("Divide")) {
var.divide(varVal);
}
}
}
// set displayfeedback
// <displayfeedback feedbacktype = "Response" linkrefid = "Correct"/>
// <!ATTLIST displayfeedback feedbacktype (Response | Solution | Hint ) 'Response' %I_LinkRefId; >
Output output = itc.getOutput();
List fbs = el_respcond.selectNodes("displayfeedback");
for (Iterator it_fbs = fbs.iterator(); it_fbs.hasNext(); ) {
Element el_dispfb = (Element) it_fbs.next();
// must exist (dtd)
String linkRefId = el_dispfb.attributeValue("linkrefid");
// must exist (dtd)
String feedbacktype = el_dispfb.attributeValue("feedbacktype");
Element el_resolved = (Element) itc.getEl_item().selectSingleNode(".//itemfeedback[@ident='" + linkRefId + "']");
if (el_resolved == null)
continue;
if (feedbacktype.equals("Response")) {
// additional (olat) rule:
// we want to render the original answer again in the simple case where the respcondition was generated
// by the olat export and contains only one varequal.
/*
<response_label ident = "2">
<flow_mat>
<material>
<mattext texttype="text/html">...</mattext>
</material>
</flow_mat>
</response_label>
...
<respcondition title="_olat_resp_feedback" continue="Yes">
<conditionvar>
<varequal respident="Frage6549" case="Yes">2</varequal>
</conditionvar>
<displayfeedback linkrefid="2"/>
</respcondition>
In this case, it is possible (and wished) to trace the feedback back to the answer which triggered this feedback.
Such a respcondition is identified by the title which is exactly "_olat_resp_feedback".
*/
Element el_chosenanswer = null;
if (respcondtitle != null && respcondtitle.equals("_olat_resp_feedback")) {
Element el_vareq = (Element) el_respcond.selectSingleNode(".//varequal");
String answerident = el_vareq.getText();
el_chosenanswer = (Element) itc.getEl_item().selectSingleNode(".//response_label[@ident='" + answerident + "']//material");
}
// give the whole itemfeedback to render
output.addItem_El_response(el_chosenanswer, el_resolved);
} else if (feedbacktype.equals("Solution")) {
Element el_solution = (Element) el_resolved.selectSingleNode(".//solution");
if (el_solution != null)
output.setSolution(new Solution(el_solution));
} else if (feedbacktype.equals("Hint")) {
// <!ENTITY % I_FeedbackStyle " feedbackstyle (Complete | Incremental | Multilevel | Proprietary ) 'Complete'">
Element el_hint = (Element) el_resolved.selectSingleNode(".//hint");
output.setHint(new Hint(el_hint));
}
}
}
return fulfilled;
}
Aggregations