This commit is contained in:
Sergey Solovyev 2011-11-11 19:18:33 +04:00
parent 046114b42d
commit c7f93700f1
9 changed files with 62 additions and 38 deletions

View File

@ -57,7 +57,7 @@
<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.not.valid">Имя переменной не валидно: им ядолжно начинаться с буквы, может содержать буквы, цифры и знак подчёркивания.</string>
<string name="c_sys.var.cannot.be.changed">Системная переменная не может быть изменена!</string> <string name="c_sys.var.cannot.be.changed">Системная переменная не может быть изменена!</string>
<string name="c_pi_description">Отношение длины окружности к диаметру</string> <string name="c_pi_description">Отношение длины окружности к диаметру</string>

View File

@ -60,7 +60,7 @@
<string name="c_value.is.not.a.number">Value must be either number or empty!</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.not.valid">Name of constant is not valid: name must start with letter, can contain letters, digits and underscore.</string>
<string name="c_sys.var.cannot.be.changed">System variable cannot be changed!</string> <string name="c_sys.var.cannot.be.changed">System variable cannot be changed!</string>
<string name="c_pi_description">Ratio of any circle\'s circumference to its diameter</string> <string name="c_pi_description">Ratio of any circle\'s circumference to its diameter</string>

View File

@ -2,10 +2,8 @@ package org.solovyev.android.calculator;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.StringUtils; import org.solovyev.common.utils.StringUtils;
/** /**
@ -39,7 +37,7 @@ public class CalculatorActivityLauncher {
if (calculatorModel.getDisplay().isValid() ) { if (calculatorModel.getDisplay().isValid() ) {
final String varValue = calculatorModel.getDisplay().getText().toString(); final String varValue = calculatorModel.getDisplay().getText().toString();
if (!StringUtils.isEmpty(varValue)) { if (!StringUtils.isEmpty(varValue)) {
if (CalculatorVarsActivity.isValid(varValue)) { if (CalculatorVarsActivity.isValidValue(varValue)) {
final Intent intent = new Intent(context, CalculatorVarsActivity.class); final Intent intent = new Intent(context, CalculatorVarsActivity.class);
intent.putExtra(CalculatorVarsActivity.CREATE_VAR_EXTRA_STRING, varValue); intent.putExtra(CalculatorVarsActivity.CREATE_VAR_EXTRA_STRING, varValue);
context.startActivity(intent); context.startActivity(intent);

View File

@ -16,9 +16,11 @@ import android.widget.*;
import jscl.math.function.Function; import jscl.math.function.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.model.Var;
import org.solovyev.common.utils.StringUtils; import org.solovyev.common.utils.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
/** /**
@ -55,6 +57,19 @@ public class CalculatorFunctionsActivity extends ListActivity{
} }
}); });
sort();
}
private void sort() {
CalculatorFunctionsActivity.this.adapter.sort(new Comparator<Function>() {
@Override
public int compare(Function function1, Function function2) {
return function1.getName().compareTo(function2.getName());
}
});
CalculatorFunctionsActivity.this.adapter.notifyDataSetChanged();
} }
private class FunctionsArrayAdapter extends ArrayAdapter<Function> { private class FunctionsArrayAdapter extends ArrayAdapter<Function> {

View File

@ -16,6 +16,9 @@ import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import jscl.text.Identifier;
import jscl.text.MutableInt;
import jscl.text.ParseException;
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.math.MathType; import org.solovyev.android.calculator.math.MathType;
@ -38,7 +41,7 @@ public class CalculatorVarsActivity extends ListActivity {
public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var"; public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var";
private final static List<Character> acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё".toCharArray())); private final static List<Character> acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray()));
@NotNull @NotNull
private VarsArrayAdapter adapter; private VarsArrayAdapter adapter;
@ -208,7 +211,7 @@ public class CalculatorVarsActivity extends ListActivity {
final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister(); final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister();
if (!StringUtils.isEmpty(name)) { if (isValidName(name)) {
boolean canBeSaved = false; boolean canBeSaved = false;
@ -232,7 +235,7 @@ public class CalculatorVarsActivity extends ListActivity {
error = null; error = null;
} else { } else {
// value is not empty => must be a number // value is not empty => must be a number
boolean valid = isValid(value); boolean valid = isValidValue(value);
if (valid) { if (valid) {
varBuilder.setName(name); varBuilder.setName(name);
@ -250,7 +253,7 @@ public class CalculatorVarsActivity extends ListActivity {
error = R.string.c_var_already_exists; error = R.string.c_var_already_exists;
} }
} else { } else {
error = R.string.c_name_is_empty; error = R.string.c_name_is_not_valid;
} }
if (error != null) { if (error != null) {
@ -284,7 +287,22 @@ public class CalculatorVarsActivity extends ListActivity {
CalculatorVarsActivity.this.adapter.notifyDataSetChanged(); CalculatorVarsActivity.this.adapter.notifyDataSetChanged();
} }
public static boolean isValid(@NotNull String value) { private static boolean isValidName(@Nullable String name) {
boolean result = false;
if (!StringUtils.isEmpty(name)) {
try {
Identifier.parser.parse(name, new MutableInt(0));
result = true;
} catch (ParseException e) {
// not valid name;
}
}
return result;
}
public static boolean isValidValue(@NotNull String value) {
// now every string might be constant // now every string might be constant
return true; return true;
} }

View File

@ -18,7 +18,7 @@ import java.util.List;
class ToJsclTextProcessor implements TextProcessor<PreparedExpression> { class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
@NotNull @NotNull
private static final Integer MAX_DEPTH = 10; private static final Integer MAX_DEPTH = 20;
@Override @Override
@NotNull @NotNull
@ -93,7 +93,9 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
assert value != null; assert value != null;
if ( var.getDoubleValue() != null ) { if ( var.getDoubleValue() != null ) {
result.append(value); //result.append(value);
// NOTE: append varName as JSCL engine will convert it to double if needed
result.append(varName);
} else { } else {
result.append("(").append(processWithDepth(value, depth, undefinedVars)).append(")"); result.append("(").append(processWithDepth(value, depth, undefinedVars)).append(")");
} }

View File

@ -189,16 +189,6 @@ public class Var implements IConstant {
this.id = id; this.id = id;
} }
@Override
public boolean same(@Nullable MathEntity mathEntity) {
if (mathEntity instanceof IConstant) {
if (mathEntity.getId().equals(this.getId())) {
return true;
}
}
return false;
}
@NotNull @NotNull
public String getName() { public String getName() {
return name; return name;

View File

@ -148,7 +148,8 @@ public class CalculatorEngineTest {
CalculatorEngine.instance.getVarsRegister().add(null, new Var.Builder("t", (String) null)); CalculatorEngine.instance.getVarsRegister().add(null, new Var.Builder("t", (String) null));
Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getResult()); Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getResult());
Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getResult()); Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getResult());
Assert.assertEquals("11×Infinityt", cm.evaluate(JsclOperation.numeric, "t11∞").getResult()); Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "").getResult());
Assert.assertEquals("11t∞", cm.evaluate(JsclOperation.numeric, "t11∞").getResult());
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult()); Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult());
Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult()); Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult());

View File

@ -45,13 +45,13 @@ public class ToJsclTextProcessorTest {
Assert.assertEquals( "(0)*ln(1)*(2*10^-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString()); Assert.assertEquals( "(0)*ln(1)*(2*10^-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString());
Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString()); Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString());
Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString()); Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString());
Assert.assertEquals( "3.141592653589793*sin(4)*3.141592653589793*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString()); Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString());
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(√(5))", preprocessor.process("πsin(4)+πcos(√(5))").toString()); Assert.assertEquals( "π*sin(4)+π*cos(√(5))", preprocessor.process("πsin(4)+πcos(√(5))").toString());
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString()); Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString());
Assert.assertEquals( "3.141592653589793*sin(4.01)+3.141592653589793*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString()); Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(√(5+(√(-1))))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString());
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(√(5+(√(-1))))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString());
Assert.assertEquals( "10^2", preprocessor.process("E2").toString()); Assert.assertEquals( "10^2", preprocessor.process("E2").toString());
Assert.assertEquals( "10^-2", preprocessor.process("E-2").toString()); Assert.assertEquals( "10^-2", preprocessor.process("E-2").toString());
Assert.assertEquals( "10^-1/2", preprocessor.process("E-1/2").toString()); Assert.assertEquals( "10^-1/2", preprocessor.process("E-1/2").toString());
@ -94,19 +94,19 @@ public class ToJsclTextProcessorTest {
Assert.assertEquals( "", preprocessor.process("").toString()); Assert.assertEquals( "", preprocessor.process("").toString());
/* try { /* try {
Assert.assertEquals( "3.141592653589793/180", preprocessor.process("°").toString()); Assert.assertEquals( "π/180", preprocessor.process("°").toString());
} catch (ParseException e) { } catch (ParseException e) {
if ( !e.getMessage().startsWith("Could not find start of prefix") ){ if ( !e.getMessage().startsWith("Could not find start of prefix") ){
junit.framework.Assert.fail(); junit.framework.Assert.fail();
} }
} }
Assert.assertEquals( "1*3.141592653589793/180", preprocessor.process("").toString()); Assert.assertEquals( "1*π/180", preprocessor.process("").toString());
Assert.assertEquals( "20.0*3.141592653589793/180", preprocessor.process("20.0°").toString()); Assert.assertEquals( "20.0*π/180", preprocessor.process("20.0°").toString());
Assert.assertEquals( "sin(30*3.141592653589793/180)", preprocessor.process("sin(30°)").toString()); Assert.assertEquals( "sin(30*π/180)", preprocessor.process("sin(30°)").toString());
Assert.assertEquals( "asin(sin(3.141592653589793/6))*3.141592653589793/180", preprocessor.process("asin(sin(π/6))°").toString()); Assert.assertEquals( "asin(sin(π/6))*π/180", preprocessor.process("asin(sin(π/6))°").toString());
Assert.assertEquals( "1*3.141592653589793/180*sin(1)", preprocessor.process("1°sin(1)").toString()); Assert.assertEquals( "1*π/180*sin(1)", preprocessor.process("1°sin(1)").toString());
try { try {
Assert.assertEquals( "1*3.141592653589793/180^sin(1)", preprocessor.process("1°^sin(1)").toString()); Assert.assertEquals( "1*π/180^sin(1)", preprocessor.process("1°^sin(1)").toString());
junit.framework.Assert.fail(); junit.framework.Assert.fail();
} catch (ParseException e) { } catch (ParseException e) {
if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) { if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) {