Your assignment is to write a "calculator" for balanced ternary integers. It will be able to do addition, subtraction, multiplication, and integer division, as well as negation and modulus (remainder). It will also have a one-number "memory,", and it will be able to convert between decimal and balanced ternary.
In the descriptions below, the word integer will refer to an ordinary integer, such as you have already been using in Python. The term balanced ternary number (BT for short) will mean a string composed of one or more of the characters '1'
, '0'
, and 'N'
(but not 'n'
)
You will have a single global variable, memory
, which will hold a single number; it is your choice whether to keep this number as an integer or as a BT string. Most of the operations specified below will change this number.
The user may type in any of the following expressions, where BT
stands for a balanced ternary number. These are the only kinds of expressions that your calculator needs to handle. There may or may not be a space between the operator and the memory. The user may also type in more than one expression on a line, with optional spaces between expressions, and the computer should do the computations left to right and display only the final answer.
Expression What it means + BT
Adds the number to memory - BT
Subtracts the number from memory * BT
Multiplies memory by the number / BT
Divides memory by the number % BT
Sets memory to memory mod the number =
BT
Just puts the number into memory
The user is allowed to enter leading zeros (such as '00N1'
); however, your calculator should not give results with leading zeros.
Save your program on a file named bt.py
and your unit tests on a file named bt_test.py
.
Here are the functions you should have.
Except as noted,
evaluate
, the functions are all called with legal arguments.
bt
will be a string representing a valid BT
.memory
variable, and return None
. evaluate
function should carefully check its input for errors, and only call the other functions with correct arguments. add(bt)
bt
to memory
.subtract(bt)
bt
from memory
.multiply(bt)
memory
by bt
.divide(bt)
memory
by bt
. Raises an Exception
if bt == 0
.remainder(bt)
memory % bt
. Raises an Exception
if bt == 0
. If negative numbers are involved, the results are the same as they would be for integers in Python (in other words, just let Python do whatever it does in this case).negate()
memory
by the decimal number -1
(or the balanced ternary number N
).store(bt)
memory
to bt
, replacing whatever value had been there previously. bt_to_int(bt)
bt
. Does not use the global variable memory
. int_to_bt(n)
BT
value of the integer parameter n
. Does not use the global variable memory
. memory_as_int()
memory
. memory_as_bt()
memory
. evaluate(string)
'=1NN1 + N01*1N'
. If an error is found, return an error message. memory
as a balanced ternary string. memory
is undefined (but probably what it was just before the exception happened). REPL()
quit
, return from the REPL
function (this will end the program). evaluate
method, REPL
. bt_to_int(bt)
and int_to_bt(dec)
are fundamental, so do these first. Both are fairly difficult; bt_to_int(bt)
is somewhat easier than int_to_bt(dec).
n % 10
. To remove the last digit of a decimal number n, use n // 10
. n % 3
, where n is an ordinary integer, to find what the rightmost ternary digit should be. That might give you 2
, with is not a legal balanced ternary digit, but you should be able to figure out what to do with it.N
↔ 1
.REPL
function is very short (7 lines), because most of the work is done in evaluate(string)
.
len(s)
-- returns the length of the strings.upper(), s.lower()
-- returns the uppercase/lowercase version of the string s.startswith(t)
-- returns True
if string s
starts with string t
s.replace(t, u)
-- returns a string like s, but with all occurrences of string t replaced by string u. u may be the empty string, ''
, in which case all occurrences of string t are deleted. s in t
-- returns True
if string s is a part of string ts[n:m]
,
s[n:]
,
and s[:m]
. It's a good idea to end your program with
if __name__ == '__main__':
REPL()
(In this program, the "main" method is named REPL
, not main
. )