from matplotlib.backends.backend_pdf import PdfPages %matplotlib inline def inverse_supply(quantity): '''Inverse supply function $p_s = {\sqrt{q_s} }$, where quantity is inputed and price is output''' return (math.sqrt(quantity)) def inverse_supply_with_tax(quantity): '''Inverse supply function with the tax added $p_s = {\sqrt{q_s} } + 2$, where quantity is inputed and price is output''' return inverse_supply(quantity) + 2 def inverse_demand(quantity): '''Inverse demand function $p_d = 100e^{-q_d}$, where quantity is inputed and price is output''' return 100 * math.pow(math.e, (0 - quantity)) def calculate_equilibrium(supply_func, demand_func): '''Loops through quantity values for supply and demand and finds where the two functions intersect within 0.0001 ''' equilibrium = 0.0001 p_s = supply_func(equilibrium) p_d = demand_func(equilibrium) while abs(p_s - p_d) > 0.0001 and equilibrium < 100: p_s = supply_func(equilibrium) p_d = demand_func(equilibrium) equilibrium += 0.0001 return equilibrium def build_line(func, X): '''build a list of y values based on x values for a given function''' y = [] for point in X: y.append(func(point)) return y def fill_consumer_surplus(X, equilibrium_w_tax): x_below_equilibrium = [point for point in X if point <= equilibrium_w_tax] y_below_equilibrium = [] y_above_equilibrium = [] for point in x_below_equilibrium: y_below_equilibrium.append(inverse_demand(point)) y_above_equilibrium.append(inverse_demand(equilibrium_w_tax)) plt.fill_between(x_below_equilibrium, y_below_equilibrium, y_above_equilibrium, step="pre", color = "c", alpha=0.4, label='CS') # fill in area for consumer surplus def fill_producer_surplus(X, equilibrium_w_tax): x_below_equilibrium = [point for point in X if point <= equilibrium_w_tax] y_below_equilibrium = [] y_above_equilibrium = [] for point in x_below_equilibrium: y_below_equilibrium.append(inverse_supply(point)) y_above_equilibrium.append(inverse_supply(equilibrium_w_tax)) plt.fill_between(x_below_equilibrium, y_below_equilibrium, y_above_equilibrium, step="pre", color = "orange", alpha=0.4, label='PS') # fill in area for consumer surplus def fill_dead_weight(X, equilibrium_w_tax, equilibrium): x_below_equilibrium = [equilibrium_w_tax] for point in X: if point >= equilibrium_w_tax and point <= equilibrium: x_below_equilibrium.append(point) x_below_equilibrium.append(equilibrium) y_below_equilibrium = [] y_above_equilibrium = [] for point in x_below_equilibrium: y_below_equilibrium.append(inverse_demand(point)) y_above_equilibrium.append(inverse_supply(point)) plt.fill_between(x_below_equilibrium, y_below_equilibrium, y_above_equilibrium, step="pre", color = "green", alpha=0.4, label='DW') # fill in area for consumer surplus # Starting point def q5(): equilibrium_w_tax = calculate_equilibrium(inverse_supply_with_tax, inverse_demand) # Get equilibrium with tax equilibrium = calculate_equilibrium(inverse_supply, inverse_demand) # get standard equilibrium demand_integral = si.quad(inverse_demand,0,equilibrium_w_tax) # get area under the inverse demand function supply_integral = si.quad(inverse_supply,0,equilibrium) # get area under the inverse supply function area_below_curves = equilibrium_w_tax * inverse_demand(equilibrium_w_tax) demand_integral[0] - area_below_curves consum_sur = demand_integral[0] - area_below_curves producer_sur = area_below_curves - supply_integral[0] fig = plt.figure() x = [] value = 2 while value <= 4: # generate list of values for x to be used in generating lines. x.append(value) value += 0.05 # each value in line is separated by 0.05 y = build_line(inverse_demand, x) # build y values for inverse demand then plot plt.plot(x, y, color='blue', label='Inverse Demand') y = build_line(inverse_supply, x) # build y values for inverse supply then plot plt.plot(x, y, color='black', label='Inverse Supply') y = build_line(inverse_supply_with_tax, x) # build y values for inverse supply w/tax then plot plt.plot(x, y, color='red', label='Inverse Supply with Tax') plt.plot(equilibrium, inverse_supply(equilibrium), 'o', color='red') # plot equilibrium point w/o tax plt.plot(equilibrium_w_tax, inverse_supply_with_tax(equilibrium_w_tax), 'o', color='black') # plot equilibrium point w/ tax plt.plot(equilibrium_w_tax, inverse_supply(equilibrium_w_tax), 'o', color='black') gov_revenue = equilibrium_w_tax * (inverse_supply_with_tax(equilibrium_w_tax) - inverse_supply(equilibrium_w_tax)) dead = (0.5 * (inverse_supply_with_tax(equilibrium_w_tax) - inverse_supply(equilibrium_w_tax))) * (equilibrium - equilibrium_w_tax) # calculate the dead weight loss fill_consumer_surplus(x, equilibrium_w_tax) fill_producer_surplus(x, equilibrium_w_tax) fill_dead_weight(x, equilibrium_w_tax, equilibrium) plt.fill_between([2, equilibrium_w_tax], [inverse_supply_with_tax(equilibrium_w_tax), inverse_supply_with_tax(equilibrium_w_tax)], [inverse_supply(equilibrium_w_tax), inverse_supply(equilibrium_w_tax)], step="pre", color = "purple", alpha=0.4, label='Gov Revenue') # fill in area for consumer surplus plt.xlabel = "Quantity" plt.ylabel = "Price" plt.legend() plt.show() pp = PdfPages(outputfolder + "//dboland_q5.pdf") fig.savefig(pp, format='pdf') pp.close() print("consumer surplus:",consum_sur) print("producer surplus:",producer_sur) print("government revenue:",gov_revenue) print("deadweight loss:",dead)