Home » Programming » Implementation of the Calculator using Functions

# Implementation of the Calculator using Functions

In this post, we will step through the development of another Python program; we will develop simple calculator which can be used to add, subtract, multiply and divide numbers. The implementation of the calculator using Python functions to help modularize the code.

## What the Calculator will do?

This will be purely command driven application that will allow the user to specify

• the operation to perform and
• the two numbers to use with that operation.

When the program starts up it can use a loop to keep processing operations until the user indicates that they wish to terminate the application. We can also use an `if statement` to select the operation to perform. As such it will also build on several other features in Python that we have already been working with.

## Getting Started

The first step will be to create a Python file. The created file can be called anything you like, but calculator seems like a reasonable name. In newly created `calculator.py` file type in a welcome print message such as

`print ("Simple Calculator App")`

## The Calculator Operations

We are going to start by defining a set of functions that will implement the add, subtract, multiply and divide operations. All of these functions take two numbers and return another number. We have also given each function a docstring to illustrate their use, although in practice the functions are so simple and self-describing that the docstring is probably redundant.

The functions are listed below; we can now add them to the `calulator.py` file.

```def add (x, y):
return x + y

def subtract (x, y):
""" Subtracts two numbers """
return x - y

def multiply (x, y):
""" Multiplies two numbers """
return x * y

def divide (x, y):
""" Divides two numbers """
return x / y
```

## Behavior of the Calculator

Essentially, we want to allow the user to be able to select the operation they want to perform, provide the two numbers to use with the operation and then for the program to call the appropriate function. The result of the operation should then be presented to the user.

We then want to ask the user whether they want to continue to use the calculator or to exit the program. This is illustrated below in flowchart form.

Based on this flowchart, we can put in place the skeleton of the logic for the calculator’s processing cycle. We will need a while loop to determine whether the user has finished or not and a variable to hold the result and print it out.

The following code snippet provides this skeleton.

```finished = False
while not finished:
result = 0
# Get the operation from the user
# Get the numbers from the user
# Select the operation
print ("Result: ", result)
print ("=================================")
# Determine if the user has finished

print ("Thank You!")```

If we try to run this right now then we will find that this code will loop forever as the user is not yet prompted to say if they wish to continue or not. However, it does provide the basic framework; we have

• a variable, `finished`, with a Boolean flag in it to indicate if the user has finished or not. This is referred to as a flag because it is a Boolean value and because it is being used to determine whether to terminate the main processing loop or not.
• a variable to hold the result of the operation and the two numbers.
• the while loop representing the main processing loop of the calculator.

## Identifying Whether the User Has Finished

We could address several of the remaining areas next; however, we will select the last step that of determining if the user has finished or not. This will allow us to start to run the application so that we can test out the behavior. To do this we need to prompt the user to ask them if they want to continue using the calculator.

At one level this is very straight forward; we could ask the user to input ‘y’ or ‘n’ to indicate yes I have finished or no I want to keep going. Therefore, we could use the input function as follows.

``user_input = input ("Do you want to finish (y/n): ")``

We could then check to see if they have entered ‘y’ character and terminate the loop. However, anytime we take any input from something outside of our program (such as the user) we should verify the input. It is much better idea to verify that the input is what is expected and to reject any input until it is either a ‘y’ or an ‘n’.

We will call the function `check_if_user_has_finished()`; this name makes it very clear what the purpose of the function is. It also means that when we use it in our main processing loop its role in that loop will be obvious.

The function is given below:

```def check_if_user_has_finished():
""" Checks that the user wants to finish or not. Perform some verification of the input."""
ok_to_finish = True
user_input_accepted = False
while not user_input_accepted:
user_input = input ("Do you want to finish (y/n): ")
if user_input == 'y':
user_input_accepted = True
elif user_input == 'n':
ok_to_finish = False
user_input_accepted = True
else:
print ("Response must be (y/n), please try again")
return ok_to_finish```

We can now add this function into our main processing loop.

```finished = False
while not finished:
result = 0
# Get the operation from the user
# Get the numbers from the user
# Select the operation
print ("Result: ", result)
print ("=================================")
finished = check_if_user_has_finished()

print ("Thank You!")```

## Selecting the Operation

Next, let us implement the function used to obtain the operation to perform. Again, we need to name this function in such a way as to help with the comprehensibility of our program. In this case, we are asking the user select which operation they want to perform, so let’s call the function `get_operation_choice`.

This time we need to present a list of options to the user and then ask them to make a selection. Again, we want to write our function defensively, so that it makes sure that user only inputs a valid option; if they do not hen the function prompts them for another input. This means our function will have a loop and some validation code.

There are four options available to the user; add, subtract, multiply and divide. We will therefore number them 1 to 4 and ask the user to select an option between 1 and 4. To check that a value is in a set of other value (that is in one of the values in the set) we can use the in operator.

We can therefore, use it in our function to verify that the user entered a valid input.

```def get_operation_choice():
input_ok = False
while not input_ok:
print ("\t 2. Subtract")
print ("\t 3. Multiply")
print ("\t 4. Divide")
print ("------------------------------------")
user_selection = input ("Please make a selection: ")
if user_selection in ("1", "2", "3", "4"):
input_ok = True
else:
print ("Invalid Input - (must be 1 to 4)")
print ("---------------------------------------------------")
return user_selection ```

We can now update our main calculator loop with this function.

```finished = False
while not finished:
result = 0
# Get the numbers from the user
# Select the operation
print ("Result: ", result)
print ("=================================")
finished = check_if_user_has_finished()

print ("Thank You!")```

## Obtaining the Input Numbers

Next we need to obtain two numbers from the user to use with the selected operation. We need to ask the user for two numbers; we will therefore create a function which uses the get_integer_input() function to prompt the user for two numbers and then return both numbers.

```def get_numbers_from_user():
num1 = get_integer_input ("Input the first number: ")
num2 = get_integer_input ("Input the second number: ")
return num1, num2

def get_integer_input (message):
value_as_string = input (message)
while not value_as_string.isnumeric():
print ("The input must be an integer")
value_as_string = input(message)
return int(value_as_string)```

Having one function call another function is very common and indeed we have already been doing this; the `input()` function has been used several times, the only difference here is that we have written the `get_integer_input()` function ourselves.

When we can `get_numbers_from user()` function we can store the results returned into two variables; one for each result. Then our main calculator loop will be

```finished = False
while not finished:
result = 0
n1, n2 = get_numbers_from_user()
# Select the operation
print ("Result: ", result)
print ("=================================")
finished = check_if_user_has_finished()

print ("Thank You!")```

## Determining the Operation to Execute

We are now almost there and can update our main calculation loop with some logic to determine the actual operation to invoke. To do this we will use an if statement with the optional elif parts. The if statement will be conditional on the operation selected and will then call the appropriate function.

```if menu_choice == "1":
result = subtract (n1, n2)
result = multiply (n1, n2)
result = divide (n1, n2)```

Each part of the if statement calls a different function; but they all store the value returned into the `result` variable. We can now add this to the calculation loop.

```finished = False
while not finished:
result = 0
n1, n2 = get_numbers_from_user()
result = subtract (n1, n2)
result = multiply (n1, n2)
result = divide (n1, n2)
print ("Result: ", result)
print ("=================================")
finished = check_if_user_has_finished()

print ("Thank You!")```

Thus, we get our fully functional calculator loop as

```# Calculator Operations
return x + y

def subtract (x, y):
""" Subtracts two numbers """
return x - y

def multiply (x, y):
""" Multiplies two numbers """
return x * y

def divide (x, y):
""" Divides two numbers """
return x / y

# Identifying whether the user has finished
def check_if_user_has_finished():
""" Checks that the user wants to finish or not. Perform some verification of the input."""
ok_to_finish = True
user_input_accepted = False
while not user_input_accepted:
user_input = input ("Do you want to finish (y/n): ")
if user_input == 'y':
user_input_accepted = True
elif user_input == 'n':
ok_to_finish = False
user_input_accepted = True
else:
print ("Response must be (y/n), please try again")
return ok_to_finish

# Selecting the operation
def get_operation_choice():
input_ok = False
while not input_ok:
print ("\t 2. Subtract")
print ("\t 3. Multiply")
print ("\t 4. Divide")
print ("------------------------------------")
user_selection = input ("Please make a selection: ")
if user_selection in ("1", "2", "3", "4"):
input_ok = True
else:
print ("Invalid Input - (must be 1 to 4)")
print ("---------------------------------------------------")
return user_selection

# Obtaining the input numbers
def get_numbers_from_user():
num1 = get_integer_input ("Input the first number: ")
num2 = get_integer_input ("Input the second number: ")
return num1, num2

def get_integer_input (message):
value_as_string = input (message)
while not value_as_string.isnumeric():
print ("The input must be an integer")
value_as_string = input(message)
return int(value_as_string)

# Calculator loop
print ("Simple Calculator App")
finished = False
while not finished:
result = 0
n1, n2 = get_numbers_from_user()
result = subtract (n1, n2)
result = multiply (n1, n2)
result = divide (n1, n2)
print ("Result: ", result)
print ("=================================")
finished = check_if_user_has_finished()

print ("Thank You!")
```

## Running the Calculator

If we now run the calculator we will be prompted as appropriate for input. We can try and break the calculator by entering characters when numbers are requested, or values out of range for the operations etc. and it should be resilient enough to handle these erroneous inputs.

The final output for the calculator loop is obtained as

``````Simple Calculator App
2. Subtract
3. Multiply
4. Divide
------------------------------------
---------------------------------------------------
Input the first number: 5
Input the second number: 2
Result:  7
=================================
Do you want to finish (y/n): n
2. Subtract
3. Multiply
4. Divide
------------------------------------