Jan-24-2019, 09:40 PM
"""
A program to run various calculators. It asks the user to first choose
between a basic or advanced calculator, and then to choose a sub-calculator.
They can press Q at any time to quit the program or H to display a help
prompt.
"""
import operator
import math
from time import sleep
# Defines text that appears when user starts the program
MAIN_TEXT = """
┌─────────────────────────────────────────────────────────────────────────────┐
│Welcome to the calculator. │
│Please enter an option. │
├─────────────────────────────────────────────────────────────────────────────┤
│1 - Basic calculator (+, -, **, etc.) │
│2 - Advanced calculator (sin, cos, etc.) │
│H - Display help │
│Q - Quit │
└─────────────────────────────────────────────────────────────────────────────┘
"""
# Defines text that appears when user starts the basic calculator (1)
BASIC_TEXT = """
┌─────────────────────────────────────────────────────────────────────────────┐
│Welcome to the basic calculator │
│Please enter an option. │
├─────────────────────────────────────────────────────────────────────────────┤
│1 - Addition (+) │
│2 - Subtraction (-) │
│3 - Multiplication (*) │
│4 - Division (/) │
│5 - Integer division (//) │
│6 - Modulo (%) │
│7 - Powers (**) │
│H - Display help │
│Q - Quit │
│R - Restart │
└─────────────────────────────────────────────────────────────────────────────┘
"""
# Defines text that appears when user starts the advanced calculator (2)
ADVANCED_TEXT = """
┌─────────────────────────────────────────────────────────────────────────────┐
│Welcome to the advanced calculator │
│Please enter an option. │
├─────────────────────────────────────────────────────────────────────────────┤
│1 - Sine (sin) │
│2 - Cosine (cos) │
│3 - Tangent (tan) │
│H - Display help │
│Q - Quit │
│R - Restart │
└─────────────────────────────────────────────────────────────────────────────┘
"""
# Defines text that appears when user displays the help prompt (H)
HELP_TEXT = """
┌─────────────────────────────────────────────────────────────────────────────┐
│Type H in any prompt to display this again. │
│If you wish to quit the calculator at any time, press Q in a prompt. │
├─────────────────────────────────────────────────────────────────────────────┤
│On the main menu, press 1 or 2 to access the basic or advanced calculator. │
├─────────────────────────────────────────────────────────────────────────────┤
│In the basic calculator, press 1, 2, 3, 4, 5, 6 or 7 to access various basic │
│calculations such as addition and subtraction. │
├─────────────────────────────────────────────────────────────────────────────┤
│In the advanced calculator, press ... │
├─────────────────────────────────────────────────────────────────────────────┤
│Confirmed to PEP8 standards (lines under 80 characters etc.) │
├─────────────────────────────────────────────────────────────────────────────┤
│Checked with pylint module and achieved 10/10 score. │
├─────────────────────────────────────────────────────────────────────────────┤
│To view the source code, type potato (exactly) in the prompt below. │
└─────────────────────────────────────────────────────────────────────────────┘
"""
#methods = {"basic_option()": basic_option()}
BASIC_CALCULATIONS = [{"calculation": "addition",
"symbol": "+",
"operator": operator.add},
{"calculation": "subtraction",
"symbol": "-",
"operator": operator.sub},
{"calculation": "multiplication",
"symbol": "*",
"operator": operator.mul},
{"calculation": "divsion",
"symbol": "/",
"operator": operator.truediv},
{"calculation": "integer division",
"symbol": "//",
"operator": operator.floordiv},
{"calculation": "modulo",
"symbol": "%",
"operator": operator.mod},
{"calculation": "powers",
"symbol": "**",
"operator": operator.pow}]
ADVANCED_CALCULATIONS = [{"calculation": "sine",
"symbol": "sin()",
"operator": math.sin},
{"calculation": "cosine",
"symbol": "cos()",
"operator": math.cos},
{"calculation": "tangent",
"symbol": "tan()",
"operator": math.tan}]
def if_tree(input_text, input_numbers, input_letters, outputs):
input_numbers_list = []
input_letters_list = []
output_list = []
for input_item in input_numbers:
input_numbers_list.append(input_item)
for input_item in input_letters:
input_letters_list.append(input_item)
for output_item in outputs:
output_list.append(output_item)
length_input_numbers = len(input_numbers)
length_input_letters = len(input_letters)
while True:
input_storage = str(input(input_text))
for i in range(length_input_numbers):
if input_storage == input_numbers_list[0]:
wait()
output_list[0]
elif input_storage == input_numbers_list[i+1]:
wait()
output_list[i+1]
else:
for i in range(length_input_letters):
if input_storage == input_letters_list[0]:
wait()
output_list[2]
elif input_storage == input_letters_list[i+1]:
wait()
output_list[i+1]
else:
wait()
incorrect_option()
def run_calculator():
"""Start the calculator"""
while True:
main_input = str(input(MAIN_TEXT))
if main_input == "1":
wait()
basic_option()
elif main_input == "2":
wait()
advanced_option()
elif main_input in ("Q", "q"):
wait()
quit_program()
elif main_input in ("H", "h"):
wait()
display_help()
elif main_input in ("R", "r"):
wait()
restart_calculator()
else:
wait()
incorrect_option()
def run_calculator():
pass
def basic_option():
"""Run the basic calculator"""
while True:
print("Now opening the basic calculator", end="", flush=True)
print_dots()
basic_input = str(input(BASIC_TEXT))
try:
if 1 <= int(basic_input) <= 7:
wait()
basic_calculator(int(basic_input) - 1)
else:
incorrect_option()
except ValueError:
if basic_input in ("Q", "q"):
quit_program()
elif basic_input in ("H", "h"):
display_help()
elif basic_input in ("R", "r"):
restart_calculator()
else:
incorrect_option()
def basic_calculator(name):
"""Run a basic calculator (+, -, etc.)"""
while True:
try:
print("Welcome to the",
BASIC_CALCULATIONS[name]["calculation"],
"calculator.")
wait()
number1 = float(input("\nPlease enter your first number. "))
number2 = float(input("Please enter your second number. "))
wait()
# prints number1 casted as a string
print("\n" + str(number1),
# prints the symbol of the equation
# from the BASIC_CALCULATIONS dictionary
str(BASIC_CALCULATIONS[name]["symbol"]),
# prints number2 casted as a string
str(number2),
# adds an equals sign
"=",
# code above takes the operator function
# from the BASIC_CALCULATIONS dictionary
# and performs it on number1 and number2,
# and casts it as a string to print the answer
str(BASIC_CALCULATIONS[name]["operator"](number1, number2)))
wait()
input("Press enter to continue.")
wait()
run_calculator()
except ValueError:
incorrect_option()
def advanced_option():
"""Run the advanced calculator"""
while True:
print("Now opening the advanced calculator", end="", flush=True)
print_dots()
advanced_input = str(input(ADVANCED_TEXT))
try:
if 1 <= int(advanced_input) <= 3:
wait()
advanced_calculator(int(advanced_input) - 1)
else:
incorrect_option()
except ValueError:
if advanced_input in ("Q", "q"):
quit_program()
elif advanced_input in ("H", "h"):
display_help()
elif advanced_input in ("R", "r"):
restart_calculator()
else:
incorrect_option()
def advanced_calculator(name):
"""Run an advanced calculator (+, -, etc.)"""
while True:
try:
print("Welcome to the",
ADVANCED_CALCULATIONS[name]["calculation"],
"calculator.")
wait()
dp = int(input("""\nHow many decimal places would you like your answer to? """))
number = float(input("\nPlease enter your number (in degrees): "))
number_radians = math.radians(number)
wait()
print(ADVANCED_CALCULATIONS[name]["calculation"] +
"(" +
str(number) +
")"+
" = " +
str(round(ADVANCED_CALCULATIONS[name]["operator"](number_radians),dp)))
wait()
input("Press enter to continue.")
wait()
run_calculator()
except ValueError:
incorrect_option()
def print_dots():
for i in range(3):
sleep(0.5)
print(".", end="", flush=True)
def display_help():
"""Display the help prompt."""
wait()
print(HELP_TEXT)
wait()
help_input = input("Press enter to continue...")
if help_input == "potato":
print("[Temporary placeholder]") # <-- fix at end
else:
wait()
def quit_program():
"""Quit the program."""
wait()
while True:
quit_input = input(
"\nAre you sure you want to quit the calculator? (Y/N) ")
if quit_input in ("Y", "y"):
break
elif quit_input in ("N", "n"):
wait()
print("Now returning to the calculator.")
wait()
run_calculator()
else:
incorrect_option()
continue
wait()
print("Now quitting", end="", flush=True)
print_dots()
wait()
raise SystemExit
def restart_calculator():
"""Restart the program."""
wait()
while True:
restart_input = input(
"\nAre you sure you want to restart the calculator? (Y/N) ")
if restart_input in ("Y", "y"):
break
elif restart_input in ("N", "n"):
return
else:
incorrect_option()
continue
wait()
print("Now restarting", end="", flush=True)
print_dots()
wait()
run_calculator()
def incorrect_option():
"""Tell the user they have entered an incorrect option."""
wait()
print("\nYou have entered an incorrect option. Please try again.")
wait()
def wait():
"""Waits the given amount of time"""
sleep(0.5) # comment this line out to stop the program waiting
# Runs the program
run_calculator()
if_tree(MAIN_TEXT, ["1", "2"], ["Q", "H", "R"], [basic_option()), advanced_option()), quit_program()), display_help()), exec("restart_calculator()")])I'm trying to optimise this code, so I thought I'd make the if lists into a callable function. However, whenever I try to call it (last line), it runs basic_option() instead. It's nothing to do with the code in if_tree() itself, because if I comment it all out the same thing still happens. However, if I replace the list of functions with something else, it works.
Basically the problem is python is calling the function in the call for if_tree unexpectedly.
Any advice on the code in general would be great as well!
If anyone can help that would be great!
Thanks in advance.
Reply
