[{"data":1,"prerenderedAt":2562},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule":3,"surround:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule":2528,"ancestors:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule":2536,"children:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule":2541,"related:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule":2542},{"id":4,"title":5,"body":6,"dateModified":2494,"datePublished":2494,"description":2495,"extension":2496,"faq":2497,"keyword":2506,"kind":2507,"meta":2508,"navigation":117,"path":2517,"seo":2518,"slug":2521,"stem":2522,"topics":2523,"type":2526,"__hash__":2527},"docs\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule\u002Findex.md","Build a Lease Liability Schedule",{"type":7,"value":8,"toc":2482},"minimark",[9,33,38,69,72,76,367,374,378,530,569,580,724,728,1310,1313,1528,1532,1923,1934,2005,2009,2356,2359,2363,2404,2408,2414,2418,2424,2430,2439,2445,2449,2478],[10,11,12,13,17,18,21,22,26,27,32],"p",{},"Since IFRS 16, a company that leases an office, a warehouse or a fleet of vans records most of those leases on its balance sheet: a ",[14,15,16],"em",{},"lease liability"," for the payments it has committed to, and a ",[14,19,20],{},"right-of-use asset"," for the thing it is allowed to use. Both have to be calculated at the start of the lease and then rolled forward every month — the liability grows with interest and falls with each payment, and the asset is depreciated over the lease term. Finance teams usually keep a spreadsheet per lease for this, and each one is a small amortisation table with room for formula mistakes. This page builds the schedule for a portfolio of leases with pandas: the opening liability as the present value of the payments, a month-by-month unwind with payments in advance, the asset's depreciation, the current and non-current split the balance sheet needs, the month's journals and the maturity analysis for the notes — and checks the starting figure against Excel's own ",[23,24,25],"code",{},"PV"," function. It belongs to ",[28,29,31],"a",{"href":30},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002F","Building Finance and Operations Reports",".",[34,35,37],"h2",{"id":36},"prerequisites","Prerequisites",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas numpy openpyxl\n","bash","",[23,46,47],{"__ignoreMap":44},[48,49,52,56,60,63,66],"span",{"class":50,"line":51},"line",1,[48,53,55],{"class":54},"sMTad","pip",[48,57,59],{"class":58},"srMev"," install",[48,61,62],{"class":58}," pandas",[48,64,65],{"class":58}," numpy",[48,67,68],{"class":58}," openpyxl\n",[10,70,71],{},"The input is a lease register with one row per lease: commencement date, term in months, the fixed monthly payment, paid at the start of each month, and the discount rate — the incremental borrowing rate the company would pay to borrow over a similar term. The month being closed is September 2026. The calculation ignores variable payments, options and remeasurements, which a real register would add as separate events.",[34,73,75],{"id":74},"step-1-the-opening-liability-is-the-present-value-of-the-payments","Step 1 — The opening liability is the present value of the payments",[39,77,81],{"className":78,"code":79,"language":80,"meta":44,"style":44},"language-python shiki shiki-themes github-light github-dark-high-contrast","import numpy as np\nimport pandas as pd\n\nleases = pd.read_excel(\"leases.xlsx\", parse_dates=[\"Commencement\"])\n\ndef opening_liability(payment, annual_rate, months):\n    r = annual_rate \u002F 12\n    t = np.arange(months)                       # payments in advance: the first is at time 0\n    return float((payment \u002F (1 + r) ** t).sum())\n\nleases[\"Opening liability\"] = [round(opening_liability(p, rate, n), 2)\n                               for p, rate, n in zip(leases[\"Monthly payment\"], leases[\"Discount rate\"], leases[\"Term (months)\"])]\nleases[\"Total payments\"] = leases[\"Monthly payment\"] * leases[\"Term (months)\"]\nprint(leases[[\"Lease\", \"Total payments\", \"Opening liability\"]].to_string(index=False))\n","python",[23,82,83,99,112,119,152,157,170,188,203,235,240,269,304,333],{"__ignoreMap":44},[48,84,85,89,93,96],{"class":50,"line":51},[48,86,88],{"class":87},"s-kum","import",[48,90,92],{"class":91},"skGVy"," numpy ",[48,94,95],{"class":87},"as",[48,97,98],{"class":91}," np\n",[48,100,102,104,107,109],{"class":50,"line":101},2,[48,103,88],{"class":87},[48,105,106],{"class":91}," pandas ",[48,108,95],{"class":87},[48,110,111],{"class":91}," pd\n",[48,113,115],{"class":50,"line":114},3,[48,116,118],{"emptyLinePlaceholder":117},true,"\n",[48,120,122,125,128,131,134,137,141,143,146,149],{"class":50,"line":121},4,[48,123,124],{"class":91},"leases ",[48,126,127],{"class":87},"=",[48,129,130],{"class":91}," pd.read_excel(",[48,132,133],{"class":58},"\"leases.xlsx\"",[48,135,136],{"class":91},", ",[48,138,140],{"class":139},"sa561","parse_dates",[48,142,127],{"class":87},[48,144,145],{"class":91},"[",[48,147,148],{"class":58},"\"Commencement\"",[48,150,151],{"class":91},"])\n",[48,153,155],{"class":50,"line":154},5,[48,156,118],{"emptyLinePlaceholder":117},[48,158,160,163,167],{"class":50,"line":159},6,[48,161,162],{"class":87},"def",[48,164,166],{"class":165},"s_Opv"," opening_liability",[48,168,169],{"class":91},"(payment, annual_rate, months):\n",[48,171,173,176,178,181,184],{"class":50,"line":172},7,[48,174,175],{"class":91},"    r ",[48,177,127],{"class":87},[48,179,180],{"class":91}," annual_rate ",[48,182,183],{"class":87},"\u002F",[48,185,187],{"class":186},"sP0c6"," 12\n",[48,189,191,194,196,199],{"class":50,"line":190},8,[48,192,193],{"class":91},"    t ",[48,195,127],{"class":87},[48,197,198],{"class":91}," np.arange(months)                       ",[48,200,202],{"class":201},"s-wDw","# payments in advance: the first is at time 0\n",[48,204,206,209,212,215,217,220,223,226,229,232],{"class":50,"line":205},9,[48,207,208],{"class":87},"    return",[48,210,211],{"class":186}," float",[48,213,214],{"class":91},"((payment ",[48,216,183],{"class":87},[48,218,219],{"class":91}," (",[48,221,222],{"class":186},"1",[48,224,225],{"class":87}," +",[48,227,228],{"class":91}," r) ",[48,230,231],{"class":87},"**",[48,233,234],{"class":91}," t).sum())\n",[48,236,238],{"class":50,"line":237},10,[48,239,118],{"emptyLinePlaceholder":117},[48,241,243,246,249,252,254,257,260,263,266],{"class":50,"line":242},11,[48,244,245],{"class":91},"leases[",[48,247,248],{"class":58},"\"Opening liability\"",[48,250,251],{"class":91},"] ",[48,253,127],{"class":87},[48,255,256],{"class":91}," [",[48,258,259],{"class":186},"round",[48,261,262],{"class":91},"(opening_liability(p, rate, n), ",[48,264,265],{"class":186},"2",[48,267,268],{"class":91},")\n",[48,270,272,275,278,281,284,287,290,293,296,298,301],{"class":50,"line":271},12,[48,273,274],{"class":87},"                               for",[48,276,277],{"class":91}," p, rate, n ",[48,279,280],{"class":87},"in",[48,282,283],{"class":186}," zip",[48,285,286],{"class":91},"(leases[",[48,288,289],{"class":58},"\"Monthly payment\"",[48,291,292],{"class":91},"], leases[",[48,294,295],{"class":58},"\"Discount rate\"",[48,297,292],{"class":91},[48,299,300],{"class":58},"\"Term (months)\"",[48,302,303],{"class":91},"])]\n",[48,305,307,309,312,314,316,319,321,323,326,328,330],{"class":50,"line":306},13,[48,308,245],{"class":91},[48,310,311],{"class":58},"\"Total payments\"",[48,313,251],{"class":91},[48,315,127],{"class":87},[48,317,318],{"class":91}," leases[",[48,320,289],{"class":58},[48,322,251],{"class":91},[48,324,325],{"class":87},"*",[48,327,318],{"class":91},[48,329,300],{"class":58},[48,331,332],{"class":91},"]\n",[48,334,336,339,342,345,347,349,351,353,356,359,361,364],{"class":50,"line":335},14,[48,337,338],{"class":186},"print",[48,340,341],{"class":91},"(leases[[",[48,343,344],{"class":58},"\"Lease\"",[48,346,136],{"class":91},[48,348,311],{"class":58},[48,350,136],{"class":91},[48,352,248],{"class":58},[48,354,355],{"class":91},"]].to_string(",[48,357,358],{"class":139},"index",[48,360,127],{"class":87},[48,362,363],{"class":186},"False",[48,365,366],{"class":91},"))\n",[10,368,369,370,373],{},"The liability at commencement is what the future payments are worth today, discounted at the lease's rate. With payments at the start of each month, the first payment is not discounted at all, the second is discounted by one month, and so on. The monthly rate is the annual rate divided by twelve, which is the common simplification; an effective monthly rate, ",[23,371,372],{},"(1 + r) ** (1\u002F12) − 1",", is the alternative some policies prefer, and the code only changes in one line. The head office lease, sixty payments of 12,500 — 750,000 in total — has an opening liability of 657,409.82; the difference of 92,590.18 is the interest that will be charged over five years. The warehouse lease, ten years at 21,000 a month, has a liability of 1,901,000.23 against payments of 2.52 million, and the vans 136,625.55 against 151,200.",[34,375,377],{"id":376},"step-2-check-the-opening-figure-against-excel","Step 2 — Check the opening figure against Excel",[39,379,381],{"className":78,"code":380,"language":80,"meta":44,"style":44},"from openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.append([\"Lease\", \"Python\", \"Excel PV\"])\nfor i, row in enumerate(leases.itertuples(index=False), start=2):\n    ws.append([row.Lease, row._6, f\"=PV({row._5}\u002F12,{row._3},-{row._4},0,1)\"])\nwb.save(\"pv_check.xlsx\")\n",[23,382,383,396,400,410,420,439,474,520],{"__ignoreMap":44},[48,384,385,388,391,393],{"class":50,"line":51},[48,386,387],{"class":87},"from",[48,389,390],{"class":91}," openpyxl ",[48,392,88],{"class":87},[48,394,395],{"class":91}," Workbook\n",[48,397,398],{"class":50,"line":101},[48,399,118],{"emptyLinePlaceholder":117},[48,401,402,405,407],{"class":50,"line":114},[48,403,404],{"class":91},"wb ",[48,406,127],{"class":87},[48,408,409],{"class":91}," Workbook()\n",[48,411,412,415,417],{"class":50,"line":121},[48,413,414],{"class":91},"ws ",[48,416,127],{"class":87},[48,418,419],{"class":91}," wb.active\n",[48,421,422,425,427,429,432,434,437],{"class":50,"line":154},[48,423,424],{"class":91},"ws.append([",[48,426,344],{"class":58},[48,428,136],{"class":91},[48,430,431],{"class":58},"\"Python\"",[48,433,136],{"class":91},[48,435,436],{"class":58},"\"Excel PV\"",[48,438,151],{"class":91},[48,440,441,444,447,449,452,455,457,459,461,464,467,469,471],{"class":50,"line":159},[48,442,443],{"class":87},"for",[48,445,446],{"class":91}," i, row ",[48,448,280],{"class":87},[48,450,451],{"class":186}," enumerate",[48,453,454],{"class":91},"(leases.itertuples(",[48,456,358],{"class":139},[48,458,127],{"class":87},[48,460,363],{"class":186},[48,462,463],{"class":91},"), ",[48,465,466],{"class":139},"start",[48,468,127],{"class":87},[48,470,265],{"class":186},[48,472,473],{"class":91},"):\n",[48,475,476,479,482,485,489,492,495,498,500,503,505,508,510,513,515,518],{"class":50,"line":172},[48,477,478],{"class":91},"    ws.append([row.Lease, row._6, ",[48,480,481],{"class":87},"f",[48,483,484],{"class":58},"\"=PV(",[48,486,488],{"class":487},"sSjpA","{",[48,490,491],{"class":91},"row._5",[48,493,494],{"class":487},"}",[48,496,497],{"class":58},"\u002F12,",[48,499,488],{"class":487},[48,501,502],{"class":91},"row._3",[48,504,494],{"class":487},[48,506,507],{"class":58},",-",[48,509,488],{"class":487},[48,511,512],{"class":91},"row._4",[48,514,494],{"class":487},[48,516,517],{"class":58},",0,1)\"",[48,519,151],{"class":91},[48,521,522,525,528],{"class":50,"line":190},[48,523,524],{"class":91},"wb.save(",[48,526,527],{"class":58},"\"pv_check.xlsx\"",[48,529,268],{"class":91},[39,531,533],{"className":41,"code":532,"language":43,"meta":44,"style":44},"soffice --headless --convert-to 'csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true' pv_check.xlsx > \u002Fdev\u002Fnull 2>&1\ncat pv_check.csv\n",[23,534,535,561],{"__ignoreMap":44},[48,536,537,540,543,546,549,552,555,558],{"class":50,"line":51},[48,538,539],{"class":54},"soffice",[48,541,542],{"class":186}," --headless",[48,544,545],{"class":186}," --convert-to",[48,547,548],{"class":58}," 'csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true'",[48,550,551],{"class":58}," pv_check.xlsx",[48,553,554],{"class":87}," >",[48,556,557],{"class":58}," \u002Fdev\u002Fnull",[48,559,560],{"class":87}," 2>&1\n",[48,562,563,566],{"class":50,"line":101},[48,564,565],{"class":54},"cat",[48,567,568],{"class":58}," pv_check.csv\n",[10,570,571,572,575,576,579],{},"Excel's ",[23,573,574],{},"PV(rate, nper, pmt, fv, type)"," computes the same present value, and ",[23,577,578],{},"type = 1"," tells it that payments are at the start of each period. Writing the formula next to the Python result and letting LibreOffice calculate it gives an independent check: the two columns agree to the penny for all three leases. It is worth keeping such a check for any number that will be audited — the reviewer can see that the Python matches the function they would use themselves.",[581,582,590,591,590,595,590,599,590,607,590,617,590,624,590,628,590,633,590,639,590,644,590,649,590,655,590,659,590,663,590,666,590,670,590,675,590,679,590,682,590,686,590,689,590,694,590,699,590,701,590,704,590,708,590,711,590,714,590,718,590,721],"svg",{"viewBox":583,"role":584,"ariaLabelledBy":585,"xmlns":588,"style":589},"4 0 752 108","img",[586,587],"lease-unwind-t","lease-unwind-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[592,593,594],"title",{"id":586},"One month of a lease",[596,597,598],"desc",{"id":587},"Each month starts from the opening liability. The payment at the start of the month reduces it, interest at the monthly rate is charged on what remains, and the result is the closing liability. The right-of-use asset is depreciated by a fixed amount each month.",[600,601],"rect",{"x":602,"y":603,"width":604,"height":605,"fill":606},"4","0","752","108","#ffffff",[600,608],{"x":609,"y":610,"width":611,"height":612,"rx":613,"fill":614,"stroke":615,"style":616},"20.0","16.0","115.2","76.5","12","#e7ebef","var(--line,#cdd5e6)","stroke-width:2px",[618,619,623],"text",{"x":620,"y":621,"style":622},"77.6","41.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Opening",[618,625,627],{"x":620,"y":626,"style":622},"59.0","liability",[618,629,632],{"x":620,"y":630,"style":631},"78.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","start of month",[50,634],{"x1":635,"y1":636,"x2":637,"y2":636,"stroke":638,"style":616},"140.2","54.2","162.2","var(--brand,#5b5cf0)",[640,641],"polygon",{"points":642,"fill":643},"166.2,54.2 157.2,59.2 157.2,49.2","#5b5cf0",[600,645],{"x":646,"y":610,"width":611,"height":612,"rx":613,"fill":647,"stroke":648,"style":616},"171.2","#fdefd8","var(--gold,#b4740a)",[618,650,654],{"x":651,"y":652,"style":653},"228.8","50.2","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","− Payment",[618,656,658],{"x":651,"y":657,"style":631},"69.8","in advance",[50,660],{"x1":661,"y1":636,"x2":662,"y2":636,"stroke":638,"style":616},"291.4","313.4",[640,664],{"points":665,"fill":643},"317.4,54.2 308.4,59.2 308.4,49.2",[600,667],{"x":668,"y":610,"width":611,"height":612,"rx":613,"fill":669,"stroke":638,"style":616},"322.4","#f0f4ff",[618,671,674],{"x":672,"y":621,"style":673},"380.0","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","+ Interest",[618,676,678],{"x":672,"y":677,"style":631},"61.0","rate ÷ 12 on the",[618,680,681],{"x":672,"y":630,"style":631},"rest",[50,683],{"x1":684,"y1":636,"x2":685,"y2":636,"stroke":638,"style":616},"442.6","464.6",[640,687],{"points":688,"fill":643},"468.6,54.2 459.6,59.2 459.6,49.2",[600,690],{"x":691,"y":610,"width":611,"height":612,"rx":613,"fill":692,"stroke":693,"style":616},"473.6","#d9f4f1","var(--teal,#0f9488)",[618,695,698],{"x":696,"y":621,"style":697},"531.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","= Closing",[618,700,627],{"x":696,"y":626,"style":697},[618,702,703],{"x":696,"y":630,"style":631},"carried forward",[50,705],{"x1":706,"y1":636,"x2":707,"y2":636,"stroke":638,"style":616},"593.8","615.8",[640,709],{"points":710,"fill":643},"619.8,54.2 610.8,59.2 610.8,49.2",[600,712],{"x":713,"y":610,"width":611,"height":612,"rx":613,"fill":614,"stroke":615,"style":616},"624.8",[618,715,717],{"x":716,"y":621,"style":622},"682.4","Asset −",[618,719,720],{"x":716,"y":626,"style":622},"depreciation",[618,722,723],{"x":716,"y":630,"style":631},"straight line",[34,725,727],{"id":726},"step-3-roll-the-liability-and-the-asset-forward","Step 3 — Roll the liability and the asset forward",[39,729,731],{"className":78,"code":730,"language":80,"meta":44,"style":44},"def schedule(lease):\n    r, n, pay = lease[\"Discount rate\"] \u002F 12, lease[\"Term (months)\"], lease[\"Monthly payment\"]\n    months = pd.period_range(lease[\"Commencement\"], periods=n, freq=\"M\")\n    rows, balance = [], lease[\"Opening liability\"]\n    dep = lease[\"Opening liability\"] \u002F n                      # right-of-use asset = opening liability here\n    for i, m in enumerate(months):\n        opening = balance\n        after_payment = opening - pay\n        interest = round(after_payment * r, 2)\n        balance = round(after_payment + interest, 2)\n        rows.append({\"Lease\": lease[\"Lease\"], \"Month\": m, \"Opening\": round(opening, 2), \"Payment\": pay,\n                     \"Interest\": interest, \"Closing\": balance, \"Depreciation\": round(dep, 2),\n                     \"ROU closing\": round(lease[\"Opening liability\"] - dep * (i + 1), 2)})\n    df = pd.DataFrame(rows)\n    df.loc[df.index[-1], \"Interest\"] += round(-df[\"Closing\"].iloc[-1], 2)    # absorb rounding so it ends at zero\n    df.loc[df.index[-1], \"Closing\"] = 0.0\n    return df\n\nsched = pd.concat([schedule(l) for _, l in leases.iterrows()], ignore_index=True)\nprint(sched.groupby(\"Lease\").agg(interest=(\"Interest\", \"sum\"), payments=(\"Payment\", \"sum\"), last=(\"Closing\", \"last\")).round(2))\nprint(sched[(sched[\"Lease\"] == \"L-01\") & (sched[\"Month\"].astype(str).isin([\"2025-01\", \"2025-02\", \"2029-12\"]))]\n      [[\"Month\", \"Opening\", \"Payment\", \"Interest\", \"Closing\"]].to_string(index=False))\n",[23,732,733,743,774,807,821,842,857,867,883,905,926,967,996,1034,1044,1093,1113,1121,1126,1157,1222,1276],{"__ignoreMap":44},[48,734,735,737,740],{"class":50,"line":51},[48,736,162],{"class":87},[48,738,739],{"class":165}," schedule",[48,741,742],{"class":91},"(lease):\n",[48,744,745,748,750,753,755,757,759,762,765,767,770,772],{"class":50,"line":101},[48,746,747],{"class":91},"    r, n, pay ",[48,749,127],{"class":87},[48,751,752],{"class":91}," lease[",[48,754,295],{"class":58},[48,756,251],{"class":91},[48,758,183],{"class":87},[48,760,761],{"class":186}," 12",[48,763,764],{"class":91},", lease[",[48,766,300],{"class":58},[48,768,769],{"class":91},"], lease[",[48,771,289],{"class":58},[48,773,332],{"class":91},[48,775,776,779,781,784,786,789,792,794,797,800,802,805],{"class":50,"line":114},[48,777,778],{"class":91},"    months ",[48,780,127],{"class":87},[48,782,783],{"class":91}," pd.period_range(lease[",[48,785,148],{"class":58},[48,787,788],{"class":91},"], ",[48,790,791],{"class":139},"periods",[48,793,127],{"class":87},[48,795,796],{"class":91},"n, ",[48,798,799],{"class":139},"freq",[48,801,127],{"class":87},[48,803,804],{"class":58},"\"M\"",[48,806,268],{"class":91},[48,808,809,812,814,817,819],{"class":50,"line":121},[48,810,811],{"class":91},"    rows, balance ",[48,813,127],{"class":87},[48,815,816],{"class":91}," [], lease[",[48,818,248],{"class":58},[48,820,332],{"class":91},[48,822,823,826,828,830,832,834,836,839],{"class":50,"line":154},[48,824,825],{"class":91},"    dep ",[48,827,127],{"class":87},[48,829,752],{"class":91},[48,831,248],{"class":58},[48,833,251],{"class":91},[48,835,183],{"class":87},[48,837,838],{"class":91}," n                      ",[48,840,841],{"class":201},"# right-of-use asset = opening liability here\n",[48,843,844,847,850,852,854],{"class":50,"line":159},[48,845,846],{"class":87},"    for",[48,848,849],{"class":91}," i, m ",[48,851,280],{"class":87},[48,853,451],{"class":186},[48,855,856],{"class":91},"(months):\n",[48,858,859,862,864],{"class":50,"line":172},[48,860,861],{"class":91},"        opening ",[48,863,127],{"class":87},[48,865,866],{"class":91}," balance\n",[48,868,869,872,874,877,880],{"class":50,"line":190},[48,870,871],{"class":91},"        after_payment ",[48,873,127],{"class":87},[48,875,876],{"class":91}," opening ",[48,878,879],{"class":87},"-",[48,881,882],{"class":91}," pay\n",[48,884,885,888,890,893,896,898,901,903],{"class":50,"line":205},[48,886,887],{"class":91},"        interest ",[48,889,127],{"class":87},[48,891,892],{"class":186}," round",[48,894,895],{"class":91},"(after_payment ",[48,897,325],{"class":87},[48,899,900],{"class":91}," r, ",[48,902,265],{"class":186},[48,904,268],{"class":91},[48,906,907,910,912,914,916,919,922,924],{"class":50,"line":237},[48,908,909],{"class":91},"        balance ",[48,911,127],{"class":87},[48,913,892],{"class":186},[48,915,895],{"class":91},[48,917,918],{"class":87},"+",[48,920,921],{"class":91}," interest, ",[48,923,265],{"class":186},[48,925,268],{"class":91},[48,927,928,931,933,936,938,940,943,946,949,952,954,957,959,961,964],{"class":50,"line":242},[48,929,930],{"class":91},"        rows.append({",[48,932,344],{"class":58},[48,934,935],{"class":91},": lease[",[48,937,344],{"class":58},[48,939,788],{"class":91},[48,941,942],{"class":58},"\"Month\"",[48,944,945],{"class":91},": m, ",[48,947,948],{"class":58},"\"Opening\"",[48,950,951],{"class":91},": ",[48,953,259],{"class":186},[48,955,956],{"class":91},"(opening, ",[48,958,265],{"class":186},[48,960,463],{"class":91},[48,962,963],{"class":58},"\"Payment\"",[48,965,966],{"class":91},": pay,\n",[48,968,969,972,975,978,981,984,986,988,991,993],{"class":50,"line":271},[48,970,971],{"class":58},"                     \"Interest\"",[48,973,974],{"class":91},": interest, ",[48,976,977],{"class":58},"\"Closing\"",[48,979,980],{"class":91},": balance, ",[48,982,983],{"class":58},"\"Depreciation\"",[48,985,951],{"class":91},[48,987,259],{"class":186},[48,989,990],{"class":91},"(dep, ",[48,992,265],{"class":186},[48,994,995],{"class":91},"),\n",[48,997,998,1001,1003,1005,1008,1010,1012,1014,1017,1019,1022,1024,1027,1029,1031],{"class":50,"line":306},[48,999,1000],{"class":58},"                     \"ROU closing\"",[48,1002,951],{"class":91},[48,1004,259],{"class":186},[48,1006,1007],{"class":91},"(lease[",[48,1009,248],{"class":58},[48,1011,251],{"class":91},[48,1013,879],{"class":87},[48,1015,1016],{"class":91}," dep ",[48,1018,325],{"class":87},[48,1020,1021],{"class":91}," (i ",[48,1023,918],{"class":87},[48,1025,1026],{"class":186}," 1",[48,1028,463],{"class":91},[48,1030,265],{"class":186},[48,1032,1033],{"class":91},")})\n",[48,1035,1036,1039,1041],{"class":50,"line":335},[48,1037,1038],{"class":91},"    df ",[48,1040,127],{"class":87},[48,1042,1043],{"class":91}," pd.DataFrame(rows)\n",[48,1045,1047,1050,1052,1054,1056,1059,1061,1064,1066,1069,1071,1074,1076,1079,1081,1083,1085,1087,1090],{"class":50,"line":1046},15,[48,1048,1049],{"class":91},"    df.loc[df.index[",[48,1051,879],{"class":87},[48,1053,222],{"class":186},[48,1055,788],{"class":91},[48,1057,1058],{"class":58},"\"Interest\"",[48,1060,251],{"class":91},[48,1062,1063],{"class":87},"+=",[48,1065,892],{"class":186},[48,1067,1068],{"class":91},"(",[48,1070,879],{"class":87},[48,1072,1073],{"class":91},"df[",[48,1075,977],{"class":58},[48,1077,1078],{"class":91},"].iloc[",[48,1080,879],{"class":87},[48,1082,222],{"class":186},[48,1084,788],{"class":91},[48,1086,265],{"class":186},[48,1088,1089],{"class":91},")    ",[48,1091,1092],{"class":201},"# absorb rounding so it ends at zero\n",[48,1094,1096,1098,1100,1102,1104,1106,1108,1110],{"class":50,"line":1095},16,[48,1097,1049],{"class":91},[48,1099,879],{"class":87},[48,1101,222],{"class":186},[48,1103,788],{"class":91},[48,1105,977],{"class":58},[48,1107,251],{"class":91},[48,1109,127],{"class":87},[48,1111,1112],{"class":186}," 0.0\n",[48,1114,1116,1118],{"class":50,"line":1115},17,[48,1117,208],{"class":87},[48,1119,1120],{"class":91}," df\n",[48,1122,1124],{"class":50,"line":1123},18,[48,1125,118],{"emptyLinePlaceholder":117},[48,1127,1129,1132,1134,1137,1139,1142,1144,1147,1150,1152,1155],{"class":50,"line":1128},19,[48,1130,1131],{"class":91},"sched ",[48,1133,127],{"class":87},[48,1135,1136],{"class":91}," pd.concat([schedule(l) ",[48,1138,443],{"class":87},[48,1140,1141],{"class":91}," _, l ",[48,1143,280],{"class":87},[48,1145,1146],{"class":91}," leases.iterrows()], ",[48,1148,1149],{"class":139},"ignore_index",[48,1151,127],{"class":87},[48,1153,1154],{"class":186},"True",[48,1156,268],{"class":91},[48,1158,1160,1162,1165,1167,1170,1173,1175,1177,1179,1181,1184,1186,1189,1191,1193,1195,1197,1199,1201,1204,1206,1208,1210,1212,1215,1218,1220],{"class":50,"line":1159},20,[48,1161,338],{"class":186},[48,1163,1164],{"class":91},"(sched.groupby(",[48,1166,344],{"class":58},[48,1168,1169],{"class":91},").agg(",[48,1171,1172],{"class":139},"interest",[48,1174,127],{"class":87},[48,1176,1068],{"class":91},[48,1178,1058],{"class":58},[48,1180,136],{"class":91},[48,1182,1183],{"class":58},"\"sum\"",[48,1185,463],{"class":91},[48,1187,1188],{"class":139},"payments",[48,1190,127],{"class":87},[48,1192,1068],{"class":91},[48,1194,963],{"class":58},[48,1196,136],{"class":91},[48,1198,1183],{"class":58},[48,1200,463],{"class":91},[48,1202,1203],{"class":139},"last",[48,1205,127],{"class":87},[48,1207,1068],{"class":91},[48,1209,977],{"class":58},[48,1211,136],{"class":91},[48,1213,1214],{"class":58},"\"last\"",[48,1216,1217],{"class":91},")).round(",[48,1219,265],{"class":186},[48,1221,366],{"class":91},[48,1223,1225,1227,1230,1232,1234,1237,1240,1243,1246,1249,1251,1254,1257,1260,1263,1265,1268,1270,1273],{"class":50,"line":1224},21,[48,1226,338],{"class":186},[48,1228,1229],{"class":91},"(sched[(sched[",[48,1231,344],{"class":58},[48,1233,251],{"class":91},[48,1235,1236],{"class":87},"==",[48,1238,1239],{"class":58}," \"L-01\"",[48,1241,1242],{"class":91},") ",[48,1244,1245],{"class":87},"&",[48,1247,1248],{"class":91}," (sched[",[48,1250,942],{"class":58},[48,1252,1253],{"class":91},"].astype(",[48,1255,1256],{"class":186},"str",[48,1258,1259],{"class":91},").isin([",[48,1261,1262],{"class":58},"\"2025-01\"",[48,1264,136],{"class":91},[48,1266,1267],{"class":58},"\"2025-02\"",[48,1269,136],{"class":91},[48,1271,1272],{"class":58},"\"2029-12\"",[48,1274,1275],{"class":91},"]))]\n",[48,1277,1279,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308],{"class":50,"line":1278},22,[48,1280,1281],{"class":91},"      [[",[48,1283,942],{"class":58},[48,1285,136],{"class":91},[48,1287,948],{"class":58},[48,1289,136],{"class":91},[48,1291,963],{"class":58},[48,1293,136],{"class":91},[48,1295,1058],{"class":58},[48,1297,136],{"class":91},[48,1299,977],{"class":58},[48,1301,355],{"class":91},[48,1303,358],{"class":139},[48,1305,127],{"class":87},[48,1307,363],{"class":186},[48,1309,366],{"class":91},[10,1311,1312],{},"Each month the payment is made first, because it is due in advance, and interest is then charged on what remains at the monthly rate. The closing balance becomes next month's opening. Over the term, total interest equals total payments minus the opening liability, and the liability falls to zero with the last payment; rounding to pence each month leaves a few pence over at the end, which are absorbed into the final month's interest so the balance closes exactly at zero. The right-of-use asset starts at the opening liability — it would also include initial direct costs and payments made before commencement, if there were any — and is depreciated in equal monthly amounts over the term.",[581,1314,590,1320,590,1323,590,1326,590,1331,590,1337,590,1340,590,1346,590,1350,590,1354,590,1357,590,1361,590,1365,590,1369,590,1373,590,1377,590,1381,590,1384,590,1387,590,1391,590,1393,590,1395,590,1397,590,1400,590,1402,590,1405,590,1407,590,1410,590,1413,590,1416,590,1418,590,1422,590,1424,590,1427,590,1429,590,1432,590,1434,590,1437,590,1439,590,1442,590,1445,590,1449,590,1451,590,1454,590,1456,590,1458,590,1460,590,1462,590,1464,590,1467,590,1469,590,1472,590,1475,590,1478,590,1480,590,1483,590,1485,590,1487,590,1489,590,1491,590,1493,590,1495,590,1497,590,1499,590,1502,590,1506,590,1508,590,1511,590,1513,590,1515,590,1517,590,1519,590,1521,590,1523,590,1525],{"viewBox":1315,"role":584,"ariaLabelledBy":1316,"xmlns":588,"style":1319},"131 0 497 196",[1317,1318],"lease-l01-t","lease-l01-d","width:100%;max-width:497px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[592,1321,1322],{"id":1317},"The head office lease, first two and last months",[596,1324,1325],{"id":1318},"The head office lease starts with a liability of 657,409.82. The January payment of 12,500 is made first and interest of 2,955.84 is charged on the remainder. By the last month the opening balance is just the final payment, no interest arises and the liability closes at zero.",[600,1327],{"x":1328,"y":603,"width":1329,"height":1330,"fill":606},"131","497","196",[600,1332],{"x":1333,"y":610,"width":1334,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"147.9","32.0","24.0","stroke-width:1px",[600,1338],{"x":1339,"y":610,"width":630,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"179.9",[618,1341,1345],{"x":1342,"y":1343,"style":1344},"219.2","33.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[600,1347],{"x":1348,"y":610,"width":1349,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"258.5","97.1",[618,1351,1353],{"x":1352,"y":1343,"style":1344},"307.0","B",[600,1355],{"x":1356,"y":610,"width":630,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"355.6",[618,1358,1360],{"x":1359,"y":1343,"style":1344},"394.8","C",[600,1362],{"x":1363,"y":610,"width":1364,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"434.1","80.9",[618,1366,1368],{"x":1367,"y":1343,"style":1344},"474.6","D",[600,1370],{"x":1371,"y":610,"width":1372,"height":1335,"rx":603,"fill":614,"stroke":615,"style":1336},"515.0","97.0",[618,1374,1376],{"x":1375,"y":1343,"style":1344},"563.5","E",[600,1378],{"x":1333,"y":1379,"width":1334,"height":1380,"rx":603,"fill":614,"stroke":615,"style":1336},"40.0","28.0",[618,1382,222],{"x":1383,"y":626,"style":1344},"163.9",[600,1385],{"x":1339,"y":1379,"width":630,"height":1380,"rx":603,"fill":669,"stroke":638,"style":1386},"stroke-width:1.5px",[618,1388,1390],{"x":1342,"y":626,"style":1389},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Month",[600,1392],{"x":1348,"y":1379,"width":1349,"height":1380,"rx":603,"fill":669,"stroke":638,"style":1386},[618,1394,623],{"x":1352,"y":626,"style":1389},[600,1396],{"x":1356,"y":1379,"width":630,"height":1380,"rx":603,"fill":669,"stroke":638,"style":1386},[618,1398,1399],{"x":1359,"y":626,"style":1389},"Payment",[600,1401],{"x":1363,"y":1379,"width":1364,"height":1380,"rx":603,"fill":669,"stroke":638,"style":1386},[618,1403,1404],{"x":1367,"y":626,"style":1389},"Interest",[600,1406],{"x":1371,"y":1379,"width":1372,"height":1380,"rx":603,"fill":669,"stroke":638,"style":1386},[618,1408,1409],{"x":1375,"y":626,"style":1389},"Closing",[600,1411],{"x":1333,"y":1412,"width":1334,"height":1380,"rx":603,"fill":614,"stroke":615,"style":1336},"68.0",[618,1414,265],{"x":1383,"y":1415,"style":1344},"87.0",[600,1417],{"x":1339,"y":1412,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1419,1421],{"x":1342,"y":1415,"style":1420},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","2025-01",[600,1423],{"x":1348,"y":1412,"width":1349,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1425,1426],{"x":1352,"y":1415,"style":1420},"657,409.82",[600,1428],{"x":1356,"y":1412,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1430,1431],{"x":1359,"y":1415,"style":1420},"12,500",[600,1433],{"x":1363,"y":1412,"width":1364,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1435,1436],{"x":1367,"y":1415,"style":1420},"2,955.84",[600,1438],{"x":1371,"y":1412,"width":1372,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1440,1441],{"x":1375,"y":1415,"style":1420},"647,865.66",[600,1443],{"x":1333,"y":1444,"width":1334,"height":1380,"rx":603,"fill":614,"stroke":615,"style":1336},"96.0",[618,1446,1448],{"x":1383,"y":1447,"style":1344},"115.0","3",[600,1450],{"x":1339,"y":1444,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1452,1453],{"x":1342,"y":1447,"style":1420},"2025-02",[600,1455],{"x":1348,"y":1444,"width":1349,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1457,1441],{"x":1352,"y":1447,"style":1420},[600,1459],{"x":1356,"y":1444,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1461,1431],{"x":1359,"y":1447,"style":1420},[600,1463],{"x":1363,"y":1444,"width":1364,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1465,1466],{"x":1367,"y":1447,"style":1420},"2,912.09",[600,1468],{"x":1371,"y":1444,"width":1372,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1470,1471],{"x":1375,"y":1447,"style":1420},"638,277.75",[600,1473],{"x":1333,"y":1474,"width":1334,"height":1380,"rx":603,"fill":614,"stroke":615,"style":1336},"124.0",[618,1476,602],{"x":1383,"y":1477,"style":1344},"143.0",[600,1479],{"x":1339,"y":1474,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1481,1482],{"x":1342,"y":1477,"style":1420},"…",[600,1484],{"x":1348,"y":1474,"width":1349,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1486,1482],{"x":1352,"y":1477,"style":1420},[600,1488],{"x":1356,"y":1474,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1490,1482],{"x":1359,"y":1477,"style":1420},[600,1492],{"x":1363,"y":1474,"width":1364,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1494,1482],{"x":1367,"y":1477,"style":1420},[600,1496],{"x":1371,"y":1474,"width":1372,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1498,1482],{"x":1375,"y":1477,"style":1420},[600,1500],{"x":1333,"y":1501,"width":1334,"height":1380,"rx":603,"fill":614,"stroke":615,"style":1336},"152.0",[618,1503,1505],{"x":1383,"y":1504,"style":1344},"171.0","5",[600,1507],{"x":1339,"y":1501,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1509,1510],{"x":1342,"y":1504,"style":1420},"2029-12",[600,1512],{"x":1348,"y":1501,"width":1349,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1514,1431],{"x":1352,"y":1504,"style":1420},[600,1516],{"x":1356,"y":1501,"width":630,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1518,1431],{"x":1359,"y":1504,"style":1420},[600,1520],{"x":1363,"y":1501,"width":1364,"height":1380,"rx":603,"fill":606,"stroke":615,"style":1336},[618,1522,603],{"x":1367,"y":1504,"style":1420},[600,1524],{"x":1371,"y":1501,"width":1372,"height":1380,"rx":603,"fill":692,"stroke":693,"style":1386},[618,1526,603],{"x":1375,"y":1504,"style":1527},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[34,1529,1531],{"id":1530},"step-4-the-months-figures-the-balance-sheet-split-and-the-maturity-analysis","Step 4 — The month's figures, the balance sheet split and the maturity analysis",[39,1533,1535],{"className":78,"code":1534,"language":80,"meta":44,"style":44},"month = pd.Period(\"2026-09\", freq=\"M\")\nnow = sched[sched[\"Month\"] == month].set_index(\"Lease\")\nin_12 = sched[sched[\"Month\"] == month + 12].set_index(\"Lease\")[\"Closing\"].reindex(now.index, fill_value=0.0)\nposition = pd.DataFrame({\"Interest\": now[\"Interest\"], \"Depreciation\": now[\"Depreciation\"], \"Payment\": now[\"Payment\"],\n                         \"Liability\": now[\"Closing\"], \"Current\": (now[\"Closing\"] - in_12).round(2),\n                         \"ROU asset\": now[\"ROU closing\"]})\nposition[\"Non-current\"] = (position[\"Liability\"] - position[\"Current\"]).round(2)\nprint(position.to_string())\nprint(position[[\"Interest\", \"Depreciation\", \"Payment\", \"Liability\", \"Current\", \"Non-current\"]].sum().round(2).to_dict())\n\nfuture = sched[sched[\"Month\"] > month]\nyears_out = (future[\"Month\"] - month).apply(lambda d: d.n) \u002F 12\nbuckets = pd.cut(years_out, [0, 1, 5, 100], labels=[\"Within 1 year\", \"1 to 5 years\", \"Over 5 years\"])\nmaturity = future.groupby(buckets, observed=False)[\"Payment\"].sum()\nprint(maturity.to_dict(), \"| total undiscounted\", maturity.sum())\n",[23,1536,1537,1560,1583,1628,1664,1694,1707,1741,1748,1785,1789,1808,1837,1886,1910],{"__ignoreMap":44},[48,1538,1539,1542,1544,1547,1550,1552,1554,1556,1558],{"class":50,"line":51},[48,1540,1541],{"class":91},"month ",[48,1543,127],{"class":87},[48,1545,1546],{"class":91}," pd.Period(",[48,1548,1549],{"class":58},"\"2026-09\"",[48,1551,136],{"class":91},[48,1553,799],{"class":139},[48,1555,127],{"class":87},[48,1557,804],{"class":58},[48,1559,268],{"class":91},[48,1561,1562,1565,1567,1570,1572,1574,1576,1579,1581],{"class":50,"line":101},[48,1563,1564],{"class":91},"now ",[48,1566,127],{"class":87},[48,1568,1569],{"class":91}," sched[sched[",[48,1571,942],{"class":58},[48,1573,251],{"class":91},[48,1575,1236],{"class":87},[48,1577,1578],{"class":91}," month].set_index(",[48,1580,344],{"class":58},[48,1582,268],{"class":91},[48,1584,1585,1588,1590,1592,1594,1596,1598,1601,1603,1605,1608,1610,1613,1615,1618,1621,1623,1626],{"class":50,"line":114},[48,1586,1587],{"class":91},"in_12 ",[48,1589,127],{"class":87},[48,1591,1569],{"class":91},[48,1593,942],{"class":58},[48,1595,251],{"class":91},[48,1597,1236],{"class":87},[48,1599,1600],{"class":91}," month ",[48,1602,918],{"class":87},[48,1604,761],{"class":186},[48,1606,1607],{"class":91},"].set_index(",[48,1609,344],{"class":58},[48,1611,1612],{"class":91},")[",[48,1614,977],{"class":58},[48,1616,1617],{"class":91},"].reindex(now.index, ",[48,1619,1620],{"class":139},"fill_value",[48,1622,127],{"class":87},[48,1624,1625],{"class":186},"0.0",[48,1627,268],{"class":91},[48,1629,1630,1633,1635,1638,1640,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661],{"class":50,"line":121},[48,1631,1632],{"class":91},"position ",[48,1634,127],{"class":87},[48,1636,1637],{"class":91}," pd.DataFrame({",[48,1639,1058],{"class":58},[48,1641,1642],{"class":91},": now[",[48,1644,1058],{"class":58},[48,1646,788],{"class":91},[48,1648,983],{"class":58},[48,1650,1642],{"class":91},[48,1652,983],{"class":58},[48,1654,788],{"class":91},[48,1656,963],{"class":58},[48,1658,1642],{"class":91},[48,1660,963],{"class":58},[48,1662,1663],{"class":91},"],\n",[48,1665,1666,1669,1671,1673,1675,1678,1681,1683,1685,1687,1690,1692],{"class":50,"line":154},[48,1667,1668],{"class":58},"                         \"Liability\"",[48,1670,1642],{"class":91},[48,1672,977],{"class":58},[48,1674,788],{"class":91},[48,1676,1677],{"class":58},"\"Current\"",[48,1679,1680],{"class":91},": (now[",[48,1682,977],{"class":58},[48,1684,251],{"class":91},[48,1686,879],{"class":87},[48,1688,1689],{"class":91}," in_12).round(",[48,1691,265],{"class":186},[48,1693,995],{"class":91},[48,1695,1696,1699,1701,1704],{"class":50,"line":159},[48,1697,1698],{"class":58},"                         \"ROU asset\"",[48,1700,1642],{"class":91},[48,1702,1703],{"class":58},"\"ROU closing\"",[48,1705,1706],{"class":91},"]})\n",[48,1708,1709,1712,1715,1717,1719,1722,1725,1727,1729,1732,1734,1737,1739],{"class":50,"line":172},[48,1710,1711],{"class":91},"position[",[48,1713,1714],{"class":58},"\"Non-current\"",[48,1716,251],{"class":91},[48,1718,127],{"class":87},[48,1720,1721],{"class":91}," (position[",[48,1723,1724],{"class":58},"\"Liability\"",[48,1726,251],{"class":91},[48,1728,879],{"class":87},[48,1730,1731],{"class":91}," position[",[48,1733,1677],{"class":58},[48,1735,1736],{"class":91},"]).round(",[48,1738,265],{"class":186},[48,1740,268],{"class":91},[48,1742,1743,1745],{"class":50,"line":190},[48,1744,338],{"class":186},[48,1746,1747],{"class":91},"(position.to_string())\n",[48,1749,1750,1752,1755,1757,1759,1761,1763,1765,1767,1769,1771,1773,1775,1777,1780,1782],{"class":50,"line":205},[48,1751,338],{"class":186},[48,1753,1754],{"class":91},"(position[[",[48,1756,1058],{"class":58},[48,1758,136],{"class":91},[48,1760,983],{"class":58},[48,1762,136],{"class":91},[48,1764,963],{"class":58},[48,1766,136],{"class":91},[48,1768,1724],{"class":58},[48,1770,136],{"class":91},[48,1772,1677],{"class":58},[48,1774,136],{"class":91},[48,1776,1714],{"class":58},[48,1778,1779],{"class":91},"]].sum().round(",[48,1781,265],{"class":186},[48,1783,1784],{"class":91},").to_dict())\n",[48,1786,1787],{"class":50,"line":237},[48,1788,118],{"emptyLinePlaceholder":117},[48,1790,1791,1794,1796,1798,1800,1802,1805],{"class":50,"line":242},[48,1792,1793],{"class":91},"future ",[48,1795,127],{"class":87},[48,1797,1569],{"class":91},[48,1799,942],{"class":58},[48,1801,251],{"class":91},[48,1803,1804],{"class":87},">",[48,1806,1807],{"class":91}," month]\n",[48,1809,1810,1813,1815,1818,1820,1822,1824,1827,1830,1833,1835],{"class":50,"line":271},[48,1811,1812],{"class":91},"years_out ",[48,1814,127],{"class":87},[48,1816,1817],{"class":91}," (future[",[48,1819,942],{"class":58},[48,1821,251],{"class":91},[48,1823,879],{"class":87},[48,1825,1826],{"class":91}," month).apply(",[48,1828,1829],{"class":87},"lambda",[48,1831,1832],{"class":91}," d: d.n) ",[48,1834,183],{"class":87},[48,1836,187],{"class":186},[48,1838,1839,1842,1844,1847,1849,1851,1853,1855,1857,1859,1862,1864,1867,1869,1871,1874,1876,1879,1881,1884],{"class":50,"line":306},[48,1840,1841],{"class":91},"buckets ",[48,1843,127],{"class":87},[48,1845,1846],{"class":91}," pd.cut(years_out, [",[48,1848,603],{"class":186},[48,1850,136],{"class":91},[48,1852,222],{"class":186},[48,1854,136],{"class":91},[48,1856,1505],{"class":186},[48,1858,136],{"class":91},[48,1860,1861],{"class":186},"100",[48,1863,788],{"class":91},[48,1865,1866],{"class":139},"labels",[48,1868,127],{"class":87},[48,1870,145],{"class":91},[48,1872,1873],{"class":58},"\"Within 1 year\"",[48,1875,136],{"class":91},[48,1877,1878],{"class":58},"\"1 to 5 years\"",[48,1880,136],{"class":91},[48,1882,1883],{"class":58},"\"Over 5 years\"",[48,1885,151],{"class":91},[48,1887,1888,1891,1893,1896,1899,1901,1903,1905,1907],{"class":50,"line":335},[48,1889,1890],{"class":91},"maturity ",[48,1892,127],{"class":87},[48,1894,1895],{"class":91}," future.groupby(buckets, ",[48,1897,1898],{"class":139},"observed",[48,1900,127],{"class":87},[48,1902,363],{"class":186},[48,1904,1612],{"class":91},[48,1906,963],{"class":58},[48,1908,1909],{"class":91},"].sum()\n",[48,1911,1912,1914,1917,1920],{"class":50,"line":1046},[48,1913,338],{"class":186},[48,1915,1916],{"class":91},"(maturity.to_dict(), ",[48,1918,1919],{"class":58},"\"| total undiscounted\"",[48,1921,1922],{"class":91},", maturity.sum())\n",[10,1924,1925,1926,1929,1930,1933],{},"For the month being closed, each lease contributes interest expense, depreciation and a payment, and ends with a liability and an asset balance. The balance sheet needs the liability split into the part due within twelve months — ",[14,1927,1928],{},"current"," — and the rest. The cleanest measure is the reduction in the liability over the next twelve months: the closing liability now minus the closing liability twelve months from now, which is the principal that will be paid off in that time. The maturity analysis in the notes to the accounts uses a different basis — the ",[14,1931,1932],{},"undiscounted"," payments still to be made — grouped into within one year, one to five years and over five years. Its total is larger than the liability, because it includes the interest not yet charged. For September 2026 the three leases carry a liability of 2,280,581.66, of which 327,653.55 is current, while the undiscounted payments still due add up to 2,814,300 — 452,400 within a year, 1,416,900 in one to five years and 945,000 after that.",[581,1935,590,1940,590,1943,590,1946,590,1949,590,1954,590,1960,590,1965,590,1969,590,1973,590,1977,590,1981,590,1984,590,1989,590,1993,590,1996,590,1999,590,2002],{"viewBox":1936,"role":584,"ariaLabelledBy":1937,"xmlns":588,"style":589},"4 0 752 199",[1938,1939],"lease-two-views-t","lease-two-views-d",[592,1941,1942],{"id":1938},"Two ways to describe what is owed",[596,1944,1945],{"id":1939},"The balance sheet shows the discounted liability split into current and non-current parts by the principal repaid in the next twelve months. The maturity analysis shows the undiscounted payments still due, grouped by when they fall due, and its total includes future interest.",[600,1947],{"x":602,"y":603,"width":604,"height":1948,"fill":606},"199",[600,1950],{"x":609,"y":610,"width":1951,"height":1952,"rx":1953,"fill":669,"stroke":638,"style":616},"351.0","167.0","14",[618,1955,1959],{"x":1956,"y":1957,"style":1958},"195.5","44.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Balance sheet",[50,1961],{"x1":1962,"y1":1963,"x2":1964,"y2":1963,"stroke":638,"style":1336},"36.0","57.0","355.0",[618,1966,1968],{"x":1956,"y":1967,"style":1420},"77.0","discounted liability",[618,1970,1972],{"x":1956,"y":1971,"style":1420},"103.0","current: principal in 12 months",[618,1974,1976],{"x":1956,"y":1975,"style":1420},"129.0","non-current: the rest",[618,1978,1980],{"x":1956,"y":1979,"style":1420},"155.0","no future interest",[600,1982],{"x":1983,"y":610,"width":1951,"height":1952,"rx":1953,"fill":692,"stroke":693,"style":616},"389.0",[618,1985,1988],{"x":1986,"y":1957,"style":1987},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Maturity analysis",[50,1990],{"x1":1991,"y1":1963,"x2":1992,"y2":1963,"stroke":693,"style":1336},"405.0","724.0",[618,1994,1995],{"x":1986,"y":1967,"style":1420},"undiscounted payments",[618,1997,1998],{"x":1986,"y":1971,"style":1420},"within 1 year, 1–5, over 5",[618,2000,2001],{"x":1986,"y":1975,"style":1420},"includes future interest",[618,2003,2004],{"x":1986,"y":1979,"style":1420},"goes in the notes",[34,2006,2008],{"id":2007},"step-5-journals-and-the-workbook","Step 5 — Journals and the workbook",[39,2010,2012],{"className":78,"code":2011,"language":80,"meta":44,"style":44},"totals = position.sum()\njournals = pd.DataFrame([\n    (\"Interest expense — leases\", totals[\"Interest\"], 0.0), (\"Lease liability\", 0.0, totals[\"Interest\"]),\n    (\"Lease liability\", totals[\"Payment\"], 0.0), (\"Cash\", 0.0, totals[\"Payment\"]),\n    (\"Depreciation — right-of-use assets\", totals[\"Depreciation\"], 0.0), (\"Right-of-use assets — accumulated depreciation\", 0.0, totals[\"Depreciation\"]),\n], columns=[\"Account\", \"Debit\", \"Credit\"]).round(2)\nassert round(journals[\"Debit\"].sum() - journals[\"Credit\"].sum(), 2) == 0\n\nwith pd.ExcelWriter(\"leases_2026-09.xlsx\") as xw:\n    position.reset_index().to_excel(xw, sheet_name=\"Position\", index=False)\n    journals.to_excel(xw, sheet_name=\"Journals\", index=False)\n    maturity.rename(\"Undiscounted payments\").reset_index().rename(columns={\"index\": \"When\"}).to_excel(xw, sheet_name=\"Maturity\", index=False)\n    sched.assign(Month=sched[\"Month\"].astype(str)).to_excel(xw, sheet_name=\"Schedules\", index=False)\nprint(journals.to_string(index=False))\n",[23,2013,2014,2024,2034,2068,2097,2127,2157,2191,2195,2213,2236,2258,2303,2341],{"__ignoreMap":44},[48,2015,2016,2019,2021],{"class":50,"line":51},[48,2017,2018],{"class":91},"totals ",[48,2020,127],{"class":87},[48,2022,2023],{"class":91}," position.sum()\n",[48,2025,2026,2029,2031],{"class":50,"line":101},[48,2027,2028],{"class":91},"journals ",[48,2030,127],{"class":87},[48,2032,2033],{"class":91}," pd.DataFrame([\n",[48,2035,2036,2039,2042,2045,2047,2049,2051,2054,2057,2059,2061,2063,2065],{"class":50,"line":114},[48,2037,2038],{"class":91},"    (",[48,2040,2041],{"class":58},"\"Interest expense — leases\"",[48,2043,2044],{"class":91},", totals[",[48,2046,1058],{"class":58},[48,2048,788],{"class":91},[48,2050,1625],{"class":186},[48,2052,2053],{"class":91},"), (",[48,2055,2056],{"class":58},"\"Lease liability\"",[48,2058,136],{"class":91},[48,2060,1625],{"class":186},[48,2062,2044],{"class":91},[48,2064,1058],{"class":58},[48,2066,2067],{"class":91},"]),\n",[48,2069,2070,2072,2074,2076,2078,2080,2082,2084,2087,2089,2091,2093,2095],{"class":50,"line":121},[48,2071,2038],{"class":91},[48,2073,2056],{"class":58},[48,2075,2044],{"class":91},[48,2077,963],{"class":58},[48,2079,788],{"class":91},[48,2081,1625],{"class":186},[48,2083,2053],{"class":91},[48,2085,2086],{"class":58},"\"Cash\"",[48,2088,136],{"class":91},[48,2090,1625],{"class":186},[48,2092,2044],{"class":91},[48,2094,963],{"class":58},[48,2096,2067],{"class":91},[48,2098,2099,2101,2104,2106,2108,2110,2112,2114,2117,2119,2121,2123,2125],{"class":50,"line":154},[48,2100,2038],{"class":91},[48,2102,2103],{"class":58},"\"Depreciation — right-of-use assets\"",[48,2105,2044],{"class":91},[48,2107,983],{"class":58},[48,2109,788],{"class":91},[48,2111,1625],{"class":186},[48,2113,2053],{"class":91},[48,2115,2116],{"class":58},"\"Right-of-use assets — accumulated depreciation\"",[48,2118,136],{"class":91},[48,2120,1625],{"class":186},[48,2122,2044],{"class":91},[48,2124,983],{"class":58},[48,2126,2067],{"class":91},[48,2128,2129,2131,2134,2136,2138,2141,2143,2146,2148,2151,2153,2155],{"class":50,"line":159},[48,2130,788],{"class":91},[48,2132,2133],{"class":139},"columns",[48,2135,127],{"class":87},[48,2137,145],{"class":91},[48,2139,2140],{"class":58},"\"Account\"",[48,2142,136],{"class":91},[48,2144,2145],{"class":58},"\"Debit\"",[48,2147,136],{"class":91},[48,2149,2150],{"class":58},"\"Credit\"",[48,2152,1736],{"class":91},[48,2154,265],{"class":186},[48,2156,268],{"class":91},[48,2158,2159,2162,2164,2167,2169,2172,2174,2177,2179,2182,2184,2186,2188],{"class":50,"line":172},[48,2160,2161],{"class":87},"assert",[48,2163,892],{"class":186},[48,2165,2166],{"class":91},"(journals[",[48,2168,2145],{"class":58},[48,2170,2171],{"class":91},"].sum() ",[48,2173,879],{"class":87},[48,2175,2176],{"class":91}," journals[",[48,2178,2150],{"class":58},[48,2180,2181],{"class":91},"].sum(), ",[48,2183,265],{"class":186},[48,2185,1242],{"class":91},[48,2187,1236],{"class":87},[48,2189,2190],{"class":186}," 0\n",[48,2192,2193],{"class":50,"line":190},[48,2194,118],{"emptyLinePlaceholder":117},[48,2196,2197,2200,2203,2206,2208,2210],{"class":50,"line":205},[48,2198,2199],{"class":87},"with",[48,2201,2202],{"class":91}," pd.ExcelWriter(",[48,2204,2205],{"class":58},"\"leases_2026-09.xlsx\"",[48,2207,1242],{"class":91},[48,2209,95],{"class":87},[48,2211,2212],{"class":91}," xw:\n",[48,2214,2215,2218,2221,2223,2226,2228,2230,2232,2234],{"class":50,"line":237},[48,2216,2217],{"class":91},"    position.reset_index().to_excel(xw, ",[48,2219,2220],{"class":139},"sheet_name",[48,2222,127],{"class":87},[48,2224,2225],{"class":58},"\"Position\"",[48,2227,136],{"class":91},[48,2229,358],{"class":139},[48,2231,127],{"class":87},[48,2233,363],{"class":186},[48,2235,268],{"class":91},[48,2237,2238,2241,2243,2245,2248,2250,2252,2254,2256],{"class":50,"line":242},[48,2239,2240],{"class":91},"    journals.to_excel(xw, ",[48,2242,2220],{"class":139},[48,2244,127],{"class":87},[48,2246,2247],{"class":58},"\"Journals\"",[48,2249,136],{"class":91},[48,2251,358],{"class":139},[48,2253,127],{"class":87},[48,2255,363],{"class":186},[48,2257,268],{"class":91},[48,2259,2260,2263,2266,2269,2271,2273,2275,2278,2280,2283,2286,2288,2290,2293,2295,2297,2299,2301],{"class":50,"line":271},[48,2261,2262],{"class":91},"    maturity.rename(",[48,2264,2265],{"class":58},"\"Undiscounted payments\"",[48,2267,2268],{"class":91},").reset_index().rename(",[48,2270,2133],{"class":139},[48,2272,127],{"class":87},[48,2274,488],{"class":91},[48,2276,2277],{"class":58},"\"index\"",[48,2279,951],{"class":91},[48,2281,2282],{"class":58},"\"When\"",[48,2284,2285],{"class":91},"}).to_excel(xw, ",[48,2287,2220],{"class":139},[48,2289,127],{"class":87},[48,2291,2292],{"class":58},"\"Maturity\"",[48,2294,136],{"class":91},[48,2296,358],{"class":139},[48,2298,127],{"class":87},[48,2300,363],{"class":186},[48,2302,268],{"class":91},[48,2304,2305,2308,2310,2312,2315,2317,2319,2321,2324,2326,2328,2331,2333,2335,2337,2339],{"class":50,"line":306},[48,2306,2307],{"class":91},"    sched.assign(",[48,2309,1390],{"class":139},[48,2311,127],{"class":87},[48,2313,2314],{"class":91},"sched[",[48,2316,942],{"class":58},[48,2318,1253],{"class":91},[48,2320,1256],{"class":186},[48,2322,2323],{"class":91},")).to_excel(xw, ",[48,2325,2220],{"class":139},[48,2327,127],{"class":87},[48,2329,2330],{"class":58},"\"Schedules\"",[48,2332,136],{"class":91},[48,2334,358],{"class":139},[48,2336,127],{"class":87},[48,2338,363],{"class":186},[48,2340,268],{"class":91},[48,2342,2343,2345,2348,2350,2352,2354],{"class":50,"line":335},[48,2344,338],{"class":186},[48,2346,2347],{"class":91},"(journals.to_string(",[48,2349,358],{"class":139},[48,2351,127],{"class":87},[48,2353,363],{"class":186},[48,2355,366],{"class":91},[10,2357,2358],{},"Three journals record the month: interest increases the liability, the payment reduces it and leaves the bank, and depreciation reduces the asset. The debits and credits are asserted to balance before anything is written. The workbook holds the position by lease, the journals, the maturity table and the full schedules, which double as the audit trail — every month of every lease, from commencement to the final payment. Changes to a lease — a new payment amount after a rent review, an extension — are handled by recalculating the liability from that date with the new payments and the rate at that date, and recording the difference against the asset; the same function serves for that, called with the remaining payments.",[34,2360,2362],{"id":2361},"common-pitfalls","Common pitfalls",[2364,2365,2366,2377,2383,2389,2395],"ul",{},[2367,2368,2369,2373,2374,2376],"li",{},[2370,2371,2372],"strong",{},"Payments in arrears by accident."," In advance means the first payment is not discounted; set ",[23,2375,578],{}," in Excel.",[2367,2378,2379,2382],{},[2370,2380,2381],{},"Rounding leftovers."," Absorb the final pennies so the liability closes at exactly zero.",[2367,2384,2385,2388],{},[2370,2386,2387],{},"Current portion as next year's payments."," Use the principal reduction, not undiscounted payments.",[2367,2390,2391,2394],{},[2370,2392,2393],{},"Maturity analysis discounted."," It shows undiscounted payments, including future interest.",[2367,2396,2397,2400,2401,2403],{},[2370,2398,2399],{},"No independent check."," Compare the opening liability with ",[23,2402,25],{}," in a spreadsheet.",[34,2405,2407],{"id":2406},"conclusion","Conclusion",[10,2409,2410,2411,2413],{},"A lease liability schedule starts with the present value of the payments at the lease's monthly rate, checked against Excel's ",[23,2412,25],{},", then each month deducts the payment in advance, adds interest on the remainder and depreciates the right-of-use asset straight line. From the schedules come the month's interest, depreciation and payment journals, the current and non-current split from the next twelve months' principal reduction, and the undiscounted maturity analysis for the notes.",[34,2415,2417],{"id":2416},"frequently-asked-questions","Frequently asked questions",[10,2419,2420,2423],{},[2370,2421,2422],{},"How do I calculate a lease liability in Python?","\nDiscount each payment at the monthly rate — for payments in advance the first is undiscounted — and sum them; that is the liability at commencement.",[10,2425,2426,2429],{},[2370,2427,2428],{},"How do I split a lease liability into current and non-current?","\nTake the closing liability now minus the closing liability twelve months later as current, and the remainder as non-current.",[10,2431,2432,2435,2438],{},[2370,2433,2434],{},"What Excel function checks the opening lease liability?",[23,2436,2437],{},"PV(rate\u002F12, months, -payment, 0, 1)",", where the final 1 means payments at the start of each period.",[10,2440,2441,2444],{},[2370,2442,2443],{},"Why is the maturity analysis bigger than the liability?","\nIt shows undiscounted future payments, which include interest that has not been charged yet.",[34,2446,2448],{"id":2447},"related","Related",[2364,2450,2451,2457,2464,2471],{},[2367,2452,2453,2454,2456],{},"Up one level: ",[28,2455,31],{"href":30}," — finance reports from Python.",[2367,2458,2459,2463],{},[28,2460,2462],{"href":2461},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-loan-amortization-schedule-in-excel\u002F","Build a Loan Amortization Schedule in Excel with Python"," — the same mechanics for a loan.",[2367,2465,2466,2470],{},[28,2467,2469],{"href":2468},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fpmt-npv-and-irr-in-python\u002F","PMT, NPV and IRR in Python"," — present values in Python.",[2367,2472,2473,2477],{},[28,2474,2476],{"href":2475},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-fixed-asset-depreciation-schedule\u002F","Build a Fixed Asset Depreciation Schedule"," — depreciating the asset side.",[2479,2480,2481],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":44,"searchDepth":101,"depth":101,"links":2483},[2484,2485,2486,2487,2488,2489,2490,2491,2492,2493],{"id":36,"depth":101,"text":37},{"id":74,"depth":101,"text":75},{"id":376,"depth":101,"text":377},{"id":726,"depth":101,"text":727},{"id":1530,"depth":101,"text":1531},{"id":2007,"depth":101,"text":2008},{"id":2361,"depth":101,"text":2362},{"id":2406,"depth":101,"text":2407},{"id":2416,"depth":101,"text":2417},{"id":2447,"depth":101,"text":2448},"2026-10-02","Calculate a lease liability and right-of-use asset the way IFRS 16 does, with pandas: discount the payments at the incremental borrowing rate, unwind interest month by month with payments in advance, depreciate the asset straight line, split the liability into current and non-current portions, produce the month's journals and a maturity analysis, and check the opening liability against Excel's PV function.","md",[2498,2500,2502,2504],{"q":2422,"a":2499},"Discount each payment at the monthly rate — for payments in advance the first is undiscounted — and sum them; that is the liability at commencement.",{"q":2428,"a":2501},"Take the closing liability now minus the closing liability twelve months later as current, and the remainder as non-current.",{"q":2434,"a":2503},"PV(rate\u002F12, months, -payment, 0, 1), where the final 1 means payments at the start of each period.",{"q":2443,"a":2505},"It shows undiscounted future payments, which include interest that has not been charged yet.","lease liability schedule python",null,{"breadcrumb":2509},[2510,2512,2515],{"name":2511,"item":183},"Home",{"name":2513,"item":2514},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":2516,"item":30},"Building Finance and Operations Reports in Excel with Python","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule",{"title":2519,"description":2520},"Build a Lease Liability Schedule in Excel with Python","IFRS 16 lease schedule with pandas: present value of payments in advance, monthly interest unwind, right-of-use depreciation, current and non-current split, journals, maturity analysis and a PV check.","build-a-lease-liability-schedule","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-lease-liability-schedule\u002Findex",[2524,2525],"report-layouts","formula-equivalents","how-to","XKTc6bg6_m7ZtIs_o9hIQFOcMpwdIpCCobdHskIBq9c",[2529,2533],{"title":2530,"path":2531,"stem":2532,"children":-1},"Build a Headcount and Attrition Report in Excel with Python","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-headcount-and-attrition-report","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-headcount-and-attrition-report\u002Findex",{"title":2462,"path":2534,"stem":2535,"children":-1},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-loan-amortization-schedule-in-excel","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-loan-amortization-schedule-in-excel\u002Findex",[2537,2539],{"path":2538,"title":2516},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports",{"path":2540,"title":2513},"\u002Fautomating-reporting-workflows",[],[2543,2547,2550,2553,2556,2559],{"path":2544,"title":2545,"kind":2546},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards","Building Multi-Sheet Excel Dashboards","guide",{"path":2548,"title":2549,"kind":2526},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-data-dictionary-sheet-to-an-excel-report","Add a Data Dictionary Sheet to an Excel Report",{"path":2551,"title":2552,"kind":2526},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-kpi-summary-block-to-an-excel-dashboard","Add a KPI Summary Block to an Excel Dashboard",{"path":2554,"title":2555,"kind":2526},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-table-of-contents-sheet-with-hyperlinks-in-excel","Add a Table of Contents Sheet with Hyperlinks in Excel",{"path":2557,"title":2558,"kind":2526},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-slicer-style-filters-to-an-excel-dashboard","Add a Dropdown Filter That Drives an Excel Dashboard",{"path":2560,"title":2561,"kind":2526},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-summary-sheet-to-excel-report-python","Add a Summary Sheet to an Excel Report with Python",1790972121606]