support for symbolic computations

This commit is contained in:
serso 2011-10-19 00:40:01 +04:00
parent 65d13357c8
commit 2624a67b11
22 changed files with 373 additions and 73 deletions

View File

@ -8,7 +8,7 @@
<uses-sdk android:minSdkVersion="8"/> <uses-sdk android:minSdkVersion="8"/>
<application android:icon="@drawable/icon" <application android:icon="@drawable/icon"
android:label="@string/c_app_icon_name"> android:label="@string/c_app_name">
<activity android:name=".CalculatorActivity" <activity android:name=".CalculatorActivity"
android:label="@string/c_app_name"> android:label="@string/c_app_name">

View File

@ -14,7 +14,6 @@
<include layout="@layout/calc_editor"/> <include layout="@layout/calc_editor"/>
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<include layout="@layout/calc_display" <include layout="@layout/calc_display"

View File

@ -49,7 +49,7 @@
<string name="c_var_create_var">Создать переменную</string> <string name="c_var_create_var">Создать переменную</string>
<string name="c_var_edit_var">Редактировать переменную</string> <string name="c_var_edit_var">Редактировать переменную</string>
<string name="c_value.is.not.a.number">Значение - не число!</string> <string name="c_value.is.not.a.number">Значение должно либо оставаться пустым либо быть числом!</string>
<string name="c_var.name.clashes">Имя переменной не может быть зарезервированным системным именем!</string> <string name="c_var.name.clashes">Имя переменной не может быть зарезервированным системным именем!</string>
<string name="c_var.already.exists">Переменная с таким именем уже существует!</string> <string name="c_var.already.exists">Переменная с таким именем уже существует!</string>
<string name="c_name.is.empty">Имя не может быть пустым!</string> <string name="c_name.is.empty">Имя не может быть пустым!</string>
@ -84,4 +84,5 @@
<string name="c_calc_color_display_summary">Включает/выключает подсветку синтаксиса в поле редактирования калькулятора</string> <string name="c_calc_color_display_summary">Включает/выключает подсветку синтаксиса в поле редактирования калькулятора</string>
<string name="c_calc_theme_summary">Устанавливает тему оформления приложения</string> <string name="c_calc_theme_summary">Устанавливает тему оформления приложения</string>
<string name="c_clear_history">Очистить историю</string> <string name="c_clear_history">Очистить историю</string>
<string name="c_simplify_instead_of_numeric">Следующие константы не определены: {0}!</string>
</resources> </resources>

View File

@ -52,7 +52,7 @@
<string name="c_var_create_var">Create variable</string> <string name="c_var_create_var">Create variable</string>
<string name="c_var_edit_var">Edit variable</string> <string name="c_var_edit_var">Edit variable</string>
<string name="c_value.is.not.a.number">Value is not a number!</string> <string name="c_value.is.not.a.number">Value must be either number or empty!</string>
<string name="c_var.name.clashes">Variable name clashes with function name!</string> <string name="c_var.name.clashes">Variable name clashes with function name!</string>
<string name="c_var.already.exists">Variable with same name already exists!</string> <string name="c_var.already.exists">Variable with same name already exists!</string>
<string name="c_name.is.empty">Name is empty!</string> <string name="c_name.is.empty">Name is empty!</string>
@ -84,4 +84,5 @@
<string name="c_calc_color_display_summary">Enables/disables colouring and styling in calculator editor</string> <string name="c_calc_color_display_summary">Enables/disables colouring and styling in calculator editor</string>
<string name="c_calc_theme_summary">Sets the theme for calculator</string> <string name="c_calc_theme_summary">Sets the theme for calculator</string>
<string name="c_clear_history">Clear history</string> <string name="c_clear_history">Clear history</string>
<string name="c_simplify_instead_of_numeric">Next constants are undefined: {0}!</string>
</resources> </resources>

View File

@ -24,6 +24,7 @@ import bsh.EvalError;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.msg.AndroidMessageRegistry;
import org.solovyev.android.view.FontSizeAdjuster; import org.solovyev.android.view.FontSizeAdjuster;
import org.solovyev.android.view.widgets.*; import org.solovyev.android.view.widgets.*;
import org.solovyev.common.BooleanMapper; import org.solovyev.common.BooleanMapper;
@ -364,9 +365,18 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance); calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
AndroidMessageRegistry.instance.init(this);
this.calculatorModel.evaluate(); this.calculatorModel.evaluate();
} }
@Override
protected void onDestroy() {
super.onDestroy();
AndroidMessageRegistry.instance.finish();
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String s) { public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String s) {
dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this)); dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this));

View File

@ -26,7 +26,7 @@ public class CalculatorEditor extends EditText {
private boolean highlightText = true; private boolean highlightText = true;
@NotNull @NotNull
private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE); private final static TextProcessor<String> textHighlighter = new TextHighlighter(Color.WHITE);
public CalculatorEditor(Context context) { public CalculatorEditor(Context context) {
super(context); super(context);

View File

@ -18,6 +18,7 @@ import android.widget.Toast;
import bsh.EvalError; import bsh.EvalError;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.model.ParseException; import org.solovyev.android.calculator.model.ParseException;

View File

@ -119,7 +119,9 @@ public class CalculatorVarsActivity extends ListActivity {
}); });
final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
if (!StringUtils.isEmpty(value)) {
editValue.setText(value); editValue.setText(value);
}
final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
editDescription.setText(description); editDescription.setText(description);
@ -198,6 +200,15 @@ public class CalculatorVarsActivity extends ListActivity {
final MathType.Result mathType = MathType.getType(name, 0); final MathType.Result mathType = MathType.getType(name, 0);
if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) { if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) {
if (StringUtils.isEmpty(value)) {
// value is empty => undefined variable
varBuilder.setName(name);
varBuilder.setDescription(description);
varBuilder.setValue(null);
error = null;
} else {
// value is not empty => must be a number
boolean correctDouble = true; boolean correctDouble = true;
try { try {
Double.valueOf(value); Double.valueOf(value);
@ -207,12 +218,13 @@ public class CalculatorVarsActivity extends ListActivity {
if (correctDouble) { if (correctDouble) {
varBuilder.setName(name); varBuilder.setName(name);
varBuilder.setValue(value);
varBuilder.setDescription(description); varBuilder.setDescription(description);
varBuilder.setValue(value);
error = null; error = null;
} else { } else {
error = R.string.c_value_is_not_a_number; error = R.string.c_value_is_not_a_number;
} }
}
} else { } else {
error = R.string.c_var_name_clashes; error = R.string.c_var_name_clashes;
} }

View File

@ -1,15 +0,0 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
*/
package org.solovyev.android.calculator;
public enum JsclOperation {
simplify,
elementary,
importCommands,
numeric;
}

View File

@ -17,7 +17,7 @@ import org.solovyev.android.calculator.model.TextProcessor;
* Date: 10/12/11 * Date: 10/12/11
* Time: 9:47 PM * Time: 9:47 PM
*/ */
public class TextHighlighter implements TextProcessor { public class TextHighlighter implements TextProcessor<String> {
private final int color; private final int color;
private final int colorRed; private final int colorRed;

View File

@ -4,10 +4,13 @@
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.jscl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.model.ParseException;
import org.solovyev.android.calculator.model.TextProcessor;
import org.solovyev.common.utils.MathUtils; import org.solovyev.common.utils.MathUtils;
import org.solovyev.util.math.Complex; import org.solovyev.util.math.Complex;
@ -16,7 +19,7 @@ import org.solovyev.util.math.Complex;
* Date: 10/6/11 * Date: 10/6/11
* Time: 9:48 PM * Time: 9:48 PM
*/ */
class FromJsclTextProcessor implements TextProcessor { class FromJsclNumericTextProcessor implements TextProcessor<String> {
@NotNull @NotNull
@Override @Override

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
*/
package org.solovyev.android.calculator.jscl;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.DummyTextProcessor;
import org.solovyev.android.calculator.model.TextProcessor;
public enum JsclOperation {
simplify(DummyTextProcessor.instance),
elementary(DummyTextProcessor.instance),
importCommands(DummyTextProcessor.instance),
numeric(new FromJsclNumericTextProcessor());
@NotNull
private final TextProcessor<String> fromProcessor;
JsclOperation(@NotNull TextProcessor<String> fromProcessor) {
this.fromProcessor = fromProcessor;
}
@NotNull
public TextProcessor<String> getFromProcessor() {
return fromProcessor;
}
}

View File

@ -11,8 +11,14 @@ import bsh.EvalError;
import bsh.Interpreter; import bsh.Interpreter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.JsclOperation; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.NumberMapper; import org.solovyev.common.NumberMapper;
import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Formatter;
/** /**
* User: serso * User: serso
@ -36,25 +42,46 @@ public enum CalculatorEngine {
private int numberOfFractionDigits = 5; private int numberOfFractionDigits = 5;
@NotNull @NotNull
public final TextProcessor preprocessor = new ToJsclTextProcessor(); public final TextProcessor<PreparedExpression> preprocessor = new ToJsclTextProcessor();
@NotNull
public final TextProcessor postprocessor = new FromJsclTextProcessor();
@NotNull @NotNull
private final VarsRegisterImpl varsRegister = new VarsRegisterImpl(); private final VarsRegisterImpl varsRegister = new VarsRegisterImpl();
public String evaluate(@NotNull JsclOperation operation, @NotNull String expression) throws EvalError, ParseException { public String evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws EvalError, ParseException {
return evaluate(operation, expression, null);
}
public String evaluate(@NotNull JsclOperation operation,
@NotNull String expression,
@Nullable MessageRegistry<AndroidMessage> mr) throws EvalError, ParseException {
synchronized (lock) { synchronized (lock) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(preprocessor.process(expression)); final PreparedExpression preparedExpression = preprocessor.process(expression);
sb.append(preparedExpression);
//Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preprocessedExpression); //Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preprocessedExpression);
if (operation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) {
operation = JsclOperation.simplify;
if (mr != null) {
final String undefinedVars = CollectionsUtils.formatValue(preparedExpression.getUndefinedVars(), ", ", new Formatter<Var>() {
@Override
public String formatValue(@Nullable Var var) throws IllegalArgumentException {
return var != null ? var.getName() : "";
}
});
mr.addMessage(new AndroidMessage(R.string.c_simplify_instead_of_numeric, MessageType.info, undefinedVars));
}
}
final Object evaluationObject = interpreter.eval(ToJsclTextProcessor.wrap(operation, sb.toString())); final Object evaluationObject = interpreter.eval(ToJsclTextProcessor.wrap(operation, sb.toString()));
return postprocessor.process(String.valueOf(evaluationObject).trim()); final String result = String.valueOf(evaluationObject).trim();
return operation.getFromProcessor().process(result);
} }
} }

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator.model;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 10/18/11
* Time: 10:39 PM
*/
public enum DummyTextProcessor implements TextProcessor<String> {
instance;
@NotNull
@Override
public String process(@NotNull String s) throws ParseException {
return s.replace(ToJsclTextProcessor.SPECIAL_STRING, "");
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator.model;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* User: serso
* Date: 10/18/11
* Time: 10:07 PM
*/
public class PreparedExpression implements CharSequence{
@NotNull
private String expression;
@NotNull
private List<Var> undefinedVars;
public PreparedExpression(@NotNull String expression, @NotNull List<Var> undefinedVars) {
this.expression = expression;
this.undefinedVars = undefinedVars;
}
@NotNull
public String getExpression() {
return expression;
}
public boolean isExistsUndefinedVar() {
return !this.undefinedVars.isEmpty();
}
@NotNull
public List<Var> getUndefinedVars() {
return undefinedVars;
}
@Override
public int length() {
return expression.length();
}
@Override
public char charAt(int i) {
return expression.charAt(i);
}
@Override
public CharSequence subSequence(int i, int i1) {
return expression.subSequence(i, i1);
}
@Override
public String toString() {
return this.expression;
}
}

View File

@ -7,8 +7,8 @@ import org.jetbrains.annotations.NotNull;
* Date: 9/26/11 * Date: 9/26/11
* Time: 12:12 PM * Time: 12:12 PM
*/ */
public interface TextProcessor { public interface TextProcessor<T extends CharSequence> {
@NotNull @NotNull
String process(@NotNull String s) throws ParseException; T process(@NotNull String s) throws ParseException;
} }

View File

@ -8,7 +8,7 @@ package org.solovyev.android.calculator.model;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.StartsWithFinder; import org.solovyev.android.calculator.StartsWithFinder;
import org.solovyev.android.calculator.math.Functions; import org.solovyev.android.calculator.math.Functions;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
@ -16,11 +16,16 @@ import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.FilterType; import org.solovyev.common.utils.FilterType;
import org.solovyev.common.utils.Finder; import org.solovyev.common.utils.Finder;
class ToJsclTextProcessor implements TextProcessor { import java.util.ArrayList;
import java.util.List;
class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
public static final String SPECIAL_STRING = "☀☀☀";
@Override @Override
@NotNull @NotNull
public String process(@NotNull String s) { public PreparedExpression process(@NotNull String s) {
final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0);
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@ -47,7 +52,7 @@ class ToJsclTextProcessor implements TextProcessor {
startsWithFinder.setI(i + 1); startsWithFinder.setI(i + 1);
if ( i < s.length() && CollectionsUtils.get(MathType.groupSymbols, startsWithFinder) != null) { if ( i < s.length() && CollectionsUtils.get(MathType.groupSymbols, startsWithFinder) != null) {
i += 2; i += 2;
sb.append("(foo)"); sb.append("(" + SPECIAL_STRING + ")");
mathTypeResult = new MathType.Result(MathType.close_group_symbol, ")"); mathTypeResult = new MathType.Result(MathType.close_group_symbol, ")");
} }
} else if (mathType == MathType.constant) { } else if (mathType == MathType.constant) {
@ -61,9 +66,12 @@ class ToJsclTextProcessor implements TextProcessor {
return replaceVariables(sb.toString()); return replaceVariables(sb.toString());
} }
private String replaceVariables(@NotNull final String s) { @NotNull
private PreparedExpression replaceVariables(@NotNull final String s) {
final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0);
final List<Var> undefinedVars = new ArrayList<Var>();
final StringBuilder result = new StringBuilder(); final StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length(); i++) { for (int i = 0; i < s.length(); i++) {
startsWithFinder.setI(i); startsWithFinder.setI(i);
@ -75,10 +83,16 @@ class ToJsclTextProcessor implements TextProcessor {
if (varName != null) { if (varName != null) {
final Var var = CalculatorEngine.instance.getVarsRegister().getVar(varName); final Var var = CalculatorEngine.instance.getVarsRegister().getVar(varName);
if (var != null) { if (var != null) {
if (var.isUndefined()) {
undefinedVars.add(var);
result.append(varName);
offset = varName.length();
} else {
result.append(var.getValue()); result.append(var.getValue());
offset = varName.length(); offset = varName.length();
} }
} }
}
} else { } else {
result.append(functionName); result.append(functionName);
offset = functionName.length(); offset = functionName.length();
@ -92,7 +106,7 @@ class ToJsclTextProcessor implements TextProcessor {
} }
} }
return result.toString(); return new PreparedExpression(result.toString(), undefinedVars);
} }
private void replaceVariables(StringBuilder sb, String s, int i, @NotNull StartsWithFinder startsWithFinder) { private void replaceVariables(StringBuilder sb, String s, int i, @NotNull StartsWithFinder startsWithFinder) {

View File

@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.solovyev.common.utils.StringUtils;
/** /**
* User: serso * User: serso
@ -24,8 +25,8 @@ public class Var {
@NotNull @NotNull
private String name; private String name;
@Element @Element(required = false)
@NotNull @Nullable
private String value; private String value;
@Element @Element
@ -40,7 +41,7 @@ public class Var {
@NotNull @NotNull
private String name; private String name;
@NotNull @Nullable
private String value; private String value;
private boolean system = false; private boolean system = false;
@ -62,7 +63,7 @@ public class Var {
this(name, String.valueOf(value)); this(name, String.valueOf(value));
} }
public Builder(@NotNull String name, @NotNull String value) { public Builder(@NotNull String name, @Nullable String value) {
this.name = name; this.name = name;
this.value = value; this.value = value;
} }
@ -71,7 +72,7 @@ public class Var {
this.name = name; this.name = name;
} }
public void setValue(@NotNull String value) { public void setValue(@Nullable String value) {
this.value = value; this.value = value;
} }
@ -107,7 +108,7 @@ public class Var {
this.system = var.system; this.system = var.system;
} }
@NotNull @Nullable
public String getValue() { public String getValue() {
return value; return value;
} }
@ -121,18 +122,22 @@ public class Var {
return name; return name;
} }
public boolean isUndefined() {
return StringUtils.isEmpty(this.value);
}
@Nullable @Nullable
public String getDescription() { public String getDescription() {
return description; return description;
} }
public void setDescription(@Nullable String description) {
this.description = description;
}
@Override @Override
public String toString() { public String toString() {
if (value != null) {
return getName() + " = " + value; return getName() + " = " + value;
} else {
return getName();
}
} }
@Override @Override

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.msg;
import org.jetbrains.annotations.NotNull;
import org.solovyev.common.msg.AbstractMessage;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/**
* User: serso
* Date: 10/18/11
* Time: 11:57 PM
*/
public class AndroidMessage extends AbstractMessage<Integer> {
public AndroidMessage(@NotNull Integer messageCode,
@NotNull MessageType messageType,
@org.jetbrains.annotations.Nullable Object... arguments) {
super(messageCode, messageType, arguments);
}
public AndroidMessage(@NotNull Integer messageCode,
@NotNull MessageType messageType,
@org.jetbrains.annotations.Nullable List<?> arguments) {
super(messageCode, messageType, arguments);
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.msg;
import android.content.Context;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import org.solovyev.common.msg.MessageRegistry;
import java.util.Locale;
/**
* User: serso
* Date: 10/18/11
* Time: 11:49 PM
*/
public enum AndroidMessageRegistry implements MessageRegistry<AndroidMessage> {
instance;
private Context context;
public void init(@NotNull Context context) {
this.context = context;
}
@Override
public void addMessage(@NotNull AndroidMessage message) {
if (context != null) {
Toast.makeText(context, formatMessage(message), Toast.LENGTH_SHORT).show();
}
}
@NotNull
@Override
public AndroidMessage getMessage() {
throw new UnsupportedOperationException();
}
@Override
public boolean hasMessage() {
throw new UnsupportedOperationException();
}
@NotNull
public String formatMessage(@NotNull AndroidMessage message) {
final String messagePattern = context.getString(message.getMessageCode());
final String result;
if (messagePattern != null) {
result = message.formatMessage(messagePattern, Locale.getDefault());
} else {
result = "";
}
return result;
}
public void finish() {
this.context = null;
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator.jscl;
import org.junit.Assert;
import org.junit.Test;
/**
* User: serso
* Date: 10/18/11
* Time: 10:42 PM
*/
public class FromJsclNumericTextProcessorTest {
@Test
public void testCreateResultForComplexNumber() throws Exception {
final FromJsclNumericTextProcessor cm = new FromJsclNumericTextProcessor();
Assert.assertEquals("1.22133+23123.0i", cm.createResultForComplexNumber("1.22133232+23123*i"));
Assert.assertEquals("1.22133+1.2i", cm.createResultForComplexNumber("1.22133232+1.2*i"));
Assert.assertEquals("1.22i", cm.createResultForComplexNumber("1.22*i"));
Assert.assertEquals("i", cm.createResultForComplexNumber("i"));
}
}

View File

@ -10,7 +10,7 @@ import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Attribute;
import org.solovyev.android.calculator.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
/** /**
* User: serso * User: serso
@ -81,17 +81,12 @@ public class CalculatorEngineTest {
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k", 3.5d)); CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k", 3.5d));
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k1", 4d)); CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k1", 4d));
Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "k11")); Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "k11"));
}
@Test
public void testComplexNumbers() throws Exception {
final FromJsclTextProcessor cm = new FromJsclTextProcessor();
Assert.assertEquals("1.22133+23123.0i", cm.createResultForComplexNumber("1.22133232+23123*i"));
Assert.assertEquals("1.22133+1.2i", cm.createResultForComplexNumber("1.22133232+1.2*i"));
Assert.assertEquals("1.22i", cm.createResultForComplexNumber("1.22*i"));
Assert.assertEquals("i", cm.createResultForComplexNumber("i"));
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("t", (String)null));
Assert.assertEquals("11*t", cm.evaluate(JsclOperation.numeric, "t11"));
Assert.assertEquals("11*2.718281828459045*t", cm.evaluate(JsclOperation.numeric, "t11e"));
Assert.assertEquals("11*Infinity*t", cm.evaluate(JsclOperation.numeric, "t11∞"));
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)"));
} }
public interface TestInterface { public interface TestInterface {