Skip to content

Commit

Permalink
Added ability to enter in a percentage
Browse files Browse the repository at this point in the history
- This will automatically divide that number by 100 and add it to the stack.  For example, you can now enter `15%` and `0.15` will be added to the stack.
- Added an automated unit test for the percent number entry.
- Updated the [User Guide](https://frossm.github.io/RPNCalc-UserGuide) to reflect this change.
- JUnit updated from 5.11.3  ->  5.11.4
  • Loading branch information
frossm committed Dec 29, 2024
1 parent e8a94b0 commit 465632f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 12 deletions.
3 changes: 1 addition & 2 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions mdbook/src/Chapters/HighLevelUsage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@

# High Level Usage

RPNCalc is a command line application that must be run from a console / command prompt. Executing it with a `-h` (or `-?`) switch, or starting the program and entering the `h` (or `help` or `?`) command will display the in-program help page. This page lists all of the commands and operands that can be used, but it is fairly terse This can be also viewed at the bottom of the `Introduction Chapter` of this guide. This document is meant as a more comprehensive guide.
RPNCalc is a command line application that must be run from a console / command prompt. Executing it with a `-h` (or `-?`) switch, or starting the program and entering
the `h` (or `help` or `?`) command will display the in-program help page. This page lists all the commands and operands that can be used, but it is fairly terse This can be also viewed at the bottom of the `Introduction Chapter` of this guide. This document is meant as a more comprehensive guide.

There are various command line switches that can be used when starting the program as are detailed in the `Command Line Options Chapter`. They generally exist so that aliases can be used to control several key parameters, most likely the `-l StackName` switch.

Once inside the program, you'll be presented a prompt where numbers, operands, and commands may be entered. Numbers will be added to the stack which you can think of as an upside down stack of plates. The top stack item (represented by `line1` in the program) is on the bottom. You can think of this stack of plates as a Last In First Out (LIFO) approach.

For example, you could enter `2 [ENTER]` it would be in the `line1` position and would be on the top of the stack. If you then enter `3 [ENTER]` the `2` would move up go `line2` and the `3` would then be on `line1` and be on the top of the stack. You can then enter in an operand, such as `+` to perform the action on the items opn the top of the stack. To continue our example, pressing `+ [ENTER]` would take the top two items off of the stack, add them, and put the result back on top of the stack (`line1`).
For example, you could enter `2 [ENTER]` it would be in the `line1` position and would be on the top of the stack. If you then enter `3 [ENTER]` the `2` would move up go `line2` and the `3` would then be on `line1` and be on the top of the stack. You can then enter an operand, such as `+` to perform the action on the items opn the top of the stack. To continue our example, pressing `+ [ENTER]` would take the top two items off of the stack, add them, and put the result back on top of the stack (`line1`).

I've gone into this in more detail in the `What is an RPN Calculator Chapter` and elsewhere and it's fairly easy and intuitive. Once you get the hang of it, you'll overwhelming regret having to use a standard calculator in the future. ;-)
I've gone into this in more detail in the `What is an RPN Calculator Chapter` and elsewhere and it's fairly easy and intuitive. Once you get the hang of it, you will regret having to use a standard calculator in the future. ;-)

#### Why is the stack "upside down?"

One question I get with RPNCalc is why is the top of the stack on the bottom? The reason is that it's simply more intuitive. The command line is on the bottom. You are usually dealing with the top of the stack so having `line1` directly above makes sense. Also, for some operations, the order is important (think subtraction or division). Having `line1` "underneath" `line2` is easy to understand as that's how we learned to do subtraction. `line1` is subtracted from `line2`.

### Decimals & Fractions

In RPNCalc, the stacks always store numbers as decimals. You can, however, enter in fractions and they will be instantly converted to a decimal equivalent and added to the stack.
In RPNCalc, the stacks always store numbers as decimals. You can, however, enter in fractions, and they will be instantly converted to a decimal equivalent and added to
the stack.

**Example:**

Expand Down Expand Up @@ -52,9 +54,14 @@ will display `1 293/6250`. This is a closer approximation than using base 16. T

As of version 5, scientific notation is supported. You can enter in values with the format `1.2345E18` and it will be saved as a value in the stack. There are a few areas where it's not 100% supported (i.e. NumOps at the time of this writing) but just about everything will work with it.

### Percent Entry

As of version 5.4.0, a number, followed by a `%` can be entered. This will be divided by 100 prior to being added onto the stack. This will work with both negative
numbers and scientific notation.

## Operands, Numbers, and Commands

Numbers, whether decimal or fractions, can be entered on the command line and they get added to the stack. That's fairly self explanatory.
Numbers, whether decimal or fractions, can be entered on the command line, and they get added to the stack. That's fairly self-explanatory.

Operands perform basic match functions on those numbers.

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.fross</groupId>
<artifactId>rpncalc</artifactId>
<version>5.3.6</version>
<version>5.4.0</version>
<packaging>jar</packaging>

<name>rpncalc</name>
Expand Down Expand Up @@ -279,7 +279,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.3</version>
<version>5.11.4</version>
<scope>test</scope>
</dependency>

Expand Down
2 changes: 1 addition & 1 deletion snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: rpncalc
version: '5.3.6'
version: '5.4.0'
summary: The command line Reverse Polish Notation (RPN) calculator
description: |
RPNCalc is an easy to use command line based Reverse Polish
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/fross/rpncalc/CommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,26 @@ public static void Parse(StackObj calcStack, StackObj calcStack2, String cmdInpu
Output.debugPrintln("Placing the number '" + cmdInputCmd + "' onto the stack");
calcStack.push(new BigDecimal(cmdInputCmd));

// If the number entered ends with a "%" then divide by 100 and add that to the stack
} else if (cmdInputCmd.matches("^\\S*\\d%$")) {
// Save current calcStack to the undoStack
calcStack.saveUndo();

String num = "";
try {
num = cmdInputCmd.substring(0, cmdInputCmd.indexOf('%'));
calcStack.push(new BigDecimal(num));
calcStack.push("100");
Math.Divide(calcStack);

Output.debugPrintln("A percent number was entered: " + num + "%");

} catch (IndexOutOfBoundsException ex) {
Output.printColorln(Ansi.Color.RED, "Unable to parse '" + cmdInputCmd + "'");
} catch (ArithmeticException | NullPointerException ex) {
Output.printColorln(Ansi.Color.RED, "Error dividing " + num + " / 100");
}

// Handle NumOps - numbers with a single operand at the end (*, /, +, -, ^)
} else if (cmdInputCmd.matches("^-?\\d*\\.?\\d*[Ee]?\\d*[*+\\-/^]")) {
// Save current calcStack to the undoStack
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/fross/rpncalc/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ public static void main(String[] args) {
}

// While in debug mode, show the entered text along with the broken up command and parameter
Output.debugPrintln("Full cmdInput: '" + cmdInput + "' | cmdInputCommand: '" + cmdInputCmd + "' | cmdInputParameter: '" + cmdInputParam + "'");
Output.debugPrintln("Full cmdInput: '" + cmdInput + "' | cmdInputCmd: '" + cmdInputCmd + "' | cmdInputParam: '" + cmdInputParam + "'");

// If recording is enabled, send the user input to be recorded
if (UserFunctions.recordingIsEnabled()) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/fross/rpncalc/UserFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ public static void FunctionRun(StackObj calcStack, StackObj calcStack2, String f
String param = "";

try {
// If the number of spaces in the full command is zero, don't execute a split so we don't get an ArrayIndexOutOfBoundsExceptionn
// If the number of spaces in the full command is zero, don't execute a split so we don't get an ArrayIndexOutOfBoundsException
// Reference: https://stackoverflow.com/questions/275944/how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string
if (fullCommand.codePoints().filter(ch -> ch == ' ').count() == 0) {
command = fullCommand.toLowerCase().trim();
Expand Down
24 changes: 24 additions & 0 deletions src/test/java/org/fross/rpncalc/CommandParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,28 @@ void testScientificNotationNumberEntry() {

}

// Test the entry of a percentage (15%, 2%, etc.)
@Test
void testPercentEntry() {
StackObj stk = new StackObj();

CommandParser.Parse(stk, stk, "15%", "15%", "");
assertEquals(1, stk.size());
assertEquals("0.15", stk.peek().toString());

CommandParser.Parse(stk, stk, "1%", "1%", "");
assertEquals(2, stk.size());
assertEquals("0.01", stk.peek().toString());

CommandParser.Parse(stk, stk, "-85%", "-85%", "");
assertEquals(3, stk.size());
assertEquals("-0.85", stk.peek().toString());

// Not sure if this makes a lot of sense, but let's test scientific notation percentages
CommandParser.Parse(stk, stk, "1.1e3%", "1.1e3%", "");
assertEquals(4, stk.size());
assertEquals("11", stk.peek().toString());

}

}

0 comments on commit 465632f

Please sign in to comment.