Skip to content

french_rev: Data Sources lists 3 of the 5 datasets, and a stray DataFrame renders above fr_fig3 #828

Description

@mmcky

Two independent reader-facing defects on the published french_rev page, both found while validating QuantEcon/data-lectures#51 by rendering the live page and running the published notebook. Neither was introduced by the data migration; the first was made more visible by it.

1. Data Sources documents three of the five datasets the lecture reads

lectures/french_rev.md:59 says "This lecture uses data from three spreadsheets assembled by {cite}sargent_velde1995" and lists fig_3.xlsx, dette.xlsx and assignat.xlsx at :60-62.

The lecture actually reads five files. caron.npy and nom_balances.npy are fetched from the same base_url at :711-714 and are named nowhere outside code cells — a case-insensitive grep of the whole file for caron|nom_balances|\.npy returns 6 hits, all of them code.

Nine of the eighteen published figures derive entirely from those two files (fr_fig104 and its five variants, plus the three exercise-solution figures). So half the lecture's figures rest on sources a reader cannot click through to, in a section whose whole purpose is provenance.

Being fair about it: this is pre-existing documentation debt, not a concealed inconsistency. Both manifests state the gap explicitly in their header comments, and CATALOG.md publicly lists this lecture as a consumer of both .npy files. But 6986e35a (#826) rewrote exactly those three bullets in place to repoint them, which was the natural moment to add the other two — and the validation checklist for that work described them as "the three Data Sources links", encoding the gap rather than catching it.

lecture-wasm/lectures/french_rev.md:57-62 is identical and needs the same fix.

2. A stray 30-row DataFrame renders above fr_fig3

The published page renders an uncaptioned 30-row DataFrame table as the output of the data1.replace(0, np.nan, inplace=True) cell, immediately above the fr_fig3 figure. Confirmed reader-visible in a headless browser: table.dataframe, visible, 1117 px tall, 30 tbody rows, not collapsed.

The cause is a pandas 3 behaviour change, not anything the migration did. In pandas 3.0.3 — the version the live build used, per the publish run's conda log — DataFrame.replace(..., inplace=True) executes return self rather than returning None, so Jupyter renders the cell's last expression. The mutation still applies correctly (NaNs applied = 2), so no figure and no number is wrong. Purely cosmetic.

It is a genuine regression rather than long-standing: the 2026-03-09 archived copy of this page has class="dataframe" ×0, and the anaconda 2026.07 bump (#797, 2026-07-20) predates the migration.

The blast radius is narrower than "every inplace=True idiom", which is worth stating so this doesn't turn into a large sweep. In pandas 3.0.3, only replace, fillna and interpolate return self; dropna, set_index, reset_index, sort_values and rename still correctly return None. So only cells whose last statement is an inplace replace/fillna/interpolate are affected.

Simplest fix here is data1 = data1.replace(0, np.nan), which is also the form pandas is steering toward.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions