solution_004.py

#!/usr/bin/python3
# ==================================================================
# Cannonball Flight Time and Distance
# Note: code has hidden (default) values built in for testing
# ==================================================================


import sys
import user_interface as ui

from math import pi, radians, cos, sin

mvmin   = 100.0                # minimum muzzle velocity
mvmax   = 2000.0               # maximum muzzle velocity
angmin  = 10.0                 # minimum angle
angmax  = 85.0                 # maximum angle

default_mv  = 100.0            # default muzzle velocity
default_ang = 45.0             #  angle


# -------------------------------------------------------------------
# ---- display description
# -------------------------------------------------------------------

def description():

    txt =  f'''
--------------------- Fire a Cannon --------------------
muzzle velocity (feet/second)  ({mvmin} <= mv  <= {mvmax})
muzzle angle    (degrees)      ({angmin} <= ang <= {angmax})
'''

    print()
    print(txt)
    print()


# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------

if __name__ == '__main__':

    description()

    while(True):

        # ---- ask the user for the muzzle velocity

        while(True):

            print()

            s = ui.get_user_input('Enter muzzle velocity (f/s): ')

            if not s:
                print()
                sys.exit()

            if s == 'z':         # default value - good for testing
                mv = default_mv
                break

            x,mv = ui.is_float(s)

            if not x:
                print()
                print('You did not enter a number - try again')
                continue

            if mv < mvmin or mv > mvmax:
                print()
                print('illegal muzzle velocity - try again')
                continue

            break

        # ---- ask the user for the angle above horizontal

        while(True):

            print()

            s = ui.get_user_input('Enter muzzle angle (deg): ')

            if not s:
                print()
                sys.exit()

            if s == 'z':         # default value - good for testing
                ang = default_ang
                break

            x,ang = ui.is_float(s)

            if not x:
                print()
                print('You did not enter a number - try again')
                continue

            if ang < angmin or ang > angmax:
                print()
                print('illegal angle - try again')
                continue

            break

        # ---- do the calculations

        vv = sin(radians(ang)) * mv  # vertical   velocity
        vh = cos(radians(ang)) * mv  # horizontal velocity

        top = vv/32.00               # time to top of arc

        tt  = 2 * top                # total flight time

        dh = tt * vh                 # horizontal distance traveled

        dv = vv**2/(2*32.0)          # vertical distance to top of arc

        print()
        print(f'muzzle velocity    : {round(mv,2):<8}   (ft/sec)')
        print(f'muzzle angle       : {round(ang,2):<8}   (deg)')
        print(f'vertical velocity  : {round(vv,2):<8}   (ft/sec)')
        print(f'horzontal velocity : {round(vh,2):<8}   (ft/sec)')
        print(f'time to top of arc : {round(top,2):<8}   (sec)')
        print(f'total flight time  : {round(tt,2):<8}   (sec)')
        print(f'distance horizontal: {round(dh,2):<8}   (ft)')
        print(f'distance vertical  : {round(dv,2):<8}   (ft)')

        ui.pause()