eagle0504 commited on
Commit
b0c7d17
Β·
verified Β·
1 Parent(s): bbabb02

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. README.md +10 -5
  2. app.py +206 -0
README.md CHANGED
@@ -1,12 +1,17 @@
1
  ---
2
  title: Basic Econ Demo App
3
- emoji: πŸ“‰
4
- colorFrom: pink
5
- colorTo: pink
6
- sdk: gradio
7
- sdk_version: 6.0.1
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
 
 
 
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
  title: Basic Econ Demo App
3
+ emoji: πŸ”₯
4
+ colorFrom: indigo
5
+ colorTo: green
6
+ sdk: streamlit
7
+ sdk_version: 1.34.0
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
  ---
12
 
13
+ # Basic Econ Demo App
14
+
15
+ This Space was created with WYN360-CLI.
16
+
17
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import streamlit as st
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+
6
+ def calculate_metrics(a, b, c, d, price_control=None):
7
+ """
8
+ Calculates equilibrium, consumer surplus, producer surplus, and deadweight loss.
9
+
10
+ Args:
11
+ a (float): Y-intercept of the supply curve (P = a + bQ).
12
+ b (float): Slope of the supply curve.
13
+ c (float): Y-intercept of the demand curve (P = c - dQ).
14
+ d (float): Slope of the demand curve.
15
+ price_control (float, optional): An enforced price (floor or ceiling). Defaults to None.
16
+
17
+ Returns:
18
+ tuple: (Q_eq, P_eq, CS, PS, TS, DWL, Q_traded, price_control)
19
+ Returns (0, 0, 0, 0, 0, 0, 0, price_control) if parameters are invalid.
20
+ """
21
+ # Ensure positive slopes for realistic curves
22
+ b = max(0.01, b) # Supply slope
23
+ d = max(0.01, d) # Demand slope
24
+
25
+ # Check for valid parameters that lead to an intersection with positive quantity
26
+ if (c - a) <= 0: # Demand intercept must be above supply intercept for Q_eq > 0
27
+ return 0, 0, 0, 0, 0, 0, 0, price_control
28
+
29
+ # 1. Equilibrium Calculation
30
+ Q_eq = (c - a) / (d + b)
31
+ P_eq = a + b * Q_eq
32
+
33
+ # Ensure valid equilibrium (positive quantity and price)
34
+ if Q_eq < 0.01 or P_eq < 0.01: # Check for near zero or negative values
35
+ return 0, 0, 0, 0, 0, 0, 0, price_control
36
+
37
+ # 2. Consumer Surplus (CS)
38
+ # Area of the triangle above equilibrium price and below demand curve
39
+ CS = 0.5 * Q_eq * (c - P_eq)
40
+ CS = max(0, CS) # Ensure non-negative
41
+
42
+ # 3. Producer Surplus (PS)
43
+ # Area of the triangle below equilibrium price and above supply curve
44
+ PS = 0.5 * Q_eq * (P_eq - a)
45
+ PS = max(0, PS) # Ensure non-negative
46
+
47
+ # 4. Total Surplus
48
+ TS = CS + PS
49
+
50
+ # 5. Deadweight Loss (DWL) and Quantity Traded under Price Control
51
+ DWL = 0
52
+ Q_traded = Q_eq # Initialize quantity traded to equilibrium quantity
53
+
54
+ if price_control is not None and price_control > 0: # If a price control is set
55
+ # Calculate quantity demanded and supplied at the controlled price
56
+ Q_demanded_at_pc = (c - price_control) / d
57
+ Q_supplied_at_pc = (price_control - a) / b
58
+
59
+ # The actual quantity traded is the minimum of Qd and Qs at the controlled price,
60
+ # ensuring it's non-negative (cannot trade negative quantity).
61
+ Q_traded = min(max(0, Q_demanded_at_pc), max(0, Q_supplied_at_pc))
62
+
63
+ # Calculate DWL if trade is restricted from equilibrium
64
+ if Q_traded < Q_eq:
65
+ # Price on the demand curve at the restricted quantity traded
66
+ P_demand_at_Q_traded = c - d * Q_traded
67
+ # Price on the supply curve at the restricted quantity traded
68
+ P_supply_at_Q_traded = a + b * Q_traded
69
+
70
+ # DWL is the area of the triangle between demand and supply curves
71
+ # from Q_traded to Q_eq. Height is the vertical distance between D & S at Q_traded.
72
+ DWL = 0.5 * (Q_eq - Q_traded) * (P_demand_at_Q_traded - P_supply_at_Q_traded)
73
+ DWL = max(0, DWL) # Ensure DWL is non-negative
74
+
75
+ return Q_eq, P_eq, CS, PS, TS, DWL, Q_traded, price_control
76
+
77
+
78
+ st.set_page_config(layout="wide", page_title="Supply & Demand Model")
79
+ st.title("πŸ“Š Econ 101: Supply and Demand Model")
80
+
81
+ st.sidebar.header("βš™οΈ Adjust Model Parameters")
82
+
83
+ # Sliders for demand curve: P = c - dQ
84
+ st.sidebar.subheader("Demand Curve: P = `c` - `d`Q")
85
+ c = st.sidebar.slider("c (Demand Intercept)", 10.0, 200.0, 100.0, 1.0, help="Maximum price consumers are willing to pay for 0 quantity.")
86
+ d = st.sidebar.slider("d (Demand Slope)", 0.1, 10.0, 2.0, 0.1, help="How much price decreases for each unit demanded.")
87
+
88
+ # Sliders for supply curve: P = a + bQ
89
+ st.sidebar.subheader("Supply Curve: P = `a` + `b`Q")
90
+ a = st.sidebar.slider("a (Supply Intercept)", 0.0, 100.0, 10.0, 1.0, help="Minimum price producers are willing to accept for 0 quantity.")
91
+ b = st.sidebar.slider("b (Supply Slope)", 0.1, 10.0, 1.0, 0.1, help="How much price increases for each unit supplied.")
92
+
93
+ # Price control slider
94
+ st.sidebar.subheader("Enforced Price (e.g., Price Floor/Ceiling)")
95
+ price_control = st.sidebar.slider("Set Enforced Price (0 for none)", 0.0, 200.0, 0.0, 0.5,
96
+ help="Set a price floor or ceiling. If 0, no price control is active.")
97
+
98
+ # Perform calculations
99
+ Q_eq, P_eq, CS, PS, TS, DWL, Q_traded, pc_used = calculate_metrics(a, b, c, d, price_control)
100
+
101
+ # Display results and plot
102
+ col1, col2 = st.columns([1, 2])
103
+
104
+ with col1:
105
+ st.header("πŸ“ˆ Economic Metrics")
106
+ if Q_eq == 0 and P_eq == 0 and CS == 0: # Indicates invalid parameters from calculate_metrics
107
+ st.error("Invalid parameters: Please adjust 'c' to be greater than 'a' to ensure a valid equilibrium.")
108
+ else:
109
+ st.metric("Equilibrium Quantity (Qe)", f"{Q_eq:.2f}")
110
+ st.metric("Equilibrium Price (Pe)", f"${P_eq:.2f}")
111
+ st.metric("Consumer Surplus (CS)", f"${CS:.2f}")
112
+ st.metric("Producer Surplus (PS)", f"${PS:.2f}")
113
+ st.metric("Total Surplus (TS)", f"${TS:.2f}")
114
+
115
+ if price_control > 0: # Only show these metrics if a price control is active
116
+ st.subheader("Metrics with Price Control")
117
+ st.metric("Enforced Price", f"${pc_used:.2f}")
118
+ st.metric("Quantity Traded (Q_traded)", f"{Q_traded:.2f}")
119
+ st.metric("Deadweight Loss (DWL)", f"${DWL:.2f}")
120
+ if DWL > 0:
121
+ st.warning("Deadweight Loss indicates market inefficiency due to the enforced price.")
122
+ else:
123
+ st.info("No Deadweight Loss with current enforced price (or price is ineffective).")
124
+ else:
125
+ st.info("Set 'Enforced Price' to calculate Deadweight Loss.")
126
+
127
+
128
+ with col2:
129
+ st.header("πŸ“‰ Supply and Demand Graph")
130
+ fig, ax = plt.subplots(figsize=(12, 8))
131
+
132
+ # Determine appropriate x and y axis limits for plotting
133
+ max_Q_plot = max(Q_eq * 1.5, (c / d) * 1.1, 20) # Extends beyond equilibrium and demand intercept
134
+ max_P_plot = max(P_eq * 1.5, c * 1.1, 150) # Extends beyond equilibrium and demand intercept
135
+
136
+ Q_values = np.linspace(0, max_Q_plot, 400)
137
+
138
+ # Demand Curve: P = c - dQ
139
+ P_demand = c - d * Q_values
140
+ # Supply Curve: P = a + bQ
141
+ P_supply = a + b * Q_values
142
+
143
+ # Filter out negative prices/quantities for plotting realism
144
+ P_demand[P_demand < 0] = np.nan # Don't plot negative prices
145
+ P_supply[P_supply < 0] = np.nan # Don't plot negative prices
146
+ Q_values[Q_values < 0] = np.nan # Don't plot negative quantities
147
+
148
+ ax.plot(Q_values, P_demand, label=f'Demand: P = {c:.1f} - {d:.1f}Q', color='blue', linewidth=2)
149
+ ax.plot(Q_values, P_supply, label=f'Supply: P = {a:.1f} + {b:.1f}Q', color='red', linewidth=2)
150
+
151
+ # Plot Equilibrium Point and lines
152
+ if Q_eq > 0 and P_eq > 0:
153
+ ax.plot(Q_eq, P_eq, 'go', markersize=8, label=f'Equilibrium (Q={Q_eq:.2f}, P=${P_eq:.2f})')
154
+ ax.vlines(Q_eq, 0, P_eq, linestyle=':', color='gray', linewidth=1)
155
+ ax.hlines(P_eq, 0, Q_eq, linestyle=':', color='gray', linewidth=1)
156
+
157
+ # Consumer Surplus Area
158
+ Q_cs_plot = np.linspace(0, Q_eq, 100)
159
+ P_cs_plot = c - d * Q_cs_plot
160
+ ax.fill_between(Q_cs_plot, P_eq, P_cs_plot, where=P_cs_plot > P_eq, color='skyblue', alpha=0.3, label='Consumer Surplus')
161
+
162
+ # Producer Surplus Area
163
+ Q_ps_plot = np.linspace(0, Q_eq, 100)
164
+ P_ps_plot = a + b * Q_ps_plot
165
+ ax.fill_between(Q_ps_plot, P_ps_plot, P_eq, where=P_eq > P_ps_plot, color='lightcoral', alpha=0.3, label='Producer Surplus')
166
+
167
+ # Plot Price Control and Deadweight Loss
168
+ if price_control > 0 and Q_traded < Q_eq:
169
+ ax.hlines(pc_used, 0, Q_traded, linestyle='--', color='purple', label=f'Enforced Price (${pc_used:.2f})', linewidth=1.5)
170
+ ax.vlines(Q_traded, 0, pc_used, linestyle='--', color='purple', linewidth=1.5)
171
+
172
+ # Identify the points for the DWL triangle
173
+ # Price on demand curve at Q_traded
174
+ P_demand_at_Q_traded_plot = c - d * Q_traded
175
+ # Price on supply curve at Q_traded
176
+ P_supply_at_Q_traded_plot = a + b * Q_traded
177
+
178
+ # Shade DWL triangle
179
+ # The points for the DWL triangle are (Q_traded, P_supply_at_Q_traded), (Q_traded, P_demand_at_Q_traded), and (Q_eq, P_eq)
180
+ # Plotting the triangle as a fill_between area between Q_traded and Q_eq
181
+ Q_dwl_fill = np.linspace(Q_traded, Q_eq, 100)
182
+ P_demand_dwl_fill = c - d * Q_dwl_fill
183
+ P_supply_dwl_fill = a + b * Q_dwl_fill
184
+
185
+ ax.fill_between(Q_dwl_fill, P_supply_dwl_fill, P_demand_dwl_fill, color='gray', alpha=0.5, label='Deadweight Loss')
186
+
187
+ # Mark points relevant to price control
188
+ # ax.plot(Q_traded, c - d * Q_traded, 'kx', markersize=8, label=f'Demand at PC ({Q_traded:.2f})')
189
+ # ax.plot(Q_traded, a + b * Q_traded, 'bx', markersize=8, label=f'Supply at PC ({Q_traded:.2f})')
190
+
191
+ ax.set_xlabel("Quantity (Q)", fontsize=12)
192
+ ax.set_ylabel("Price (P)", fontsize=12)
193
+ ax.set_title("Supply and Demand Equilibrium", fontsize=14)
194
+ ax.set_ylim(bottom=0, top=max_P_plot)
195
+ ax.set_xlim(left=0, right=max_Q_plot)
196
+ ax.legend(loc='upper right')
197
+ ax.grid(True, linestyle='--', alpha=0.7)
198
+ st.pyplot(fig)
199
+
200
+ # Create a requirements.txt file for the Streamlit app
201
+ requirements_content = """
202
+ streamlit
203
+ numpy
204
+ matplotlib
205
+ """
206
+ print(default_api.write_file(file_path='requirements.txt', content=requirements_content, overwrite=True))