my-markdown-library 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/F24LS_md/ Lecture 4 - Public.md +347 -0
- data/F24LS_md/Lecture 1 - Introduction and Overview.md +327 -0
- data/F24LS_md/Lecture 10 - Development_.md +631 -0
- data/F24LS_md/Lecture 11 - Econometrics.md +345 -0
- data/F24LS_md/Lecture 12 - Finance.md +692 -0
- data/F24LS_md/Lecture 13 - Environmental Economics.md +299 -0
- data/F24LS_md/Lecture 15 - Conclusion.md +272 -0
- data/F24LS_md/Lecture 2 - Demand.md +349 -0
- data/F24LS_md/Lecture 3 - Supply.md +329 -0
- data/F24LS_md/Lecture 5 - Production C-D.md +291 -0
- data/F24LS_md/Lecture 6 - Utility and Latex.md +440 -0
- data/F24LS_md/Lecture 7 - Inequality.md +607 -0
- data/F24LS_md/Lecture 8 - Macroeconomics.md +704 -0
- data/F24LS_md/Lecture 8 - Macro.md +700 -0
- data/F24LS_md/Lecture 9 - Game Theory_.md +436 -0
- data/F24LS_md/summary.yaml +105 -0
- data/F24Lec_MD/LecNB_summary.yaml +206 -0
- data/F24Lec_MD/lec01/lec01.md +267 -0
- data/F24Lec_MD/lec02/Avocados_demand.md +425 -0
- data/F24Lec_MD/lec02/Demand_Steps_24.md +126 -0
- data/F24Lec_MD/lec02/PriceElasticity.md +83 -0
- data/F24Lec_MD/lec02/ScannerData_Beer.md +171 -0
- data/F24Lec_MD/lec02/demand-curve-Fa24.md +213 -0
- data/F24Lec_MD/lec03/3.0-CubicCostCurve.md +239 -0
- data/F24Lec_MD/lec03/3.1-Supply.md +274 -0
- data/F24Lec_MD/lec03/3.2-sympy.md +332 -0
- data/F24Lec_MD/lec03/3.3a-california-energy.md +120 -0
- data/F24Lec_MD/lec03/3.3b-a-really-hot-tuesday.md +121 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey-closed.md +335 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey.md +331 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand-closed.md +519 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand.md +514 -0
- data/F24Lec_MD/lec04/lec04-four-plot-24.md +34 -0
- data/F24Lec_MD/lec04/lec04-four-plot.md +34 -0
- data/F24Lec_MD/lec05/Lec5-Cobb-Douglas.md +131 -0
- data/F24Lec_MD/lec05/Lec5-CobbD-AER1928.md +283 -0
- data/F24Lec_MD/lec06/6.1-Sympy-Differentiation.md +253 -0
- data/F24Lec_MD/lec06/6.2-3D-utility.md +287 -0
- data/F24Lec_MD/lec06/6.3-QuantEcon-Optimization.md +399 -0
- data/F24Lec_MD/lec06/6.4-latex.md +138 -0
- data/F24Lec_MD/lec06/6.5-Edgeworth.md +269 -0
- data/F24Lec_MD/lec07/7.1-inequality.md +283 -0
- data/F24Lec_MD/lec07/7.2-historical-inequality.md +237 -0
- data/F24Lec_MD/lec08/macro-fred-api.md +313 -0
- data/F24Lec_MD/lec09/lecNB-prisoners-dilemma.md +88 -0
- data/F24Lec_MD/lec10/Lec10.2-waterguard.md +401 -0
- data/F24Lec_MD/lec10/lec10.1-mapping.md +199 -0
- data/F24Lec_MD/lec11/11.1-slr.md +305 -0
- data/F24Lec_MD/lec11/11.2-mlr.md +171 -0
- data/F24Lec_MD/lec12/Lec12-4-PersonalFinance.md +590 -0
- data/F24Lec_MD/lec12/lec12-1_Interest_Payments.md +267 -0
- data/F24Lec_MD/lec12/lec12-2-stocks-options.md +235 -0
- data/F24Lec_MD/lec13/Co2_ClimateChange.md +139 -0
- data/F24Lec_MD/lec13/ConstructingMAC.md +213 -0
- data/F24Lec_MD/lec13/EmissionsTracker.md +170 -0
- data/F24Lec_MD/lec13/KuznetsHypothesis.md +219 -0
- data/F24Lec_MD/lec13/RoslingPlots.md +217 -0
- data/F24Lec_MD/lec15/vibecession.md +485 -0
- data/F24Textbook_MD/00-intro/index.md +292 -0
- data/F24Textbook_MD/01-demand/01-demand.md +152 -0
- data/F24Textbook_MD/01-demand/02-example.md +131 -0
- data/F24Textbook_MD/01-demand/03-log-log.md +284 -0
- data/F24Textbook_MD/01-demand/04-elasticity.md +248 -0
- data/F24Textbook_MD/01-demand/index.md +15 -0
- data/F24Textbook_MD/02-supply/01-supply.md +203 -0
- data/F24Textbook_MD/02-supply/02-eep147-example.md +86 -0
- data/F24Textbook_MD/02-supply/03-sympy.md +138 -0
- data/F24Textbook_MD/02-supply/04-market-equilibria.md +204 -0
- data/F24Textbook_MD/02-supply/index.md +16 -0
- data/F24Textbook_MD/03-public/govt-intervention.md +73 -0
- data/F24Textbook_MD/03-public/index.md +10 -0
- data/F24Textbook_MD/03-public/surplus.md +351 -0
- data/F24Textbook_MD/03-public/taxes-subsidies.md +282 -0
- data/F24Textbook_MD/04-production/index.md +15 -0
- data/F24Textbook_MD/04-production/production.md +178 -0
- data/F24Textbook_MD/04-production/shifts.md +296 -0
- data/F24Textbook_MD/05-utility/budget-constraints.md +166 -0
- data/F24Textbook_MD/05-utility/index.md +15 -0
- data/F24Textbook_MD/05-utility/utility.md +136 -0
- data/F24Textbook_MD/06-inequality/historical-inequality.md +253 -0
- data/F24Textbook_MD/06-inequality/index.md +15 -0
- data/F24Textbook_MD/06-inequality/inequality.md +226 -0
- data/F24Textbook_MD/07-game-theory/bertrand.md +257 -0
- data/F24Textbook_MD/07-game-theory/cournot.md +333 -0
- data/F24Textbook_MD/07-game-theory/equilibria-oligopolies.md +96 -0
- data/F24Textbook_MD/07-game-theory/expected-utility.md +61 -0
- data/F24Textbook_MD/07-game-theory/index.md +19 -0
- data/F24Textbook_MD/07-game-theory/python-classes.md +340 -0
- data/F24Textbook_MD/08-development/index.md +35 -0
- data/F24Textbook_MD/09-macro/CentralBanks.md +101 -0
- data/F24Textbook_MD/09-macro/Indicators.md +77 -0
- data/F24Textbook_MD/09-macro/fiscal_policy.md +36 -0
- data/F24Textbook_MD/09-macro/index.md +14 -0
- data/F24Textbook_MD/09-macro/is_curve.md +76 -0
- data/F24Textbook_MD/09-macro/phillips_curve.md +70 -0
- data/F24Textbook_MD/10-finance/index.md +10 -0
- data/F24Textbook_MD/10-finance/options.md +178 -0
- data/F24Textbook_MD/10-finance/value-interest.md +60 -0
- data/F24Textbook_MD/11-econometrics/index.md +16 -0
- data/F24Textbook_MD/11-econometrics/multivariable.md +218 -0
- data/F24Textbook_MD/11-econometrics/reading-econ-papers.md +25 -0
- data/F24Textbook_MD/11-econometrics/single-variable.md +483 -0
- data/F24Textbook_MD/11-econometrics/statsmodels.md +58 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis-Copy1.md +187 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis.md +187 -0
- data/F24Textbook_MD/12-environmental/MAC.md +254 -0
- data/F24Textbook_MD/12-environmental/index.md +36 -0
- data/F24Textbook_MD/LICENSE.md +11 -0
- data/F24Textbook_MD/intro.md +26 -0
- data/F24Textbook_MD/references.md +25 -0
- data/F24Textbook_MD/summary.yaml +414 -0
- metadata +155 -0
@@ -0,0 +1,519 @@
|
|
1
|
+
---
|
2
|
+
title: "lec04-Supply-Demand-closed"
|
3
|
+
type: lecture-notebook
|
4
|
+
week: 4
|
5
|
+
source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec04/lec04-Supply-Demand-closed.ipynb"
|
6
|
+
---
|
7
|
+
|
8
|
+
<table style="width: 100%;">
|
9
|
+
<tr style="background-color: transparent;"><td>
|
10
|
+
<img src="https://data-88e.github.io/assets/images/blue_text.png" width="250px" style="margin-left: 0;" />
|
11
|
+
</td><td>
|
12
|
+
<p style="text-align: right; font-size: 10pt;"><strong>Economic Models</strong>, Fall 2024<br>
|
13
|
+
Dr. Eric Van Dusen <br>
|
14
|
+
</p></td></tr>
|
15
|
+
</table>
|
16
|
+
|
17
|
+
```python
|
18
|
+
import sympy
|
19
|
+
solve = lambda x,y: sympy.solve(x-y)[0] if len(sympy.solve(x-y))==1 else "Not Single Solution"
|
20
|
+
import matplotlib.pyplot as plt
|
21
|
+
plt.style.use('ggplot')
|
22
|
+
%matplotlib inline
|
23
|
+
|
24
|
+
from ipywidgets import interact, interactive, fixed, interact_manual
|
25
|
+
import ipywidgets as widgets
|
26
|
+
from IPython.display import display
|
27
|
+
#import nbinteract as nbi
|
28
|
+
import numpy as np
|
29
|
+
|
30
|
+
import warnings
|
31
|
+
warnings.filterwarnings('ignore')
|
32
|
+
|
33
|
+
import matplotlib
|
34
|
+
print(matplotlib.__version__)
|
35
|
+
```
|
36
|
+
|
37
|
+
# Supply, Demand, and Equilibrium
|
38
|
+
|
39
|
+
## Set-up
|
40
|
+
|
41
|
+
With this notebook, we are going to plot and solve equations, hopefully giving some more hands on exposure to the materials that you've already seen in class.
|
42
|
+
|
43
|
+
We have already covered
|
44
|
+
- sympy
|
45
|
+
- getting slope and intercept for deman curve
|
46
|
+
- solving for equilibrium
|
47
|
+
|
48
|
+
## Solving Equations with SymPy
|
49
|
+
|
50
|
+
In order to treat variables like the symbols you would using pen and paper, we have to declare them as such first. We are going to use the inverse forms, so our equations will both be a function of quantity. We create a variable for quantity below.
|
51
|
+
|
52
|
+
```python
|
53
|
+
Q = sympy.Symbol("Q")
|
54
|
+
```
|
55
|
+
|
56
|
+
Now when we call this variable, we can see that it is a symbolic variable, and not some other Python type.
|
57
|
+
|
58
|
+
We cn decplare an upward sloping supply curve with a name, `supply`.
|
59
|
+
|
60
|
+
```python
|
61
|
+
supply = 3*Q + 4
|
62
|
+
supply
|
63
|
+
```
|
64
|
+
|
65
|
+
We can then substitue in values for our quantity variable. We do so in the following cell. Using the method `subs`, we take the equation we already defined, `supply`, and plug in the value 3 in place of `Q`.
|
66
|
+
|
67
|
+
```python
|
68
|
+
supply.subs(Q, 3)
|
69
|
+
```
|
70
|
+
|
71
|
+
Next we'll define an inverse-demand equation.
|
72
|
+
|
73
|
+
```python
|
74
|
+
demand = -4*Q+15
|
75
|
+
demand
|
76
|
+
```
|
77
|
+
|
78
|
+
We are now able to take our supply and demand equations and find where they intersect. When we use the `solve` function, it will tell us the x-value of the point where the two lines intercept. This is the equilibrium quantity, which we will call that value `Q_star`.
|
79
|
+
|
80
|
+
```python
|
81
|
+
Q_star = solve(demand, supply) # our version of solve is simplified for single solution systems
|
82
|
+
Q_star
|
83
|
+
```
|
84
|
+
|
85
|
+
We can then substitute `Q_star` back into our original inverse-supply and inverse-demand equations to solve for our equilibrium price.
|
86
|
+
|
87
|
+
```python
|
88
|
+
demand.subs(Q, Q_star)
|
89
|
+
```
|
90
|
+
|
91
|
+
```python
|
92
|
+
supply.subs(Q, Q_star)
|
93
|
+
```
|
94
|
+
|
95
|
+
## Visualizing those supply and demand equations
|
96
|
+
|
97
|
+
```python
|
98
|
+
def plot_equation(equation, price_start, price_end, label=None):
|
99
|
+
plot_prices = [price_start, price_end]
|
100
|
+
plot_quantities = [equation.subs(list(equation.free_symbols)[0], c) for c in plot_prices]
|
101
|
+
plt.plot(plot_prices, plot_quantities, label=label)
|
102
|
+
|
103
|
+
def plot_intercept(eq1, eq2):
|
104
|
+
ex = sympy.solve(eq1-eq2)[0]
|
105
|
+
why = eq1.subs(list(eq1.free_symbols)[0], ex)
|
106
|
+
plt.scatter([ex], [why])
|
107
|
+
return (ex, why)
|
108
|
+
|
109
|
+
plot_equation(demand, 0, 5)
|
110
|
+
plot_equation(supply, 0, 5)
|
111
|
+
plt.ylim(0,20)
|
112
|
+
plot_intercept(supply, demand)
|
113
|
+
```
|
114
|
+
|
115
|
+
## Modeling a Shift in Demand
|
116
|
+
We would like to be able to add in the ability to shift the demand curve, using a slider
|
117
|
+
|
118
|
+
```python
|
119
|
+
|
120
|
+
def shift_demand():
|
121
|
+
equation = demand
|
122
|
+
def shift_helper(shift):
|
123
|
+
plot_equation(equation, -10, 10)
|
124
|
+
plot_equation(supply, -10, 10)
|
125
|
+
old = plot_intercept(equation, supply)
|
126
|
+
print('Original Intercept:', old)
|
127
|
+
|
128
|
+
if shift != 0:
|
129
|
+
plot_equation(equation + shift, -10, 10, 'shifted')
|
130
|
+
new = plot_intercept(equation + shift, supply)
|
131
|
+
print('New intercept:', new)
|
132
|
+
print('Change in Quantity:', round(float(new[0]-old[0]), 2))
|
133
|
+
print('Change in Price:', round(float(new[1]-old[1]), 2))
|
134
|
+
else:
|
135
|
+
print('Nothing shifted yet, use the slider to move the line!')
|
136
|
+
plt.xlim(0,8)
|
137
|
+
plt.ylim(0,20)
|
138
|
+
plt.legend()
|
139
|
+
plt.ylabel("Price")
|
140
|
+
plt.xlabel("Quantity")
|
141
|
+
interact(shift_helper, shift=(-6, 12, 3))
|
142
|
+
|
143
|
+
shift_demand()
|
144
|
+
```
|
145
|
+
|
146
|
+
## Externalities
|
147
|
+
Ok lets 'shift' the analysis to
|
148
|
+
|
149
|
+
**Marginal Private Benefit (MPB)**
|
150
|
+
The marginal private benefit (MPB) is the benefit that an individual or firm receives from consuming or producing an additional unit of a good or service. This benefit is internal to the consumer or producer and does not take into account any external costs or benefits that might affect others.
|
151
|
+
|
152
|
+
In the case of consumption, the marginal private benefit is the value a consumer places on the next unit of a good, which typically decreases as more units are consumed (due to diminishing marginal utility). This is represented by the private demand curve, which shows the relationship between the quantity demanded and the price.
|
153
|
+
|
154
|
+
For example:
|
155
|
+
|
156
|
+
If you buy a textbook, the benefit you receive from reading it is the private benefit. You might be willing to pay a certain price for the book based on how much you value the knowledge it provides.
|
157
|
+
|
158
|
+
**Marginal Social Benefit (MSB)**
|
159
|
+
The marginal social benefit (MSB) is the total benefit to society from consuming or producing an additional unit of a good or service. It includes both the marginal private benefit and any external benefits (or subtracts external costs, in the case of negative externalities).
|
160
|
+
|
161
|
+
When externalities exist, the marginal social benefit differs from the marginal private benefit. In the case of positive externalities, the MSB is greater than the MPB because the good or service provides additional benefits to third parties that are not captured by the individual consumer.
|
162
|
+
|
163
|
+
For example:
|
164
|
+
|
165
|
+
Education creates positive externalities. While the student receives private benefits from increased knowledge and skills (MPB), society as a whole also benefits from having a more educated population, leading to increased productivity, lower crime rates, and higher civic engagement. These additional benefits form the social benefit.
|
166
|
+
In a competitive market without intervention, only the private benefits are considered, leading to under-consumption of goods with positive externalities. The market does not provide enough of the good relative to the socially optimal level because individuals do not account for the benefits that spill over to others.
|
167
|
+
|
168
|
+
**Market Outcome vs. Socially Optimal Outcome**
|
169
|
+
In the presence of a positive externality:
|
170
|
+
|
171
|
+
The market outcome is determined by the intersection of the supply curve (marginal cost) and the private demand curve (MPB).
|
172
|
+
However, the socially optimal outcome occurs at the intersection of the supply curve and the social demand curve (MSB), which lies above the private demand curve due to the external benefits.
|
173
|
+
|
174
|
+
Let's do a simpler version where we just solve the following :
|
175
|
+
\begin{align*}
|
176
|
+
\text{Private Demand (MPB)}: & \quad P = 100 - 0.3Q \\
|
177
|
+
\text{Social Demand (MSB)}: & \quad P = (100 + \text{Externality Shift}) - 0.3Q \\
|
178
|
+
\text{Supply (MC)}: & \quad P = 10 + 0.2Q\\
|
179
|
+
\text {Where}: & \quad \text{Externality Shift} = +10\\
|
180
|
+
\end{align*}
|
181
|
+
|
182
|
+
```python
|
183
|
+
def private_demand(q):
|
184
|
+
return 100 - 0.3 * q
|
185
|
+
|
186
|
+
def social_demand(q):
|
187
|
+
return 110 - 0.3 * q
|
188
|
+
|
189
|
+
def supply(q):
|
190
|
+
return 10 + 0.2 * q
|
191
|
+
|
192
|
+
market_quantity = (100 - 10) / (0.2 + 0.3)
|
193
|
+
optimal_quantity = (110 - 10) / (0.2 + 0.3)
|
194
|
+
```
|
195
|
+
|
196
|
+
```python
|
197
|
+
|
198
|
+
quantities = np.linspace(0, 300, 500)
|
199
|
+
|
200
|
+
#Plotting
|
201
|
+
plt.figure(figsize=(6, 6))
|
202
|
+
plt.plot(quantities, private_demand(quantities), label='Private Demand (MPB)', color='green')
|
203
|
+
plt.plot(quantities, social_demand(quantities), label='Social Demand (MSB)', color='purple', linestyle='--')
|
204
|
+
plt.plot(quantities, supply(quantities), label='Supply (MC)', color='blue')
|
205
|
+
|
206
|
+
plt.axvline(market_quantity, color='green', linestyle='--', label='Market Quantity')
|
207
|
+
plt.axvline(optimal_quantity, color='purple', linestyle='--', label='Optimal Quantity')
|
208
|
+
|
209
|
+
plt.fill_between(quantities, private_demand(quantities), social_demand(quantities), where=(quantities <= optimal_quantity), color='lightblue', alpha=0.3)
|
210
|
+
|
211
|
+
plt.title('Positive Externality: Demand Curve')
|
212
|
+
plt.xlabel('Quantity')
|
213
|
+
plt.ylabel('Price')
|
214
|
+
plt.legend()
|
215
|
+
plt.grid(True)
|
216
|
+
plt.show()
|
217
|
+
```
|
218
|
+
|
219
|
+
Let's do an interactive version where we solve the following with a variable externality :
|
220
|
+
\begin{align*}
|
221
|
+
\text{Private Demand (MPB)}: & \quad P = 100 - 0.3Q \\
|
222
|
+
\text{Social Demand (MSB)}: & \quad P = (100 + \text{Externality Shift}) - 0.3Q \\
|
223
|
+
\text{Supply (MC)}: & \quad P = 10 + 0.2Q
|
224
|
+
\end{align*}
|
225
|
+
|
226
|
+
```python
|
227
|
+
#Everything is wrapped in a function that the slider can interact with
|
228
|
+
|
229
|
+
def plot_externality(externality_shift):
|
230
|
+
def social_demand(q):
|
231
|
+
return (100 + externality_shift) - 0.3 * q # Marginal Social Benefit (MSB)
|
232
|
+
|
233
|
+
#Hard coded values for Equilibrium from solving Demand and Supply
|
234
|
+
market_quantity = (100 - 10) / (0.2 + 0.3)
|
235
|
+
optimal_quantity = ((100 + externality_shift) - 10) / (0.2 + 0.3)
|
236
|
+
|
237
|
+
market_price = private_demand(market_quantity)
|
238
|
+
optimal_price = social_demand(optimal_quantity)
|
239
|
+
|
240
|
+
#Plotting
|
241
|
+
plt.figure(figsize=(8, 6))
|
242
|
+
plt.plot(quantities, private_demand(quantities), color='green')
|
243
|
+
plt.plot(quantities, social_demand(quantities), color='purple', linestyle='--')
|
244
|
+
plt.plot(quantities, supply(quantities), color='blue')
|
245
|
+
|
246
|
+
plt.axvline(market_quantity, color='green', linestyle='--', label=f'Market Quantity: {market_quantity:.2f}')
|
247
|
+
plt.axvline(optimal_quantity, color='purple', linestyle='--', label=f'Social Quantity: {optimal_quantity:.2f}')
|
248
|
+
|
249
|
+
plt.axhline(market_price, color='green', linestyle='--', label=f'Market Price: {market_price:.2f}')
|
250
|
+
plt.axhline(optimal_price, color='purple', linestyle='--', label=f'Social Price: {optimal_price:.2f}')
|
251
|
+
|
252
|
+
|
253
|
+
plt.fill_between(quantities, private_demand(quantities), social_demand(quantities), where=(quantities <= optimal_quantity), color='lightblue', alpha=0.3)
|
254
|
+
|
255
|
+
#Labels on demand
|
256
|
+
plt.text(300, private_demand(300) + 2, 'Marginal Private Benefit (MPB)', color='green', fontsize=12)
|
257
|
+
plt.text(300, social_demand(300) + 2, 'Marginal Social Benefit (MSB)', color='purple', fontsize=12)
|
258
|
+
#Labels on supply
|
259
|
+
plt.text(300, supply(300) + 2, 'Supply ', color='blue', fontsize=12)
|
260
|
+
|
261
|
+
|
262
|
+
plt.title(f' Externality: Externality Shift = {externality_shift}')
|
263
|
+
plt.xlabel('Quantity')
|
264
|
+
plt.ylabel('Price')
|
265
|
+
plt.legend()
|
266
|
+
plt.grid(True)
|
267
|
+
plt.show()
|
268
|
+
|
269
|
+
#Slider for externality shift
|
270
|
+
interact(plot_externality, externality_shift=widgets.IntSlider(min=-20, max=20, step=1, value=10, description="Externality Shift"));
|
271
|
+
```
|
272
|
+
|
273
|
+
## Consumer and Producer Surplus
|
274
|
+
|
275
|
+
```python
|
276
|
+
import numpy as np
|
277
|
+
import matplotlib.pyplot as plt
|
278
|
+
import sympy
|
279
|
+
from sympy import symbols
|
280
|
+
import matplotlib.patches as patches
|
281
|
+
|
282
|
+
# Define the quantity symbol for sympy
|
283
|
+
Q = symbols('Q')
|
284
|
+
|
285
|
+
# Simplified Equilibrium function with a range of quantities
|
286
|
+
def Equilibrium(demandParam, supplyParam):
|
287
|
+
# Define demand and supply equations as functions of quantity
|
288
|
+
demandEquation = demandParam - Q # P = demandParam - Q
|
289
|
+
supplyEquation = (supplyParam / 10) * Q # P = (supplyParam / 10) * Q
|
290
|
+
|
291
|
+
# Convert the sympy equations to numerical functions using lambdify
|
292
|
+
demandFunc = sympy.lambdify(Q, demandEquation, "numpy")
|
293
|
+
supplyFunc = sympy.lambdify(Q, supplyEquation, "numpy")
|
294
|
+
|
295
|
+
# Define a fixed range of quantities (from 0 to 100)
|
296
|
+
quantities = np.linspace(0, 50, 50)
|
297
|
+
|
298
|
+
# Calculate corresponding prices for each quantity for demand and supply
|
299
|
+
demandPrices = demandFunc(quantities) # Evaluate demand prices as numerical values
|
300
|
+
supplyPrices = supplyFunc(quantities) # Evaluate supply prices as numerical values
|
301
|
+
|
302
|
+
# Find the equilibrium quantity by solving where demand equals supply
|
303
|
+
equilibriumQ = sympy.solve(demandEquation - supplyEquation, Q)[0]
|
304
|
+
equilibriumP = demandEquation.subs(Q, equilibriumQ)
|
305
|
+
|
306
|
+
# Convert equilibrium values to float for plotting
|
307
|
+
equilibriumQ = float(equilibriumQ)
|
308
|
+
equilibriumP = float(equilibriumP)
|
309
|
+
|
310
|
+
# Plot demand and supply curves
|
311
|
+
plt.plot(quantities, demandPrices, label="Demand (MPB)", color="green")
|
312
|
+
plt.plot(quantities, supplyPrices, label="Supply (MC)", color="blue")
|
313
|
+
|
314
|
+
# Mark equilibrium point
|
315
|
+
plt.plot(equilibriumQ, equilibriumP, 'ro', label=f"Equilibrium Q={round(equilibriumQ, 2)}, P={round(equilibriumP, 2)}")
|
316
|
+
|
317
|
+
# Shade consumer and producer surplus
|
318
|
+
triangle1 = patches.Polygon([[0, equilibriumP], [equilibriumQ, equilibriumP], [0, demandFunc(0)]], closed=True, color="green", alpha=0.3)
|
319
|
+
triangle2 = patches.Polygon([[0, equilibriumP], [equilibriumQ, equilibriumP], [0, 0]], closed=True, color="red", alpha=0.3)
|
320
|
+
currentAxis = plt.gca()
|
321
|
+
currentAxis.add_patch(triangle1)
|
322
|
+
currentAxis.add_patch(triangle2)
|
323
|
+
|
324
|
+
# Add labels and legend
|
325
|
+
plt.xlabel("Quantity")
|
326
|
+
plt.ylabel("Price")
|
327
|
+
plt.xlim(0, 50) # Fixed quantity range from 0 to 100
|
328
|
+
plt.ylim(0, max(demandPrices)) # Set y-limits based on demand prices
|
329
|
+
plt.legend()
|
330
|
+
plt.grid(True)
|
331
|
+
|
332
|
+
# Display plot
|
333
|
+
plt.show()
|
334
|
+
|
335
|
+
# Print equilibrium information
|
336
|
+
print(f"The equilibrium price is {round(float(equilibriumP), 2)} and equilibrium quantity is {round(float(equilibriumQ), 2)}.")
|
337
|
+
print(f"The consumer surplus at this equilibrium is {(demandFunc(0) - equilibriumP) * equilibriumQ * 0.5}")
|
338
|
+
print(f"The producer surplus at this equilibrium is {(equilibriumP * equilibriumQ) * 0.5}")
|
339
|
+
|
340
|
+
# Example usage
|
341
|
+
Equilibrium(demandParam=50, supplyParam=20)
|
342
|
+
```
|
343
|
+
|
344
|
+
```python
|
345
|
+
import sympy
|
346
|
+
import matplotlib.pyplot as plt
|
347
|
+
import matplotlib.patches as patches
|
348
|
+
p = sympy.Symbol("p")
|
349
|
+
def Equilibrium(demandParam, supplyParam, priceStart):
|
350
|
+
demandEquation = demandParam - p
|
351
|
+
# change the slope
|
352
|
+
supplyEquation = p * (supplyParam/10)
|
353
|
+
priceEnd = sympy.solve(demandEquation)[0]
|
354
|
+
prices = []
|
355
|
+
demandQ = []
|
356
|
+
supplyQ = []
|
357
|
+
for price in range(priceStart,priceEnd+1):
|
358
|
+
prices += [price]
|
359
|
+
demandQ += [demandEquation.subs(p,price)]
|
360
|
+
supplyQ += [supplyEquation.subs(p,price)]
|
361
|
+
|
362
|
+
equilibriumP = sympy.solve(demandEquation-supplyEquation)[0]
|
363
|
+
equilibriumQ = demandEquation.subs(p,equilibriumP)
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
triangle1 = patches.Polygon([[equilibriumQ,equilibriumP],[0,equilibriumP],[0,priceEnd]],closed=True,color="green")
|
368
|
+
triangle2 = patches.Polygon([[equilibriumQ,equilibriumP],[0,equilibriumP],[0,0]],closed=True,color="red")
|
369
|
+
currentAxis = plt.gca()
|
370
|
+
currentAxis.add_patch(triangle1)
|
371
|
+
currentAxis.add_patch(triangle2)
|
372
|
+
|
373
|
+
plt.plot(demandQ,prices)
|
374
|
+
plt.plot(supplyQ,prices)
|
375
|
+
plt.legend(["Demand","Supply"])
|
376
|
+
plt.plot(equilibriumQ,equilibriumP, 'ro')
|
377
|
+
plt.xlabel("Supply and Demand Quantity")
|
378
|
+
plt.ylabel("Price")
|
379
|
+
plt.ylim(0, 15)
|
380
|
+
plt.xlim(0, 10)
|
381
|
+
plt.show()
|
382
|
+
print("The equilibrium price is "+str(round(equilibriumP,2))+" and equilibrium quantity is "+str(round(equilibriumQ,2))+".")
|
383
|
+
print("The consumer surplus at this equilibrium "+str((priceEnd-equilibriumP)*(equilibriumQ)*.5))
|
384
|
+
print("The producer surplus at this equilibrium "+str((equilibriumP)*(equilibriumQ)*.5))
|
385
|
+
|
386
|
+
|
387
|
+
# you can change the range here
|
388
|
+
slider1 = widgets.IntSlider(min=5, max=15,step=1,value=10, description="Demand Intercept")
|
389
|
+
slider2 = widgets.IntSlider(min=1, max=20,step=1,value=10, description="Supply Slope")
|
390
|
+
slider3 = widgets.IntSlider(min=-5, max=5,step=1,value=0)
|
391
|
+
|
392
|
+
# Add additional text using widgets.Label or widgets.HTML
|
393
|
+
text_before = widgets.HTML(
|
394
|
+
value="<h3>Equilibrium Simulation</h3><p>This interactive simulation allows you to explore the equilibrium price and quantity based on different demand and supply parameters.</p>"
|
395
|
+
)
|
396
|
+
|
397
|
+
text_after = widgets.HTML(
|
398
|
+
value="<p>Adjust the <b>Demand Param</b> and <b>Supply Param</b> sliders to change the shape of the curves, and observe how the equilibrium changes.</p>"
|
399
|
+
)
|
400
|
+
|
401
|
+
# Display all elements together
|
402
|
+
ui = widgets.VBox([text_before, slider1, slider2, slider3, text_after])
|
403
|
+
out = widgets.interactive_output(Equilibrium, {'demandParam': slider1, 'supplyParam': slider2, 'priceStart': slider3})
|
404
|
+
|
405
|
+
display(ui, out)
|
406
|
+
```
|
407
|
+
|
408
|
+
## Effects of Taxes
|
409
|
+
|
410
|
+
```python
|
411
|
+
def eqSolve(eq1,eq2,tax):
|
412
|
+
demandP = sympy.solve(eq1-q,p)[0]
|
413
|
+
supplyP = sympy.solve(eq2-q,p)[0]
|
414
|
+
demandP = demandP-cTax
|
415
|
+
supplyP = supplyP+pTax
|
416
|
+
|
417
|
+
demandQ = sympy.solve(demandP-p,q)[0]
|
418
|
+
supplyQ = sympy.solve(supplyP-p,q)[0]
|
419
|
+
|
420
|
+
return sympy.solve((demandP-supplyP, demandQ-supplyQ,tax-cTax-pTax), q,p,cTax,pTax)[q]
|
421
|
+
```
|
422
|
+
|
423
|
+
```python
|
424
|
+
|
425
|
+
p = sympy.Symbol("p")
|
426
|
+
q = sympy.Symbol("q")
|
427
|
+
cTax = sympy.Symbol("cTax")
|
428
|
+
pTax = sympy.Symbol("pTax")
|
429
|
+
|
430
|
+
def EquilibriumTax(demandParam,supplyParam,priceStart,priceEnd,tax):
|
431
|
+
demandEquation = demandParam - p
|
432
|
+
supplyEquation = p * (supplyParam/10)
|
433
|
+
prices = []
|
434
|
+
demand = []
|
435
|
+
supply = []
|
436
|
+
for price in range(priceStart,priceEnd+1):
|
437
|
+
prices += [price]
|
438
|
+
demand += [demandEquation.subs(p,price)]
|
439
|
+
supply += [supplyEquation.subs(p,price)]
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
nonTaxPrice = sympy.solve(demandEquation-supplyEquation)[0]
|
444
|
+
nonTaxQ = demandEquation.subs(p,nonTaxPrice)
|
445
|
+
|
446
|
+
|
447
|
+
equilibriumQ = eqSolve(demandEquation,supplyEquation,tax)
|
448
|
+
equilibriumP1 = sympy.solve(demandEquation-equilibriumQ)[0]
|
449
|
+
equilibriumP2 = sympy.solve(supplyEquation-equilibriumQ)[0]
|
450
|
+
|
451
|
+
triangle1 = patches.Polygon([[nonTaxQ,nonTaxPrice],[equilibriumQ,nonTaxPrice],[equilibriumQ,equilibriumP1]],closed=True,color="green")
|
452
|
+
triangle2 = patches.Polygon([[nonTaxQ,nonTaxPrice],[equilibriumQ,nonTaxPrice],[equilibriumQ,equilibriumP2]],closed=True)
|
453
|
+
#triangle1 = patches.Polygon([[0, equilibriumP1], [equilibriumQ, equilibriumP], [0, demandFunc(0)]], closed=True, color="green", alpha=0.3)
|
454
|
+
#triangle2 = patches.Polygon([[0, equilibriumP2], [equilibriumQ, equilibriumP], [0, 0]], closed=True, color="red", alpha=0.3)
|
455
|
+
currentAxis = plt.gca()
|
456
|
+
currentAxis.add_patch(triangle1)
|
457
|
+
currentAxis.add_patch(triangle2)
|
458
|
+
|
459
|
+
|
460
|
+
rect1 = patches.Rectangle((0,nonTaxPrice),equilibriumQ,equilibriumP1-nonTaxPrice,linewidth=1,facecolor="red")
|
461
|
+
rect2 = patches.Rectangle((0,nonTaxPrice),equilibriumQ,equilibriumP2-nonTaxPrice,linewidth=1,facecolor="yellow")
|
462
|
+
currentAxis.add_patch(rect1)
|
463
|
+
currentAxis.add_patch(rect2)
|
464
|
+
|
465
|
+
plt.plot(demand,prices)
|
466
|
+
plt.plot(supply,prices)
|
467
|
+
|
468
|
+
|
469
|
+
plt.legend([rect1,rect2,triangle1,triangle2], ["Consumer Tax","Producer Tax","Consumer Deadweight Loss","Producer Deadweight Loss"])
|
470
|
+
plt.plot(equilibriumQ,equilibriumP1, 'ro')
|
471
|
+
plt.plot(equilibriumQ,equilibriumP2, 'ro')
|
472
|
+
plt.xlabel("Supply and Demand Quantity")
|
473
|
+
plt.ylabel("Price")
|
474
|
+
plt.ylim(0, 15)
|
475
|
+
plt.xlim(0, 10)
|
476
|
+
plt.show()
|
477
|
+
print("Without Tax - the equilibrium price is "+str(round(nonTaxPrice,2))+" and equilibrium quantity is "+str(round(nonTaxQ,2)))
|
478
|
+
print("With Tax - Price paid by consumers is "+str(equilibriumP1)+" Price received by suppliers is "+str(round(equilibriumP2,2))+" and equilibrium quantity is "+str(equilibriumQ)+".")
|
479
|
+
print("Taxes raised from consumers equals "+str(round(equilibriumQ*(equilibriumP1-nonTaxPrice),2)))
|
480
|
+
print("Taxes raised from producers equals "+str(round(equilibriumQ*(nonTaxPrice-equilibriumP2),2)))
|
481
|
+
print("Total taxes raised equals "+str(equilibriumQ*tax))
|
482
|
+
|
483
|
+
slider1 = widgets.IntSlider(min=5, max=15,step=1,value=10)
|
484
|
+
slider2 = widgets.IntSlider(min=1, max=20,step=1,value=10)
|
485
|
+
slider3 = widgets.IntSlider(min=-5, max=5,step=1,value=0)
|
486
|
+
slider4 = widgets.IntSlider(min=5, max=20,step=1,value=10)
|
487
|
+
slider5 = widgets.IntSlider(min=0, max=8,step=1,value=4)
|
488
|
+
display(widgets.interactive(EquilibriumTax, demandParam=slider1, supplyParam=slider2, priceStart=slider3, priceEnd=slider4, tax=slider5))
|
489
|
+
```
|
490
|
+
|
491
|
+
## Shifts in Demand and Supply and Incidence of Tax
|
492
|
+
In this graph the second line with the suppply plus tax is not graphed but the new equilibrium point is.
|
493
|
+
|
494
|
+
## Question 3.1 - Demand Shift - Intercept Slider
|
495
|
+
Shift the Demand Parameter - This slider is only shifting the intercept which leads to a parrallel shift in Demand. What happens to the amount of tax paid as demand shifts out. What happens to the ratio of tax paid from Consumer Surplus to Producer Surplus?
|
496
|
+
|
497
|
+
.... Type your answer in here
|
498
|
+
|
499
|
+
## Question 3.2 - Supply Shift - Slope Slider
|
500
|
+
Shift the Supply Parameter - This slider is shifting the slope which leads to a change in the steepness of the Supply curve. What happens to the amount of Consumer Surplus as supply becomes steeper? What happens to the tax incidence - the ratio of tax coming from Consumer Surplus vs. Producer Surplus?
|
501
|
+
|
502
|
+
.... Type your answer in here
|
503
|
+
|
504
|
+
## Question 3.3 - Tax Shift -
|
505
|
+
Shift the Tax Parameter - This slider is increasing or decreasing the amount of tax.
|
506
|
+
|
507
|
+
Is it affecting the slope or the intercept?
|
508
|
+
|
509
|
+
An increase in tax leads to and increase in the price paid by consumers. In this case how much does a given tax lead to an increase in price?
|
510
|
+
|
511
|
+
|
512
|
+
When shifting the tax alone - how does the incidence of tax between producers and consumers change?
|
513
|
+
|
514
|
+
.... Type your answer in here
|
515
|
+
|
516
|
+
|
517
|
+
|
518
|
+
|
519
|
+
|