# Calculator that does basic functions and area/volume in Python 3.6

This is my first big project that I've made in Python. I've noticed as I was writing it that it's extremely repetitive and I just don't know how to make it less so.

# This is a basic calculator that also has area/volume calculations for certain shapes.

import math
import sys

def main():
choice = input('Which operation would you like?\n'
'1) Area\n'
'2) Volume\n'
'3) Basic Math\n'
'4) Quit\n')

if choice == '1':
area()
elif choice == '2':
volume()
elif choice == '3':
basic_math()
elif choice == '4':
sys.exit('Choice 4 selected.  Quitting...')
else:

# Menu to choose which area you'd like to calculate
def area():
choice = input('Please enter what you\'d like to calculate\n'
'1) Area of a square\n'
'2) Area of a rectangle\n'
'3) Area of a circle\n'
'4) Area of a triangle\n'
'5) Area of a equilateral triangle\n'
'6) Area of a trapezoid\n'
'7) Area of a cube\n'
'8) Quit\n'

try:
if choice == '1':
area_of_square()

elif choice == '2':
area_of_rectangle()

elif choice == '3':
area_of_circle()

elif choice == '4':
area_of_triangle()

elif choice == '5':
area_of_equilateral_triangle()

elif choice == '6':
area_of_trapezoid()

elif choice == '7':
area_of_cube()

elif choice == '8':
sys.exit('Choice 8 selected.  Quitting...')

elif choice == '9':
main()

else:
main()
except NameError:
print('You forgot to define a function!')
area()

def volume():
choice = input('Please enter what you\'d like to calculate\n'
'1) Volume of a cube\n'
'2) Volume of a sphere\n'
'3) Volume of a cylinder\n'
'4) Volume of a cone\n'
'5) Volume of a rectangular prism\n'
'6) Volume of a triangular prism\n'
'7) Quit\n'
try:
if choice == '1':
volume_of_cube()

elif choice == '2':
volume_of_sphere()

elif choice == '3':
volume_of_cylinder()

elif choice == '4':
volume_of_cone()

elif choice == '5':
volume_of_rect_prism()

elif choice == '6':
volume_of_tri_prism()

elif choice == '7':
sys.exit('Option 7 selected.  Quitting...')

elif choice == '8':
main()

else:
volume()

except NameError:
print('Programmer forgot to define a function!')
volume()

def basic_math():
choice = input('Please enter which operation you would like\n'
'2) Subtraction\n'
'3) Multiplication\n'
'4) Division\n'
'5) Quit\n'

try:
if choice == '1':

elif choice == '2':
subtraction()

elif choice == '3':
multiplication()

elif choice == '4':
division()

elif choice == '5':
sys.exit('Option 5 selected.  Quitting...')

elif choice == '6':
main()

else:
print('I\'m sorry, I didn\'t understand your input.')
basic_math()
except NameError:
print('Programmer forgot to define a function! How lazy of him/her')
basic_math()

#############################################
# Start Basic Math functions
#############################################

try:
y = int(input('Please enter the next value '))
print('The sum is {0}'.format(x + y))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')

def subtraction():
try:
print('The value is {0}'.format(x - y))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
subtraction()

def multiplication():
try:
print('The value is {0}'.format(x * y))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
multiplication()

def division():
try:
print('The value is {0}'.format(x / y))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
division()

#################################################
# End Basic Math Functions, start area
#################################################

def area_of_square():
try:
area = int(input('The area of your square is... '))
print(area**2)
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_square()

def area_of_circle():
try:
print(area)
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_circle()

def area_of_triangle():
try:
base = int(input('Please enter the base... '))
height = int(input('Please enter the height...'))
print(base * height / 2)
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_triangle()

def area_of_equilateral_triangle():
try:
area = int(input('The area of your equilateral triangle is... '))
x = math.sqrt(3) / 4 * area**2
print(x)
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_equilateral_triangle()

def area_of_trapezoid():
try:
a = int(input('Enter base 1: '))
b = int(input('Enter base 2: '))
height = int(input('Enter the height: '))
# For some reason, when this was on the same line, it messed up the
# order of operations, so I set the formula into 3 different variables.
area = a + b
area1 = area / 2
area2 = area1 * height
print('The area is {0}'.format(area2))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_trapezoid()

def area_of_cube():
try:
a = int(input('Enter an edge of your cube... '))
area = 6 * a**2
print('The area of your cube is {0}'.format(area))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
area_of_cube()

#######################################################################
# End Area functions here: Start Volume functions.
#######################################################################

def volume_of_cube():
try:
a = int(input('Enter an edge of your cube... '))
volume = a**3
print('The volume of your cube is {0}'.format(volume))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
volume_of_cube()

def volume_of_cone():
try:
r = int(input('Enter the radius... '))
h = int(input('Enter the height... '))
volume = math.pi * r**2 * h / 3
print('The volume of the cone is {0}'.format(volume))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
volume_of_cone()

def volume_of_sphere():
try:
volume = 4/3 * math.pi * r**3
print('The volume of your sphere is {0}'.format(volume))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
volume_of_sphere()

def volume_of_cylinder():
try:
h = int(input('Enter the height of your cylinder... '))
volume = math.pi * r**2 * h
print('The volume of yoru cylinder is {0}'.format(volume))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
volume_of_cylinder()

def volume_of_rect_prism():
try:
w = int(input('Enter the width '))
h = int(input('Enter the height '))
l = int(input('Enter the length '))
volume = l * w * h
print('The volume of the rectangular prism is {0}'.format(volume))
except ValueError:
print('You entered alphabetic characters!  Please enter integers only.')
volume_of_rect_prism()

#def volume_of_tri_prism():
#    try:
#        a = int(input('Enter 1st base side '))
#        b = int(input('Enter 2nd base side '))
#        c = int(input('Enter 3rd base side '))
#        h = int(input('Enter the height '))
#        volume = 1 / 4 * h
#        volume1 = a**4 + 2(a + b)**2
#        print('The volume of the triangular prism is {0}'.format(volume))
#    except ValueError:
#        print('You entered alphabetic characters!  Please enter integers only.')
#        volume_of_tri_prism()

if __name__ == "__main__":
main()


The main problem is the repetetiveness and nestedness when it comes to reading user inputs and mapping them to the function calls. You are currently using multiple if/else branches, but, what if you would use a dictionary to map choices into function names:

COMMANDS = {
'2': subtraction,
'3': multiplication,
'4': division,
'5': exit,
'6': main
}

if choice not in COMMANDS:
print('I\'m sorry, I didn\'t understand your input.')
basic_math()
else:
COMMANDS[choice]()


Note that exit here is a function you might have to exit the app.

Also, look through the third-party apps in the CLI space - there might be a tool that can ease creating this kind of question-choice style programs.

Here are some other notes:

• the program is too long - split it into multiple logical parts to have a better separation of concern and modularity. For example, the calculations of areas and volumes should be separated from the question-choice handling functions
• you can use multi-line strings instead of having regular strings with newline characters
• you can wrap the string inside the print() statement around double quotes so that you won't need to escape the single quote (credit to @Dex'ter):

"I'm sorry, I didn't understand your input."

• You can wrap the string inside the print() statement around double quotes so that you won't need to escape the single quote: print("I'm sorry, I didn't understand your input.") Commented Feb 13, 2017 at 16:45
• I ran this code with your dictionary, but then it runs each function, instead of just stopping at one. Any way around this? Commented Feb 13, 2017 at 16:46
• @LeviPorter you are probably running/calling the functions - make sure to not have () after the function names in the dictionary. Commented Feb 13, 2017 at 16:48
• @Dex'ter included your suggestion into the answer, thanks! Commented Feb 13, 2017 at 16:48
• @alecxe You were right, I was calling the functions. Thank you. Commented Feb 13, 2017 at 16:50