A reverse polish notation calculator written in Python 3.
Python
Clone or download

README.md

rpcalc

A reverse polish notation calculator written in Python 3.

About

rpcalc is a stack-based reverse polish notation calculator based on the HP 11C Scientific Calculator with extended features, such as:

  • An advanced stack datatype with native floating-point precision
  • Choice of unlimited or limited stack length (see Command-Line Switches)
  • User-extendible operators with simple, familiar syntax

Contents

Installation and Execution

You will need Python 3.3 or higher to run rpcalc.

Archlinux

The latest stable version of rpcalc is available on the AUR as rpcalc-git. Install it as you would any other AUR software.

All other systems

I am working to put rpcalc on many repositories of various linux distributions. Until then, simply download the necessary files from the git repository.

Installing

Switch to the rpcalc directory, and run the following from a command shell:

python3 setup.py install

It is possible that your system calls your Python 3.3 binary something different, such as python (ArchLinux) or py33.exe (some Windows). If this is the case, replace python3 in the above example with the proper executable.

rpcalc should now be installed. Type rpcalc into a command shell to run it.

Running rpcalc for Testing

If you would prefer not to install rpcalc to your system, follow these instructions.

Switch to the rpcalc directory, and run the following from a command shell:

python3 rpcalc.py

It is possible that your system calls your Python 3.3 binary something different, such as python (ArchLinux) or py33.exe (some Windows). If this is the case, replace python3 in the above example with the proper executable.

Operation

rpcalc uses a stack for all operations. Users unfamiliar with RPN or stack-based calculation are encouraged to read Basic Example below and a general RPN tutorial (short and sweet).

Basic Example

To multiply seven by the sum of two and one million:

  • Type 2 Enter. This puts two into the stack.
  • Type 1e6 +. This adds what you just typed with the most recent stack entry.
  • Type 7 x. This multiplies seven with the result of the last calculation.

Your result, 7000014.0, is now the only entry in the stack. You can confirm this by pressing p or #.

Concepts

  • Numbers are pushed into the stack once Enter is pressed or an operation is entered.
  • Operations are executed as soon as they are typed; do not follow operations with Enter.
  • There is no artificial limit placed on stack length.
  • If in doubt, use the program as you would an 11C, if you are familiar with its operation.

Operators

The most recent and second-most recent stack entries will be denoted x and y respectively. You can always peek inside operators.py for a more objective explanation of these functions.

Program

  • ? - enter interactive help mode
  • p - prints the stack
  • Q - quits the program, no matter what

Stack

  • D - drops x and pushes stack items to compensate
  • C - clears the stack
  • # - displays a message with the current stack length (does not push anything to the stack)
  • w - swaps x and y
  • Enter (while no number is being entered) - duplicates x and pushes it

Arithmetic

  • + - * / - basic arithmetic operations
  • x - shortcut for *
  • n - returns ( x * -1 )
  • % - returns the remainder of the division of y by x
  • f - floor-rounds x to an integer
  • ln - returns the natural log of the most recent stack entry ( x )
  • ^ - returns y to the xth power
  • sqrt - returns the square root of x
  • abs - returns the absolute value of x
  • ! - returns the factorial of x

Sequence Operators

  • S - returns the sum of all stack entries
  • P - returns the product of all stack entries

Statistics

  • mean - returns the arithmetic mean of all stack entries
  • med - returns the median of all stack entries

Constants

in rpcalc, constant operators begin with k to prevent conflicts with other operators

  • ke - returns Euler's number: the base of the natural logarithm and the exponential function
  • kpi - returns pi: the ratio of a circle's circumference to its diameter

Logic

  • == - returns 1 if x is equal to y, otherwise returns 0
  • =! - returns 0 if x is equal to y, otherwise returns 1
  • < - returns 1 if y is less than x, otherwise returns 0
  • > - returns 1 if y is greater than x, otherwise returns 0
  • =< - returns 1 if y is less than or equal to x, otherwise returns 0
  • => - returns 1 if y is greater than or equal to x, otherwise returns 0

Trigonometry

  • deg - converts x (radians) to degrees
  • rad - converts x (degrees) to radians
  • sin - returns the sine of x (radians)
  • cos - returns the cosine of x (radians)
  • tan - returns the tangent of x (radians)
  • asin - returns the arcsine of x (radians)
  • acos - returns the arccosine of x (radians)
  • atan - returns the arctangent of x (radians)

Other

  • rand - returns a random number between 0 and 1

Other operations can easily be added by modifying operators.py.

Examples

Results are designated with >>>, but these are really stored in the stack and displayed only because they are the current x value.

1 Enter 2 +
>>> 3.0

2 Enter Enter Enter * *
>>> 8.0

10 ln
>>> 2.302585092994046

256 ln 2 ln /
>>> 8.0

2 Enter 256 ln w ln /
>>> 8.0

2 Enter 3 ==
>>> 0

2 Enter Enter ==
>>> 1

Command-Line Switches

  • -s or --stack-size - limits the stack size to the integer provided. Empty stack entries become 0 when using a limited-size stack.
  • -i or --initial-values - takes space-separated numbers and pushes them to the stack.
  • -e or --exclusive - sets the stack length to the amount of numbers provided with -i

FAQ

I found a bug! Let me email that to you...

Thank you, but please don't email me the bug! Make sure it's not a known issue, and write me a bug report here or if you're familiar with git: fork, fix, and file a pull request.

How do I do log base x?

A log function is not scheduled to be implemented because the functionality is already there and because there is no reason to memorize which stack item will be the base and on which item the log will operate.

You will need to use the change of base formula:

Logarithmic Change of Base Formula

256 ln 2 ln /

There's mean and med, so why are there no mode, maximum, or minimum operators?

Arithmetic mean and median return one result, which is pushed into the stack. Mode, maximum, and minimum all have the capacity to produce more than one result. There is no non-arbitrary method of deciding the order in which the multiple answers would be pushed into the stack. Answers like these would be no good if the user didn't know which answer s/he wanted or where it went in the stack. Procedurally, these functions would be easy to write, but there is no clear way to display the answer to the user.

Known Issues

  • Some of the operators defined in operators.py still have #DEBUG tags. This is intentional; these operators will be removed once rpcalc graduates from version zero.

Motivation

At time of writing (August 2013), no stack-based RPN existed with the features and extensibility for which the author was looking. This project is meant to be a test of git, GitHub, vim, Python 3, and Object-Oriented Programming in general.

-Quintus