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