Skip to content

Instantly share code, notes, and snippets.

@debpu06
Created October 1, 2023 00:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save debpu06/572dded87159a3d0e2e8cdf2725346e2 to your computer and use it in GitHub Desktop.
Save debpu06/572dded87159a3d0e2e8cdf2725346e2 to your computer and use it in GitHub Desktop.
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment