Code
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltThis appendix provides reusable Python code patterns for NREC4410: International Agricultural Trade. The code is written for teaching, not for advanced software engineering. Copy and adapt the examples when preparing figures, tables, or simple simulations.
The code chunks in this appendix are shown for reference and are not executed during rendering.
trade_data = pd.DataFrame({
"Category": ["Agricultural products", "Non-agricultural products"],
"Exports": [1834, 42718],
"Imports": [5133, 25747]
})
ax = trade_data.set_index("Category").plot(kind="bar")
ax.set_xlabel("")
ax.set_ylabel("Million US dollars")
ax.set_title("Merchandise trade by category")
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()top_exports = pd.DataFrame({
"Product": [
"Crude petroleum",
"Petroleum gases",
"Refined petroleum",
"Nitrogenous fertilizers",
"Motor cars"
],
"Value": [18686, 4403, 3865, 1498, 955]
})
ax = top_exports.plot(kind="barh", x="Product", y="Value", legend=False)
ax.set_xlabel("Million US dollars")
ax.set_ylabel("")
ax.set_title("Top exported products")
ax.invert_yaxis()
plt.tight_layout()
plt.show()The Ricardian labor constraint is:
\[ a_{LF}Q_F + a_{LC}Q_C = L \]
Solving for cloth:
\[ Q_C = \frac{L - a_{LF}Q_F}{a_{LC}} \]
# Oman example
L = 2000
a_LF = 1
a_LC = 2
food = np.linspace(0, L / a_LF, 100)
cloth = (L - a_LF * food) / a_LC
plt.figure()
plt.plot(food, cloth)
plt.xlabel("Food")
plt.ylabel("Cloth")
plt.title("Production Possibility Frontier")
plt.xlim(0, L / a_LF)
plt.ylim(0, L / a_LC)
plt.tight_layout()
plt.show()L = 2000
a_LF = 1
a_LC = 2
world_price_food = 1.0 # 1 food = 1 cloth
food = np.linspace(0, L / a_LF, 100)
ppf_cloth = (L - a_LF * food) / a_LC
# Specialization in food
max_food = L / a_LF
tpf_cloth = world_price_food * (max_food - food)
plt.figure()
plt.plot(food, ppf_cloth, label="PPF")
plt.plot(food, tpf_cloth, linestyle="--", label="TPF")
plt.xlabel("Food")
plt.ylabel("Cloth")
plt.title("PPF and TPF")
plt.legend()
plt.tight_layout()
plt.show()For linear demand and supply:
\[ Q_d = a - bP \]
\[ Q_s = c + dP \]
def demand(P, a, b):
return a - b * P
def supply(P, c, d):
return c + d * P
def autarky_equilibrium(a, b, c, d):
P = (a - c) / (b + d)
Q = supply(P, c, d)
return P, Q
def surplus_at_price(P, a, b, c, d):
Qd = demand(P, a, b)
Qs = supply(P, c, d)
P_max = a / b
P_min = -c / d
CS = 0.5 * (P_max - P) * Qd
PS = 0.5 * (P - P_min) * Qs
TS = CS + PS
return CS, PS, TS, Qd, Qs
# Example
P, Q = autarky_equilibrium(a=80, b=1, c=0, d=1)
CS, PS, TS, Qd, Qs = surplus_at_price(P, a=80, b=1, c=0, d=1)
print(P, Q, CS, PS, TS)a, b = 80, 1
c, d = 0, 1
P_eq, Q_eq = autarky_equilibrium(a, b, c, d)
P_values = np.linspace(0, a / b, 200)
Qd_values = demand(P_values, a, b)
Qs_values = supply(P_values, c, d)
plt.figure()
plt.plot(Qd_values, P_values, label="Demand")
plt.plot(Qs_values, P_values, label="Supply")
plt.axhline(P_eq, linestyle="--", label=f"Price = {P_eq:.0f}")
plt.axvline(Q_eq, linestyle="--", label=f"Quantity = {Q_eq:.0f}")
plt.fill_betweenx(P_values, 0, Qd_values, where=P_values >= P_eq, alpha=0.2)
plt.fill_betweenx(P_values, 0, Qs_values, where=P_values <= P_eq, alpha=0.2)
plt.xlabel("Quantity")
plt.ylabel("Price")
plt.title("Consumer and Producer Surplus")
plt.legend()
plt.tight_layout()
plt.show()# Country 1
params_1 = {"a": 80, "b": 1, "c": 0, "d": 1}
# Country 2
params_2 = {"a": 100, "b": 0.5, "c": 0, "d": 0.5}
P_values = np.linspace(0, 120, 200)
ES = supply(P_values, params_1["c"], params_1["d"]) - demand(P_values, params_1["a"], params_1["b"])
ED = demand(P_values, params_2["a"], params_2["b"]) - supply(P_values, params_2["c"], params_2["d"])
plt.figure()
plt.plot(ES, P_values, label="Export supply")
plt.plot(ED, P_values, label="Import demand")
plt.axhline(60, linestyle="--", label="World price")
plt.axvline(40, linestyle="--", label="Trade volume")
plt.xlabel("Trade quantity")
plt.ylabel("Price")
plt.title("World Equilibrium")
plt.legend()
plt.tight_layout()
plt.show()def effective_rate_of_protection(output_world, input_world, output_tariff, input_tariffs):
"""
output_world: world price of final good
input_world: list of input costs at world prices
output_tariff: tariff rate on final good, such as 0.20
input_tariffs: list of tariff rates for each input
"""
VA_world = output_world - sum(input_world)
output_domestic = output_world * (1 + output_tariff)
inputs_domestic = [cost * (1 + tariff) for cost, tariff in zip(input_world, input_tariffs)]
VA_domestic = output_domestic - sum(inputs_domestic)
ERP = (VA_domestic - VA_world) / VA_world * 100
return VA_world, VA_domestic, ERP
# Cheese example
output_world = 20
input_world = [10, 5]
output_tariff = 0.20
input_tariffs = [0.10, 0.10]
effective_rate_of_protection(output_world, input_world, output_tariff, input_tariffs)P0 = 6000
P1 = 5500
Q0 = 10 # thousand cars
Q1 = 15 # thousand cars
tariff = 1000
price_drop = P0 - P1
cs_gain = price_drop * Q0 + 0.5 * price_drop * (Q1 - Q0)
tariff_revenue_loss = tariff * Q0
net_welfare = cs_gain - tariff_revenue_loss
print(f"Consumer surplus gain = {cs_gain:.2f} million USD")
print(f"Tariff revenue loss = {tariff_revenue_loss:.2f} million USD")
print(f"Net welfare effect = {net_welfare:.2f} million USD")gravity_data = pd.DataFrame({
"Partner": ["India", "UAE", "Saudi Arabia", "China", "Germany"],
"GDP_partner": [3900, 500, 1100, 18000, 4200],
"Distance": [1700, 450, 1200, 5600, 5200],
"Trade": [5.2, 9.1, 4.8, 6.5, 2.4]
})
gravity_data["ln_trade"] = np.log(gravity_data["Trade"])
gravity_data["ln_gdp_partner"] = np.log(gravity_data["GDP_partner"])
gravity_data["ln_distance"] = np.log(gravity_data["Distance"])
gravity_dataUse SVG when you want a clean figure for the website.
#| label: fig-example
#| fig-cap: "Figure caption here."
#| fig-width: 7
#| fig-height: 4
#| echo: true
#| warning: false
#| message: false
pandas, numpy, and matplotlib.---
title: "Python Code Guide"
execute:
eval: false
echo: true
warning: false
message: false
---
This appendix provides reusable Python code patterns for **NREC4410: International Agricultural Trade**. The code is written for teaching, not for advanced software engineering. Copy and adapt the examples when preparing figures, tables, or simple simulations.
The code chunks in this appendix are shown for reference and are not executed during rendering.
## Basic imports
```{python}
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```
## Create a simple table
```{python}
trade_data = pd.DataFrame({
"Country": ["Oman", "India"],
"Exports": [45.0, 780.0],
"Imports": [31.0, 720.0]
})
trade_data
```
## Calculate trade balance and openness
```{python}
exports = 28
imports = 36
gdp = 120
trade_balance = exports - imports
trade_openness = (exports + imports) / gdp * 100
print(f"Trade balance = {trade_balance:.1f} billion USD")
print(f"Trade openness = {trade_openness:.1f}%")
```
## Bar chart for exports and imports
```{python}
trade_data = pd.DataFrame({
"Category": ["Agricultural products", "Non-agricultural products"],
"Exports": [1834, 42718],
"Imports": [5133, 25747]
})
ax = trade_data.set_index("Category").plot(kind="bar")
ax.set_xlabel("")
ax.set_ylabel("Million US dollars")
ax.set_title("Merchandise trade by category")
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
```
## Horizontal bar chart for top products
```{python}
top_exports = pd.DataFrame({
"Product": [
"Crude petroleum",
"Petroleum gases",
"Refined petroleum",
"Nitrogenous fertilizers",
"Motor cars"
],
"Value": [18686, 4403, 3865, 1498, 955]
})
ax = top_exports.plot(kind="barh", x="Product", y="Value", legend=False)
ax.set_xlabel("Million US dollars")
ax.set_ylabel("")
ax.set_title("Top exported products")
ax.invert_yaxis()
plt.tight_layout()
plt.show()
```
## Ricardian PPF
The Ricardian labor constraint is:
$$
a_{LF}Q_F + a_{LC}Q_C = L
$$
Solving for cloth:
$$
Q_C = \frac{L - a_{LF}Q_F}{a_{LC}}
$$
```{python}
# Oman example
L = 2000
a_LF = 1
a_LC = 2
food = np.linspace(0, L / a_LF, 100)
cloth = (L - a_LF * food) / a_LC
plt.figure()
plt.plot(food, cloth)
plt.xlabel("Food")
plt.ylabel("Cloth")
plt.title("Production Possibility Frontier")
plt.xlim(0, L / a_LF)
plt.ylim(0, L / a_LC)
plt.tight_layout()
plt.show()
```
## Ricardian PPF and TPF
```{python}
L = 2000
a_LF = 1
a_LC = 2
world_price_food = 1.0 # 1 food = 1 cloth
food = np.linspace(0, L / a_LF, 100)
ppf_cloth = (L - a_LF * food) / a_LC
# Specialization in food
max_food = L / a_LF
tpf_cloth = world_price_food * (max_food - food)
plt.figure()
plt.plot(food, ppf_cloth, label="PPF")
plt.plot(food, tpf_cloth, linestyle="--", label="TPF")
plt.xlabel("Food")
plt.ylabel("Cloth")
plt.title("PPF and TPF")
plt.legend()
plt.tight_layout()
plt.show()
```
## Consumer surplus and producer surplus
For linear demand and supply:
$$
Q_d = a - bP
$$
$$
Q_s = c + dP
$$
```{python}
def demand(P, a, b):
return a - b * P
def supply(P, c, d):
return c + d * P
def autarky_equilibrium(a, b, c, d):
P = (a - c) / (b + d)
Q = supply(P, c, d)
return P, Q
def surplus_at_price(P, a, b, c, d):
Qd = demand(P, a, b)
Qs = supply(P, c, d)
P_max = a / b
P_min = -c / d
CS = 0.5 * (P_max - P) * Qd
PS = 0.5 * (P - P_min) * Qs
TS = CS + PS
return CS, PS, TS, Qd, Qs
# Example
P, Q = autarky_equilibrium(a=80, b=1, c=0, d=1)
CS, PS, TS, Qd, Qs = surplus_at_price(P, a=80, b=1, c=0, d=1)
print(P, Q, CS, PS, TS)
```
## Plot supply and demand with surplus areas
```{python}
a, b = 80, 1
c, d = 0, 1
P_eq, Q_eq = autarky_equilibrium(a, b, c, d)
P_values = np.linspace(0, a / b, 200)
Qd_values = demand(P_values, a, b)
Qs_values = supply(P_values, c, d)
plt.figure()
plt.plot(Qd_values, P_values, label="Demand")
plt.plot(Qs_values, P_values, label="Supply")
plt.axhline(P_eq, linestyle="--", label=f"Price = {P_eq:.0f}")
plt.axvline(Q_eq, linestyle="--", label=f"Quantity = {Q_eq:.0f}")
plt.fill_betweenx(P_values, 0, Qd_values, where=P_values >= P_eq, alpha=0.2)
plt.fill_betweenx(P_values, 0, Qs_values, where=P_values <= P_eq, alpha=0.2)
plt.xlabel("Quantity")
plt.ylabel("Price")
plt.title("Consumer and Producer Surplus")
plt.legend()
plt.tight_layout()
plt.show()
```
## Export supply and import demand
```{python}
# Country 1
params_1 = {"a": 80, "b": 1, "c": 0, "d": 1}
# Country 2
params_2 = {"a": 100, "b": 0.5, "c": 0, "d": 0.5}
P_values = np.linspace(0, 120, 200)
ES = supply(P_values, params_1["c"], params_1["d"]) - demand(P_values, params_1["a"], params_1["b"])
ED = demand(P_values, params_2["a"], params_2["b"]) - supply(P_values, params_2["c"], params_2["d"])
plt.figure()
plt.plot(ES, P_values, label="Export supply")
plt.plot(ED, P_values, label="Import demand")
plt.axhline(60, linestyle="--", label="World price")
plt.axvline(40, linestyle="--", label="Trade volume")
plt.xlabel("Trade quantity")
plt.ylabel("Price")
plt.title("World Equilibrium")
plt.legend()
plt.tight_layout()
plt.show()
```
## Effective rate of protection calculator
```{python}
def effective_rate_of_protection(output_world, input_world, output_tariff, input_tariffs):
"""
output_world: world price of final good
input_world: list of input costs at world prices
output_tariff: tariff rate on final good, such as 0.20
input_tariffs: list of tariff rates for each input
"""
VA_world = output_world - sum(input_world)
output_domestic = output_world * (1 + output_tariff)
inputs_domestic = [cost * (1 + tariff) for cost, tariff in zip(input_world, input_tariffs)]
VA_domestic = output_domestic - sum(inputs_domestic)
ERP = (VA_domestic - VA_world) / VA_world * 100
return VA_world, VA_domestic, ERP
# Cheese example
output_world = 20
input_world = [10, 5]
output_tariff = 0.20
input_tariffs = [0.10, 0.10]
effective_rate_of_protection(output_world, input_world, output_tariff, input_tariffs)
```
## FTA welfare calculation
```{python}
P0 = 6000
P1 = 5500
Q0 = 10 # thousand cars
Q1 = 15 # thousand cars
tariff = 1000
price_drop = P0 - P1
cs_gain = price_drop * Q0 + 0.5 * price_drop * (Q1 - Q0)
tariff_revenue_loss = tariff * Q0
net_welfare = cs_gain - tariff_revenue_loss
print(f"Consumer surplus gain = {cs_gain:.2f} million USD")
print(f"Tariff revenue loss = {tariff_revenue_loss:.2f} million USD")
print(f"Net welfare effect = {net_welfare:.2f} million USD")
```
## Exchange rate and import price
```{python}
foreign_price_usd = 300
exchange_rate = 0.385 # OMR per USD
domestic_price_omr = foreign_price_usd * exchange_rate
print(f"Domestic price = {domestic_price_omr:.2f} OMR")
```
## Simulated gravity model data
```{python}
gravity_data = pd.DataFrame({
"Partner": ["India", "UAE", "Saudi Arabia", "China", "Germany"],
"GDP_partner": [3900, 500, 1100, 18000, 4200],
"Distance": [1700, 450, 1200, 5600, 5200],
"Trade": [5.2, 9.1, 4.8, 6.5, 2.4]
})
gravity_data["ln_trade"] = np.log(gravity_data["Trade"])
gravity_data["ln_gdp_partner"] = np.log(gravity_data["GDP_partner"])
gravity_data["ln_distance"] = np.log(gravity_data["Distance"])
gravity_data
```
## Gravity-style scatter plot
```{python}
plt.figure()
plt.scatter(gravity_data["Distance"], gravity_data["Trade"])
for _, row in gravity_data.iterrows():
plt.text(row["Distance"], row["Trade"], row["Partner"])
plt.xlabel("Distance from Oman, km")
plt.ylabel("Trade value")
plt.title("Trade and Distance")
plt.tight_layout()
plt.show()
```
## TINA simulation table
```{python}
tina_results = pd.DataFrame({
"Direction": ["Oman exports to India", "India exports to Oman"],
"Trade creation": [402.80, 550.61],
"Trade diversion": [164.67, 106.02]
})
tina_results["Total trade effect"] = tina_results["Trade creation"] + tina_results["Trade diversion"]
tina_results
```
## TINA results chart
```{python}
ax = tina_results.set_index("Direction")[["Trade creation", "Trade diversion"]].plot(kind="bar")
ax.set_ylabel("USD million")
ax.set_title("CEPA simulated trade effects")
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
```
## Save a figure as SVG
Use SVG when you want a clean figure for the website.
```{python}
plt.figure()
plt.plot([1, 2, 3], [1, 4, 9])
plt.xlabel("x")
plt.ylabel("y")
plt.title("Example figure")
plt.tight_layout()
plt.savefig("figures/example-figure.svg")
plt.show()
```
## Common Quarto chunk options
```text
#| label: fig-example
#| fig-cap: "Figure caption here."
#| fig-width: 7
#| fig-height: 4
#| echo: true
#| warning: false
#| message: false
```
## Suggested coding rules for this course
1. Keep examples short.
2. Use clear variable names.
3. Label axes and figures.
4. Use tables before complex graphs.
5. Avoid unnecessary packages.
6. Prefer `pandas`, `numpy`, and `matplotlib`.
7. Do not use code that requires private data.
8. For final projects, explain the economic interpretation before the code.