import operator
import functools
'''
Copy and Run this program on
      https://repl.it/X3G
			or
	  Google ‘repl.it python shell’ and chose the second link
	  (NOT the Python 2.7 Editor)
to test the program!

Make sure to use a Python 3 language runner
'''
while(1==1):
    print("Welcome to the Simple Machine Calculator"+'\n'+"Make sure to run this in Python 3!")
    type = str(input(("Type 'GR_Calc()' to run the Gear Train Calculator."+'\n'+"Type 'MA_Calc()' to run the Mechanical Advantage Calculator: ")))
    # THE CODE BELOW IS THE MECHANICAL ADVANTAGE CALCULATOR (Run "MA_Calc()" in the terminal to use)
    if(type=="MA_Calc()"):
        print("AMA Enter")                        #To begin with calculating AMA...
        rForce = float(input("Enter rForce: "))   #We entered the resistance force of 30N
        eForce = float(input("Enter eForce: "))   #We entered the effort we input at the crank
        print('===')
        print("IMA Enter")                        #Then onto finding IMA...
        eDist = float(input("Enter eDist: "))     #This is where we enter the effort distance of a simple machine (i.e. the wheel radius)
        rDist = float(input("Enter rDist: "))     #Then we entered the resistance distance of that simple machine part (i.e. the wheel's axle)
        
        AMA = rForce/eForce    #This is the formula for AMA, given resistance and effort forces
        IMA = eDist/rDist      #This is the formula for IMA, given effort and resistance distances
        Eff = (AMA/IMA)*100    #And then efficiency, AMA divided by IMA expressed as a percent
        
        print("AMA:",str(AMA))
        print("IMA:",str(IMA))
        print("Eff:",str(Eff)+'\n')
        
        print("---------------------")
        print("Constant Resistance Force of:",rForce)
        print("Increase efficiency by:")
        eF_needed = rForce/IMA
        eD_needed = AMA*rDist
        rD_needed = eDist/AMA
        
        print("eForce close to:",eF_needed)
        print("eDistance close to:",eD_needed)
        print("rDistance close to:",rD_needed)

    # THE CODE BELOW IS THE COMPOUND GEAR TRAIN CALCULATOR PROGRAM (Run "GR_Calc()" in terminal to use)
    if(type=="GR_Calc()"):                  # This only calculates for COMPOUND GEAR TRAINS with even number of gears
        
        initGear = str(input("Enter each gear (identified as letters) in your gear train, separated by spaces: "))
                                    # The code above, the USER inputs how many gears to calculate (i.e. 4 gears: A,B,C,D)
                                                    
        gears = initGear.split(" ") # This would take the number of gears (i.e. A, B, C, D) and put them into a list
        gearTeeth = []              # This will later hold the gear teeth for each corresponding A,B,C,D gears in the 'gears' list
        gearRatio = []              # And this will later hold the separate calculated gear ratios between each gear set
        print(gears)

        
        for i in range(len(gears)): # Repeat this code for however many gears (i.e. A,B,C,D is 4 times) the USER inputs
            teethEnter = int(input("Enter the number of gear teeth in the " + gears[i] + " gear: ")) #The USER would then input teeth of each gear here
            gearTeeth.append(teethEnter) #The gearTeeth list would be updated with gear teeth values
        print(gearTeeth)

        
        gearDriver = str(input("Which end of the gear train will be the driver? (" + gears[0] + " or " + gears[len(gears)-1] + "): "))
                                    # The line above would then determine the driver gear (either the left one "A" or the very right one "last gear")                        
        if(gearDriver == "A" or gearDriver == "a"): # If the driver gear was the very left one, it would divide from RIGHT to LEFT
            i = 0 

            
            while(i<len(gears)-1):  # This would keep repeating calculations until all gears ratio sets are divided by (i.e. 4 gears = 2 sets)
                print("Dividing",gearTeeth[i+1],"by",gearTeeth[i]) 
               # For example, 'i+1' would be the 2nd gear in the 'gearTeeth' list and 'i' would be the first one. 
               # It would now divide the 2nd gear's teeth by the 1st gear's teeth, finding us one part of the gear ratio

                gearRatio.append(gearTeeth[i+1]/gearTeeth[i]) # This now stores the value of our separate gear ratios into the 'gearRatio' list

                i += 2 # THIS is what allows the program to calculate ONLY COMPOUND gear trains.
                       # By incrementing 'i' by 2, it makes sure that we are only calculating for DIRECTLY linked gears, not compounded gears
                       # For example, I have gear A,B,C,D. 'i=0' is the first gear (A), 'i=1' the second (B), 'i=2' third (C), and 'i=3' is (D)
                       # A is DIRECT to B, B is COMP to C, and C is DIRECT to D
                       # So then we divide the '0+1' (gear B) by '0' (gear A) -> Increment 'i' by 2 -> divide the '2+1' (gear D) by '2' (Gear C)
                       # The increase by 2 skips the division between (gear C) / (gear B), which would be incorrect for a COMPOUND gear train ratio
                       
                       # You can use Example (2) on the 1.1.3/4 Power Trains Worksheet on Compound Gear Trains to test this program
                       # There are online python shells, and type "GR_Calc()" into the terminal to run the gear calculator

                                                 
        else:          # This block of code is the same as above, just that it reverses the order of gears if the driver gear is the right-end gear
            gearTeeth.reverse()  
            i = 0
            while(i<len(gears)-1):
                print("Dividing",gearTeeth[i+1],"by",gearTeeth[i])
                gearRatio.append(gearTeeth[i+1]/gearTeeth[i])
                i += 2
        print(gearRatio)

    
                       # Finally, we multiply together all of the separate gear ratios (from the 'gearRatio' list) together to get TOTAL GEAR RATIO
        print("Total gear ratio:",functools.reduce(operator.mul, gearRatio, 1))