Skip to content

Commit

Permalink
Default values in use when no Mapping.
Browse files Browse the repository at this point in the history
  • Loading branch information
= committed Jan 12, 2016
1 parent ded0c88 commit 87e9604
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 105 deletions.
88 changes: 43 additions & 45 deletions src/qtism/runtime/expressions/MapResponsePointProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2013-2014 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
* Copyright (c) 2013-2016 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
* @author Jérôme Bogaerts <[email protected]>
* @license GPLv2
Expand Down Expand Up @@ -73,66 +73,64 @@ public function process()
if ($var instanceof ResponseVariable) {
$areaMapping = $var->getAreaMapping();

if (!is_null($areaMapping)) {
if (is_null($areaMapping)) {
return new QtiFloat(0.0);
}

// Correct cardinality ?
if ($var->getBaseType() === BaseType::POINT && ($var->isSingle() || $var->isMultiple())) {
// Correct cardinality ?
if ($var->getBaseType() === BaseType::POINT && ($var->isSingle() || $var->isMultiple())) {

// We can begin!
// We can begin!

// -- Null value, nothing will match
if ($var->isNull()) {
return new QtiFloat($areaMapping->getDefaultValue());
}
// -- Null value, nothing will match
if ($var->isNull()) {
return new QtiFloat($areaMapping->getDefaultValue());
}

if ($var->isSingle()) {
$val = new MultipleContainer(BaseType::POINT, array($state[$identifier]));
} else {
$val = $state[$identifier];
}
if ($var->isSingle()) {
$val = new MultipleContainer(BaseType::POINT, array($state[$identifier]));
} else {
$val = $state[$identifier];
}

$result = 0;
$mapped = array();
$result = 0;
$mapped = array();

foreach ($val as $point) {
foreach ($areaMapping->getAreaMapEntries() as $areaMapEntry) {
foreach ($val as $point) {
foreach ($areaMapping->getAreaMapEntries() as $areaMapEntry) {

$coords = $areaMapEntry->getCoords();
$coords = $areaMapEntry->getCoords();

if (!in_array($coords, $mapped) && $coords->inside($point)) {
$mapped[] = $coords;
$result += $areaMapEntry->getMappedValue();
}
if (!in_array($coords, $mapped) && $coords->inside($point)) {
$mapped[] = $coords;
$result += $areaMapEntry->getMappedValue();
}
}
}

// If no relevant mapping found, return the default.
if (count($mapped) === 0) {
return new QtiFloat($areaMapping->getDefaultValue());
} else {
// Check upper and lower bound.
if ($areaMapping->hasLowerBound() && $result < $areaMapping->getLowerBound()) {
return new QtiFloat($areaMapping->getLowerBound());
} elseif ($areaMapping->hasUpperBound() && $result > $areaMapping->getUpperBound()) {
return new QtiFloat($areaMapping->getUpperBound());
} else {
return new QtiFloat(floatval($result));
}
}
// If no relevant mapping found, return the default.
if (count($mapped) === 0) {
return new QtiFloat($areaMapping->getDefaultValue());
} else {
if ($var->isRecord()) {
$msg = "The MapResponsePoint expression cannot be applied to RECORD variables.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_CARDINALITY);
// Check upper and lower bound.
if ($areaMapping->hasLowerBound() && $result < $areaMapping->getLowerBound()) {
return new QtiFloat($areaMapping->getLowerBound());
} elseif ($areaMapping->hasUpperBound() && $result > $areaMapping->getUpperBound()) {
return new QtiFloat($areaMapping->getUpperBound());
} else {
$strBaseType = BaseType::getNameByConstant($var->getBaseType());
$msg = "The MapResponsePoint expression applies only on variables with baseType 'point', baseType '${strBaseType}' given.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
return new QtiFloat(floatval($result));
}
}
} else {
$msg = "Variable with identifier '${identifier}' has no areaMapping.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::INCONSISTENT_VARIABLE);
}
if ($var->isRecord()) {
$msg = "The MapResponsePoint expression cannot be applied to RECORD variables.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_CARDINALITY);
} else {
$strBaseType = BaseType::getNameByConstant($var->getBaseType());
$msg = "The MapResponsePoint expression applies only on variables with baseType 'point', baseType '${strBaseType}' given.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
}
}
} else {
$msg = "The variable with identifier '${identifier}' is not a ResponseVariable.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_TYPE);
Expand Down
109 changes: 54 additions & 55 deletions src/qtism/runtime/expressions/MapResponseProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2013-2014 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
* Copyright (c) 2013-2016 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
* @author Jérôme Bogaerts <[email protected]>
* @license GPLv2
Expand Down Expand Up @@ -78,89 +78,88 @@ public function process()

$mapping = $variable->getMapping();

if (!is_null($mapping)) {
if (is_null($mapping)) {
return new QtiFloat(0.0);
}

if ($variable->isSingle()) {
if ($variable->isSingle()) {

foreach ($mapping->getMapEntries() as $mapEntry) {
foreach ($mapping->getMapEntries() as $mapEntry) {

$val = $state[$identifier];
$mapKey = $mapEntry->getMapKey();
$val = $state[$identifier];
$mapKey = $mapEntry->getMapKey();

if ($val instanceof QtiString && $mapEntry->isCaseSensitive() === false) {
$val = mb_strtolower($val->getValue(), 'UTF-8');
$mapKey = mb_strtolower($mapKey, 'UTF-8');
}
if ($val instanceof QtiString && $mapEntry->isCaseSensitive() === false) {
$val = mb_strtolower($val->getValue(), 'UTF-8');
$mapKey = mb_strtolower($mapKey, 'UTF-8');
}

if ($val instanceof Comparable && $val->equals($mapKey) || $val === $mapKey) {
// relevant mapping found.
$mappedValue = $mapEntry->getMappedValue();
if ($val instanceof Comparable && $val->equals($mapKey) || $val === $mapKey) {
// relevant mapping found.
$mappedValue = $mapEntry->getMappedValue();

return new QtiFloat($mappedValue);
}
return new QtiFloat($mappedValue);
}
}

// No relevant mapping found, return mapping default.
return new QtiFloat($mapping->getDefaultValue());
} elseif ($variable->isMultiple()) {

$result = 0.0;
// No relevant mapping found, return mapping default.
return new QtiFloat($mapping->getDefaultValue());
} elseif ($variable->isMultiple()) {

if (!is_null($variable->getValue())) {
$mapped = array(); // already mapped keys.
$mapEntries = $mapping->getMapEntries();
$result = 0.0;

foreach ($variable->getValue() as $val) {
if (!is_null($variable->getValue())) {
$mapped = array(); // already mapped keys.
$mapEntries = $mapping->getMapEntries();

for ($i = 0; $i < count($mapEntries); $i++) {
foreach ($variable->getValue() as $val) {

$mapKey = $rawMapKey = $mapEntries[$i]->getMapKey();
for ($i = 0; $i < count($mapEntries); $i++) {

if ($val instanceof QtiString && $mapEntries[$i]->isCaseSensitive() === false) {
$val = mb_strtolower($val->getValue(), 'UTF-8');
$mapKey = mb_strtolower($mapKey, 'UTF-8');
}
$mapKey = $rawMapKey = $mapEntries[$i]->getMapKey();

if (($val instanceof Comparable && $val->equals($mapKey) === true) || $val === $mapKey) {
if (in_array($rawMapKey, $mapped, true) === false) {
$result += $mapEntries[$i]->getMappedValue();
$mapped[] = $rawMapKey;
if ($val instanceof QtiString && $mapEntries[$i]->isCaseSensitive() === false) {
$val = mb_strtolower($val->getValue(), 'UTF-8');
$mapKey = mb_strtolower($mapKey, 'UTF-8');
}

}
// else...
// This value has already been mapped.
if (($val instanceof Comparable && $val->equals($mapKey) === true) || $val === $mapKey) {
if (in_array($rawMapKey, $mapped, true) === false) {
$result += $mapEntries[$i]->getMappedValue();
$mapped[] = $rawMapKey;

break;
}
}
// else...
// This value has already been mapped.

if ($i >= count($mapEntries)) {
// No explicit mapping found for source value $val.
$result += $mapping->getDefaultValue();
break;
}
}

// When mapping a container, try to apply lower or upper bound.
if ($mapping->hasLowerBound() && $result < $mapping->getLowerBound()) {
return new QtiFloat($mapping->getLowerBound());
} elseif ($mapping->hasUpperBound() && $result > $mapping->getUpperBound()) {
return new QtiFloat($mapping->getUpperBound());
} else {
return new QtiFloat($result);
if ($i >= count($mapEntries)) {
// No explicit mapping found for source value $val.
$result += $mapping->getDefaultValue();
}
}

// When mapping a container, try to apply lower or upper bound.
if ($mapping->hasLowerBound() && $result < $mapping->getLowerBound()) {
return new QtiFloat($mapping->getLowerBound());
} elseif ($mapping->hasUpperBound() && $result > $mapping->getUpperBound()) {
return new QtiFloat($mapping->getUpperBound());
} else {
// Returns a 0.0 result.
return new QtiFloat($result);
}

} else {
$msg = "MapResponse cannot be applied on a RECORD container.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
// Returns a 0.0 result.
return new QtiFloat($result);
}

} else {
$msg = "The target variable has no mapping while processing MapResponse.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::INCONSISTENT_VARIABLE);
$msg = "MapResponse cannot be applied on a RECORD container.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
}

} else {
$msg = "The target variable must be a ResponseVariable, OutcomeVariable given while processing MapResponse.";
throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public function testWrongBaseType() {
}

public function testNoAreaMapping() {
// When no areaMapping is found, we consider a default value of 0.0.
$expr = $this->createComponentFromXml('<mapResponsePoint identifier="response1"/>');
$variableDeclaration = $this->createComponentFromXml('
<responseDeclaration identifier="response1" baseType="integer" cardinality="single"/>
Expand All @@ -159,8 +160,8 @@ public function testNoAreaMapping() {
$processor = new MapResponsePointProcessor($expr);
$processor->setState(new State(array($variable)));

$this->setExpectedException("qtism\\runtime\\expressions\\ExpressionProcessingException");
$result = $processor->process();
$this->assertEquals(0.0, $result->getValue());
}

public function testWrongVariableType() {
Expand Down Expand Up @@ -234,4 +235,4 @@ public function testWithRecord() {
$this->setExpectedException('qtism\\runtime\\expressions\\ExpressionProcessingException', 'The MapResponsePoint expression cannot be applied to RECORD variables.', ExpressionProcessingException::WRONG_VARIABLE_CARDINALITY);
$result = $processor->process();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,15 @@ public function testVariableNotDefined() {
}

public function testNoMapping() {
$this->setExpectedException("qtism\\runtime\\expressions\\ExpressionProcessingException");
// When no mapping is set. We consider a "fake" mapping with a default value of 0.
$variableDeclaration = $this->createComponentFromXml('<responseDeclaration identifier="response1" baseType="duration" cardinality="multiple"/>');
$variable = ResponseVariable::createFromDataModel($variableDeclaration);
$mapResponseExpr = $this->createComponentFromXml('<mapResponse identifier="response1"/>');
$mapResponseProcessor = new MapResponseProcessor($mapResponseExpr);

$mapResponseProcessor->setState(new State(array($variable)));
$mapResponseProcessor->process();
$result = $mapResponseProcessor->process();
$this->assertEquals(0.0, $result->getValue());
}

public function testMultipleCardinalityIdentifierToFloat() {
Expand Down Expand Up @@ -221,4 +222,4 @@ public function testOutcomeDeclaration() {
$mapResponseProcessor->setState(new State(array($variable)));
$mapResponseProcessor->process();
}
}
}

0 comments on commit 87e9604

Please sign in to comment.