Machinist Calculator

I’ve been working on learning Python. Below is a calculator I’m programming with functions that are useful for me. I’ve programmed most of this on my phone, hence all the line breaks for display on a small screen. I keep adding more functions as they occur to me. I will update this page as I go. You should be able to copy/paste the text into a Python editor and run it. Give it a ‘.py’ extension and run it on your computer. I think I’ve got everything here. Formatting may drop the ends of some lines. Check for missing ” or ).

 

import math


def do_over():
    """Creates an error message in case of bad input."""
    print("Error.")
    try_again = input("Do you want to start over? 'Y' for yes. Any other key for no. \n").lower()
    if try_again == "y":
        calculator()
    else:
        exit()


"""This section works with spot drill/countersink info."""
def drill_depth():
    drill_point_angle = float(input("Enter the drill point angle. \n"))
    chamfer_diameter = float(input("Enter the chamfer diameter. \n"))
    hole_diameter = float(input("Enter the hole diameter. \n"))
    depth = round((math.tan(math.radians(180 - drill_point_angle) / 2)) * (chamfer_diameter / 2), 4)
    chamfer_size = round((chamfer_diameter - hole_diameter) / 2, 4)
    print(f"Countersink to a depth of: {depth} for a {drill_point_angle}deg. "
          f"{chamfer_diameter}diameter chamfer.")
    print(f"Chamfer size will be: {chamfer_size}")

"""This section works with inch size taps."""
def cut_inch():
    nom_diam = float(input("Enter the nominal thread diameter as a decimal. \n"))
    per_engage = float(input("Enter the percent of thread engagement. \n"))
    threads_inch = float(input("Enter the number of threads per inch. \n"))
    tap_drill = round(nom_diam - (per_engage) / (76.98 * threads_inch), 4)
    print(f"Tap drill size: {tap_drill} for {per_engage}% {nom_diam}-{threads_inch} cut tap.")

def form_inch():
    nom_diam = float(input("Enter the nominal thread diameter as a decimal. \n"))
    per_engage = float(input("Enter the percent of thread engagement. \n"))
    threads_inch = float(input("Enter the number of threads per inch. \n"))
    tap_drill = round(nom_diam - (.0068 * per_engage) / threads_inch, 4)
    print(f"Tap drill size: {tap_drill} for {per_engage}% {nom_diam}-{threads_inch} form tap.")

def which_inch_tap():
    what_tap = int(input("Which type of tap? \n'1' for cut. \n'2' for form. \n"))
    if what_tap == 1:
        cut_inch()
    elif what_tap == 2:
        form_inch()

"""This section works with metric size taps."""
def cut_metric():
    nom_diam = float(input("Enter the nominal thread diameter. \n"))
    per_engage = float(input("Enter the percent of thread engagement. \n"))
    thread_pitch = float(input("Enter the pitch of the thread. \n"))
    tap_drill = round(nom_diam - (per_engage * thread_pitch) / 76.98, 4)
    print(f"Tap drill size: {tap_drill} for {per_engage}% M{nom_diam}×{thread_pitch} cut tap.")

def form_metric():
    nom_diam = float(input("Enter the nominal thread diameter. \n"))
    per_engage = float(input("Enter the percent of thread engagement. \n"))
    thread_pitch = float(input("Enter the pitch of the thread. \n"))
    tap_drill = round(nom_diam - (per_engage * thread_pitch) / 147.06, 4)
    print(f"Tap drill size: {tap_drill} for {per_engage}% M{nom_diam}×{thread_pitch} form tap.")

def which_metric_tap():
    what_tap = int(input("Which type of tap? \n'1' for cut. \n'2' for form. \n"))
    if what_tap == 1:
        cut_metric()
    elif what_tap == 2:
        form_metric()
        
        
"""Determines whether inch or metric tap."""
def tap_calculator():
    which_thread = int(input("Which thread? \n'1' for inch(unc/unf). \n'2' for metric. \n"))
    if which_thread == 1:
        which_inch_tap()
    elif which_thread == 2:
        which_metric_tap()
        

"""This section works with rotary broaching."""
def rotary_broach_hex():
    hex_flats = float(input("Enter dimension across the flats. \n"))
    drill_size = round(hex_flats * 1.035, 4)
    print(f"Drill {drill_size} diameter hole for a {hex_flats} hex socket.")

def rotary_broach_square():
    square_flats = float(input("Enter dimension across the flats. \n"))
    drill_size = round(square_flats * 1.1, 4)
    print(f"Drill {drill_size} diameter hole for a {square_flats} square socket.")

def which_shape():
    what_shape = int(input("Which shape? \n'1' for hex/torx. \n'2' for square. \n"))
    if what_shape == 1:
        rotary_broach_hex()
    elif what_shape == 2:
        rotary_broach_square()
        
"""This section determines preturn dimensions for hex and square shapes."""
def turn_hex():
    dim_hex = float(input("Enter the dimension across the hex flats as a decimal. \n"))
    turn_dim = round(2 * ((dim_hex / 2) / (math.sin(math.radians(60)))), 4)
    print(f"Turn to {turn_dim} for a {dim_hex} hex.")
    
def turn_square():
    dim_square = float(input("Enter the dimension across the square flats as a decimal. \n"))
    turn_dim = round(2 * ((dim_square / 2) / (math.sin(math.radians(45)))), 4)
    print(f"Turn to {turn_dim} for a {dim_square} square.")
    
def turn_random_shape():
    num_sides = int(input("Enter the number of sides. \n"))
    center_dist = float(input("Enter the distance from the center of the shape to the center of a flat edge. "
                              "\n"))
    turn_dim = round((2 * (center_dist)) / (math.sin(math.radians((180 - (360 / num_sides)) / 2))), 4)
    print(f"Turn to {turn_dim} for a {num_sides} sided shape with {center_dist} from center to the flats.")
    
def preturn_shape():
    turn_shape = int(input("Preturn which shape? \n'1' for hex. \n'2' for square. \n'3' for random shapes. \n"))
    if turn_shape == 1:
        turn_hex()
    elif turn_shape == 2:
        turn_square()
    elif turn_shape == 3:
        turn_random_shape()
    else:
        do_over()
        
        
"""This section works with speeds and feeds."""
def spindle_speed():
    surface_footage = float(input("What is the recomended surface footage? \n"))
    diameter_size = float(input("What is the diameter? \n"))
    revs_per_minute = round((12 * surface_footage) / (math.pi * diameter_size), 0)
    print(f"RPM is: {revs_per_minute} for {diameter_size} diameter at {surface_footage} SFM.")
    
def feed_rate():
    num_of_teeth = int(input("Enter the number of cutting teeth. \n"))
    feed_per_tooth = float(input("Enter the recommended feed per tooth. \n"))
    revs_per_minute = float(input("Enter the RPM. \n"))
    feed_rate = round(revs_per_minute * num_of_teeth * feed_per_tooth, 2)
    print(f"Feed rate is: {feed_rate} IPM for {feed_per_tooth} FPT at {revs_per_minute} RPM.")
    
def sfm_calc():
    r_p_m = int(input("Enter the RPM. \n"))
    tool_diam = float(input("Enter the diameter as a decimal. \n"))
    s_f_m = round(((r_p_m * tool_diam) / 3.82), 0)
    print(f"SFM is :{s_f_m} for {tool_diam} diameter running at {r_p_m} RPM.")
    
def speed_or_feed():
    speed_feed = int(input("Do you need RPM, feedrate, or SFM? \n'1' for RPM. \n'2' for feedrate. \n"
                           "'3' for SFM. \n"))
    if speed_feed == 1:
        spindle_speed()
    elif speed_feed == 2:
        feed_rate()  
    elif speed_feed == 3:
        sfm_calc()
         
         
def weight_matl():
    """Determines the weight of materials based on size and shape."""
    sel_matl = int(input("Select material. \n'1' for steel/stainless. \n'2' for aluminum/granite. \n"
                         "'3' for titanium. \n'4' for brass/bronze/inconel. \n"))
    if sel_matl == 1:
        """steel/stainless"""
        weight_matl = .2833
        des_matl = "steel/stainless"
    elif sel_matl == 2:
        """aluminum/granite"""
        weight_matl = .0975
        des_matl = "aluminum/granite"
    elif sel_matl == 3:
        """titanium"""
        weight_matl = .163
        des_matl = "titanium"
    elif sel_matl == 4:
        """brass/bronze/inconel"""
        weight_matl = .308
        des_matl = "brass/bronze/inconel"
    else:
        do_over()
    sel_shape = int(input("Select shape. \n'1' for rectangular bar. \n'2' for round rod. \n"))
    if sel_shape == 1:
        len_bar = float(input("Length in inches. \n"))
        wth_bar = float(input("Width in inches. \n"))
        hgt_bar = float(input("Height in inches. \n"))
        weight_bar = round(((len_bar * wth_bar * hgt_bar) * weight_matl), 2) 
        print(f"Weight of {des_matl} {len_bar} × {wth_bar} × {hgt_bar}: {weight_bar} lbs.")
    elif sel_shape == 2:
        diam_rod = float(input("Enter the diameter in inches. \n"))
        len_rod = float(input("Length in inches. \n"))
        weight_rod = round(((diam_rod / 2) **2) * (math.pi) * (len_rod) * weight_matl, 2)
        print(f"Weight of {des_matl} {diam_rod} × {len_rod} is {weight_rod} lbs.")
    else:
        do_over()
        
"""This section deals with unit conversion."""        
def dec_hours():
    """Converts decimal time to hours:minutes."""
    dec_hrs = float(input("Enter time as a decimal. \n"))
    hours = int(dec_hrs)
    minutes = (dec_hrs * 60) % 60
    print(f"{dec_hrs}hrs = %d:%02d" % (hours, minutes))
    
def inch_mm():
    """Convert inch to mm."""
    in_ch = float(input("Enter inches. \n"))
    m_m = round((in_ch * 25.4), 4)
    print(f"{in_ch}in. ={m_m}mm.")
    
def mm_inch():
    """Convert mm to inch."""
    m_m = float(input("Enter mm. \n"))
    in_ch = round((m_m / 25.4), 4)
    print(f"{m_m}mm.= {in_ch}in.")
    
def mi_km():
    """Convert miles to kilometers."""
    mi_le = float(input("Enter miles. \n"))
    k_m = round((mi_le * 1.609), 2)
    print(f"{mi_le}mi. = {k_m}km.")
    
def km_mi():
    """Convert kilometers to miles."""
    k_m = float(input("Enter kilometers. \n"))
    mi_le = round((k_m / 1.609), 2)
    print(f"{k_m}km. = {mi_le}mi.")
    
def degc_to_f():
    """Convert Celsius to Fahrenheit."""
    deg_c = int(input("Enter degrees Celsius. \n"))
    deg_f = round(((deg_c * (9/5)) + 32), 1)
    print(f"{deg_c}C = {deg_f}F.")
    
def degf_to_c():
    """Convert Fahrenheit to Celsius."""
    deg_f = int(input("Enter degrees Fahrenheit. \n"))
    deg_c = round((deg_f - 32) * (5/9), 1)
    print(f"{deg_f}F = {deg_c}C.")
    
def lbs_kg():
    """Convert pounds to kilograms."""
    wgt_lbs = float(input("Enter weight in pounds. \n"))
    wgt_kg = round((wgt_lbs * .454), 2)
    print(f"{wgt_lbs}lbs. = {wgt_kg}kg.")
    
def kg_lbs():
    """Convert kilograms to pounds."""
    wgt_kg = float(input("Enter the weight in kilograms. \n"))
    wgt_lbs = round((wgt_kg / .454), 2)
    print(f"{wgt_kg}kg. = {wgt_lbs}lbs.")
    
def conv_what():
    conv_unit = int(input("Convert what? \n'1' to convert decimal time to hh:mm \n'2' to convert inches to mm. "
                          "\n'3' to convert mm to inches. \n'4' to convert miles to km. "
                          "\n'5' to convert km to miles. \n'6' to convert Celsius to Fahrenheit. "
                          "\n'7' to convert Fahrenheit to Celsius. \n'8' to convert pounds to kilograms. "
                          "\n'9' to convert kilograms to pounds. \n"))
    if conv_unit == 1:
        dec_hours()
    elif conv_unit == 2:
        inch_mm()
    elif conv_unit == 3:
        mm_inch()
    elif conv_unit == 4:
        mi_km()
    elif conv_unit == 5:
        km_mi()
    elif conv_unit == 6:
        degc_to_f()
    elif conv_unit == 7:
        degf_to_c()
    elif conv_unit == 8:
        lbs_kg()
    elif conv_unit == 9:
        kg_lbs()
        


def speed_time():
    """Determines time to travel a distance."""
    dist_miles = int(input("Enter the distance in miles. \n"))
    speed_mph = int(input("Enter the speed in miles per hour. \n"))
    time = round((dist_miles / speed_mph), 3)
    hours = int(time)
    minutes = (time * 60) % 60
    print(f"To travel {dist_miles} miles at an average speed of {speed_mph}MPH is: %d:%02d" % (hours, minutes))


def center_finder():
    """Finds the midpoint of two locations."""
    dim_1 = float(input("Enter the first location. \n"))
    dim_2 = float(input("Enter the second location. \n"))
    center_loc = round(((dim_1 + dim_2) / 2), 4)
    print(f"Center between {dim_1} and {dim_2} is at {center_loc}.")    
    


def do_what():
    """This makes it work. Call new functionality here."""
    do_what = int(input("What do you want to do? \n'1' for spot drill/countersink depth. "
                        "\n'2' for tap drill info. \n'3' for rotary broach info. "
                        "\n'4' for preturn dimensions for hex, square and random shapes. "
                        "\n'5' for material weights. \n'6' to convert various units. "
                        "\n'7' to calculate trip travel time. \n'8' for speeds and feeds. "
                        "\n'9' to find center between two points. \n"))
    if do_what == 1:
        drill_depth()
    elif do_what == 2:
        tap_calculator()
    elif do_what == 3:
        which_shape()
    elif do_what == 4:
        preturn_shape()
    elif do_what == 5:
        weight_matl()
    elif do_what == 6:
        conv_what()
    elif do_what == 7:
        speed_time()
    elif do_what == 8:
        speed_or_feed()
    elif do_what == 9:
        center_finder()

def calculator():
    keep_going = True
    while keep_going:
        do_what()
        carry_on = input("Do you want to continue? Y or N. \n").lower()
        if carry_on == "y":
            keep_going = True
        elif carry_on == "n":
            keep_going = False
        else:
            print("Error")
            try_again = input("Do you want to continue? 'Y' for yes, any other key for no. \n").lower()
            if try_again == "y":
                keep_going = True
            else:
                keep_going = False
                
calculator()