Index: samigo-app/pom.xml
===================================================================
--- samigo-app/pom.xml (revision 93242)
+++ samigo-app/pom.xml (working copy)
@@ -123,6 +123,11 @@
commons-logging
+ commons-math
+ commons-math
+ 1.2
+
+
dom4j
dom4j
1.6.1
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages.properties
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages.properties (revision 93242)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages.properties (working copy)
@@ -506,3 +506,8 @@
st_strong_agree = Strongly agree
st_unacceptable = Unacceptable
st_excellent = Excellent
+
+science_format_fin = Scientist format: Always use the point symbol as decimal separator and the letter 'E' for exponent.
+science_format_fin_sample = For example: The Avogadro number is {6.022E24}
+complex_format_fin = Complex numbers should be in the form (a + bi). We shall indicate explicitly both the real and the imaginary part.
+complex_format_fin_sample = For example: we must put {1+1i} instead of {1+i}, also we must put {0+9i} instead of {9i}.
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages_es.properties
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages_es.properties (revision 93242)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AuthorMessages_es.properties (working copy)
@@ -418,3 +418,7 @@
st_unacceptable = Inaceptable
st_excellent = Excelente
+science_format_fin = Formato cient\u00EDfico: Utiliza siempre el punto como separador de decimales y la letra 'E' para el exponente.
+science_format_fin_sample = Por ejemplo: El n\u00FAmero de Avogadro es {6.022E24}
+complex_format_fin = Los n\u00FAmeros complejos deben tener el formato {a + bi}. Deberemos indicar expl\u00EDcitamente tanto la parte real como la imaginaria.
+complex_format_fin_sample = Por ejemplo: no reconoce {1+i} (debemos poner {1+1i}) ni tampoco {9i} (debemos poner {0+9i}).
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages.properties
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages.properties (revision 93242)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages.properties (working copy)
@@ -485,3 +485,6 @@
submission_allowed_2=time(s).
submission_allowed_3=more times.
+formatNumber_error=The value entered {0} is not a valid number
+rangeNumber_error=The range of values between {0} and {1} must be increased
+rangeformat_error=The value {0} in range {1} is not a valid real number format
\ No newline at end of file
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages_es.properties
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages_es.properties (revision 93242)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/DeliveryMessages_es.properties (working copy)
@@ -619,3 +619,6 @@
seeOrHide=Haga clic en la flecha inferior para mostrar u ocultar la lista de preguntas
assessment_exit_warning_title=Aviso de salida de evaluaci\u00F3n
+formatNumber_error=El valor introducido {0} no es un n\u00FAmero v\u00E1lido
+rangeNumber_error=El rango de valores entre {0} y {1} debe ser creciente
+rangeformat_error=El valor {0} del rango {1} no es un n\u00FAmero real en formato v\u00E1lido
\ No newline at end of file
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinQuestionValidator.java
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinQuestionValidator.java (revision 0)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinQuestionValidator.java (revision 0)
@@ -0,0 +1,117 @@
+package org.sakaiproject.tool.assessment.jsf.validator;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.complex.ComplexFormat;
+import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
+
+public class FinQuestionValidator implements Validator {
+
+ public FinQuestionValidator() {
+ // TODO Auto-generated constructor stub
+ }
+
+ public void validate(FacesContext context, UIComponent component, Object value)
+ throws ValidatorException {
+
+ String text = (String)value;
+
+ int i = text.indexOf("{", 0);
+ int j = text.indexOf("}", 0);
+
+ while (i != -1) {
+ String number = text.substring(i+1, j);
+
+ StringTokenizer st = new StringTokenizer(number, "|");
+
+ if (st.countTokens() > 1) {
+ String number1 = st.nextToken().trim();
+ String number2 = st.nextToken().trim();
+
+ // The first value in range must have a valid format
+ if (!isRealNumber(number1)) {
+ String error=(String)ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.DeliveryMessages", "rangeformat_error");
+ MessageFormat format = new MessageFormat(error);
+ throw new ValidatorException(new FacesMessage(format.format(new String[] {number1, number})));
+ }
+
+ // The second value in range must have a valid format
+ if (!isRealNumber(number2)) {
+ String error=(String)ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.DeliveryMessages", "rangeformat_error");
+ MessageFormat format = new MessageFormat(error);
+ throw new ValidatorException(new FacesMessage(format.format(new String[] {number2, number})));
+ }
+
+ // The range must be in increasing order
+ BigDecimal rango1 = new BigDecimal(number1);
+ BigDecimal rango2 = new BigDecimal(number2);
+ if (rango1.compareTo(rango2) != -1) {
+ String error=(String)ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.DeliveryMessages", "rangeNumber_error");
+ MessageFormat format = new MessageFormat(error);
+ throw new ValidatorException(new FacesMessage(format.format(new String[] {number1, number2})));
+ }
+ }
+ else {
+ // The number can be in a decimal format or complex format
+ if (!isRealNumber(number) && !isComplexNumber(number)) {
+ String error=(String)ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.DeliveryMessages", "formatNumber_error");
+ MessageFormat format = new MessageFormat(error);
+ throw new ValidatorException(new FacesMessage(format.format(new String[] {number})));
+ }
+ }
+
+ i = text.indexOf("{", i+1);
+ if (j+1 < text.length()) j = text.indexOf("}", j+1);
+ else j = -1;
+ }
+
+ }
+
+ boolean isComplexNumber(String value) {
+
+ boolean isComplex = true;
+ Complex complex=null;
+ try {
+ DecimalFormat df = (DecimalFormat)NumberFormat.getNumberInstance(Locale.US);
+ df.setGroupingUsed(false);
+
+ // Numerical format ###.## (decimal symbol is the point)
+ ComplexFormat complexFormat = new ComplexFormat(df);
+ complex = complexFormat.parse(value);
+
+ // This is because there is a bug parsing complex number. 9i is parsed as 9
+ if (complex.getImaginary() == 0 && value.contains("i")) isComplex = false;
+ } catch (Exception e) {
+ isComplex = false;
+ }
+
+ return isComplex;
+ }
+
+ boolean isRealNumber(String value) {
+
+ boolean isReal = true;
+ try {
+ // Number has decimal format? If no, Exception is throw
+ BigDecimal decimal = new BigDecimal(value);
+
+ } catch (Exception e) {
+ isReal = false;
+ }
+
+ return isReal;
+ }
+
+}
\ No newline at end of file
Index: samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinResponseValidator.java
===================================================================
--- samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinResponseValidator.java (revision 0)
+++ samigo-app/src/java/org/sakaiproject/tool/assessment/jsf/validator/FinResponseValidator.java (revision 0)
@@ -0,0 +1,73 @@
+package org.sakaiproject.tool.assessment.jsf.validator;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.complex.ComplexFormat;
+import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
+
+public class FinResponseValidator implements Validator {
+
+ public FinResponseValidator() {
+ // TODO Auto-generated constructor stub
+ }
+
+ public void validate(FacesContext context, UIComponent component, Object value)
+ throws ValidatorException {
+
+ // The number can be in a decimal format or complex format
+ if (!isRealNumber((String)value) && !isComplexNumber((String)value)) {
+ String error = (String)ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.DeliveryMessages", "formatNumber_error");
+ MessageFormat format = new MessageFormat(error);
+ throw new ValidatorException(new FacesMessage(format.format(new String[] {(String)value})));
+ }
+
+ }
+
+ boolean isComplexNumber(String value) {
+
+ boolean isComplex = true;
+ Complex complex=null;
+ try {
+ // Numerical format ###.## (decimal symbol is the point)
+ DecimalFormat df = (DecimalFormat)NumberFormat.getNumberInstance(Locale.US);
+ df.setGroupingUsed(false);
+
+ // Number has complex number? If no, ParseException is throw
+ ComplexFormat complexFormat = new ComplexFormat(df);
+ complex = complexFormat.parse(value);
+
+ // This is because there is a bug parsing complex number. 9i is parsed as 9
+ if (complex.getImaginary() == 0 && value.contains("i")) isComplex = false;
+ } catch (Exception e) {
+ isComplex = false;
+ }
+
+ return isComplex;
+ }
+
+ boolean isRealNumber(String value) {
+
+ boolean isReal = true;
+ try {
+ // Number has decimal format? If no, Exception is throw
+ BigDecimal decimal = new BigDecimal(value);
+
+ } catch (Exception e) {
+ isReal = false;
+ }
+
+ return isReal;
+ }
+
+}
Index: samigo-app/src/webapp/WEB-INF/faces-config.xml
===================================================================
--- samigo-app/src/webapp/WEB-INF/faces-config.xml (revision 93242)
+++ samigo-app/src/webapp/WEB-INF/faces-config.xml (working copy)
@@ -1306,6 +1306,14 @@
+
+ finResponseValidator
+ org.sakaiproject.tool.assessment.jsf.validator.FinResponseValidator
+
+
+ finQuestionValidator
+ org.sakaiproject.tool.assessment.jsf.validator.FinQuestionValidator
+
Index: samigo-app/src/webapp/jsf/author/item/fillInNumeric.jsp
===================================================================
--- samigo-app/src/webapp/jsf/author/item/fillInNumeric.jsp (revision 93242)
+++ samigo-app/src/webapp/jsf/author/item/fillInNumeric.jsp (working copy)
@@ -89,11 +89,19 @@
-
+
+
+
+
+
+
+
+
+
Index: samigo-app/src/webapp/jsf/delivery/item/deliverFillInNumeric.jsp
===================================================================
--- samigo-app/src/webapp/jsf/delivery/item/deliverFillInNumeric.jsp (revision 93242)
+++ samigo-app/src/webapp/jsf/delivery/item/deliverFillInNumeric.jsp (working copy)
@@ -44,7 +44,9 @@
+ value="#{answer.response}" onkeypress="return noenter()">
+
+
commons-logging
+ commons-math
+ commons-math
+ 1.2
+
+
javax.servlet
servlet-api
Index: samigo-services/src/java/org/sakaiproject/tool/assessment/services/GradingService.java
===================================================================
--- samigo-services/src/java/org/sakaiproject/tool/assessment/services/GradingService.java (revision 93242)
+++ samigo-services/src/java/org/sakaiproject/tool/assessment/services/GradingService.java (working copy)
@@ -34,9 +34,13 @@
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.text.ParseException;
+import java.math.BigDecimal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.complex.ComplexFormat;
import org.sakaiproject.event.cover.EventTrackingService;
import org.sakaiproject.service.gradebook.shared.GradebookService;
import org.sakaiproject.spring.SpringBeanLocator;
@@ -1387,9 +1391,12 @@
String studentanswer = "";
boolean range;
boolean matchresult = false;
- float studentAnswerNum,answer1Num,answer2Num,answerNum;
-
- if (data.getPublishedAnswerId() == null) {
+ ComplexFormat complexFormat = new ComplexFormat();
+ Complex answerComplex = null;
+ Complex studentAnswerComplex = null;
+ BigDecimal answerNum = null, answer1Num = null, answer2Num = null, studentAnswerNum = null;
+
+ if (data.getPublishedAnswerId() == null) {
return false;
}
@@ -1422,9 +1429,9 @@
}
try{
- answer1Num = Float.valueOf(answer1).floatValue();
+ answer1Num = new BigDecimal(answer1);
}catch(NumberFormatException ex){
- answer1Num = Float.NaN;
+ answer1Num = new BigDecimal(Float.toString(Float.NaN)) ;
}
log.debug("answer1Num= " + answer1Num);
if (answer2 != null){
@@ -1432,15 +1439,15 @@
}
try{
- answer2Num = Float.valueOf(answer2).floatValue();
+ answer2Num = new BigDecimal(answer2);
}catch(NumberFormatException ex){
- answer2Num = Float.NaN;
+ answer2Num = new BigDecimal(Float.toString(Float.NaN));
}
log.debug("answer2Num= " + answer2Num);
// Can accept increasing and decreasing ranges
- if (answer1Num > answer2Num) {
- float swap = answer1Num;
+ if (answer1Num.compareTo(answer2Num)==1){
+ BigDecimal swap = answer1Num;
answer1Num = answer2Num;
answer2Num = swap;
}
@@ -1448,14 +1455,18 @@
if (data.getAnswerText() != null){
studentanswer= data.getAnswerText().trim().replace(',','.'); // in Spain, comma is used as a decimal point
try{
- studentAnswerNum = Float.valueOf(studentanswer).floatValue();
+ studentAnswerNum = new BigDecimal(studentanswer);
}catch(NumberFormatException ex){
- studentAnswerNum = Float.NaN;
+ studentAnswerNum = new BigDecimal(Float.toString(Float.NaN));
//Temporal. Directamente contar\? como mala.
}
- log.debug("studentAnswerNum= " + studentAnswerNum);
- if (!(Float.isNaN(studentAnswerNum) || Float.isNaN(answer1Num) || Float.isNaN(answer2Num))){
- matchresult=((answer1Num <= studentAnswerNum) && (answer2Num >= studentAnswerNum)) ;
+ log.debug("studentAnswerNum= " + studentAnswerNum);
+ boolean studentAnswerNumIsNaN = studentAnswerNum.compareTo(new BigDecimal(Float.toString(Float.NaN)))==0;
+ boolean answer1NumIsNaN = answer1Num.compareTo(new BigDecimal(Float.toString(Float.NaN)))==0;
+ boolean answer2NumIsNaN =answer2Num.compareTo(new BigDecimal(Float.toString(Float.NaN)))==0;
+
+ if (!(studentAnswerNumIsNaN || answer1NumIsNaN || answer2NumIsNaN)){
+ matchresult=((answer1Num.compareTo(studentAnswerNum)!=1) && (answer2Num.compareTo(studentAnswerNum)!=-1) ) ;
}
}
@@ -1466,31 +1477,44 @@
}
try{
- answerNum = Float.valueOf(answer).floatValue();
+ answerNum = new BigDecimal(Float.valueOf(answer).toString());
}catch(NumberFormatException ex){
- answerNum = Float.NaN;
+ answerNum = new BigDecimal(Float.toString(Float.NaN));
// should not go here
}
log.debug("answerNum= " + answerNum);
-
+ try {
+ answerComplex = complexFormat.parse(answer);
+ } catch(ParseException ex) {
+ log.debug("Number is not Complex: " + answer);
+ }
if (data.getAnswerText() != null){
studentanswer= data.getAnswerText().trim().replace(',','.'); // in Spain, comma is used as a decimal point
- try{
- studentAnswerNum = Float.valueOf(studentanswer).floatValue();
- }catch(NumberFormatException ex){
- studentAnswerNum = Float.NaN;
- }
- log.debug("studentAnswerNum= " + studentAnswerNum);
- if (!(Float.isNaN(studentAnswerNum) || Float.isNaN(answerNum))){
- matchresult=(answerNum == studentAnswerNum) ;
- }
- }
+ if (answerNum!=null){
+ try{
+ studentAnswerNum = new BigDecimal(Float.valueOf(studentanswer).toString());
+ }catch(NumberFormatException ex){
+ studentAnswerNum = new BigDecimal(Float.toString(Float.NaN));
+ }
+ log.debug("studentAnswerNum= " + studentAnswerNum);
+ boolean studentAnswerNumIsNaN = studentAnswerNum.compareTo(new BigDecimal(Float.toString(Float.NaN)))==0;
+ boolean answerNumIsNaN = answerNum.compareTo(new BigDecimal(Float.toString(Float.NaN)))==0;
+ if (!(studentAnswerNumIsNaN || answerNumIsNaN)){
+ matchresult=(answerNum.compareTo(studentAnswerNum) == 0) ;
+ }
+ }else if (answerComplex != null) {
+ try {
+ studentAnswerComplex = complexFormat.parse(studentanswer);
+ log.debug("studentAnswerComplex= " + studentAnswerComplex.getReal() + "+" + studentAnswerComplex.getImaginary() + "i");
+ } catch(ParseException ex) {
+ log.debug("Number is not Complex: " + studentanswer);
+ }
+ matchresult = (studentAnswerComplex != null && answerComplex.equals(studentAnswerComplex));
+ }
}
-
-
-
}
+ }
return matchresult;
}