Improving the calculator
Goal
The previous calculator can be considered a minimal viable product; therefore, it has some weaknesses. Our goal in this page is to analyze what can be done to improve it.
Previous Python Code w/ Commentary
# Basic Calculator
# Input Handling
number1 = int(input("Enter number 1: "))
number2 = int(input("Enter number 2: "))
# Since we convert the inputs to integers, we cannot handle inputs with decimals.
# There is no feature built-in to our code to prevent non-numeric inputs at the moment.
# Operations
result1 = number1 + number2
result2 = number1 - number2
result3 = number1 * number2
result4 = number1 / number2
# Instead of asking the user which operation to perform, we execute all the operations.
# Output
print(f"{number1} + {number2} = {result1}")
print(f"{number1} - {number2} = {result2}")
print(f"{number1} * {number2} = {result3}")
print(f"{number1} / {number2} = {result4}")
Extended Requirements
Ability to choose a desired operation (add, subtract, multiply, divide) from the user
Put restrictions on the inputs so that the inputted values from the user are numeric
Allow the program to obtain decimal inputs.
Put restrictions on the denominator when dividing; cannot be zero.
Execute the desired operation with the given inputs and store the result
Output the stored results back to the user
User Chooses Desired Operation
# User choosing a desired operation
print('''Please choose one of the following possible operations:
- 1. Add
- 2. Subtract
- 3. Multiply
- 4. Divide
''')
choice = None
while True:
choice = input("Option chosen: ")
choice = choice.lower()
if choice not in {'add', 'subtract', 'multiply', 'divide'}:
print("Invalid option, please choose again.")
else:
print(f"Operation {choice} was chosen.")
break
# end of desired operation handling
Code 1 Explanation:
Printing the Operation Choices:
print('''Please chooses the following possible operations:
- 1. Add
- 2. Subtract
- 3. Multiply
- 4. Divide
''')
This block of code uses a multi-line string (enclosed in triple single quotes) to print a list of possible operations the user can choose from.
The operations are listed as Add
, Subtract
, Multiply
, and Divide
.
Initializing the Choice Variable:
choice = None
This initializes the variable choice
to None
. This step is not strictly necessary since the variable is immediately assigned a value inside the while
loop, but it can be useful for clarity and to avoid potential reference before assignment errors.
Starting an Infinite Loop:
while True:
This begins an infinite loop, which will keep running until it is explicitly broken.
Prompting the User for Input:
choice = input("Option chosen: ")
choice = choice.lower()
Inside the loop, the user is prompted to input their choice of operation. The input
function captures this input as a string. The choice.lower()
method converts the input to lowercase to ensure case-insensitivity when checking the user's input.
Validating the User's Choice:
if choice not in {'add', 'subtract', 'multiply', 'divide'}:
print("Invalid option, please choose again.")
else:
print(f"Operation {choice} was chosen.")
break # Added break to exit the loop when a valid choice is made
The code checks if the user's input (choice
) is one of the valid operations ('add'
, 'subtract'
, 'multiply'
, 'divide'
).
If the input is not valid, it prints an error message and the loop continues, prompting the user again.
If the input is valid, it prints a confirmation message and breaks out of the loop, ending the infinite loop.
Numeric Inputs Only + Supporting Decimals
# Numeric Inputs Only
number1 = None
while True:
try:
user_input = input("Enter number 1:")
number1 = float(user_input)
print(f"First Input: {number1}")
break
except ValueError:
print(f"{user_input} cannot be converted to a floating point value")
Code 2 Explanation:
Variable Initialization:
codenumber1 = None
This initializes the variable number1
to None
. This variable will later store the user's input after it has been successfully converted to a float.
Infinite Loop:
while True:
The while True
loop runs indefinitely until it is explicitly broken. This allows the program to continually prompt the user for input until valid input is received.
Try Block:
try:
user_input = input("Enter number 1:")
number1 = float(user_input)
print(f"First Input: {number1}")
break
user_input = input("Enter number 1:")
: This line prompts the user to enter a value and stores the input as a string inuser_input
.number1 = float(user_input)
: This line attempts to convert the input string to a floating point number and assigns it tonumber1
.print(f"First Input: {number1}")
: If the conversion is successful, this line prints the successfully converted floating point number.break
: If the conversion and print statements are successful, thebreak
statement exits the infinite loop, indicating that valid input has been received.
Except Block:
except ValueError:
print(f"{user_input} cannot be converted to a floating point value")
If the conversion
float(user_input)
raises aValueError
(meaning the input could not be converted to a float), theexcept
block is executed.print(f"{user_input} cannot be converted to a floating point value")
: This line prints an error message indicating that the input was invalid and could not be converted to a float.
# Numeric Input Code held in a function
def numericInput(prompt: str) -> float:
number1 = None
while True:
try:
user_input = input(prompt)
number1 = float(user_input)
print(f"First Input: {number1}")
return number1 # instead of break
except ValueError:
print(f"{user_input} cannot be converted to a floating point value")
# end of numericInput()
Restrict Division by Zero
-- lets assume that variable: choice = "divide"
# Restrict Division by Zero
if choice == "divide":
try:
result = number1 / number2
except ZeroDivisionError:
result = None
print(f"Since the variable number2 is a zero, there is no solution.")
Conditional Check:
if choice == "divide":
This line checks if the user has chosen the division operation. If choice
is equal to the string "divide"
, the code inside the if
block will be executed.
Try Block:
try:
result = number1 / number2
The try
block attempts to perform the division number1 / number2
.
If number2
is not zero, the division is successful, and the result is assigned to the variable result
.
Except Block:
except ZeroDivisionError:
result = None
print(f"Since the variable number2 is a zero, there is no solution.")
If number2
is zero, attempting to divide by zero raises a ZeroDivisionError
.
The except
block catches this exception.
Inside the except
block, result
is set to None
to indicate that the division could not be performed.
A message is printed to inform the user that division by zero is not possible.
The Full Final Code
# Basic Calculator v2
# Numeric Input Code held in a function
def numericInput(prompt: str) -> float:
number1 = None
while True:
try:
user_input = input(prompt)
number1 = float(user_input)
print(f"First Input: {number1}")
return number1 # instead of break
except ValueError:
print(f"{user_input} cannot be converted to a floating point value")
# end of numericInput()
# User choosing a desired operation
print('''Please chooses the following possible operations:
- 1. Add
- 2. Subtract
- 3. Multiply
- 4. Divide
''')
choice = None
while True:
choice = input("Option chosen: ")
choice = choice.lower()
if choice not in {'add', 'subtract', 'multiply', 'divide'}:
print("Invalid option, please choose again.")
else:
print(f"Operation {choice} was chosen.")
break
# end of desired operation handling
# Using our custom numericInput Function
number1 = numericInput("Enter Number 1: ")
number2 = numericInput("Enter Number 2: ")
# Doing our desired calculation
result = None
if choice == "add":
result = number1 + number2
elif choice == "subtract":
result = number1 - number2
elif choice == "multiply":
result = number1 * number2
elif choice == "divide":
# Restrict Division by Zero
if choice == "divide":
try:
result = number1 / number2
except ZeroDivisionError:
result = None
print(f"Since the variable number2 is zero, there is no solution.")
# Outputting the result
if result is not None:
print(f"The result is: {result}.")
Code Explanation:
Defining the Numeric Input Function
# Numeric Input Code held in a function
def numericInput(prompt: str) -> float:
number1 = None
while True:
try:
user_input = input(prompt)
number1 = float(user_input)
print(f"First Input: {number1}")
return number1 # instead of break
except ValueError:
print(f"{user_input} cannot be converted to a floating point value")
# end of numericInput()
def numericInput(prompt: str) -> float:
defines a function namednumericInput
that takes a stringprompt
and returns a float.Inside the function, an infinite loop is used to repeatedly prompt the user for input until a valid float is provided.
The
try...except
block attempts to convert the user's input to a float and returns it if successful. If not, it catches theValueError
and prompts the user again.
User Choosing a Desired Operation
# User choosing a desired operation
print('''Please choose the following possible operations:
- 1. Add
- 2. Subtract
- 3. Multiply
- 4. Divide
''')
choice = None
while True:
choice = input("Option chosen: ").lower()
if choice not in {'add', 'subtract', 'multiply', 'divide'}:
print("Invalid option, please choose again.")
else:
print(f"Operation {choice} was chosen.")
break
# end of desired operation handling
A multi-line string is printed to show the user the available operations.
An infinite loop prompts the user to choose an operation.
The user's input is converted to lowercase to ensure case-insensitive comparison.
If the input is not a valid option, the user is prompted again. If it is valid, the loop breaks.
Using the Numeric Input Function
# Using our custom numericInput Function
number1 = numericInput("Enter Number 1: ")
number2 = numericInput("Enter Number 2: ")
numericInput()
:
The
numericInput()
function is called twice to get two numeric inputs from the user, storing them innumber1
andnumber2
.
Performing the Desired Calculation
# Doing our desired calculation
result = None
if choice == "add":
result = number1 + number2
elif choice == "subtract":
result = number1 - number2
elif choice == "multiply":
result = number1 * number2
elif choice == "divide":
# Restrict Division by Zero
if choice == "divide":
try:
result = number1 / number2
except ZeroDivisionError:
result = None
print(f"Since the variable number2 is a zero, there is no solution.")
Performing the Operation:
Based on the user's choice, the appropriate arithmetic operation is performed.
If the user chose "divide" -> a
try...except
block handles the possibility of division by zero.If
number2
is zero, aZeroDivisionError
is caught, andresult
is set toNone
.
Outputting the Result
# Outputting the result
if result is not None:
print(f"The result is: {result}.")
If
result
is notNone
, it means the calculation was successful, and the result is printed.If
result
isNone
, it indicates an error occurred (e.g., division by zero), and no result is printed.
Key Points:
Input Validation: The
numericInput
function ensures only valid numeric inputs are accepted.Operation Selection: A loop ensures the user selects a valid operation.
Error Handling: Division by zero is handled gracefully using a
try...except
block.Function Reusability: The
numericInput
function is reusable for any numeric input prompt, making the code modular and clean.
Last updated