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