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

Code
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

Create a simple table

Code
trade_data = pd.DataFrame({
    "Country": ["Oman", "India"],
    "Exports": [45.0, 780.0],
    "Imports": [31.0, 720.0]
})

trade_data

Calculate trade balance and openness

Code
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

Code
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

Code
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}} \]

Code
# 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

Code
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 \]

Code
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

Code
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

Code
# 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

Code
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

Code
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

Code
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

Code
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

Code
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

Code
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

Code
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.

Code
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

#| 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.