audit-labs/tutorials

Learn how to perform data analysis, scripting, automation, and more!

clone: git clone https://gitbay.org/audit-labs/tutorials.git

fa836e350724abb7354004df1de488d8fd3decb8

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-02-22T00:06:51Z

add sampling notebook
 .../sampling/Sampling_Workpaper_Stratified.xlsx    |  Bin 0 -> 8906 bytes
 notebooks/sampling/sampling.ipynb                  | 1089 ++++++++++++++++++++
 notebooks/sampling/transactions.csv                |  101 ++
 3 files changed, 1190 insertions(+)

diff --git a/notebooks/sampling/Sampling_Workpaper_Stratified.xlsx b/notebooks/sampling/Sampling_Workpaper_Stratified.xlsx
new file mode 100644
index 0000000..3cebfdd
Binary files /dev/null and b/notebooks/sampling/Sampling_Workpaper_Stratified.xlsx differ
diff --git a/notebooks/sampling/sampling.ipynb b/notebooks/sampling/sampling.ipynb
new file mode 100644
index 0000000..53486d6
--- /dev/null
+++ b/notebooks/sampling/sampling.ipynb
@@ -0,0 +1,1089 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000001",
+   "metadata": {},
+   "source": [
+    "# Audit Sampling\n",
+    "\n",
+    "Auditors rarely test every transaction or record in a population. Testing everything is time-consuming and often unnecessary — a well-chosen sample can give you the same level of confidence at a fraction of the effort.\n",
+    "\n",
+    "This notebook covers:\n",
+    "1. Why auditors sample, and key concepts\n",
+    "2. How to calculate an appropriate sample size\n",
+    "3. Three sampling methods: random, systematic, and stratified\n",
+    "4. How to export your sample with metadata for documentation\n",
+    "\n",
+    "We'll use a dataset of 100 vendor transactions as our population throughout."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000002",
+   "metadata": {},
+   "source": [
+    "## 1. Why Auditors Sample\n",
+    "\n",
+    "**Population** — the full set of records you're auditing (e.g., all 5,000 invoices processed this year).\n",
+    "\n",
+    "**Sample** — a subset of that population you actually test.\n",
+    "\n",
+    "**Confidence level** — how certain you want to be that your sample reflects the population. Audits typically use 90% or 95%.\n",
+    "\n",
+    "**Tolerable error rate** — the maximum rate of errors you'd accept before concluding a control has failed. Common values are 5% or 10%.\n",
+    "\n",
+    "The core tradeoff: a higher confidence level or lower tolerable error rate means you need a larger sample. The relationship isn't linear — going from 90% to 95% confidence increases your sample size more than you might expect.\n",
+    "\n",
+    "**When to sample vs. test everything:**\n",
+    "- Sample when the population is large and testing everything isn't practical\n",
+    "- Test everything (100%) when the population is small (e.g., only 10 journal entries), when the control only fires occasionally, or when the risk is very high"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000003",
+   "metadata": {},
+   "source": [
+    "## 2. Load the Population"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "7ab8b26e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Defaulting to user installation because normal site-packages is not writeable\n",
+      "Requirement already satisfied: pandas in /Users/cmc/Library/Python/3.9/lib/python/site-packages (2.3.3)\n",
+      "Collecting openpyxl\n",
+      "  Downloading openpyxl-3.1.5-py2.py3-none-any.whl.metadata (2.5 kB)\n",
+      "Requirement already satisfied: numpy>=1.22.4 in /Users/cmc/Library/Python/3.9/lib/python/site-packages (from pandas) (2.0.2)\n",
+      "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/cmc/Library/Python/3.9/lib/python/site-packages (from pandas) (2.9.0.post0)\n",
+      "Requirement already satisfied: pytz>=2020.1 in /Users/cmc/Library/Python/3.9/lib/python/site-packages (from pandas) (2025.2)\n",
+      "Requirement already satisfied: tzdata>=2022.7 in /Users/cmc/Library/Python/3.9/lib/python/site-packages (from pandas) (2025.3)\n",
+      "Collecting et-xmlfile (from openpyxl)\n",
+      "  Downloading et_xmlfile-2.0.0-py3-none-any.whl.metadata (2.7 kB)\n",
+      "Requirement already satisfied: six>=1.5 in /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site-packages (from python-dateutil>=2.8.2->pandas) (1.15.0)\n",
+      "Downloading openpyxl-3.1.5-py2.py3-none-any.whl (250 kB)\n",
+      "Downloading et_xmlfile-2.0.0-py3-none-any.whl (18 kB)\n",
+      "Installing collected packages: et-xmlfile, openpyxl\n",
+      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2/2\u001b[0m [openpyxl]\n",
+      "\u001b[1A\u001b[2KSuccessfully installed et-xmlfile-2.0.0 openpyxl-3.1.5\n",
+      "Note: you may need to restart the kernel to use updated packages.\n"
+     ]
+    }
+   ],
+   "source": [
+    "%pip install pandas openpyxl"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "a1b2c3d4-0001-0001-0001-000000000004",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Population size: 100 records\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Transaction_ID</th>\n",
+       "      <th>Date</th>\n",
+       "      <th>Vendor</th>\n",
+       "      <th>Amount</th>\n",
+       "      <th>Department</th>\n",
+       "      <th>Approved_By</th>\n",
+       "      <th>Payment_Method</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>T0001</td>\n",
+       "      <td>2024-01-03</td>\n",
+       "      <td>Staples</td>\n",
+       "      <td>124.50</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>T0002</td>\n",
+       "      <td>2024-01-05</td>\n",
+       "      <td>AWS</td>\n",
+       "      <td>3200.00</td>\n",
+       "      <td>Engineering</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>T0003</td>\n",
+       "      <td>2024-01-07</td>\n",
+       "      <td>Office Depot</td>\n",
+       "      <td>87.25</td>\n",
+       "      <td>HR</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>T0004</td>\n",
+       "      <td>2024-01-08</td>\n",
+       "      <td>Delta Airlines</td>\n",
+       "      <td>1450.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>T0005</td>\n",
+       "      <td>2024-01-10</td>\n",
+       "      <td>Adobe</td>\n",
+       "      <td>599.99</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "  Transaction_ID        Date          Vendor   Amount   Department  \\\n",
+       "0          T0001  2024-01-03         Staples   124.50    Marketing   \n",
+       "1          T0002  2024-01-05             AWS  3200.00  Engineering   \n",
+       "2          T0003  2024-01-07    Office Depot    87.25           HR   \n",
+       "3          T0004  2024-01-08  Delta Airlines  1450.00        Sales   \n",
+       "4          T0005  2024-01-10           Adobe   599.99    Marketing   \n",
+       "\n",
+       "  Approved_By Payment_Method  \n",
+       "0   J. Rivera    Credit Card  \n",
+       "1    S. Patel            ACH  \n",
+       "2     M. Chen    Credit Card  \n",
+       "3   J. Rivera    Credit Card  \n",
+       "4     M. Chen            ACH  "
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import pandas as pd\n",
+    "import math\n",
+    "\n",
+    "# Load the transaction population\n",
+    "df = pd.read_csv('transactions.csv')\n",
+    "\n",
+    "print(f\"Population size: {len(df)} records\")\n",
+    "df.head()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "a1b2c3d4-0001-0001-0001-000000000005",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Transactions by Department:\n",
+      "Department\n",
+      "Sales          23\n",
+      "Engineering    20\n",
+      "Operations     16\n",
+      "Marketing      15\n",
+      "HR             14\n",
+      "IT             12\n",
+      "Name: count, dtype: int64\n",
+      "\n",
+      "Amount summary:\n",
+      "count     100.00\n",
+      "mean     1287.50\n",
+      "std      1856.76\n",
+      "min        22.60\n",
+      "25%        91.64\n",
+      "50%       420.00\n",
+      "75%      1670.00\n",
+      "max      6500.00\n",
+      "Name: Amount, dtype: float64\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Get a quick overview of the population before sampling\n",
+    "print(\"Transactions by Department:\")\n",
+    "print(df['Department'].value_counts())\n",
+    "print()\n",
+    "print(\"Amount summary:\")\n",
+    "print(df['Amount'].describe().round(2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000006",
+   "metadata": {},
+   "source": [
+    "## 3. Calculate Sample Size\n",
+    "\n",
+    "A common formula for attribute sampling (testing whether something is present or absent, like an approval) is:\n",
+    "\n",
+    "$$n = \\frac{Z^2 \\times p \\times (1 - p)}{E^2}$$\n",
+    "\n",
+    "Where:\n",
+    "- **Z** = Z-score for your confidence level (1.645 for 90%, 1.96 for 95%)\n",
+    "- **p** = expected error rate in the population (use 0.5 if unknown — this gives the most conservative/largest sample)\n",
+    "- **E** = tolerable error rate (e.g., 0.05 for 5%)\n",
+    "\n",
+    "This formula assumes an infinite population. For smaller populations, apply the **finite population correction (FPC)**:\n",
+    "\n",
+    "$$n_{adjusted} = \\frac{n}{1 + \\frac{n - 1}{N}}$$\n",
+    "\n",
+    "Where **N** is the population size."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "a1b2c3d4-0001-0001-0001-000000000007",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Population size:       100\n",
+      "Confidence level:      95%\n",
+      "Tolerable error rate:  5%\n",
+      "Base sample size:      385\n",
+      "Adjusted sample size:  80 (after finite population correction)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# --- Configure your sampling parameters here ---\n",
+    "CONFIDENCE_LEVEL = 0.95   # 90% = 0.90, 95% = 0.95\n",
+    "TOLERABLE_ERROR  = 0.05   # 5% = 0.05, 10% = 0.10\n",
+    "EXPECTED_ERROR   = 0.5    # Use 0.5 (most conservative) if unknown\n",
+    "# ------------------------------------------------\n",
+    "\n",
+    "POPULATION_SIZE = len(df)\n",
+    "\n",
+    "# Z-scores for common confidence levels\n",
+    "z_scores = {0.90: 1.645, 0.95: 1.96, 0.99: 2.576}\n",
+    "z = z_scores.get(CONFIDENCE_LEVEL)\n",
+    "\n",
+    "if z is None:\n",
+    "    raise ValueError(\"Confidence level must be 0.90, 0.95, or 0.99\")\n",
+    "\n",
+    "# Base sample size (infinite population)\n",
+    "n_base = (z**2 * EXPECTED_ERROR * (1 - EXPECTED_ERROR)) / (TOLERABLE_ERROR**2)\n",
+    "\n",
+    "# Finite population correction\n",
+    "n_adjusted = n_base / (1 + (n_base - 1) / POPULATION_SIZE)\n",
+    "SAMPLE_SIZE = math.ceil(n_adjusted)\n",
+    "\n",
+    "print(f\"Population size:       {POPULATION_SIZE}\")\n",
+    "print(f\"Confidence level:      {int(CONFIDENCE_LEVEL * 100)}%\")\n",
+    "print(f\"Tolerable error rate:  {int(TOLERABLE_ERROR * 100)}%\")\n",
+    "print(f\"Base sample size:      {math.ceil(n_base)}\")\n",
+    "print(f\"Adjusted sample size:  {SAMPLE_SIZE} (after finite population correction)\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000008",
+   "metadata": {},
+   "source": [
+    "Notice that the adjusted sample size is smaller than the base. When your population is small relative to the uncorrected sample size, the FPC has a meaningful impact. For very large populations, the correction is negligible.\n",
+    "\n",
+    "We'll use this `SAMPLE_SIZE` across all three sampling methods below."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000009",
+   "metadata": {},
+   "source": [
+    "## 4. Method 1 — Random Sampling\n",
+    "\n",
+    "Every item in the population has an equal chance of being selected. This is the simplest method and appropriate for most general audit tests where the population is relatively homogeneous.\n",
+    "\n",
+    "We set a `random_state` so the sample is reproducible — running the notebook again will produce the same selection, which is important for documentation and review."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "a1b2c3d4-0001-0001-0001-000000000010",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Random sample: 80 records\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Transaction_ID</th>\n",
+       "      <th>Date</th>\n",
+       "      <th>Vendor</th>\n",
+       "      <th>Amount</th>\n",
+       "      <th>Department</th>\n",
+       "      <th>Approved_By</th>\n",
+       "      <th>Payment_Method</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>T0001</td>\n",
+       "      <td>2024-01-03</td>\n",
+       "      <td>Staples</td>\n",
+       "      <td>124.50</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>T0004</td>\n",
+       "      <td>2024-01-08</td>\n",
+       "      <td>Delta Airlines</td>\n",
+       "      <td>1450.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>T0005</td>\n",
+       "      <td>2024-01-10</td>\n",
+       "      <td>Adobe</td>\n",
+       "      <td>599.99</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>T0006</td>\n",
+       "      <td>2024-01-11</td>\n",
+       "      <td>Zoom</td>\n",
+       "      <td>149.00</td>\n",
+       "      <td>IT</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>T0007</td>\n",
+       "      <td>2024-01-14</td>\n",
+       "      <td>FedEx</td>\n",
+       "      <td>62.10</td>\n",
+       "      <td>Operations</td>\n",
+       "      <td>L. Gomez</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>75</th>\n",
+       "      <td>T0096</td>\n",
+       "      <td>2024-05-20</td>\n",
+       "      <td>Slack</td>\n",
+       "      <td>320.00</td>\n",
+       "      <td>IT</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>76</th>\n",
+       "      <td>T0097</td>\n",
+       "      <td>2024-05-21</td>\n",
+       "      <td>FedEx</td>\n",
+       "      <td>41.70</td>\n",
+       "      <td>Operations</td>\n",
+       "      <td>L. Gomez</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>77</th>\n",
+       "      <td>T0098</td>\n",
+       "      <td>2024-05-22</td>\n",
+       "      <td>Delta Airlines</td>\n",
+       "      <td>1730.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>78</th>\n",
+       "      <td>T0099</td>\n",
+       "      <td>2024-05-23</td>\n",
+       "      <td>Office Depot</td>\n",
+       "      <td>119.50</td>\n",
+       "      <td>HR</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>79</th>\n",
+       "      <td>T0100</td>\n",
+       "      <td>2024-05-24</td>\n",
+       "      <td>Salesforce</td>\n",
+       "      <td>6500.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>80 rows × 7 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "   Transaction_ID        Date          Vendor   Amount  Department  \\\n",
+       "0           T0001  2024-01-03         Staples   124.50   Marketing   \n",
+       "1           T0004  2024-01-08  Delta Airlines  1450.00       Sales   \n",
+       "2           T0005  2024-01-10           Adobe   599.99   Marketing   \n",
+       "3           T0006  2024-01-11            Zoom   149.00          IT   \n",
+       "4           T0007  2024-01-14           FedEx    62.10  Operations   \n",
+       "..            ...         ...             ...      ...         ...   \n",
+       "75          T0096  2024-05-20           Slack   320.00          IT   \n",
+       "76          T0097  2024-05-21           FedEx    41.70  Operations   \n",
+       "77          T0098  2024-05-22  Delta Airlines  1730.00       Sales   \n",
+       "78          T0099  2024-05-23    Office Depot   119.50          HR   \n",
+       "79          T0100  2024-05-24      Salesforce  6500.00       Sales   \n",
+       "\n",
+       "   Approved_By Payment_Method  \n",
+       "0    J. Rivera    Credit Card  \n",
+       "1    J. Rivera    Credit Card  \n",
+       "2      M. Chen            ACH  \n",
+       "3     S. Patel            ACH  \n",
+       "4     L. Gomez    Credit Card  \n",
+       "..         ...            ...  \n",
+       "75    S. Patel            ACH  \n",
+       "76    L. Gomez    Credit Card  \n",
+       "77   J. Rivera    Credit Card  \n",
+       "78     M. Chen    Credit Card  \n",
+       "79   J. Rivera            ACH  \n",
+       "\n",
+       "[80 rows x 7 columns]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "RANDOM_SEED = 42  # Change this to get a different random sample; document what seed you used\n",
+    "\n",
+    "random_sample = df.sample(n=SAMPLE_SIZE, random_state=RANDOM_SEED).copy()\n",
+    "random_sample = random_sample.sort_values('Transaction_ID').reset_index(drop=True)\n",
+    "\n",
+    "print(f\"Random sample: {len(random_sample)} records\")\n",
+    "random_sample"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000011",
+   "metadata": {},
+   "source": [
+    "## 5. Method 2 — Systematic Sampling\n",
+    "\n",
+    "Select every *k*th item from the population, starting from a random point. The interval *k* is calculated as `population size ÷ sample size`.\n",
+    "\n",
+    "Systematic sampling is useful when records are already ordered (e.g., by date or transaction ID) and you want even coverage across the full period. It's also easy to explain to a reviewer — \"we took every 4th transaction starting from record 2.\"\n",
+    "\n",
+    "**Caution:** Avoid systematic sampling if the data has a pattern that aligns with your interval (e.g., if transactions are grouped in batches of 4, every 4th record could always land on the same type)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "a1b2c3d4-0001-0001-0001-000000000012",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Interval:          every 1 records\n",
+      "Starting index:    0\n",
+      "Systematic sample: 80 records\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Transaction_ID</th>\n",
+       "      <th>Date</th>\n",
+       "      <th>Vendor</th>\n",
+       "      <th>Amount</th>\n",
+       "      <th>Department</th>\n",
+       "      <th>Approved_By</th>\n",
+       "      <th>Payment_Method</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>T0001</td>\n",
+       "      <td>2024-01-03</td>\n",
+       "      <td>Staples</td>\n",
+       "      <td>124.50</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>T0002</td>\n",
+       "      <td>2024-01-05</td>\n",
+       "      <td>AWS</td>\n",
+       "      <td>3200.00</td>\n",
+       "      <td>Engineering</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>T0003</td>\n",
+       "      <td>2024-01-07</td>\n",
+       "      <td>Office Depot</td>\n",
+       "      <td>87.25</td>\n",
+       "      <td>HR</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>T0004</td>\n",
+       "      <td>2024-01-08</td>\n",
+       "      <td>Delta Airlines</td>\n",
+       "      <td>1450.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>T0005</td>\n",
+       "      <td>2024-01-10</td>\n",
+       "      <td>Adobe</td>\n",
+       "      <td>599.99</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>75</th>\n",
+       "      <td>T0076</td>\n",
+       "      <td>2024-04-22</td>\n",
+       "      <td>UPS</td>\n",
+       "      <td>47.30</td>\n",
+       "      <td>Operations</td>\n",
+       "      <td>L. Gomez</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>76</th>\n",
+       "      <td>T0077</td>\n",
+       "      <td>2024-04-23</td>\n",
+       "      <td>Staples</td>\n",
+       "      <td>73.20</td>\n",
+       "      <td>Marketing</td>\n",
+       "      <td>M. Chen</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>77</th>\n",
+       "      <td>T0078</td>\n",
+       "      <td>2024-04-24</td>\n",
+       "      <td>GitHub</td>\n",
+       "      <td>420.00</td>\n",
+       "      <td>Engineering</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>78</th>\n",
+       "      <td>T0079</td>\n",
+       "      <td>2024-04-25</td>\n",
+       "      <td>Adobe</td>\n",
+       "      <td>599.99</td>\n",
+       "      <td>Engineering</td>\n",
+       "      <td>S. Patel</td>\n",
+       "      <td>ACH</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>79</th>\n",
+       "      <td>T0080</td>\n",
+       "      <td>2024-04-26</td>\n",
+       "      <td>Delta Airlines</td>\n",
+       "      <td>1560.00</td>\n",
+       "      <td>Sales</td>\n",
+       "      <td>J. Rivera</td>\n",
+       "      <td>Credit Card</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>80 rows × 7 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "   Transaction_ID        Date          Vendor   Amount   Department  \\\n",
+       "0           T0001  2024-01-03         Staples   124.50    Marketing   \n",
+       "1           T0002  2024-01-05             AWS  3200.00  Engineering   \n",
+       "2           T0003  2024-01-07    Office Depot    87.25           HR   \n",
+       "3           T0004  2024-01-08  Delta Airlines  1450.00        Sales   \n",
+       "4           T0005  2024-01-10           Adobe   599.99    Marketing   \n",
+       "..            ...         ...             ...      ...          ...   \n",
+       "75          T0076  2024-04-22             UPS    47.30   Operations   \n",
+       "76          T0077  2024-04-23         Staples    73.20    Marketing   \n",
+       "77          T0078  2024-04-24          GitHub   420.00  Engineering   \n",
+       "78          T0079  2024-04-25           Adobe   599.99  Engineering   \n",
+       "79          T0080  2024-04-26  Delta Airlines  1560.00        Sales   \n",
+       "\n",
+       "   Approved_By Payment_Method  \n",
+       "0    J. Rivera    Credit Card  \n",
+       "1     S. Patel            ACH  \n",
+       "2      M. Chen    Credit Card  \n",
+       "3    J. Rivera    Credit Card  \n",
+       "4      M. Chen            ACH  \n",
+       "..         ...            ...  \n",
+       "75    L. Gomez    Credit Card  \n",
+       "76     M. Chen    Credit Card  \n",
+       "77    S. Patel            ACH  \n",
+       "78    S. Patel            ACH  \n",
+       "79   J. Rivera    Credit Card  \n",
+       "\n",
+       "[80 rows x 7 columns]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import random\n",
+    "\n",
+    "random.seed(RANDOM_SEED)\n",
+    "\n",
+    "interval = math.floor(POPULATION_SIZE / SAMPLE_SIZE)\n",
+    "start = random.randint(0, interval - 1)  # Random start within the first interval\n",
+    "\n",
+    "systematic_indices = list(range(start, POPULATION_SIZE, interval))[:SAMPLE_SIZE]\n",
+    "systematic_sample = df.iloc[systematic_indices].copy().reset_index(drop=True)\n",
+    "\n",
+    "print(f\"Interval:          every {interval} records\")\n",
+    "print(f\"Starting index:    {start}\")\n",
+    "print(f\"Systematic sample: {len(systematic_sample)} records\")\n",
+    "systematic_sample"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000013",
+   "metadata": {},
+   "source": [
+    "## 6. Method 3 — Stratified Sampling\n",
+    "\n",
+    "Divide the population into subgroups (strata) and sample from each group proportionally. Use this when the population has distinct segments that vary significantly — for example, departments with very different transaction volumes or risk levels.\n",
+    "\n",
+    "Stratified sampling ensures that smaller but important subgroups aren't missed entirely, which can happen with random sampling.\n",
+    "\n",
+    "Here we'll stratify by **Department**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "a1b2c3d4-0001-0001-0001-000000000014",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Stratum breakdown:\n",
+      "  Sales            23 records  (23%)  → 18 samples\n",
+      "  Engineering      20 records  (20%)  → 16 samples\n",
+      "  Operations       16 records  (16%)  → 12 samples\n",
+      "  Marketing        15 records  (15%)  → 12 samples\n",
+      "  HR               14 records  (14%)  → 11 samples\n",
+      "  IT               12 records  (12%)  → 9 samples\n"
+     ]
+    }
+   ],
+   "source": [
+    "STRATIFY_COLUMN = 'Department'\n",
+    "\n",
+    "# Calculate each stratum's proportion of the population\n",
+    "strata_counts = df[STRATIFY_COLUMN].value_counts()\n",
+    "strata_proportions = strata_counts / POPULATION_SIZE\n",
+    "\n",
+    "print(\"Stratum breakdown:\")\n",
+    "for stratum, count in strata_counts.items():\n",
+    "    proportion = strata_proportions[stratum]\n",
+    "    allocated = math.floor(SAMPLE_SIZE * proportion)\n",
+    "    print(f\"  {stratum:<15} {count:>3} records  ({proportion:.0%})  → {allocated} samples\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "a1b2c3d4-0001-0001-0001-000000000015",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Stratified sample: 80 records\n",
+      "\n",
+      "Sample breakdown by department:\n",
+      "Department\n",
+      "Sales          18\n",
+      "Engineering    16\n",
+      "Operations     13\n",
+      "Marketing      12\n",
+      "HR             11\n",
+      "IT             10\n",
+      "Name: count, dtype: int64\n"
+     ]
+    }
+   ],
+   "source": [
+    "strata_samples = []\n",
+    "\n",
+    "for stratum, proportion in strata_proportions.items():\n",
+    "    n = math.floor(SAMPLE_SIZE * proportion)\n",
+    "    if n == 0:\n",
+    "        continue\n",
+    "    stratum_df = df[df[STRATIFY_COLUMN] == stratum]\n",
+    "    if n > len(stratum_df):\n",
+    "        raise ValueError(f\"Stratum '{stratum}' has fewer records ({len(stratum_df)}) than required samples ({n})\")\n",
+    "    strata_samples.append(stratum_df.sample(n=n, random_state=RANDOM_SEED))\n",
+    "\n",
+    "stratified_sample = pd.concat(strata_samples)\n",
+    "\n",
+    "# Fill any rounding gap by randomly selecting from the remaining records\n",
+    "shortfall = SAMPLE_SIZE - len(stratified_sample)\n",
+    "if shortfall > 0:\n",
+    "    already_selected = stratified_sample.index\n",
+    "    remaining = df.drop(index=already_selected)\n",
+    "    extras = remaining.sample(n=shortfall, random_state=RANDOM_SEED)\n",
+    "    stratified_sample = pd.concat([stratified_sample, extras])\n",
+    "\n",
+    "stratified_sample = stratified_sample.sort_values('Transaction_ID').reset_index(drop=True)\n",
+    "\n",
+    "print(f\"Stratified sample: {len(stratified_sample)} records\")\n",
+    "print()\n",
+    "print(\"Sample breakdown by department:\")\n",
+    "print(stratified_sample[STRATIFY_COLUMN].value_counts())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000016",
+   "metadata": {},
+   "source": [
+    "## 7. Comparing the Methods\n",
+    "\n",
+    "It's worth looking at how the three samples differ before deciding which to use — or which to document."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "a1b2c3d4-0001-0001-0001-000000000017",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Method</th>\n",
+       "      <th>Sample Size</th>\n",
+       "      <th>Avg Amount</th>\n",
+       "      <th>Unique Departments</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>Random</td>\n",
+       "      <td>80</td>\n",
+       "      <td>1258.68</td>\n",
+       "      <td>6</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>Systematic</td>\n",
+       "      <td>80</td>\n",
+       "      <td>1244.90</td>\n",
+       "      <td>6</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>Stratified</td>\n",
+       "      <td>80</td>\n",
+       "      <td>1287.08</td>\n",
+       "      <td>6</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "       Method  Sample Size  Avg Amount  Unique Departments\n",
+       "0      Random           80     1258.68                   6\n",
+       "1  Systematic           80     1244.90                   6\n",
+       "2  Stratified           80     1287.08                   6"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "comparison = pd.DataFrame({\n",
+    "    'Method': ['Random', 'Systematic', 'Stratified'],\n",
+    "    'Sample Size': [len(random_sample), len(systematic_sample), len(stratified_sample)],\n",
+    "    'Avg Amount': [\n",
+    "        random_sample['Amount'].mean(),\n",
+    "        systematic_sample['Amount'].mean(),\n",
+    "        stratified_sample['Amount'].mean()\n",
+    "    ],\n",
+    "    'Unique Departments': [\n",
+    "        random_sample['Department'].nunique(),\n",
+    "        systematic_sample['Department'].nunique(),\n",
+    "        stratified_sample['Department'].nunique()\n",
+    "    ]\n",
+    "})\n",
+    "\n",
+    "comparison['Avg Amount'] = comparison['Avg Amount'].round(2)\n",
+    "comparison"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000018",
+   "metadata": {},
+   "source": [
+    "**Which method to use:**\n",
+    "\n",
+    "- **Random** — default choice; easy to implement and defend. Use when the population is homogeneous.\n",
+    "- **Systematic** — good for ordered populations (e.g., daily transactions); provides even coverage over time.\n",
+    "- **Stratified** — use when subgroups differ significantly in size or risk, and you want guaranteed representation from each group.\n",
+    "\n",
+    "All three methods are defensible to auditors and regulators as long as you document how the sample was selected."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1b2c3d4-0001-0001-0001-000000000019",
+   "metadata": {},
+   "source": [
+    "## 8. Export the Sample\n",
+    "\n",
+    "Documentation is as important as the sample itself. When you hand off your sample to a reviewer or include it in a workpaper, they need to know:\n",
+    "- What population was tested\n",
+    "- What method was used\n",
+    "- What parameters were applied\n",
+    "- When the sample was selected\n",
+    "\n",
+    "We'll export the sample to Excel with a metadata sheet capturing all of this."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "a1b2c3d4-0001-0001-0001-000000000020",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Exported: Sampling_Workpaper_Stratified.xlsx\n",
+      "  Sheet 'Metadata' — sampling parameters\n",
+      "  Sheet 'Sample'   — 80 selected records\n"
+     ]
+    }
+   ],
+   "source": [
+    "from datetime import datetime\n",
+    "\n",
+    "# Choose which sample to export\n",
+    "EXPORT_METHOD = 'Stratified'  # Change to 'Random' or 'Systematic' as needed\n",
+    "\n",
+    "samples_map = {\n",
+    "    'Random': random_sample,\n",
+    "    'Systematic': systematic_sample,\n",
+    "    'Stratified': stratified_sample\n",
+    "}\n",
+    "\n",
+    "export_sample = samples_map[EXPORT_METHOD]\n",
+    "\n",
+    "# Build a metadata summary\n",
+    "metadata = pd.DataFrame([\n",
+    "    {'Parameter': 'Population File',      'Value': 'transactions.csv'},\n",
+    "    {'Parameter': 'Population Size',      'Value': POPULATION_SIZE},\n",
+    "    {'Parameter': 'Sampling Method',      'Value': EXPORT_METHOD},\n",
+    "    {'Parameter': 'Confidence Level',     'Value': f\"{int(CONFIDENCE_LEVEL * 100)}%\"},\n",
+    "    {'Parameter': 'Tolerable Error Rate', 'Value': f\"{int(TOLERABLE_ERROR * 100)}%\"},\n",
+    "    {'Parameter': 'Sample Size',          'Value': len(export_sample)},\n",
+    "    {'Parameter': 'Random Seed',          'Value': RANDOM_SEED},\n",
+    "    {'Parameter': 'Date Generated',       'Value': datetime.today().strftime('%Y-%m-%d')},\n",
+    "])\n",
+    "\n",
+    "output_file = f'Sampling_Workpaper_{EXPORT_METHOD}.xlsx'\n",
+    "\n",
+    "with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n",
+    "    metadata.to_excel(writer, sheet_name='Metadata', index=False)\n",
+    "    export_sample.to_excel(writer, sheet_name='Sample', index=False)\n",
+    "\n",
+    "print(f\"Exported: {output_file}\")\n",
+    "print(f\"  Sheet 'Metadata' — sampling parameters\")\n",
+    "print(f\"  Sheet 'Sample'   — {len(export_sample)} selected records\")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/sampling/transactions.csv b/notebooks/sampling/transactions.csv
new file mode 100644
index 0000000..e3b767a
--- /dev/null
+++ b/notebooks/sampling/transactions.csv
@@ -0,0 +1,101 @@
+Transaction_ID,Date,Vendor,Amount,Department,Approved_By,Payment_Method
+T0001,2024-01-03,Staples,124.50,Marketing,J. Rivera,Credit Card
+T0002,2024-01-05,AWS,3200.00,Engineering,S. Patel,ACH
+T0003,2024-01-07,Office Depot,87.25,HR,M. Chen,Credit Card
+T0004,2024-01-08,Delta Airlines,1450.00,Sales,J. Rivera,Credit Card
+T0005,2024-01-10,Adobe,599.99,Marketing,M. Chen,ACH
+T0006,2024-01-11,Zoom,149.00,IT,S. Patel,ACH
+T0007,2024-01-14,FedEx,62.10,Operations,L. Gomez,Credit Card
+T0008,2024-01-15,Marriott,980.00,Sales,J. Rivera,Credit Card
+T0009,2024-01-16,AWS,4100.00,Engineering,S. Patel,ACH
+T0010,2024-01-17,Uber,43.75,HR,M. Chen,Credit Card
+T0011,2024-01-18,Slack,320.00,IT,S. Patel,ACH
+T0012,2024-01-21,United Airlines,2200.00,Sales,J. Rivera,Credit Card
+T0013,2024-01-22,Staples,55.40,Operations,L. Gomez,Credit Card
+T0014,2024-01-23,GitHub,420.00,Engineering,S. Patel,ACH
+T0015,2024-01-24,Hilton,760.00,Marketing,J. Rivera,Credit Card
+T0016,2024-01-25,UPS,38.90,Operations,L. Gomez,Credit Card
+T0017,2024-01-28,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0018,2024-01-29,Office Depot,112.80,HR,M. Chen,Credit Card
+T0019,2024-01-30,Zoom,149.00,IT,S. Patel,ACH
+T0020,2024-01-31,AWS,2875.00,Engineering,S. Patel,ACH
+T0021,2024-02-01,FedEx,74.20,Operations,L. Gomez,Credit Card
+T0022,2024-02-02,Delta Airlines,1890.00,Sales,J. Rivera,Credit Card
+T0023,2024-02-05,Staples,99.95,Marketing,M. Chen,Credit Card
+T0024,2024-02-06,Adobe,599.99,Marketing,M. Chen,ACH
+T0025,2024-02-07,Marriott,1100.00,HR,M. Chen,Credit Card
+T0026,2024-02-08,GitHub,420.00,Engineering,S. Patel,ACH
+T0027,2024-02-09,Uber,31.50,Sales,J. Rivera,Credit Card
+T0028,2024-02-12,Slack,320.00,IT,S. Patel,ACH
+T0029,2024-02-13,UPS,55.60,Operations,L. Gomez,Credit Card
+T0030,2024-02-14,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0031,2024-02-15,AWS,3750.00,Engineering,S. Patel,ACH
+T0032,2024-02-16,Office Depot,143.20,HR,M. Chen,Credit Card
+T0033,2024-02-19,United Airlines,1650.00,Marketing,J. Rivera,Credit Card
+T0034,2024-02-20,Zoom,149.00,IT,S. Patel,ACH
+T0035,2024-02-21,FedEx,88.40,Operations,L. Gomez,Credit Card
+T0036,2024-02-22,Staples,67.30,HR,M. Chen,Credit Card
+T0037,2024-02-23,Adobe,599.99,Engineering,S. Patel,ACH
+T0038,2024-02-26,Hilton,840.00,Sales,J. Rivera,Credit Card
+T0039,2024-02-27,GitHub,420.00,Engineering,S. Patel,ACH
+T0040,2024-02-28,AWS,5100.00,Engineering,S. Patel,ACH
+T0041,2024-03-01,Uber,28.90,HR,M. Chen,Credit Card
+T0042,2024-03-04,Delta Airlines,2100.00,Sales,J. Rivera,Credit Card
+T0043,2024-03-05,UPS,44.75,Operations,L. Gomez,Credit Card
+T0044,2024-03-06,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0045,2024-03-07,Slack,320.00,IT,S. Patel,ACH
+T0046,2024-03-08,Marriott,920.00,Marketing,J. Rivera,Credit Card
+T0047,2024-03-11,Office Depot,78.60,Operations,L. Gomez,Credit Card
+T0048,2024-03-12,AWS,3300.00,Engineering,S. Patel,ACH
+T0049,2024-03-13,Staples,115.40,Marketing,M. Chen,Credit Card
+T0050,2024-03-14,Adobe,599.99,Marketing,M. Chen,ACH
+T0051,2024-03-15,United Airlines,1750.00,Sales,J. Rivera,Credit Card
+T0052,2024-03-18,GitHub,420.00,Engineering,S. Patel,ACH
+T0053,2024-03-19,FedEx,51.30,Operations,L. Gomez,Credit Card
+T0054,2024-03-20,Zoom,149.00,IT,S. Patel,ACH
+T0055,2024-03-21,Hilton,1050.00,Sales,J. Rivera,Credit Card
+T0056,2024-03-22,Uber,37.40,HR,M. Chen,Credit Card
+T0057,2024-03-25,UPS,62.80,Operations,L. Gomez,Credit Card
+T0058,2024-03-26,AWS,4400.00,Engineering,S. Patel,ACH
+T0059,2024-03-27,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0060,2024-03-28,Office Depot,95.20,HR,M. Chen,Credit Card
+T0061,2024-04-01,Delta Airlines,1320.00,Marketing,J. Rivera,Credit Card
+T0062,2024-04-02,Slack,320.00,IT,S. Patel,ACH
+T0063,2024-04-03,Staples,88.75,Operations,L. Gomez,Credit Card
+T0064,2024-04-04,Adobe,599.99,Marketing,M. Chen,ACH
+T0065,2024-04-05,GitHub,420.00,Engineering,S. Patel,ACH
+T0066,2024-04-08,Marriott,1200.00,Sales,J. Rivera,Credit Card
+T0067,2024-04-09,AWS,2950.00,Engineering,S. Patel,ACH
+T0068,2024-04-10,FedEx,69.50,Operations,L. Gomez,Credit Card
+T0069,2024-04-11,United Airlines,1980.00,Sales,J. Rivera,Credit Card
+T0070,2024-04-12,Uber,22.60,HR,M. Chen,Credit Card
+T0071,2024-04-15,Zoom,149.00,IT,S. Patel,ACH
+T0072,2024-04-16,Office Depot,131.40,HR,M. Chen,Credit Card
+T0073,2024-04-17,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0074,2024-04-18,AWS,3600.00,Engineering,S. Patel,ACH
+T0075,2024-04-19,Hilton,890.00,Marketing,J. Rivera,Credit Card
+T0076,2024-04-22,UPS,47.30,Operations,L. Gomez,Credit Card
+T0077,2024-04-23,Staples,73.20,Marketing,M. Chen,Credit Card
+T0078,2024-04-24,GitHub,420.00,Engineering,S. Patel,ACH
+T0079,2024-04-25,Adobe,599.99,Engineering,S. Patel,ACH
+T0080,2024-04-26,Delta Airlines,1560.00,Sales,J. Rivera,Credit Card
+T0081,2024-04-29,Slack,320.00,IT,S. Patel,ACH
+T0082,2024-04-30,FedEx,83.10,Operations,L. Gomez,Credit Card
+T0083,2024-05-01,Marriott,1040.00,Sales,J. Rivera,Credit Card
+T0084,2024-05-02,AWS,4800.00,Engineering,S. Patel,ACH
+T0085,2024-05-03,Office Depot,108.90,HR,M. Chen,Credit Card
+T0086,2024-05-06,Uber,45.20,Sales,J. Rivera,Credit Card
+T0087,2024-05-07,Salesforce,6500.00,Sales,J. Rivera,ACH
+T0088,2024-05-08,United Airlines,2350.00,Marketing,J. Rivera,Credit Card
+T0089,2024-05-09,Zoom,149.00,IT,S. Patel,ACH
+T0090,2024-05-10,GitHub,420.00,Engineering,S. Patel,ACH
+T0091,2024-05-13,UPS,58.40,Operations,L. Gomez,Credit Card
+T0092,2024-05-14,Staples,92.60,HR,M. Chen,Credit Card
+T0093,2024-05-15,Adobe,599.99,Marketing,M. Chen,ACH
+T0094,2024-05-16,AWS,3100.00,Engineering,S. Patel,ACH
+T0095,2024-05-17,Hilton,780.00,Sales,J. Rivera,Credit Card
+T0096,2024-05-20,Slack,320.00,IT,S. Patel,ACH
+T0097,2024-05-21,FedEx,41.70,Operations,L. Gomez,Credit Card
+T0098,2024-05-22,Delta Airlines,1730.00,Sales,J. Rivera,Credit Card
+T0099,2024-05-23,Office Depot,119.50,HR,M. Chen,Credit Card
+T0100,2024-05-24,Salesforce,6500.00,Sales,J. Rivera,ACH
\ No newline at end of file