

import math
from numpy import linspace
import matplotlib.pyplot as plt

def bisection(f,x1,x2):
    fx1=f(x1)
    fx2=f(x2)
    
    if fx1*fx2>0:
        print('f(x1) and f(x2) must have different sing')
        return None
    
    for _ in range(50):
        
        x3=(x1+x2)/2
        fx3=f(x3)
        
        if fx3== 0:
            break
        
        if fx1*fx3>0:
            x1, fx1 =x3,fx3
            
        if fx2*fx3>0:
            x2, fx2 =x3,fx3
            
    return x3

def f(c): return ((9.8*68.1)/c)*(1-(math.exp(-10*c/68.1)))-40

"""
If this file is being imported from another module, __name__ will be set to the module’s name.
Module’s name is available as value to __name__ global variable.
You can test whether your script is being run directly or being imported by something else by testing __name__ variable.
This code is important to us. Because we need to distinguish between the values ​​of the root operations (series values) 
and the values ​​for which the graph is calculated.
"""
if __name__ == "__main__":
    if True: 
        cs = linspace( 4.0,+20.01,1000 ) # The series to be calculated for the graph.
        fcs = [ f(_) for _ in cs ] #We replaced the unknown of the F () equation with cs.
        
plt.plot( cs, fcs ); 
plt.axhline(y=0,color='k')#Darken the y-axis color.
plt.xlabel('c')
plt.ylabel('f(c)')
plt.grid() 
plt.show()

root = bisection( f, 12.,16.)
print (root)


"""
zz=f(4)   #f(4)=34.114844174677984   f(20)= -8.400628721768179
print(zz)
"""