In this project, you'll build your own Desktop Calculator with CircuitPython. Along the way you'll also learn about the alternative "RPN" notation for calculating, how a keyboard matrix works (and how to create your own!), and more!
What is "RPN", anyway?
Most of us are accustomed to standard mathematical notation, like 2+3*7 or (2+3)*7. Because most operations (like "+") appear between the two things operated on (like 2 and 3), this is called "infix" notation. Two alternatives to "infix" are "postfix" and "prefix". Postfix notation is also called RPN, which stands for "Reverse Polish Notation".
Possibly because it was used in some classic HP calculators, many people have a fondness for RPN or even feel that it works better than standard notation.
In standard infix notation, you have to know the "precedence rule", and understand that when given 2+3*7 you first compute 3*7=21 and then compute 2+21=23. When the rule does not reflect your intent, you add parentheses: (2+3)*7. In this case you evaluate 2+3=5 first, then 5*7=35. Mnemonic devices such as PEDMAS help us remember the rules.
In postfix notation, there are no parentheses and no rules of precedence. Instead, there what is called the "stack". When you enter a number, it is placed on the stack. When you enter an operator such as "+" that operates on two values, the "top" two values are taken off the stack, the operation is performed, and the result is put back on the stack.
If you'd like to know more about RPN, I found that the short paper "Order of Operations and RPN" provides helpful background.
To interpret "2 3 7 * +", start with the empty stack and place each number on the stack as you encounter it. When you encounter "*", your stack will contain "2", "3", and "7" in that order. This makes the values that "+" will operate on "3" and "7", so they are removed and replaced with "21". Now the stack contains "2" and "21" in that order. When you encounter "+", you take "2" and "21" off and put "23" on. That's the same as "2 + 3 * 7" in standard notation.
Operations don't have to appear at the end only, they can appear in the middle. Consider "2 3 + 7 *". When you encounter "+", the stack has "2" and "3", so replace it with "5". Next, 7 gets placed on the stack. When you encouter "*", the stack has "5" and "7" so replace them with "35". That's the same as "(2 + 3) * 7" in standard notation.
What is Decimal Arithmetic?
This calculator uses a decimal arithmetic library ported from standard Python3. It's available in the community bundle under the name jepler_udecimal. Decimal is "designed with people in mind, and necessarily has a paramount guiding principle–computers must provide an arithmetic that works in the same way as the arithmetic that people learn at school."
In this library, "0.1 + 0.2" is exactly equal to "0.3". Even better, the precision isn't limited to just 6 digits. In Python code, you can select any number of digits (even in the hundreds!). For this project, so that numbers fit on the display, numbers up to 14 digits are displayed.
This stands in contrast with how floats work in CircuitPython. CircuitPython flating point numbers only have about 6 to 7 digits of decimal precision, and values like "0.1" are not exact values.
Text editor powered by tinymce.