<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Norman Li</title>
    <link>https://normanli.net/</link>
    <description>Recent content on Norman Li</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 25 Aug 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://normanli.net/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Syntetos–Boylan Demand Classification Template</title>
      <link>https://normanli.net/lab/syntetos-boylan-demand-classification/</link>
      <pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/syntetos-boylan-demand-classification/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Not all SKUs deserve the same forecasting treatment. A slow-moving spare part and a high-volume production item behave completely differently, and applying a single forecasting method to both guarantees poor accuracy somewhere.&lt;/p&gt;&#xA;&lt;p&gt;The classic response is ABC segmentation, but ABC only ranks by value — it says nothing about &lt;strong&gt;how often&lt;/strong&gt; demand occurs or &lt;strong&gt;how variable&lt;/strong&gt; demand sizes are. Two SKUs with identical annual value can have completely different demand patterns and need completely different forecasting and stocking policies.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Demand Planning for Industrial, B2B and Project-Driven Businesses</title>
      <link>https://normanli.net/essays/demand-planning-industrial-b2b-project-driven-businesses/</link>
      <pubDate>Thu, 20 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/demand-planning-industrial-b2b-project-driven-businesses/</guid>
      <description>Industrial and B2B demand is driven by projects, tenders, shutdowns and one-off orders — not continuous consumer buying. A practical framework that combines ABC segmentation, demand-pattern classification, customer intelligence, inventory exposure and procurement commitments to make better decisions under uncertainty.</description>
    </item>
    <item>
      <title>Ecommerce Sales Analytics: A 5,000-Order Dataset Walkthrough</title>
      <link>https://normanli.net/essays/ecommerce-sales-analytics-dataset-walkthrough/</link>
      <pubDate>Tue, 18 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/ecommerce-sales-analytics-dataset-walkthrough/</guid>
      <description>A quick tour of a 5,000-order ecommerce sales dataset — what&amp;rsquo;s inside, what the data says about categories, regions, payments and pricing, and what to watch out for before using it.</description>
    </item>
    <item>
      <title>A Practical Guide to Forecast Error Metrics</title>
      <link>https://normanli.net/essays/practical-guide-to-forecast-error-metrics/</link>
      <pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/practical-guide-to-forecast-error-metrics/</guid>
      <description>MAPE is every planner&amp;rsquo;s default accuracy number — and it quietly misleads on slow-moving and intermittent demand. A practical comparison of MAPE, MAE, RMSE, WAPE and sMAPE, and when to use each.</description>
    </item>
    <item>
      <title>Exploratory Data Analysis: The Math and Python for Every Step</title>
      <link>https://normanli.net/essays/eda-guide-math-and-python/</link>
      <pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/eda-guide-math-and-python/</guid>
      <description>A visual EDA guide turned into a reference: for each of the nine steps — overview, missing values, descriptive stats, univariate, bivariate, correlation, outliers, distribution, insights — the exact formula and the exact pandas/seaborn function to run.</description>
    </item>
    <item>
      <title>Demand Exception Reports: Purpose, Review Process, and Practical Challenges</title>
      <link>https://normanli.net/essays/demand-exception-reports/</link>
      <pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/demand-exception-reports/</guid>
      <description>A Demand Exception Report is an analytical tool used in demand planning and S&amp;amp;OP to identify the products that require human investigation. This guide covers exception categories such as forecast variance, bias, spikes, stockout distortions and launch deviations, plus an eight-step review process and the practical challenges of designing a report that planners actually use.</description>
    </item>
    <item>
      <title>Store Sales Forecasting with SARIMAX: A Full Walkthrough</title>
      <link>https://normanli.net/essays/store-sales-forecasting-sarimax-walkthrough/</link>
      <pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/store-sales-forecasting-sarimax-walkthrough/</guid>
      <description>A complete SARIMAX forecasting pipeline on the Store Sales dataset — from EDA and stationarity testing through model fitting, residual diagnostics, back-transformation, and forecasting with confidence intervals.</description>
    </item>
    <item>
      <title>Store Sales SARIMAX Forecast</title>
      <link>https://normanli.net/lab/store-sales-sarimax-forecast/</link>
      <pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/store-sales-sarimax-forecast/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Daily sales at a grocery chain follow a strong weekly rhythm, but promotions and holidays throw spikes at it that a naive forecast can&amp;rsquo;t see coming. Baseline forecasts either ignore the weekly seasonality entirely or get blindsided by holiday demand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding SARIMAX Outputs: A Diagnostic Guide for Junior Analysts</title>
      <link>https://normanli.net/essays/understanding-sarimax-outputs-diagnostic-guide/</link>
      <pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/understanding-sarimax-outputs-diagnostic-guide/</guid>
      <description>A step-by-step diagnostic guide for junior analysts on evaluating, interpreting, and refining statsmodels time-series reports.</description>
    </item>
    <item>
      <title>Excel Solver - Returns-Distribution Fitter</title>
      <link>https://normanli.net/lab/solver-returns-distribution/</link>
      <pubDate>Mon, 27 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/solver-returns-distribution/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;When assets are issued each week and returned over subsequent weeks—such as containers, pallets, tools, and other returnable equipment—planners need a model that captures the return-lag distribution.&lt;/p&gt;&#xA;&lt;p&gt;In practice, return timing is often represented by a fixed cycle time based on experience. However, this assumption may not reflect actual return behaviour and can lead to inaccurate return forecasts, inventory imbalances, or unnecessary asset purchases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ABC-XYZ Analysis: A Practical Guide to Inventory Segmentation for Demand Planning</title>
      <link>https://normanli.net/essays/abc-xyz-analysis-inventory-segmentation/</link>
      <pubDate>Sat, 25 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/abc-xyz-analysis-inventory-segmentation/</guid>
      <description>ABC tells you what matters financially. XYZ tells you what you can actually forecast. Together they form the foundation of every sensible inventory strategy.</description>
    </item>
    <item>
      <title>Demand Planning KPIs: Learning Notes on Forecast Accuracy Metrics</title>
      <link>https://normanli.net/essays/demand-planning-kpi-learning-notes/</link>
      <pubDate>Wed, 15 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/demand-planning-kpi-learning-notes/</guid>
      <description>Eight forecast KPIs that come up constantly in demand planning — with the formula, the business meaning, and the trap hidden inside each one.</description>
    </item>
    <item>
      <title>Reading Theory of Constraints again</title>
      <link>https://normanli.net/stream/reading-theory-of-constraints/</link>
      <pubDate>Sat, 11 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/stream/reading-theory-of-constraints/</guid>
      <description>&lt;p&gt;Reading about theory of constraints again. Keep circling back to it whenever a planning process feels stuck — the bottleneck is rarely where the complaints are loudest.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TIL: pandas .explode() for BOM flattening</title>
      <link>https://normanli.net/stream/til-explode/</link>
      <pubDate>Wed, 08 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/stream/til-explode/</guid>
      <description>&lt;p&gt;TIL: &lt;code&gt;pandas.DataFrame.explode()&lt;/code&gt; solves the bill-of-materials flattening problem cleanly — one list-column per parent, exploded into one row per component, no manual loop.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Your Safety Stock Is Lying to You</title>
      <link>https://normanli.net/essays/why-your-safety-stock-is-lying-to-you/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/why-your-safety-stock-is-lying-to-you/</guid>
      <description>Every planner inherits the same textbook formula for safety stock. Almost nobody checks whether their demand actually looks the way the formula assumes it does.</description>
    </item>
    <item>
      <title>Reorder-Point Simulator</title>
      <link>https://normanli.net/lab/reorder-point-simulator/</link>
      <pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/reorder-point-simulator/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Planners kept asking &amp;ldquo;what happens to stockouts if we drop safety stock by 10%&amp;rdquo; and getting an answer three days later, after a spreadsheet exercise. This simulator answers it in a few seconds.&lt;/p&gt;&#xA;&lt;h2 id=&#34;approach&#34;&gt;Approach&lt;/h2&gt;&#xA;&lt;p&gt;A discrete-event simulation over historical daily demand: feed in a demand series, a lead time distribution, and a reorder policy, and it plays the policy forward against real (not assumed-normal) demand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>On forecast accuracy metrics</title>
      <link>https://normanli.net/stream/on-forecast-accuracy-metrics/</link>
      <pubDate>Thu, 25 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/stream/on-forecast-accuracy-metrics/</guid>
      <description>&lt;p&gt;Every team measures forecast accuracy differently, and almost nobody states which one they mean. MAPE punishes low-volume SKUs unfairly; WMAPE fixes that but hides SKU-level misses. Worth writing up properly at some point.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Demand Planner&#39;s Guide to LLM Evals</title>
      <link>https://normanli.net/essays/demand-planners-guide-to-llm-evals/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/demand-planners-guide-to-llm-evals/</guid>
      <description>Evaluating a prompt change is a forecasting problem in disguise: you need a baseline, a held-out test set, and a way to tell signal from noise.</description>
    </item>
    <item>
      <title>The Join That Broke Procurement</title>
      <link>https://normanli.net/essays/the-join-that-broke-procurement/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/essays/the-join-that-broke-procurement/</guid>
      <description>A silent one-to-many join quietly tripled our open-PO totals for two months before anyone noticed the number looked wrong.</description>
    </item>
    <item>
      <title>PO Anomaly Detector</title>
      <link>https://normanli.net/lab/po-anomaly-detector/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/po-anomaly-detector/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Duplicate and near-duplicate purchase orders were slipping through — same vendor, same amount, submitted twice within a few days. Manual review only caught them after the second payment cleared.&lt;/p&gt;&#xA;&lt;h2 id=&#34;approach&#34;&gt;Approach&lt;/h2&gt;&#xA;&lt;p&gt;A nightly SQL job flags PO pairs within the same vendor where amount and description are within a similarity threshold and the submission dates are close together, surfaced in a Power BI report the procurement team checks each morning.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vendor Scorecard</title>
      <link>https://normanli.net/lab/vendor-scorecard/</link>
      <pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/lab/vendor-scorecard/</guid>
      <description>&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;Vendor performance reviews ran on whichever spreadsheet the category manager happened to maintain — inconsistent metrics, no history, no way to compare vendors across categories.&lt;/p&gt;&#xA;&lt;h2 id=&#34;approach&#34;&gt;Approach&lt;/h2&gt;&#xA;&lt;p&gt;A single Power BI model combining on-time delivery, quality rejection rate, and price variance against contract, refreshed weekly from the ERP and quality systems.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bullwhip Effect</title>
      <link>https://normanli.net/garden/bullwhip-effect/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/garden/bullwhip-effect/</guid>
      <description>&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;&#xA;&lt;p&gt;Retail demand for a product ticks up 10% one week. The retailer, wanting a buffer, orders 20% more from the distributor. The distributor, seeing that 20% jump and wanting its own buffer, orders 40% more from the manufacturer. By the time the signal reaches raw-material suppliers, a 10% demand change looks like a 60%+ swing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>KL Divergence</title>
      <link>https://normanli.net/garden/kl-divergence/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/garden/kl-divergence/</guid>
      <description>&lt;p&gt;KL divergence—Kullback–Leibler divergence—measures how different one probability distribution is from another.&lt;/p&gt;&#xA;&lt;p&gt;For discrete distributions $P$ and $Q$:&lt;/p&gt;&#xA;$$D_{\mathrm{KL}}(P\|Q)=\sum_x P(x)\log\left(\frac{P(x)}{Q(x)}\right)$$&lt;p&gt;It can be interpreted as:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The extra information loss incurred when using $Q$ to approximate the true distribution $P$.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;simple-example&#34;&gt;Simple Example&lt;/h2&gt;&#xA;&lt;p&gt;Suppose the true coin distribution is:&lt;/p&gt;</description>
    </item>
    <item>
      <title>LLM Eval Harness</title>
      <link>https://normanli.net/garden/llm-eval-harness/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/garden/llm-eval-harness/</guid>
      <description>&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;&#xA;&lt;p&gt;A fixed set of representative inputs, each with a rubric of pass/fail checks rather than a single subjective quality score:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;RUBRIC&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;mentions_driver&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;because&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;correct_direction&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expected_direction&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;no_hallucinated_numbers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contains_unverified_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every candidate prompt runs against the same fixed set before it ships, so a change is judged against a stable baseline instead of a handful of examples that happened to look good.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pandas &amp; NumPy Time Series Cleaning</title>
      <link>https://normanli.net/garden/pandas-numpy-timeseries-cleaning/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/garden/pandas-numpy-timeseries-cleaning/</guid>
      <description>&lt;p&gt;A quick-reference cheat sheet of the most commonly used functions, organized by workflow stage. Written for use alongside SARIMAX / Chronos-2 / AutoGluon forecasting scripts.&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-loading--initial-inspection&#34;&gt;1. Loading &amp;amp; Initial Inspection&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_csv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_dates&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date_col&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index_col&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date_col&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_excel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sheet_name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_dates&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date_col&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;                  &lt;span class=&#34;c1&#34;&gt;# dtypes, nulls, memory&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;describe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;               &lt;span class=&#34;c1&#34;&gt;# summary stats&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dtypes&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;columns&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tolist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always parse dates on load with &lt;code&gt;parse_dates=&lt;/code&gt; rather than converting after — avoids silent object-dtype dates that break resampling later.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reorder Point</title>
      <link>https://normanli.net/garden/reorder-point/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://normanli.net/garden/reorder-point/</guid>
      <description>&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;&#xA;&lt;p&gt;A SKU sells 42 units a day on average, with a 9-day supplier lead time and 120 units of safety stock:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;reorder_point = (42 × 9) + 120 = 498 units&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When on-hand plus on-order inventory drops to 498, a new order is placed — not when the shelf is already empty.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
