Repository navigation
Conversation
…ecture
The lecture has been left out of this site because its data reads are
live API calls: wbgapi against the World Bank and pandas_datareader
against FRED. It now reads four cached snapshots from
QuantEcon/data-lectures on raw.githubusercontent.com at main, the form
that serves access-control-allow-origin: * (repoint rule 5):
gdp_growth_annual.csv World Bank NY.GDP.MKTP.KD.ZG
unemployment_rate_annual.csv World Bank SL.UEM.TOTL.NE.ZS
private_credit_to_gdp.csv World Bank FS.AST.PRVT.GD.ZS
us_business_cycle_monthly.csv FRED M0892AUSM156SNBR, UNRATE, USREC,
UMCSENT, CPILFESL and INDPRO
The file is a port of lecture-python-intro main's business_cycle.md
(901462c; the file last changed there in
QuantEcon/lecture-python-intro#770), not an edit of this repo's
2025-10-23 copy. So it carries intro's later changes and its "to the
present" prose, which fits snapshots that refresh (FRED monthly, the
World Bank annually). This repo's conventions from #31 are kept: the
:label: options with :::{figure} blocks, short-form tags, front matter.
Beyond those conventions, only data access changes:
- the pip cell and both API imports go; pyodide_http.patch_all() runs
in the imports cell, as in mle and simple_linear_regression;
- each wb.data.DataFrame(..., labels=True) becomes a read_csv with
index_col='economy', followed by .loc on the economies the API call
named;
- each web.DataReader(id, 'fred', start, end) becomes
fred_series(id, start, end), a small helper over the composite that
returns what DataReader returned: one column named for the series,
holding only that series' own observations in the window;
- the two wbgapi teaching calls, wb.series.info and
wb.series.metadata.get, are shown as non-executing python blocks,
with a note linking the intro edition that runs them live;
- the two year-on-year changes pass fill_method=None to pct_change.
Pyodide 0.27.0 ships pandas 2.2.3, which otherwise pads FRED's
2025-10 hole in CPILFESL and warns; intro builds on pandas 3, which
does neither, so the browser's figure now matches intro's.
Two sentences are new (the page reads snapshots; the API calls are
shown without running), and three are reworded because the port made
them untrue: "through to the most recent available data", "use this
series ID to obtain the data" and the metadata sentence's "(click to
expand)".
myst.yml uncomments business_cycle. The README drops business_cycle
and short_path from the unsupported list (short_path has been enabled
in myst.yml since #31), and retires the rule to sync from intro's wasm
branch: that branch has not changed since 2025-04-24, and PRs here edit
lectures/ directly. update_lectures.py stays for now.
Verified on 2026-09-30:
- all 22 code cells run in order in one namespace under the Pyodide
0.27.0 pins (Python 3.12, pandas 2.2.3, numpy 2.0.2, matplotlib
3.8.4; pyodide_http stubbed, wbgapi and pandas_datareader blocked),
drawing 12 figures with no errors and no warnings;
- mystmd 1.9.1 builds the site (exit 0), and its only business_cycle
message is the toc-extension notice every entry gets;
- the data-url-guard step passes;
- all four URLs return 200 with access-control-allow-origin: *, and
their bytes match the manifests' sha256;
- the World Bank reads match live wbgapi at all four call sites (only
the row order differs), and fred_series matches web.DataReader at
all eight FRED call sites in columns, index, dtypes and nulls; values
differ only by FRED's latest INDPRO revisions and its newer month.
Not verified: a run in a browser.
Block B of QuantEcon/data-lectures#118; the issue here is #70.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ Deploy Preview for beautiful-dodol-cb9543 failed.
|
|
📖 Netlify Preview Ready! Preview URL: https://pr-85--beautiful-dodol-cb9543.netlify.app (adaf9bc) ✨ Browse the preview at the URL above. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-enables
business_cycleon this site. The lecture was left out because its data reads were live API calls,wbgapiagainst the World Bank andpandas_datareaderagainst FRED. It now reads four cached snapshots that QuantEcon/data-lectures serves and refreshes by pull request, so it can run in the reader's browser. This is block B of thewasm-dynamic-snapshotsproject, tracked in QuantEcon/data-lectures#118.Closes #70.
What changes
lectures/business_cycle.mdis a port of lecture-python-intromain's copy, not an edit of this repo's 2025-10-23 copy. The port is from intro commit 901462c; the file last changed there in Update business cycle data to latest available (#364) lecture-python-intro#770. So it carries intro's later changes and its "to the present" prose, which suits snapshots that refresh. That is option (a) of decision 1 on lecture-wasm dynamic snapshots: business_cycle reads the four data-lectures snapshots (P4) data-lectures#118, taken on 2026-09-30. This repo's conventions from ENH: Migrate to usemystmdand quantecon-theme. #31 are kept::label:options with:::{figure}blocks, short-form tags and the front matter. Beyond those conventions, only data access changes:pip installcell and both API imports go, andpyodide_http.patch_all()runs in the imports cell, as inmleandsimple_linear_regression;wb.data.DataFrame(…, labels=True)becomespd.read_csv(…, index_col='economy'), followed by.loc[[…]]on the economies the API call named;web.DataReader(id, 'fred', start, end)becomesfred_series(id, start, end), a helper described below;wbgapiteaching calls,wb.series.infoandwb.series.metadata.get, become non-executingpythonblocks, with a note linking the intro edition that runs them live;fill_method=Nonetopct_change, described below.lectures/myst.ymluncommentsbusiness_cycle, betweenlong_run_growthandinflation_history.README.md:business_cycleandshort_pathleave the unsupported list, so the list matches the six entries still commented out inmyst.yml(short_pathhas been enabled inmyst.ymlsince ENH: Migrate to usemystmdand quantecon-theme. #31). The rule "do not edit lectures here; sync from intro'swasmbranch" gives way to "editlectures/directly and check the change on the PR's preview". That branch has not changed since 2025-04-24 (c870cca) and is 131 commits behind intromain, and PRs here already editlectures/directly.Enabling the page also mends a link. On
main,long_run_growth's[business cycle](business_cycle)builds as a download of the raw.mdfile; on this branch it links to the page. Nothing is deleted, because this repo holds no copy of these data.The four snapshots
All four are read at
mainonraw.githubusercontent.com, the form that works in the browser (data-lectures repoint rule 5).NY.GDP.MKTP.KD.ZG, nine economiesSL.UEM.TOTL.NE.ZS, four economiesFS.AST.PRVT.GD.ZS, United KingdomM0892AUSM156SNBR,UNRATE,USREC,UMCSENT,CPILFESLandINDPROon one monthly indexfred_seriesat eight call sitesFor the lecture's authors to accept
The
fred_serieshelperThis is the one piece of new logic that intro does not have (lines 322 to 328):
The composite pads all six series to one index starting in 1919, but
web.DataReaderreturned only a series' own observations in the window. The helper returns the same thing. I compared it live withweb.DataReader(pandas-datareader 0.11.1) at all eight call sites on 2026-09-30. The frames have the same columns, index name and dtype, value dtypes and null placement, includingUNRATE's 2025-10 hole, which FRED also serves. Values differ only where FRED has revisedINDPROsince the snapshot was taken, by at most 0.13 in the YoY change, and by FRED's newer month.The alternative is to repeat the slice and the trim at each of the eight call sites. The helper has one limit, which no call here reaches: for a window with no observations it returns every row of the window, all NaN, rather than an empty frame.
fill_method=Nonein the twopct_changecalls (lines 645 and 704)Pyodide 0.27.0, which this site loads, ships pandas 2.2.3. There,
pct_change(12)pads FRED's 2025-10 hole inCPILFESLforward. That plots a point intro's figure does not have and prints a FutureWarning under the consumption figure. Intro builds on pandas 3 (anaconda 2026.07), wherefill_method=Noneis already the behaviour, so intro does neither. Passing it explicitly makes the browser's figure match intro's, and pandas 3 accepts it unchanged.INDPROhas no hole, so the production figure does not change; the keyword is there for symmetry. Drop both if you would rather keep intro's code verbatim, at the cost of the padded point and the warning.For an author's eye: five sentences
Two sentences are new, in Data acquisition:
wbgapibelow are shown without running; the edition of this lecture on intro.quantecon.org runs them live." (linked to intro's Data acquisition section)Three existing sentences are reworded, because the port made them untrue:
The first non-executing block also gains
import wbgapi as wb, becausewbis otherwise never bound on the page. The code comment at line 101 now reads "Read the same snapshot again".What was verified, and how (2026-09-30)
{code-cell}blocks of the committed file, in order, in one namespace, under the Pyodide 0.27.0 pins that this build's thebe bundle loads (pandas 2.2.3, numpy 2.0.2, matplotlib 3.8.4; CPython 3.12.13, where Pyodide has 3.12.7). Agg backend, a no-oppyodide_httpstub, and imports ofwbgapiandpandas_datareaderblocked, since the browser has neithernpx mystmd@1.9.1 build --htmlinlectures/, asci.ymldoes, on this branch rebased onmain(ff9196d, theme v3.2.0)us_gdptodcpc)data-url-guardrun:step, taken from.github/workflows/data-url-guard.ymland run on this branchscripts/build_audit.pyatmain) applied to the filehttps://raw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/<file>, with nogithub.com/…/raw/form, no media host and no other ref. The audit finds four data-lectures refs and no live-API marker; onmainit flagswbgapiandpandas_datareadercurlwithOrigin: https://quantecon.github.io, and again with a Netlify preview originaccess-control-allow-origin: *, with bytes matching its manifest'ssha256on data-lecturesmainat the timewb.data.DataFrame(…, labels=True)at all four call sites, against the snapshot readsCountrylabels, nulls and values; only the row order differsfred_seriesgit merge-treeagainst #81's headNot verified: a run in a browser. The code ran on CPython with
pyodide_httpstubbed, so the browser's fetch path is untested here.The gate: Run all on this PR's preview
Someone needs to open this PR's own preview at
https://pr-<N>--beautiful-dodol-cb9543.netlify.app/business-cycle/, where N is this PR's number (the "Netlify Preview Ready!" comment gives the URL), and run "Run all". JupyterLite stops at the first failing cell, so the lecture passes when all 12 figures draw. Ignore the red Netlify app check: it fails on every PR here (#62), while the workflow's own preview serves real pages. CI cannot do this check, becauseci.ymlbuilds without running any code. Run it after data-lectures' first monthly refresh has merged (its PR should open on Monday 2026-10-05), so the gate tests the bytes this page will read.Before merging
permittedon Michigan's FAQ, so the Consumption subsection stays as it is.repointed. Between the two merges, data-lectures' strict audit fails, because alandedrecord has a reader. Every push to data-lecturesmainand any PR there that touches a manifest go red, and its Pages deploy is skipped. So merge B and C the same day, with no Monday 05:17 UTC audit run between the two merges.Open questions
update_lectures.pygo? This PR keeps it. The README now retires the sync, but the script still downloads intro'swasmbranch and copies itslectures/over this repo's (shutil.copytree(…, dirs_exist_ok=True)). That branch still has abusiness_cycle.md, so running the script would bring back the old live-API copy, along with other stale files. Delete the script, or keep it as history? Without it, porting from intro means applying its conversions by hand (!pipto%pip, dropping--upgrade).wbgapicalls run here after all? Include business_cycle: what it reads, what data-lectures now serves, and the sequence #70 assumed the API hosts send no CORS headers. Todayapi.worldbank.org/v2answersaccess-control-allow-origin: *, though FRED'sfredgraph.csvsends none. Whetherwbgapiinstalls through piplite and runs underpyodide_httpis untested, so this PR follows Include business_cycle: what it reads, what data-lectures now serves, and the sequence #70 and shows the calls without running them. Its prose does not claim they cannot run.wbgapireturns the API's order. Values, labels and figures are unaffected.Left alone on purpose
This is prose inherited from intro that the snapshots do not fully bear out. Changing it is intro's call, not this port's.
end_date, "To freeze the data for a reproducible build…": this site builds without executing code, and a fixed date does not freeze a snapshot that is refreshed in place.🤖 Generated with Claude Code