Some refactoring, improved help
This commit is contained in:
@@ -0,0 +1 @@
|
||||
,ondra,Penguin,29.09.2013 21:06,file:///home/ondra/.config/libreoffice/4;
|
||||
Binary file not shown.
+2
-2
@@ -1,4 +1,4 @@
|
||||
package net.mightypork.semestralka;
|
||||
package net.mightypork.calculator;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
@@ -19,7 +19,7 @@ import net.mightypork.rcalc.numbers.Fraction;
|
||||
*/
|
||||
public class CalculatorBatch implements Runnable {
|
||||
|
||||
/** Rcalc Session used by the calculator */
|
||||
/** RCalc Session used by the calculator */
|
||||
private RCalcSession session = new RCalcSession();
|
||||
|
||||
/** File to load the expressions from */
|
||||
+14
-6
@@ -1,4 +1,4 @@
|
||||
package net.mightypork.semestralka;
|
||||
package net.mightypork.calculator;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
@@ -17,7 +17,7 @@ import net.mightypork.rcalc.numbers.Fraction;
|
||||
*/
|
||||
public class CalculatorInteractive implements Runnable {
|
||||
|
||||
/** Rcalc Session used by the calculator */
|
||||
/** RCalc Session used by the calculator */
|
||||
private RCalcSession session = new RCalcSession();
|
||||
|
||||
/** Show results as fractions */
|
||||
@@ -42,17 +42,18 @@ public class CalculatorInteractive implements Runnable {
|
||||
+ "Commands:\n"
|
||||
+ "\thelp - show this help\n"
|
||||
+ "\texit - quit the calculator\n"
|
||||
+ "\tdebug - toggle debug mode (default off)\n"
|
||||
+ "\tdecimal - toggle decimal/fractional output\n"
|
||||
+ "\tvars - print a list of variables\n"
|
||||
+ "\tdebug - toggle debug mode (default off)\n"
|
||||
+ "\tutest - perform RCalc unit tests\n"
|
||||
+ "\tload filename - execute commands from a file\n"
|
||||
+ "\t\t(Expressions from the file can use/change variables)\n"
|
||||
+ "\n"
|
||||
+ "Mathematical operations, syntax\n"
|
||||
+ "\tSupported: + - * / % ^ ! ( )\n"
|
||||
+ "\tMultiplication sign can be omitted where it makes sense.\n"
|
||||
+ "\tAlong with fractions, decimal-point format works too.\n"
|
||||
+ "\tUse 'a/b' syntax to express a fraction.\n"
|
||||
+ "\tDecimal-point numbers are supported, too.\n"
|
||||
+ "\n"
|
||||
+ "Variables\n"
|
||||
+ "\tAssign a variable:\n"
|
||||
@@ -91,7 +92,7 @@ public class CalculatorInteractive implements Runnable {
|
||||
while (!sc.hasNextLine()) {}
|
||||
|
||||
String expr = sc.nextLine().toLowerCase().trim();
|
||||
|
||||
|
||||
if (expr.equals("%")) { // repeat last expression
|
||||
if (history.size() > 0) {
|
||||
expr = history.get(history.size() - 1);
|
||||
@@ -101,7 +102,10 @@ public class CalculatorInteractive implements Runnable {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// can't use a switch on strings because of java 6 :(
|
||||
|
||||
if (expr.equals("exit")) { // quit
|
||||
System.out.println("Exit.");
|
||||
return;
|
||||
@@ -109,6 +113,10 @@ public class CalculatorInteractive implements Runnable {
|
||||
} else if (expr.equals("help")) { // show help
|
||||
System.out.println(helpMessage);
|
||||
|
||||
} else if (expr.equals("utest")) { // show help
|
||||
Runnable r = new Tests();
|
||||
r.run();
|
||||
|
||||
} else if (expr.equals("debug")) { // toggle debug mode
|
||||
|
||||
if (session.isDebug()) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.mightypork.semestralka;
|
||||
package net.mightypork.calculator;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
+14
-14
@@ -1,4 +1,4 @@
|
||||
package net.mightypork.semestralka;
|
||||
package net.mightypork.calculator;
|
||||
|
||||
|
||||
import net.mightypork.rcalc.RCalc;
|
||||
@@ -9,13 +9,15 @@ import net.mightypork.rcalc.RCalc;
|
||||
*
|
||||
* @author Ondrej Hruska
|
||||
*/
|
||||
public class Tests {
|
||||
public class Tests implements Runnable {
|
||||
|
||||
/**
|
||||
* Run the tests
|
||||
*/
|
||||
public static void run() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
System.out.println("--- RCalc Unit Tests ---");
|
||||
RCalc rc = new RCalc();
|
||||
rc.setDebug(true);
|
||||
|
||||
@@ -27,22 +29,18 @@ public class Tests {
|
||||
"(1-1)(1--1)(1---1)(1----1)(1--+-+-+++--+-+1)(1--+-+-+-+-----1)(5*-1)", // minus, plus
|
||||
"-(15/2)+(72*43-2)-(12+1)", // minus with parentheses
|
||||
"+34-(--8+2*+13)", // + at beginning of scope
|
||||
// misc
|
||||
"23%(6/5)",
|
||||
"53/(5-4-1)",
|
||||
"100!",
|
||||
"24/4/3",
|
||||
"(10+1)(15-3)",
|
||||
"13(55-3/12)^2",
|
||||
"(1/2)^-2",
|
||||
"13^(1/2)", // should fail
|
||||
"(1/2)*(3/4)",
|
||||
"1000!", // big factorial
|
||||
"24/4/3", // chained division must go LTR
|
||||
"5-4-1", // subtraction must go LTR
|
||||
"5(10+1)(4!3)", // implicit multiplication
|
||||
"(1/2)^-2", // inverting a fraction
|
||||
"(1/2)/(3/4)", // compound fraction
|
||||
"(1/2)*(3/4)", // fraction multiplication
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
for (String expr : testCases) {
|
||||
System.out.println("\n\n###### test case begin ######");
|
||||
System.out.println("\n\n# Test Case #");
|
||||
|
||||
try {
|
||||
System.out.println("IN: " + expr);
|
||||
@@ -52,5 +50,7 @@ public class Tests {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("--- Unit Tests End ---");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.mightypork.rcalc;
|
||||
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -109,11 +108,11 @@ public class Tokenizer implements IDebugable {
|
||||
if (debug && deepDebug) System.out.println("\nNormalize sequences of '+' and '-'\n" + input);
|
||||
|
||||
// turn '-' to '+-' between numbers
|
||||
input = input.replaceAll("(?<=[0-9)!])-(?=[0-9])", "+-");
|
||||
input = input.replaceAll("(?<=[0-9)!])-(?=[0-9.])", "+-");
|
||||
if (debug && deepDebug) System.out.println("\n'-' to '+-' between numbers\n" + input);
|
||||
|
||||
// convert '-' to '+-1*' in front of non-numbers
|
||||
input = input.replaceAll("-(?=[^0-9])", "+-1*");
|
||||
input = input.replaceAll("-(?=[^0-9.])", "+-1*");
|
||||
if (debug && deepDebug) System.out.println("\n'-' to '+-1*' in front of non-numbers\n" + input);
|
||||
|
||||
// discard useless + signs
|
||||
|
||||
@@ -94,16 +94,29 @@ public class Fraction implements IEvaluableToken {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a fraction with numerator parsed from a string, and 1 as
|
||||
* denominator.
|
||||
*
|
||||
* @param number numerator as string
|
||||
*/
|
||||
public Fraction(String number) {
|
||||
if(number.contains(".")) {
|
||||
|
||||
if (number.matches("[.][0-9]+")) {
|
||||
number = "0" + number;
|
||||
}
|
||||
|
||||
if (number.matches("-[.][0-9]+")) {
|
||||
number = "-0" + number.substring(1);
|
||||
}
|
||||
|
||||
if (number.matches("-?[0-9]+[.][0-9]+")) {
|
||||
String[] parts = number.split("[.]");
|
||||
try{
|
||||
if(parts.length != 2) throw new ParseError(""); // for the catch
|
||||
this.numerator = new BigInteger(parts[0]+parts[1]);
|
||||
try {
|
||||
this.numerator = new BigInteger(parts[0] + parts[1]);
|
||||
this.denominator = BigInteger.valueOf(10).pow(parts[1].length());
|
||||
this.simplify_ip();
|
||||
}catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
throw new ParseError("Invalid number format.");
|
||||
}
|
||||
} else {
|
||||
@@ -270,13 +283,13 @@ public class Fraction implements IEvaluableToken {
|
||||
|
||||
return new Fraction(numerator.divide(gcd), denominator.divide(gcd));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Simplify the fraction (in place)
|
||||
*/
|
||||
private void simplify_ip() {
|
||||
|
||||
BigInteger gcd = numerator.gcd(denominator);
|
||||
|
||||
numerator = numerator.divide(gcd);
|
||||
|
||||
Reference in New Issue
Block a user