{
 "about": "CK-M, the Modeler checkpoint: the two briefs and the supplied model of part B, for readers who work outside Python. No tasks, answers or solutions: those are on the checkpoint page. The water brief and all costs are illustrative; the three days are real 2025 SPP shapes (EIA-930), scaled as the page says.",
 "version": "ck-m v2 (3 Nov 2026)",
 "brief": {
  "text": "Prairie Town's water utility pumps groundwater into a water tower, and the town draws its water from the tower. Find tomorrow's pumping schedule that meets the town's water use at the least electricity cost for the day.",
  "facts": [
   [
    "Water use",
    "forecast for each hour of tomorrow, in the table below (m³)"
   ],
   [
    "Pumps",
    "lift up to 900 m³ an hour and use 0.5 kWh of electricity per m³ pumped"
   ],
   [
    "Tower",
    "holds 800 to 4,000 m³; 2,000 m³ at the start of the day, and at least as much at the end"
   ],
   [
    "Energy price",
    "the rural electric co-op's time-of-use price: $0.06 per kWh from 22:00 to 06:00, $0.20 from 16:00 to 21:00, $0.10 otherwise"
   ],
   [
    "Demand charge",
    "$0.40 for each kW of the day's highest hourly draw"
   ]
  ],
  "note": "All numbers in this brief are illustrative.",
  "water": [
   180,
   160,
   150,
   150,
   170,
   250,
   420,
   610,
   640,
   560,
   480,
   450,
   440,
   430,
   420,
   430,
   470,
   560,
   640,
   650,
   560,
   430,
   320,
   230
  ],
  "price": [
   0.06,
   0.06,
   0.06,
   0.06,
   0.06,
   0.06,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.1,
   0.2,
   0.2,
   0.2,
   0.2,
   0.2,
   0.1,
   0.06,
   0.06
  ],
  "kWhPerM3": 0.5,
  "pumpMax": 900,
  "towerMin": 800,
  "towerMax": 4000,
  "towerStart": 2000,
  "demandCharge": 0.4
 },
 "empirical": {
  "text": "Prairie Town's planners want to know how far its wind and solar farms can be counted on when the town needs power most. Report what the town can and cannot count on, and how far your results depend on the dataset's scaling.",
  "facts": [
   [
    "Data",
    "town_year.json, the course's year file: the real 2025 hourly demand, wind and solar of the Southwest Power Pool grid (EIA-930), each as a shape in thousandths of its own highest 2025 hour"
   ],
   [
    "Metadata",
    "the file's meta block gives the source, the time convention and how bad hours were filled"
   ],
   [
    "Scaling",
    "as lesson 0: demand × 450 MW, the wind farm × 150 MW, the solar farm × 200 MW, so SPP's highest hour means a farm at its full size"
   ],
   [
    "Compare",
    "each farm's output in the 100 hours of highest demand, and in the 100 hours of highest net load (demand minus wind and solar), with its average over the year"
   ],
   [
    "Ties",
    "where hours tie, take the earlier one first"
   ]
  ],
  "demandPeakMW": 450,
  "windMW": 150,
  "solarMW": 200,
  "topN": 100,
  "eiaWind": 0.338,
  "eiaSolar": 0.24
 },
 "defect": {
  "about": "The supplied model: what should Prairie Town build (wind, solar, a gas combined-cycle plant, a gas peaker) to meet demand on three representative days of 2025, each weighted by the days of the year it stands for? One planted defect.",
  "V": 10000,
  "techs": {
   "wind": {
    "label": "Wind farm",
    "capital": 100000,
    "cost": 0
   },
   "solar": {
    "label": "Solar farm",
    "capital": 70000,
    "cost": 0
   },
   "cc": {
    "label": "Gas combined-cycle",
    "capital": 80000,
    "cost": 40
   },
   "pk": {
    "label": "Gas peaker",
    "capital": 50000,
    "cost": 100
   }
  },
  "notes": [
   [
    "Costs",
    "illustrative round numbers: capital already annualized ($ per MW of capacity per year); running costs as in lesson 0"
   ],
   [
    "Demand",
    "the three real days' SPP shape × 450 MW"
   ],
   [
    "Wind and solar",
    "output per MW built: the SPP shapes scaled to EIA's 2025 U.S. capacity factors (33.8% and 24.0%) with the course's scale method"
   ]
  ],
  "paper": [
   [
    "Weights",
    "w_d = the days of the year that day d stands for (121, 122, 122; they sum to 365)."
   ],
   [
    "Goal",
    "min Σ_g A_g K_g + Σ_d w_d Σ_t [ (Σ_g c_g p_g,d,t) + V u_d,t ]   ($ a year)"
   ],
   [
    "Balance",
    "Σ_g p_g,d,t + u_d,t = D_d,t   (MW, every day and hour)"
   ],
   [
    "Wind and solar",
    "p_g,d,t ≤ a_g,d,t K_g   (a: output per MW built, 0 to 1)"
   ],
   [
    "Gas plants",
    "p_g,d,t ≤ K_g"
   ],
   [
    "Domains",
    "K_g ≥ 0,  p_g,d,t ≥ 0,  u_d,t ≥ 0"
   ]
  ],
  "symbols": [
   [
    "g",
    "a technology: wind, solar, gas combined-cycle (cc), gas peaker (pk)",
    "–"
   ],
   [
    "d, t",
    "a representative day, and an hour of it (t = 0 to 23, one hour each)",
    "–"
   ],
   [
    "w_d",
    "the days of the year that day d stands for",
    "days"
   ],
   [
    "A_g",
    "capital cost, already annualized",
    "$ per MW of capacity per year"
   ],
   [
    "K_g",
    "capacity built: a decision",
    "MW"
   ],
   [
    "c_g",
    "running cost",
    "$/MWh"
   ],
   [
    "p_g,d,t",
    "output in hour t of day d: a decision",
    "MW (held for one hour, so also MWh)"
   ],
   [
    "u_d,t",
    "demand left unserved: a decision",
    "MW (also MWh in its hour)"
   ],
   [
    "V",
    "the cost of unserved demand, $10,000",
    "$/MWh"
   ],
   [
    "D_d,t",
    "demand",
    "MW"
   ],
   [
    "a_g,d,t",
    "output per MW built, 0 to 1 (wind and solar)",
    "MW per MW"
   ]
  ],
  "code": [
   "DAYS = {\"winter\": 121, \"shoulder\": 122, \"summer\": 122}       # days of 2025 each day stands for",
   "weight = {d: DAYS[d] / 365 for d in DAYS}                    # share of the year",
   "cost = {\"wind\": 0, \"solar\": 0, \"cc\": 40, \"pk\": 100}           # running cost, $ per MWh",
   "capital = {\"wind\": 100_000, \"solar\": 70_000, \"cc\": 80_000, \"pk\": 50_000}   # $ per MW-year, annualized",
   "V = 10_000                                                    # $ per MWh of demand left unserved",
   "minimize( sum(capital[g] * K[g] for g) + sum(weight[d] * (sum(cost[g] * p[g,d,t] for g) + V * u[d,t]) for d, t) )",
   "for d, t: sum(p[g,d,t] for g) + u[d,t] == demand[d][t]                 # balance, MW",
   "for g in (\"wind\", \"solar\"), d, t: p[g,d,t] <= avail[g][d][t] * K[g]   # output per MW built",
   "for g in (\"cc\", \"pk\"), d, t: p[g,d,t] <= K[g]",
   "report(K, annual_cost=objective, demand_in_year=sum(weight[d] * demand[d][t] for d, t))"
  ],
  "days": [
   {
    "id": "winter",
    "date": "2025-01-16",
    "weight": 121,
    "demand": [
     277.65,
     275.85,
     275.85,
     277.2,
     281.7,
     292.5,
     310.05,
     319.95,
     315.45,
     302.85,
     292.05,
     283.95,
     275.85,
     269.1,
     264.15,
     261,
     263.25,
     274.05,
     284.85,
     287.55,
     288,
     284.85,
     277.2,
     270
    ],
    "wind": [
     0.4741,
     0.4722,
     0.4645,
     0.4677,
     0.4645,
     0.4459,
     0.4248,
     0.3646,
     0.289,
     0.1768,
     0.0942,
     0.075,
     0.0871,
     0.1205,
     0.1768,
     0.2345,
     0.3024,
     0.3851,
     0.469,
     0.5049,
     0.5279,
     0.5324,
     0.5331,
     0.5209
    ],
    "solar": [
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0.001,
     0.1158,
     0.3996,
     0.4939,
     0.4447,
     0.3617,
     0.3709,
     0.3494,
     0.4324,
     0.3084,
     0.0717,
     0,
     0,
     0,
     0,
     0,
     0
    ],
    "label": "Thursday 16 January 2025",
    "stands": "December to March (121 days)"
   },
   {
    "id": "shoulder",
    "date": "2025-04-02",
    "weight": 122,
    "demand": [
     231.3,
     226.8,
     223.65,
     222.75,
     224.55,
     231.3,
     244.8,
     255.15,
     257.85,
     259.65,
     261.45,
     262.8,
     261.9,
     262.8,
     262.8,
     262.35,
     263.7,
     264.6,
     263.25,
     261,
     263.25,
     256.5,
     244.8,
     232.65
    ],
    "wind": [
     0.4421,
     0.4235,
     0.4145,
     0.4062,
     0.3921,
     0.3652,
     0.3466,
     0.3332,
     0.3678,
     0.4158,
     0.4414,
     0.4286,
     0.3998,
     0.3806,
     0.3614,
     0.3441,
     0.3453,
     0.3139,
     0.2774,
     0.2102,
     0.2031,
     0.2236,
     0.2383,
     0.2665
    ],
    "solar": [
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0.0102,
     0.2203,
     0.4488,
     0.4509,
     0.5472,
     0.5226,
     0.5769,
     0.6292,
     0.5697,
     0.497,
     0.4355,
     0.333,
     0.0615,
     0,
     0,
     0,
     0
    ],
    "label": "Wednesday 2 April 2025",
    "stands": "April, May, October and November (122 days)"
   },
   {
    "id": "summer",
    "date": "2025-09-15",
    "weight": 122,
    "demand": [
     257.85,
     248.85,
     242.55,
     238.95,
     239.85,
     246.6,
     261,
     269.55,
     278.1,
     290.7,
     308.7,
     328.95,
     348.75,
     365.85,
     377.1,
     383.4,
     386.55,
     383.4,
     373.5,
     359.55,
     347.85,
     329.85,
     308.7,
     288.45
    ],
    "wind": [
     0.3562,
     0.3364,
     0.3312,
     0.3389,
     0.3319,
     0.3261,
     0.3184,
     0.2966,
     0.2351,
     0.1403,
     0.1211,
     0.1307,
     0.1378,
     0.1454,
     0.1538,
     0.1647,
     0.1877,
     0.2178,
     0.2242,
     0.2518,
     0.3453,
     0.4338,
     0.4812,
     0.4754
    ],
    "solar": [
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0.0236,
     0.2285,
     0.6486,
     0.8249,
     0.8474,
     0.8136,
     0.8074,
     0.788,
     0.8331,
     0.789,
     0.787,
     0.4478,
     0.0728,
     0,
     0,
     0,
     0
    ],
    "label": "Monday 15 September 2025",
    "stands": "June to September (122 days)"
   }
  ]
 },
 "sources": {
  "eia-930": {
   "text": "EIA, Hourly Electric Grid Monitor (Form EIA-930), Southwest Power Pool, 2025",
   "url": "https://www.eia.gov/electricity/gridmonitor/",
   "asOf": "accessed 2 Nov 2026"
  },
  "eia-cf": {
   "text": "EIA, Electric Power Monthly, Table 6.07.B (capacity factors, U.S. utility-scale fleets)",
   "url": "https://www.eia.gov/electricity/monthly/epm_table_grapher.php?t=epmt_6_07_b",
   "asOf": "2025 annual values (wind 33.8%, solar 24.0%); issue of 23 October 2026, accessed 2 November 2026"
  },
  "eia-860m": {
   "text": "EIA, Preliminary Monthly Electric Generator Inventory (Form EIA-860M), December 2025 data (file december_generator2025.xlsx)",
   "url": "https://www.eia.gov/electricity/data/eia860m/",
   "asOf": "December 2025 inventory, file last modified 26 January 2026; accessed 5 November 2026"
  }
 }
}
