import math
import operator
# Use a dictionary to define the menu of operations.
# Structure: key: (description, function, number_of_arguments, symbol)
OPERATIONS = {
'1': ("Add", operator.add, 2, '+'),
'2': ("Subtract", operator.sub, 2, '-'),
'3': ("Multiply", operator.mul, 2, '*'),
'4': ("Divide", operator.truediv, 2, '/'),
'5': ("Power", operator.pow, 2, '**'),
'6': ("Square Root", math.sqrt, 1, '√'),
'7': ("Exit", None, 0, None)
}
def get_operands(num_args: int) -> list[float]:
"""Prompts the user for the required number of operands and validates them."""
operands = []
for i in range(num_args):
while True:
try:
prompt = f"Enter the {i + 1}{'st' if i == 0 else 'nd' if i == 1 else 'rd' if i == 2 else 'th'} number: "
if num_args == 1:
prompt = "Enter the number: "
num = float(input(prompt))
operands.append(num)
break
except ValueError:
print("Invalid input. Please enter a number.")
return operands
def present_menu(operations: dict) -> str:
"""Displays the menu of options and returns a validated user choice."""
print("\nSelect operation.")
for key, (description, _, _, _) in operations.items():
print(f"{key}. {description}")
while True:
choice = input(f"Enter choice ({', '.join(operations.keys())}): ")
if choice in operations:
return choice
else:
print("Invalid choice. Please select a valid option.")
def main():
"""Main function to run the calculator."""
while True:
choice = present_menu(OPERATIONS)
description, operation_func, num_args, symbol = OPERATIONS[choice]
if operation_func is None: # Exit condition
print("bye")
break
operands = get_operands(num_args)
# Add error handling for specific operations
if operation_func == operator.truediv and operands[1] == 0:
print("Error: Cannot divide by zero.")
elif operation_func == math.sqrt and operands[0] < 0:
print("Error: Cannot take the square root of a negative number.")
else:
result = operation_func(*operands)
# Format the output string based on the operation
if num_args == 2:
print(f"{operands[0]} {symbol} {operands[1]} = {result}")
elif num_args == 1:
print(f"{symbol}{operands[0]} = {result}")
# Ask user if they want to continue
while True:
next_calc = input("Continue? (y/n): ").lower()
if next_calc in ('y', 'n'):
break
else:
print("Invalid input, Enter y or n.")
if next_calc == 'n':
print("bye")
break
if __name__ == "__main__":
main()