[{"data":1,"prerenderedAt":3049},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments":3,"surround:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments":3016,"ancestors:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments":3024,"children:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments":3028,"related:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments":3029},{"id":4,"title":5,"body":6,"dateModified":2982,"datePublished":2982,"description":2983,"extension":2984,"faq":2985,"keyword":2994,"kind":2995,"meta":2996,"navigation":258,"path":3005,"seo":3006,"slug":3009,"stem":3010,"topics":3011,"type":3014,"__hash__":3015},"docs\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments\u002Findex.md","Allocate Shared Costs Across Departments with Python",{"type":7,"value":8,"toc":2968},"minimark",[9,19,24,56,70,74,77,210,214,217,536,539,543,546,849,853,861,1198,1201,1365,1369,1372,1486,1489,1665,1669,1672,1793,1797,1804,2843,2850,2854,2889,2893,2896,2900,2906,2912,2918,2924,2928,2964],[10,11,12,13,18],"p",{},"Every department P&L has a line for costs it did not choose: a share of the office rent, the IT team, HR, the finance function. How those shared costs are spread changes which departments look profitable, so the method has to be fair, explainable and exactly reproducible. In a spreadsheet the allocation usually lives in a grid of formulas that nobody wants to touch. In Python it is a small table of drivers and a few lines of arithmetic, and the same numbers can be written back to Excel with formulas for review. This page is part of ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002F","Building Finance and Operations Reports",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl xlsxwriter\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47,50,53],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," pandas",[35,51,52],{"class":45}," openpyxl",[35,54,55],{"class":45}," xlsxwriter\n",[10,57,58,61,62,65,66,69],{},[32,59,60],{},"allocation_inputs.xlsx"," has two sheets. ",[32,63,64],{},"Departments"," lists the seven departments for the quarter: four operating departments that serve customers and three service departments (IT, HR, Finance) that serve the others, each with its direct costs and the measures used as drivers: floor area in square metres, headcount, devices supported and finance transactions processed. ",[32,67,68],{},"Pools"," lists the cost pools and the driver each is spread by. Rent is a pool of its own, 84,000 for the quarter; the three service departments' own direct costs are the other pools.",[20,71,73],{"id":72},"choosing-drivers","Choosing drivers",[10,75,76],{},"A driver should be the thing that makes the cost go up. Rent follows floor area; IT support follows devices, more than headcount; HR effort follows headcount; finance effort follows the number of transactions a department generates. A driver that is easy to measure but unrelated to the cost, such as allocating everything by revenue, makes the allocation look precise while shifting cost to whoever sells most.",[78,79,87,88,87,92,87,96,87,104,87,113,87,120,87,124,87,128,87,132,87,136,87,141,87,146,87,150,87,154,87,156,87,159,87,162,87,166,87,168,87,171,87,173,87,176,87,179,87,183,87,185,87,188,87,190,87,193,87,196,87,200,87,202,87,205,87,207],"svg",{"viewBox":80,"role":81,"ariaLabelledBy":82,"xmlns":85,"style":86},"200 0 359 172","img",[83,84],"al-drivers-t","al-drivers-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:359px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[89,90,91],"title",{"id":83},"One driver per cost pool",[93,94,95],"desc",{"id":84},"A table of cost pools, their drivers and the reason. Rent is allocated by floor area because space drives rent. IT by devices because support effort follows devices. HR by headcount. Finance by the number of transactions processed.",[97,98],"rect",{"x":99,"y":100,"width":101,"height":102,"fill":103},"200","0","359","172","#ffffff",[97,105],{"x":106,"y":107,"width":108,"height":109,"rx":100,"fill":110,"stroke":111,"style":112},"216.8","16.0","68.7","28.0","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[114,115,119],"text",{"x":116,"y":117,"style":118},"251.1","35.0","font-size:11px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Pool",[97,121],{"x":122,"y":107,"width":123,"height":109,"rx":100,"fill":110,"stroke":111,"style":112},"285.5","98.4",[114,125,127],{"x":126,"y":117,"style":118},"334.7","Driver",[97,129],{"x":130,"y":107,"width":131,"height":109,"rx":100,"fill":110,"stroke":111,"style":112},"383.9","159.4",[114,133,135],{"x":134,"y":117,"style":118},"463.5","Why",[97,137],{"x":106,"y":138,"width":108,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},"44.0","var(--line,#cdd5e6)","stroke-width:1px",[114,142,145],{"x":116,"y":143,"style":144},"63.0","font-size:11px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Rent",[97,147],{"x":122,"y":138,"width":123,"height":109,"rx":100,"fill":148,"stroke":149,"style":112},"#d9f4f1","var(--teal,#0f9488)",[114,151,153],{"x":126,"y":143,"style":152},"font-size:11px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Floor area",[97,155],{"x":130,"y":138,"width":131,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},[114,157,158],{"x":134,"y":143,"style":144},"space drives the cost",[97,160],{"x":106,"y":161,"width":108,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},"72.0",[114,163,165],{"x":116,"y":164,"style":144},"91.0","IT",[97,167],{"x":122,"y":161,"width":123,"height":109,"rx":100,"fill":148,"stroke":149,"style":112},[114,169,170],{"x":126,"y":164,"style":152},"Devices",[97,172],{"x":130,"y":161,"width":131,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},[114,174,175],{"x":134,"y":164,"style":144},"support follows devices",[97,177],{"x":106,"y":178,"width":108,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},"100.0",[114,180,182],{"x":116,"y":181,"style":144},"119.0","HR",[97,184],{"x":122,"y":178,"width":123,"height":109,"rx":100,"fill":148,"stroke":149,"style":112},[114,186,187],{"x":126,"y":181,"style":152},"Headcount",[97,189],{"x":130,"y":178,"width":131,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},[114,191,192],{"x":134,"y":181,"style":144},"effort follows people",[97,194],{"x":106,"y":195,"width":108,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},"128.0",[114,197,199],{"x":116,"y":198,"style":144},"147.0","Finance",[97,201],{"x":122,"y":195,"width":123,"height":109,"rx":100,"fill":148,"stroke":149,"style":112},[114,203,204],{"x":126,"y":198,"style":152},"Transactions",[97,206],{"x":130,"y":195,"width":131,"height":109,"rx":100,"fill":103,"stroke":139,"style":140},[114,208,209],{"x":134,"y":198,"style":144},"effort follows volume",[20,211,213],{"id":212},"step-1-shares-that-add-up-exactly","Step 1 — Shares that add up exactly",[10,215,216],{},"A department's share of a pool is its driver divided by the total driver. Multiplying the pool by the shares and rounding each result to cents rarely adds back to the pool: three departments of equal size sharing 100.00 get 33.33 each, and a cent disappears. The largest-remainder method fixes that: round everything down to the cent, then hand the missing cents to the departments with the largest fractional remainders:",[25,218,222],{"className":219,"code":220,"language":221,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","import numpy as np\nimport pandas as pd\n\ndef allocate(amount, weights):\n    \"\"\"Split amount across weights in proportion, to the cent, summing exactly to amount.\"\"\"\n    weights = pd.Series(weights, dtype=float)\n    cents = round(amount * 100)\n    raw = cents * weights \u002F weights.sum()\n    floor = np.floor(raw).astype(int)\n    short = cents - floor.sum()\n    order = (raw - floor).sort_values(ascending=False, kind=\"stable\").index[:short]\n    floor[order] += 1\n    return floor \u002F 100\n\nprint(allocate(100.00, {\"A\": 1, \"B\": 1, \"C\": 1}).to_dict())\nprint(allocate(84000.00, {\"Sales\": 310, \"Support\": 180, \"Ops\": 260}).to_dict())\n","python",[32,223,224,240,253,260,273,279,304,326,348,364,380,418,430,444,449,494],{"__ignoreMap":30},[35,225,226,230,234,237],{"class":37,"line":38},[35,227,229],{"class":228},"s-kum","import",[35,231,233],{"class":232},"skGVy"," numpy ",[35,235,236],{"class":228},"as",[35,238,239],{"class":232}," np\n",[35,241,243,245,248,250],{"class":37,"line":242},2,[35,244,229],{"class":228},[35,246,247],{"class":232}," pandas ",[35,249,236],{"class":228},[35,251,252],{"class":232}," pd\n",[35,254,256],{"class":37,"line":255},3,[35,257,259],{"emptyLinePlaceholder":258},true,"\n",[35,261,263,266,270],{"class":37,"line":262},4,[35,264,265],{"class":228},"def",[35,267,269],{"class":268},"s_Opv"," allocate",[35,271,272],{"class":232},"(amount, weights):\n",[35,274,276],{"class":37,"line":275},5,[35,277,278],{"class":45},"    \"\"\"Split amount across weights in proportion, to the cent, summing exactly to amount.\"\"\"\n",[35,280,282,285,288,291,295,297,301],{"class":37,"line":281},6,[35,283,284],{"class":232},"    weights ",[35,286,287],{"class":228},"=",[35,289,290],{"class":232}," pd.Series(weights, ",[35,292,294],{"class":293},"sa561","dtype",[35,296,287],{"class":228},[35,298,300],{"class":299},"sP0c6","float",[35,302,303],{"class":232},")\n",[35,305,307,310,312,315,318,321,324],{"class":37,"line":306},7,[35,308,309],{"class":232},"    cents ",[35,311,287],{"class":228},[35,313,314],{"class":299}," round",[35,316,317],{"class":232},"(amount ",[35,319,320],{"class":228},"*",[35,322,323],{"class":299}," 100",[35,325,303],{"class":232},[35,327,329,332,334,337,339,342,345],{"class":37,"line":328},8,[35,330,331],{"class":232},"    raw ",[35,333,287],{"class":228},[35,335,336],{"class":232}," cents ",[35,338,320],{"class":228},[35,340,341],{"class":232}," weights ",[35,343,344],{"class":228},"\u002F",[35,346,347],{"class":232}," weights.sum()\n",[35,349,351,354,356,359,362],{"class":37,"line":350},9,[35,352,353],{"class":232},"    floor ",[35,355,287],{"class":228},[35,357,358],{"class":232}," np.floor(raw).astype(",[35,360,361],{"class":299},"int",[35,363,303],{"class":232},[35,365,367,370,372,374,377],{"class":37,"line":366},10,[35,368,369],{"class":232},"    short ",[35,371,287],{"class":228},[35,373,336],{"class":232},[35,375,376],{"class":228},"-",[35,378,379],{"class":232}," floor.sum()\n",[35,381,383,386,388,391,393,396,399,401,404,407,410,412,415],{"class":37,"line":382},11,[35,384,385],{"class":232},"    order ",[35,387,287],{"class":228},[35,389,390],{"class":232}," (raw ",[35,392,376],{"class":228},[35,394,395],{"class":232}," floor).sort_values(",[35,397,398],{"class":293},"ascending",[35,400,287],{"class":228},[35,402,403],{"class":299},"False",[35,405,406],{"class":232},", ",[35,408,409],{"class":293},"kind",[35,411,287],{"class":228},[35,413,414],{"class":45},"\"stable\"",[35,416,417],{"class":232},").index[:short]\n",[35,419,421,424,427],{"class":37,"line":420},12,[35,422,423],{"class":232},"    floor[order] ",[35,425,426],{"class":228},"+=",[35,428,429],{"class":299}," 1\n",[35,431,433,436,439,441],{"class":37,"line":432},13,[35,434,435],{"class":228},"    return",[35,437,438],{"class":232}," floor ",[35,440,344],{"class":228},[35,442,443],{"class":299}," 100\n",[35,445,447],{"class":37,"line":446},14,[35,448,259],{"emptyLinePlaceholder":258},[35,450,452,455,458,461,464,467,470,473,475,478,480,482,484,487,489,491],{"class":37,"line":451},15,[35,453,454],{"class":299},"print",[35,456,457],{"class":232},"(allocate(",[35,459,460],{"class":299},"100.00",[35,462,463],{"class":232},", {",[35,465,466],{"class":45},"\"A\"",[35,468,469],{"class":232},": ",[35,471,472],{"class":299},"1",[35,474,406],{"class":232},[35,476,477],{"class":45},"\"B\"",[35,479,469],{"class":232},[35,481,472],{"class":299},[35,483,406],{"class":232},[35,485,486],{"class":45},"\"C\"",[35,488,469],{"class":232},[35,490,472],{"class":299},[35,492,493],{"class":232},"}).to_dict())\n",[35,495,497,499,501,504,506,509,511,514,516,519,521,524,526,529,531,534],{"class":37,"line":496},16,[35,498,454],{"class":299},[35,500,457],{"class":232},[35,502,503],{"class":299},"84000.00",[35,505,463],{"class":232},[35,507,508],{"class":45},"\"Sales\"",[35,510,469],{"class":232},[35,512,513],{"class":299},"310",[35,515,406],{"class":232},[35,517,518],{"class":45},"\"Support\"",[35,520,469],{"class":232},[35,522,523],{"class":299},"180",[35,525,406],{"class":232},[35,527,528],{"class":45},"\"Ops\"",[35,530,469],{"class":232},[35,532,533],{"class":299},"260",[35,535,493],{"class":232},[10,537,538],{},"The results always add to the pool to the cent, which matters when the allocated amounts are posted as journals and the pool account must end at zero.",[20,540,542],{"id":541},"step-2-the-direct-method","Step 2 — The direct method",[10,544,545],{},"The simplest method allocates every pool straight to the operating departments, ignoring that service departments use each other. IT supports HR's laptops, but in the direct method HR's share of IT is simply not charged:",[25,547,549],{"className":219,"code":548,"language":221,"meta":30,"style":30},"depts = pd.read_excel(\"allocation_inputs.xlsx\", sheet_name=\"Departments\").set_index(\"Department\")\npools = pd.read_excel(\"allocation_inputs.xlsx\", sheet_name=\"Pools\")\nservice = depts.index[depts[\"Kind\"] == \"Service\"]\noperating = depts.index[depts[\"Kind\"] == \"Operating\"]\n\npool_amounts = {\"Rent\": 84000.00, **{p: depts.loc[p, \"DirectCost\"] for p in [\"IT\", \"HR\", \"Finance\"]}}\ndriver_of = dict(zip(pools[\"Pool\"], pools[\"Driver\"]))\n\ndirect = pd.DataFrame({\n    pool: allocate(amount, depts.loc[operating, driver_of[pool]])\n    for pool, amount in pool_amounts.items()\n})\ndirect[\"Total allocated\"] = direct.sum(axis=1)\nprint(direct.round(2).to_string())\nprint(\"pools:\", sum(pool_amounts.values()), \" allocated:\", direct[\"Total allocated\"].sum().round(2))\n",[32,550,551,582,604,629,649,653,711,742,746,756,761,774,779,803,816],{"__ignoreMap":30},[35,552,553,556,558,561,564,566,569,571,574,577,580],{"class":37,"line":38},[35,554,555],{"class":232},"depts ",[35,557,287],{"class":228},[35,559,560],{"class":232}," pd.read_excel(",[35,562,563],{"class":45},"\"allocation_inputs.xlsx\"",[35,565,406],{"class":232},[35,567,568],{"class":293},"sheet_name",[35,570,287],{"class":228},[35,572,573],{"class":45},"\"Departments\"",[35,575,576],{"class":232},").set_index(",[35,578,579],{"class":45},"\"Department\"",[35,581,303],{"class":232},[35,583,584,587,589,591,593,595,597,599,602],{"class":37,"line":242},[35,585,586],{"class":232},"pools ",[35,588,287],{"class":228},[35,590,560],{"class":232},[35,592,563],{"class":45},[35,594,406],{"class":232},[35,596,568],{"class":293},[35,598,287],{"class":228},[35,600,601],{"class":45},"\"Pools\"",[35,603,303],{"class":232},[35,605,606,609,611,614,617,620,623,626],{"class":37,"line":255},[35,607,608],{"class":232},"service ",[35,610,287],{"class":228},[35,612,613],{"class":232}," depts.index[depts[",[35,615,616],{"class":45},"\"Kind\"",[35,618,619],{"class":232},"] ",[35,621,622],{"class":228},"==",[35,624,625],{"class":45}," \"Service\"",[35,627,628],{"class":232},"]\n",[35,630,631,634,636,638,640,642,644,647],{"class":37,"line":262},[35,632,633],{"class":232},"operating ",[35,635,287],{"class":228},[35,637,613],{"class":232},[35,639,616],{"class":45},[35,641,619],{"class":232},[35,643,622],{"class":228},[35,645,646],{"class":45}," \"Operating\"",[35,648,628],{"class":232},[35,650,651],{"class":37,"line":275},[35,652,259],{"emptyLinePlaceholder":258},[35,654,655,658,660,663,666,668,670,672,675,678,681,683,686,689,692,695,698,700,703,705,708],{"class":37,"line":281},[35,656,657],{"class":232},"pool_amounts ",[35,659,287],{"class":228},[35,661,662],{"class":232}," {",[35,664,665],{"class":45},"\"Rent\"",[35,667,469],{"class":232},[35,669,503],{"class":299},[35,671,406],{"class":232},[35,673,674],{"class":228},"**",[35,676,677],{"class":232},"{p: depts.loc[p, ",[35,679,680],{"class":45},"\"DirectCost\"",[35,682,619],{"class":232},[35,684,685],{"class":228},"for",[35,687,688],{"class":232}," p ",[35,690,691],{"class":228},"in",[35,693,694],{"class":232}," [",[35,696,697],{"class":45},"\"IT\"",[35,699,406],{"class":232},[35,701,702],{"class":45},"\"HR\"",[35,704,406],{"class":232},[35,706,707],{"class":45},"\"Finance\"",[35,709,710],{"class":232},"]}}\n",[35,712,713,716,718,721,724,727,730,733,736,739],{"class":37,"line":306},[35,714,715],{"class":232},"driver_of ",[35,717,287],{"class":228},[35,719,720],{"class":299}," dict",[35,722,723],{"class":232},"(",[35,725,726],{"class":299},"zip",[35,728,729],{"class":232},"(pools[",[35,731,732],{"class":45},"\"Pool\"",[35,734,735],{"class":232},"], pools[",[35,737,738],{"class":45},"\"Driver\"",[35,740,741],{"class":232},"]))\n",[35,743,744],{"class":37,"line":328},[35,745,259],{"emptyLinePlaceholder":258},[35,747,748,751,753],{"class":37,"line":350},[35,749,750],{"class":232},"direct ",[35,752,287],{"class":228},[35,754,755],{"class":232}," pd.DataFrame({\n",[35,757,758],{"class":37,"line":366},[35,759,760],{"class":232},"    pool: allocate(amount, depts.loc[operating, driver_of[pool]])\n",[35,762,763,766,769,771],{"class":37,"line":382},[35,764,765],{"class":228},"    for",[35,767,768],{"class":232}," pool, amount ",[35,770,691],{"class":228},[35,772,773],{"class":232}," pool_amounts.items()\n",[35,775,776],{"class":37,"line":420},[35,777,778],{"class":232},"})\n",[35,780,781,784,787,789,791,794,797,799,801],{"class":37,"line":432},[35,782,783],{"class":232},"direct[",[35,785,786],{"class":45},"\"Total allocated\"",[35,788,619],{"class":232},[35,790,287],{"class":228},[35,792,793],{"class":232}," direct.sum(",[35,795,796],{"class":293},"axis",[35,798,287],{"class":228},[35,800,472],{"class":299},[35,802,303],{"class":232},[35,804,805,807,810,813],{"class":37,"line":446},[35,806,454],{"class":299},[35,808,809],{"class":232},"(direct.round(",[35,811,812],{"class":299},"2",[35,814,815],{"class":232},").to_string())\n",[35,817,818,820,822,825,827,830,833,836,839,841,844,846],{"class":37,"line":451},[35,819,454],{"class":299},[35,821,723],{"class":232},[35,823,824],{"class":45},"\"pools:\"",[35,826,406],{"class":232},[35,828,829],{"class":299},"sum",[35,831,832],{"class":232},"(pool_amounts.values()), ",[35,834,835],{"class":45},"\" allocated:\"",[35,837,838],{"class":232},", direct[",[35,840,786],{"class":45},[35,842,843],{"class":232},"].sum().round(",[35,845,812],{"class":299},[35,847,848],{"class":232},"))\n",[20,850,852],{"id":851},"step-3-the-step-down-method","Step 3 — The step-down method",[10,854,855,856,860],{},"The step-down (sequential) method recognises that service departments serve each other. Service departments are allocated one at a time, in a fixed order: each spreads its costs, including whatever it has received from earlier steps, over the operating departments ",[857,858,859],"em",{},"and the service departments not yet allocated",". Rent goes first, because every department uses space; then the service department that serves the others most:",[25,862,864],{"className":219,"code":863,"language":221,"meta":30,"style":30},"ORDER = [\"Rent\", \"IT\", \"HR\", \"Finance\"]\nremaining = list(service)                  # service departments still able to receive costs\nbalance = {d: 0.0 for d in depts.index}    # costs received so far\nfor d in service:\n    balance[d] += depts.loc[d, \"DirectCost\"]\n\nsteps = {}\nfor pool in ORDER:\n    if pool == \"Rent\":\n        amount, receivers = 84000.00, list(depts.index)\n    else:\n        amount = round(balance[pool], 2)\n        balance[pool] = 0.0\n        remaining.remove(pool)\n        receivers = list(operating) + remaining\n    shares = allocate(amount, depts.loc[receivers, driver_of[pool]])\n    steps[pool] = shares\n    for d, v in shares.items():\n        balance[d] += v\n\nstep = pd.DataFrame(steps).fillna(0.0)\nprint(step.round(2).to_string())\nleft = {d: round(balance[d], 2) for d in service}\nprint(\"left in service departments:\", left)\n",[32,865,866,892,909,936,947,961,965,975,990,1004,1022,1029,1045,1055,1060,1078,1088,1099,1112,1123,1128,1143,1155,1185],{"__ignoreMap":30},[35,867,868,871,874,876,878,880,882,884,886,888,890],{"class":37,"line":38},[35,869,870],{"class":299},"ORDER",[35,872,873],{"class":228}," =",[35,875,694],{"class":232},[35,877,665],{"class":45},[35,879,406],{"class":232},[35,881,697],{"class":45},[35,883,406],{"class":232},[35,885,702],{"class":45},[35,887,406],{"class":232},[35,889,707],{"class":45},[35,891,628],{"class":232},[35,893,894,897,899,902,905],{"class":37,"line":242},[35,895,896],{"class":232},"remaining ",[35,898,287],{"class":228},[35,900,901],{"class":299}," list",[35,903,904],{"class":232},"(service)                  ",[35,906,908],{"class":907},"s-wDw","# service departments still able to receive costs\n",[35,910,911,914,916,919,922,925,928,930,933],{"class":37,"line":255},[35,912,913],{"class":232},"balance ",[35,915,287],{"class":228},[35,917,918],{"class":232}," {d: ",[35,920,921],{"class":299},"0.0",[35,923,924],{"class":228}," for",[35,926,927],{"class":232}," d ",[35,929,691],{"class":228},[35,931,932],{"class":232}," depts.index}    ",[35,934,935],{"class":907},"# costs received so far\n",[35,937,938,940,942,944],{"class":37,"line":262},[35,939,685],{"class":228},[35,941,927],{"class":232},[35,943,691],{"class":228},[35,945,946],{"class":232}," service:\n",[35,948,949,952,954,957,959],{"class":37,"line":275},[35,950,951],{"class":232},"    balance[d] ",[35,953,426],{"class":228},[35,955,956],{"class":232}," depts.loc[d, ",[35,958,680],{"class":45},[35,960,628],{"class":232},[35,962,963],{"class":37,"line":281},[35,964,259],{"emptyLinePlaceholder":258},[35,966,967,970,972],{"class":37,"line":306},[35,968,969],{"class":232},"steps ",[35,971,287],{"class":228},[35,973,974],{"class":232}," {}\n",[35,976,977,979,982,984,987],{"class":37,"line":328},[35,978,685],{"class":228},[35,980,981],{"class":232}," pool ",[35,983,691],{"class":228},[35,985,986],{"class":299}," ORDER",[35,988,989],{"class":232},":\n",[35,991,992,995,997,999,1002],{"class":37,"line":350},[35,993,994],{"class":228},"    if",[35,996,981],{"class":232},[35,998,622],{"class":228},[35,1000,1001],{"class":45}," \"Rent\"",[35,1003,989],{"class":232},[35,1005,1006,1009,1011,1014,1016,1019],{"class":37,"line":366},[35,1007,1008],{"class":232},"        amount, receivers ",[35,1010,287],{"class":228},[35,1012,1013],{"class":299}," 84000.00",[35,1015,406],{"class":232},[35,1017,1018],{"class":299},"list",[35,1020,1021],{"class":232},"(depts.index)\n",[35,1023,1024,1027],{"class":37,"line":382},[35,1025,1026],{"class":228},"    else",[35,1028,989],{"class":232},[35,1030,1031,1034,1036,1038,1041,1043],{"class":37,"line":420},[35,1032,1033],{"class":232},"        amount ",[35,1035,287],{"class":228},[35,1037,314],{"class":299},[35,1039,1040],{"class":232},"(balance[pool], ",[35,1042,812],{"class":299},[35,1044,303],{"class":232},[35,1046,1047,1050,1052],{"class":37,"line":432},[35,1048,1049],{"class":232},"        balance[pool] ",[35,1051,287],{"class":228},[35,1053,1054],{"class":299}," 0.0\n",[35,1056,1057],{"class":37,"line":446},[35,1058,1059],{"class":232},"        remaining.remove(pool)\n",[35,1061,1062,1065,1067,1069,1072,1075],{"class":37,"line":451},[35,1063,1064],{"class":232},"        receivers ",[35,1066,287],{"class":228},[35,1068,901],{"class":299},[35,1070,1071],{"class":232},"(operating) ",[35,1073,1074],{"class":228},"+",[35,1076,1077],{"class":232}," remaining\n",[35,1079,1080,1083,1085],{"class":37,"line":496},[35,1081,1082],{"class":232},"    shares ",[35,1084,287],{"class":228},[35,1086,1087],{"class":232}," allocate(amount, depts.loc[receivers, driver_of[pool]])\n",[35,1089,1091,1094,1096],{"class":37,"line":1090},17,[35,1092,1093],{"class":232},"    steps[pool] ",[35,1095,287],{"class":228},[35,1097,1098],{"class":232}," shares\n",[35,1100,1102,1104,1107,1109],{"class":37,"line":1101},18,[35,1103,765],{"class":228},[35,1105,1106],{"class":232}," d, v ",[35,1108,691],{"class":228},[35,1110,1111],{"class":232}," shares.items():\n",[35,1113,1115,1118,1120],{"class":37,"line":1114},19,[35,1116,1117],{"class":232},"        balance[d] ",[35,1119,426],{"class":228},[35,1121,1122],{"class":232}," v\n",[35,1124,1126],{"class":37,"line":1125},20,[35,1127,259],{"emptyLinePlaceholder":258},[35,1129,1131,1134,1136,1139,1141],{"class":37,"line":1130},21,[35,1132,1133],{"class":232},"step ",[35,1135,287],{"class":228},[35,1137,1138],{"class":232}," pd.DataFrame(steps).fillna(",[35,1140,921],{"class":299},[35,1142,303],{"class":232},[35,1144,1146,1148,1151,1153],{"class":37,"line":1145},22,[35,1147,454],{"class":299},[35,1149,1150],{"class":232},"(step.round(",[35,1152,812],{"class":299},[35,1154,815],{"class":232},[35,1156,1158,1161,1163,1165,1168,1171,1173,1176,1178,1180,1182],{"class":37,"line":1157},23,[35,1159,1160],{"class":232},"left ",[35,1162,287],{"class":228},[35,1164,918],{"class":232},[35,1166,1167],{"class":299},"round",[35,1169,1170],{"class":232},"(balance[d], ",[35,1172,812],{"class":299},[35,1174,1175],{"class":232},") ",[35,1177,685],{"class":228},[35,1179,927],{"class":232},[35,1181,691],{"class":228},[35,1183,1184],{"class":232}," service}\n",[35,1186,1188,1190,1192,1195],{"class":37,"line":1187},24,[35,1189,454],{"class":299},[35,1191,723],{"class":232},[35,1193,1194],{"class":45},"\"left in service departments:\"",[35,1196,1197],{"class":232},", left)\n",[10,1199,1200],{},"Every service department ends at zero: its own costs and everything it received were passed on. The order matters; a different order gives different answers, so it is a policy that should be written down, usually \"the department that provides the most service to other service departments goes first\".",[78,1202,87,1208,87,1211,87,1214,87,1219,87,1226,87,1237,87,1242,87,1247,87,1252,87,1257,87,1260,87,1267,87,1272,87,1276,87,1280,87,1284,87,1287,87,1290,87,1297,87,1301,87,1303,87,1305,87,1309,87,1312,87,1317,87,1324,87,1328,87,1331,87,1334,87,1338,87,1341,87,1344,87,1350,87,1355,87,1358,87,1361],{"viewBox":1203,"role":81,"ariaLabelledBy":1204,"xmlns":85,"style":1207},"4 0 752 160",[1205,1206],"al-step-t","al-step-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[89,1209,1210],{"id":1205},"The step-down order",[93,1212,1213],{"id":1206},"Rent is allocated first to every department. IT's costs plus its rent share are then allocated to the operating departments and to HR and Finance. HR's costs plus what it received go to the operating departments and Finance. Finance goes last, to the operating departments only.",[97,1215],{"x":1216,"y":100,"width":1217,"height":1218,"fill":103},"4","752","160",[97,1220],{"x":1221,"y":107,"width":1222,"height":195,"rx":1223,"fill":1224,"stroke":139,"style":1225},"20.0","115.2","12","#e7ebef","stroke-width:2px",[1227,1228,1230],"g",{"transform":1229},"translate(65.6,46.5) scale(1.000)",[1231,1232],"path",{"d":1233,"fill":1234,"stroke":1235,"style":1236},"M3 6h6l2 2h10v11H3z","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[114,1238,145],{"x":1239,"y":1240,"style":1241},"77.6","93.0","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle",[114,1243,1246],{"x":1239,"y":1244,"style":1245},"112.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","to all seven",[37,1248],{"x1":1249,"y1":1250,"x2":1251,"y2":1250,"stroke":111,"style":1225},"140.2","80.0","162.2",[1253,1254],"polygon",{"points":1255,"fill":1256},"166.2,80.0 157.2,85.0 157.2,75.0","#5b5cf0",[97,1258],{"x":1259,"y":107,"width":1222,"height":195,"rx":1223,"fill":110,"stroke":111,"style":1225},"171.2",[1227,1261,1263],{"transform":1262},"translate(216.8,37.8) scale(1.000)",[1231,1264],{"d":1265,"fill":1234,"stroke":1266,"style":1236},"M4 4h16v6H4z M4 14h16v6H4z M8 7h.01 M8 17h.01","var(--brand-strong,#4338ca)",[114,1268,165],{"x":1269,"y":1270,"style":1271},"228.8","84.2","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[114,1273,1275],{"x":1269,"y":1274,"style":1245},"103.8","to operating,",[114,1277,1279],{"x":1269,"y":1278,"style":1245},"121.2","HR, Finance",[37,1281],{"x1":1282,"y1":1250,"x2":1283,"y2":1250,"stroke":111,"style":1225},"291.4","313.4",[1253,1285],{"points":1286,"fill":1256},"317.4,80.0 308.4,85.0 308.4,75.0",[97,1288],{"x":1289,"y":107,"width":1222,"height":195,"rx":1223,"fill":148,"stroke":149,"style":1225},"322.4",[1227,1291,1293],{"transform":1292},"translate(368.0,37.8) scale(1.000)",[1231,1294],{"d":1295,"fill":1234,"stroke":1296,"style":1236},"M9 11a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z M2.5 20c0-3.6 2.9-6 6.5-6s6.5 2.4 6.5 6 M16 4.5a3.3 3.3 0 0 1 0 6.3 M18 14.3c2.2.7 3.5 2.8 3.5 5.7","var(--teal-ink,#0b6157)",[114,1298,182],{"x":1299,"y":1270,"style":1300},"380.0","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[114,1302,1275],{"x":1299,"y":1274,"style":1245},[114,1304,199],{"x":1299,"y":1278,"style":1245},[37,1306],{"x1":1307,"y1":1250,"x2":1308,"y2":1250,"stroke":111,"style":1225},"442.6","464.6",[1253,1310],{"points":1311,"fill":1256},"468.6,80.0 459.6,85.0 459.6,75.0",[97,1313],{"x":1314,"y":107,"width":1222,"height":195,"rx":1223,"fill":1315,"stroke":1316,"style":1225},"473.6","#fdefd8","var(--gold,#b4740a)",[1227,1318,1320],{"transform":1319},"translate(519.2,37.8) scale(1.000)",[1231,1321],{"d":1322,"fill":1234,"stroke":1323,"style":1236},"M5 9h14 M4 15h14 M10 4l-2 16 M16 4l-2 16","var(--gold-ink,#7a4e06)",[114,1325,199],{"x":1326,"y":1270,"style":1327},"531.2","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[114,1329,1330],{"x":1326,"y":1274,"style":1245},"to operating",[114,1332,1333],{"x":1326,"y":1278,"style":1245},"only",[37,1335],{"x1":1336,"y1":1250,"x2":1337,"y2":1250,"stroke":111,"style":1225},"593.8","615.8",[1253,1339],{"points":1340,"fill":1256},"619.8,80.0 610.8,85.0 610.8,75.0",[97,1342],{"x":1343,"y":107,"width":1222,"height":195,"rx":1223,"fill":110,"stroke":111,"style":1225},"624.8",[1227,1345,1347],{"transform":1346},"translate(670.4,29.0) scale(1.000)",[1231,1348],{"d":1349,"fill":1234,"stroke":1266,"style":1236},"M5 12.5l4.5 4.5L19 7",[114,1351,1354],{"x":1352,"y":1353,"style":1271},"682.4","75.5","Operating",[114,1356,1357],{"x":1352,"y":1240,"style":1271},"depts",[114,1359,1360],{"x":1352,"y":1244,"style":1245},"carry",[114,1362,1364],{"x":1352,"y":1363,"style":1245},"130.0","everything",[20,1366,1368],{"id":1367},"step-4-compare-the-methods","Step 4 — Compare the methods",[10,1370,1371],{},"The totals must match: both methods allocate exactly the same costs. Which department carries them differs:",[25,1373,1375],{"className":219,"code":1374,"language":221,"meta":30,"style":30},"compare = pd.DataFrame({\n    \"Direct\": direct[\"Total allocated\"],\n    \"Step-down\": step.loc[operating].sum(axis=1),\n})\ncompare[\"Difference\"] = compare[\"Step-down\"] - compare[\"Direct\"]\nprint(compare.round(2).to_string())\nprint(\"totals:\", compare[[\"Direct\", \"Step-down\"]].sum().round(2).to_dict())\n",[32,1376,1377,1386,1399,1416,1420,1449,1460],{"__ignoreMap":30},[35,1378,1379,1382,1384],{"class":37,"line":38},[35,1380,1381],{"class":232},"compare ",[35,1383,287],{"class":228},[35,1385,755],{"class":232},[35,1387,1388,1391,1394,1396],{"class":37,"line":242},[35,1389,1390],{"class":45},"    \"Direct\"",[35,1392,1393],{"class":232},": direct[",[35,1395,786],{"class":45},[35,1397,1398],{"class":232},"],\n",[35,1400,1401,1404,1407,1409,1411,1413],{"class":37,"line":255},[35,1402,1403],{"class":45},"    \"Step-down\"",[35,1405,1406],{"class":232},": step.loc[operating].sum(",[35,1408,796],{"class":293},[35,1410,287],{"class":228},[35,1412,472],{"class":299},[35,1414,1415],{"class":232},"),\n",[35,1417,1418],{"class":37,"line":262},[35,1419,778],{"class":232},[35,1421,1422,1425,1428,1430,1432,1435,1438,1440,1442,1444,1447],{"class":37,"line":275},[35,1423,1424],{"class":232},"compare[",[35,1426,1427],{"class":45},"\"Difference\"",[35,1429,619],{"class":232},[35,1431,287],{"class":228},[35,1433,1434],{"class":232}," compare[",[35,1436,1437],{"class":45},"\"Step-down\"",[35,1439,619],{"class":232},[35,1441,376],{"class":228},[35,1443,1434],{"class":232},[35,1445,1446],{"class":45},"\"Direct\"",[35,1448,628],{"class":232},[35,1450,1451,1453,1456,1458],{"class":37,"line":281},[35,1452,454],{"class":299},[35,1454,1455],{"class":232},"(compare.round(",[35,1457,812],{"class":299},[35,1459,815],{"class":232},[35,1461,1462,1464,1466,1469,1472,1474,1476,1478,1481,1483],{"class":37,"line":306},[35,1463,454],{"class":299},[35,1465,723],{"class":232},[35,1467,1468],{"class":45},"\"totals:\"",[35,1470,1471],{"class":232},", compare[[",[35,1473,1446],{"class":45},[35,1475,406],{"class":232},[35,1477,1437],{"class":45},[35,1479,1480],{"class":232},"]].sum().round(",[35,1482,812],{"class":299},[35,1484,1485],{"class":232},").to_dict())\n",[10,1487,1488],{},"Engineering carries about 1,900 less under step-down, and Sales and Operations about 1,000 more each. Two things move the costs. Rent is now spread over all seven departments, so part of it lands in IT, HR and Finance and from there follows devices, headcount and transactions instead of floor area, and Engineering has the largest floor area. And Finance, which grows from 27,600 to about 35,900 as it receives its shares of rent, IT and HR, is allocated by transactions, which Sales and Operations generate most of. The differences are modest here; they grow when service departments are large and use each other heavily. A third option, the reciprocal method, solves simultaneous equations so that service departments charge each other both ways; it is the most accurate and the hardest to explain, and most businesses settle for step-down.",[78,1490,87,1496,87,1499,87,1502,87,1506,87,1512,87,1518,87,1521,87,1525,87,1530,87,1536,87,1540,87,1544,87,1546,87,1550,87,1553,87,1557,87,1560,87,1564,87,1567,87,1572,87,1576,87,1580,87,1584,87,1590,87,1596,87,1601,87,1606,87,1611,87,1616,87,1620,87,1625,87,1629,87,1635,87,1640,87,1645,87,1650,87,1655,87,1660],{"viewBox":1491,"role":81,"ariaLabelledBy":1492,"xmlns":85,"style":1495},"4 0 748 280",[1493,1494],"al-compare-t","al-compare-d","width:100%;max-width:748px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[89,1497,1498],{"id":1493},"Allocated costs by method, in thousands",[93,1500,1501],{"id":1494},"A column chart comparing the direct and step-down allocations for the four operating departments. Sales 48.9 thousand direct and 50.0 step-down; Engineering 80.7 and 78.8; Support 27.4 and 27.1; Operations 38.3 and 39.3.",[97,1503],{"x":1216,"y":100,"width":1504,"height":1505,"fill":103},"748","280",[97,1507],{"x":1508,"y":1509,"width":1510,"height":1510,"rx":1511,"fill":1224,"stroke":139,"style":112},"64.0","18.0","14.0","3",[114,1513,1517],{"x":1514,"y":1515,"style":1516},"84.0","29.5","font-size:12px;font-weight:600;fill:var(--text,#172033);text-anchor:start","Direct",[97,1519],{"x":1520,"y":1509,"width":1510,"height":1510,"rx":1511,"fill":110,"stroke":111,"style":112},"149.2",[114,1522,1524],{"x":1523,"y":1515,"style":1516},"169.2","Step-down",[37,1526],{"x1":1527,"y1":1528,"x2":1529,"y2":1528,"stroke":139,"style":140},"57.6","242.0","736.0",[114,1531,1535],{"x":1532,"y":1533,"style":1534},"32.8","246.0","font-size:11px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","0k",[37,1537],{"x1":1527,"y1":1538,"x2":1529,"y2":1538,"stroke":139,"style":1539},"194.5","stroke-width:1px;stroke-dasharray:5 4",[114,1541,1543],{"x":1532,"y":1542,"style":1534},"198.5","25k",[37,1545],{"x1":1527,"y1":198,"x2":1529,"y2":198,"stroke":139,"style":1539},[114,1547,1549],{"x":1532,"y":1548,"style":1534},"151.0","50k",[37,1551],{"x1":1527,"y1":1552,"x2":1529,"y2":1552,"stroke":139,"style":1539},"99.5",[114,1554,1556],{"x":1532,"y":1555,"style":1534},"103.5","75k",[37,1558],{"x1":1527,"y1":1559,"x2":1529,"y2":1559,"stroke":139,"style":1539},"52.0",[114,1561,1563],{"x":1532,"y":1562,"style":1534},"56.0","100k",[37,1565],{"x1":1527,"y1":1528,"x2":1529,"y2":1528,"stroke":1566,"style":112},"var(--muted,#5b6780)",[114,1568,1571],{"x":1569,"y":1570,"style":1245},"142.4","260.0","Sales",[114,1573,1575],{"x":1574,"y":1570,"style":1245},"312.0","Engineering",[114,1577,1579],{"x":1578,"y":1570,"style":1245},"481.6","Support",[114,1581,1583],{"x":1582,"y":1570,"style":1245},"651.2","Operations",[97,1585],{"x":1586,"y":1587,"width":1588,"height":1589,"rx":1511,"fill":1224,"stroke":139,"style":112},"105.4","149.1","36.0","92.9",[114,1591,1595],{"x":1592,"y":1593,"style":1594},"123.4","143.1","font-size:10.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","48.9",[97,1597],{"x":1598,"y":1599,"width":1588,"height":1600,"rx":1511,"fill":1224,"stroke":139,"style":112},"275.0","88.7","153.3",[114,1602,1605],{"x":1603,"y":1604,"style":1594},"293.0","82.7","80.7",[97,1607],{"x":1608,"y":1609,"width":1588,"height":1610,"rx":1511,"fill":1224,"stroke":139,"style":112},"444.6","189.9","52.1",[114,1612,1615],{"x":1613,"y":1614,"style":1594},"462.6","183.9","27.4",[97,1617],{"x":1618,"y":1523,"width":1588,"height":1619,"rx":1511,"fill":1224,"stroke":139,"style":112},"614.2","72.8",[114,1621,1624],{"x":1622,"y":1623,"style":1594},"632.2","163.2","38.3",[97,1626],{"x":1627,"y":198,"width":1588,"height":1628,"rx":1511,"fill":110,"stroke":111,"style":112},"143.4","95.0",[114,1630,1634],{"x":1631,"y":1632,"style":1633},"161.4","141.0","font-size:10.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","50",[97,1636],{"x":1637,"y":1638,"width":1588,"height":1639,"rx":1511,"fill":110,"stroke":111,"style":112},"313.0","92.3","149.7",[114,1641,1644],{"x":1642,"y":1643,"style":1633},"331.0","86.3","78.8",[97,1646],{"x":1647,"y":1648,"width":1588,"height":1649,"rx":1511,"fill":110,"stroke":111,"style":112},"482.6","190.5","51.5",[114,1651,1654],{"x":1652,"y":1653,"style":1633},"500.6","184.5","27.1",[97,1656],{"x":1657,"y":1658,"width":1588,"height":1659,"rx":1511,"fill":110,"stroke":111,"style":112},"652.2","167.3","74.7",[114,1661,1664],{"x":1662,"y":1663,"style":1633},"670.2","161.3","39.3",[20,1666,1668],{"id":1667},"step-5-department-results-after-allocation","Step 5 — Department results after allocation",[10,1670,1671],{},"The point of the exercise: each operating department's direct costs plus its allocated share, and for the revenue-earning department, its contribution after overheads:",[25,1673,1675],{"className":219,"code":1674,"language":221,"meta":30,"style":30},"result = depts.loc[operating, [\"Revenue\", \"DirectCost\"]].copy()\nresult[\"Allocated\"] = step.loc[operating].sum(axis=1)\nresult[\"Fully loaded cost\"] = result[\"DirectCost\"] + result[\"Allocated\"]\nresult[\"Allocated % of direct\"] = result[\"Allocated\"] \u002F result[\"DirectCost\"] * 100\nprint(result.round(1).to_string())\n",[32,1676,1677,1697,1720,1746,1782],{"__ignoreMap":30},[35,1678,1679,1682,1684,1687,1690,1692,1694],{"class":37,"line":38},[35,1680,1681],{"class":232},"result ",[35,1683,287],{"class":228},[35,1685,1686],{"class":232}," depts.loc[operating, [",[35,1688,1689],{"class":45},"\"Revenue\"",[35,1691,406],{"class":232},[35,1693,680],{"class":45},[35,1695,1696],{"class":232},"]].copy()\n",[35,1698,1699,1702,1705,1707,1709,1712,1714,1716,1718],{"class":37,"line":242},[35,1700,1701],{"class":232},"result[",[35,1703,1704],{"class":45},"\"Allocated\"",[35,1706,619],{"class":232},[35,1708,287],{"class":228},[35,1710,1711],{"class":232}," step.loc[operating].sum(",[35,1713,796],{"class":293},[35,1715,287],{"class":228},[35,1717,472],{"class":299},[35,1719,303],{"class":232},[35,1721,1722,1724,1727,1729,1731,1734,1736,1738,1740,1742,1744],{"class":37,"line":255},[35,1723,1701],{"class":232},[35,1725,1726],{"class":45},"\"Fully loaded cost\"",[35,1728,619],{"class":232},[35,1730,287],{"class":228},[35,1732,1733],{"class":232}," result[",[35,1735,680],{"class":45},[35,1737,619],{"class":232},[35,1739,1074],{"class":228},[35,1741,1733],{"class":232},[35,1743,1704],{"class":45},[35,1745,628],{"class":232},[35,1747,1748,1750,1753,1757,1760,1762,1764,1766,1768,1770,1772,1774,1776,1778,1780],{"class":37,"line":262},[35,1749,1701],{"class":232},[35,1751,1752],{"class":45},"\"Allocated ",[35,1754,1756],{"class":1755},"sSjpA","% o",[35,1758,1759],{"class":45},"f direct\"",[35,1761,619],{"class":232},[35,1763,287],{"class":228},[35,1765,1733],{"class":232},[35,1767,1704],{"class":45},[35,1769,619],{"class":232},[35,1771,344],{"class":228},[35,1773,1733],{"class":232},[35,1775,680],{"class":45},[35,1777,619],{"class":232},[35,1779,320],{"class":228},[35,1781,443],{"class":299},[35,1783,1784,1786,1789,1791],{"class":37,"line":275},[35,1785,454],{"class":299},[35,1787,1788],{"class":232},"(result.round(",[35,1790,472],{"class":299},[35,1792,815],{"class":232},[20,1794,1796],{"id":1795},"step-6-write-the-workbook-with-formulas","Step 6 — Write the workbook with formulas",[10,1798,1799,1800,1803],{},"Finance will want to see how each number was produced. Write the drivers and pools as inputs, and the direct-method allocation as formulas that read them, ",[32,1801,1802],{},"pool × driver \u002F SUM(drivers)",". The step-down results are written as values from Python, with the order and receivers documented beside them:",[25,1805,1807],{"className":219,"code":1806,"language":221,"meta":30,"style":30},"import xlsxwriter\nfrom xlsxwriter.utility import xl_rowcol_to_cell, xl_col_to_name\n\nwb = xlsxwriter.Workbook(\"cost_allocation_q3.xlsx\")\nmoney = wb.add_format({\"num_format\": \"#,##0.00\"})\nhead = wb.add_format({\"bold\": True, \"bg_color\": \"#EEF2FF\", \"bottom\": 1})\n\ninp = wb.add_worksheet(\"Inputs\")\ncols = [\"FloorArea\", \"Devices\", \"Headcount\", \"Transactions\"]\ninp.write_row(0, 0, [\"Department\"] + cols, head)\nfor r, d in enumerate(operating, start=1):\n    inp.write(r, 0, d)\n    for c, col in enumerate(cols, start=1):\n        inp.write_number(r, c, float(depts.loc[d, col]))\ninp.write_row(len(operating) + 3, 0, [\"Pool\", \"Amount\", \"Driver column\"], head)\nfor i, (pool, amount) in enumerate(pool_amounts.items()):\n    r = len(operating) + 4 + i\n    inp.write(r, 0, pool)\n    inp.write_number(r, 1, amount, money)\n    inp.write(r, 2, driver_of[pool])\ninp.set_column(0, 4, 14)\n\nout = wb.add_worksheet(\"Direct method\")\nout.write_row(0, 0, [\"Department\"] + list(pool_amounts) + [\"Total\"], head)\nn = len(operating)\nfor r, d in enumerate(operating, start=1):\n    out.write(r, 0, d)\n    for c, pool in enumerate(pool_amounts, start=1):\n        dcol = xl_col_to_name(1 + cols.index(driver_of[pool]))\n        amount_cell = \"Inputs!\" + xl_rowcol_to_cell(n + 4 + c - 1, 1, row_abs=True, col_abs=True)\n        out.write_formula(r, c, f\"=ROUND({amount_cell}*Inputs!{dcol}{r + 1}\u002FSUM(Inputs!{dcol}$2:{dcol}${n + 1}),2)\", money)\n    out.write_formula(r, len(pool_amounts) + 1, f\"=SUM(B{r + 1}:{xl_col_to_name(len(pool_amounts))}{r + 1})\", money)\nout.write(n + 1, 0, \"Total\", head)\nfor c in range(1, len(pool_amounts) + 2):\n    out.write_formula(n + 1, c, f\"=SUM({xl_col_to_name(c)}2:{xl_col_to_name(c)}{n + 1})\", money)\nout.set_column(0, 5, 14)\n\nsd = wb.add_worksheet(\"Step-down\")\nsd.write(0, 0, \"Order: \" + \" → \".join(ORDER) + \". Each service department allocates to operating departments and to service departments later in the order.\")\nsd.write_row(2, 0, [\"Department\"] + ORDER + [\"Total\"], head)\nfor r, d in enumerate(step.index, start=3):\n    sd.write(r, 0, d)\n    for c, pool in enumerate(ORDER, start=1):\n        sd.write_number(r, c, float(step.loc[d, pool]), money)\n    sd.write_formula(r, len(ORDER) + 1, f\"=SUM(B{r + 1}:E{r + 1})\", money)\nsd.set_column(0, 5, 14)\nwb.close()\nprint(\"written\")\n",[32,1808,1809,1815,1828,1832,1847,1867,1905,1909,1924,1953,1976,2001,2011,2033,2043,2078,2092,2115,2124,2134,2143,2161,2165,2179,2212,2225,2246,2256,2279,2297,2351,2429,2488,2509,2538,2584,2603,2608,2622,2658,2688,2710,2720,2745,2756,2807,2825,2831],{"__ignoreMap":30},[35,1810,1811,1813],{"class":37,"line":38},[35,1812,229],{"class":228},[35,1814,55],{"class":232},[35,1816,1817,1820,1823,1825],{"class":37,"line":242},[35,1818,1819],{"class":228},"from",[35,1821,1822],{"class":232}," xlsxwriter.utility ",[35,1824,229],{"class":228},[35,1826,1827],{"class":232}," xl_rowcol_to_cell, xl_col_to_name\n",[35,1829,1830],{"class":37,"line":255},[35,1831,259],{"emptyLinePlaceholder":258},[35,1833,1834,1837,1839,1842,1845],{"class":37,"line":262},[35,1835,1836],{"class":232},"wb ",[35,1838,287],{"class":228},[35,1840,1841],{"class":232}," xlsxwriter.Workbook(",[35,1843,1844],{"class":45},"\"cost_allocation_q3.xlsx\"",[35,1846,303],{"class":232},[35,1848,1849,1852,1854,1857,1860,1862,1865],{"class":37,"line":275},[35,1850,1851],{"class":232},"money ",[35,1853,287],{"class":228},[35,1855,1856],{"class":232}," wb.add_format({",[35,1858,1859],{"class":45},"\"num_format\"",[35,1861,469],{"class":232},[35,1863,1864],{"class":45},"\"#,##0.00\"",[35,1866,778],{"class":232},[35,1868,1869,1872,1874,1876,1879,1881,1884,1886,1889,1891,1894,1896,1899,1901,1903],{"class":37,"line":281},[35,1870,1871],{"class":232},"head ",[35,1873,287],{"class":228},[35,1875,1856],{"class":232},[35,1877,1878],{"class":45},"\"bold\"",[35,1880,469],{"class":232},[35,1882,1883],{"class":299},"True",[35,1885,406],{"class":232},[35,1887,1888],{"class":45},"\"bg_color\"",[35,1890,469],{"class":232},[35,1892,1893],{"class":45},"\"#EEF2FF\"",[35,1895,406],{"class":232},[35,1897,1898],{"class":45},"\"bottom\"",[35,1900,469],{"class":232},[35,1902,472],{"class":299},[35,1904,778],{"class":232},[35,1906,1907],{"class":37,"line":306},[35,1908,259],{"emptyLinePlaceholder":258},[35,1910,1911,1914,1916,1919,1922],{"class":37,"line":328},[35,1912,1913],{"class":232},"inp ",[35,1915,287],{"class":228},[35,1917,1918],{"class":232}," wb.add_worksheet(",[35,1920,1921],{"class":45},"\"Inputs\"",[35,1923,303],{"class":232},[35,1925,1926,1929,1931,1933,1936,1938,1941,1943,1946,1948,1951],{"class":37,"line":350},[35,1927,1928],{"class":232},"cols ",[35,1930,287],{"class":228},[35,1932,694],{"class":232},[35,1934,1935],{"class":45},"\"FloorArea\"",[35,1937,406],{"class":232},[35,1939,1940],{"class":45},"\"Devices\"",[35,1942,406],{"class":232},[35,1944,1945],{"class":45},"\"Headcount\"",[35,1947,406],{"class":232},[35,1949,1950],{"class":45},"\"Transactions\"",[35,1952,628],{"class":232},[35,1954,1955,1958,1960,1962,1964,1967,1969,1971,1973],{"class":37,"line":366},[35,1956,1957],{"class":232},"inp.write_row(",[35,1959,100],{"class":299},[35,1961,406],{"class":232},[35,1963,100],{"class":299},[35,1965,1966],{"class":232},", [",[35,1968,579],{"class":45},[35,1970,619],{"class":232},[35,1972,1074],{"class":228},[35,1974,1975],{"class":232}," cols, head)\n",[35,1977,1978,1980,1983,1985,1988,1991,1994,1996,1998],{"class":37,"line":382},[35,1979,685],{"class":228},[35,1981,1982],{"class":232}," r, d ",[35,1984,691],{"class":228},[35,1986,1987],{"class":299}," enumerate",[35,1989,1990],{"class":232},"(operating, ",[35,1992,1993],{"class":293},"start",[35,1995,287],{"class":228},[35,1997,472],{"class":299},[35,1999,2000],{"class":232},"):\n",[35,2002,2003,2006,2008],{"class":37,"line":420},[35,2004,2005],{"class":232},"    inp.write(r, ",[35,2007,100],{"class":299},[35,2009,2010],{"class":232},", d)\n",[35,2012,2013,2015,2018,2020,2022,2025,2027,2029,2031],{"class":37,"line":432},[35,2014,765],{"class":228},[35,2016,2017],{"class":232}," c, col ",[35,2019,691],{"class":228},[35,2021,1987],{"class":299},[35,2023,2024],{"class":232},"(cols, ",[35,2026,1993],{"class":293},[35,2028,287],{"class":228},[35,2030,472],{"class":299},[35,2032,2000],{"class":232},[35,2034,2035,2038,2040],{"class":37,"line":446},[35,2036,2037],{"class":232},"        inp.write_number(r, c, ",[35,2039,300],{"class":299},[35,2041,2042],{"class":232},"(depts.loc[d, col]))\n",[35,2044,2045,2047,2050,2052,2054,2057,2059,2061,2063,2065,2067,2070,2072,2075],{"class":37,"line":451},[35,2046,1957],{"class":232},[35,2048,2049],{"class":299},"len",[35,2051,1071],{"class":232},[35,2053,1074],{"class":228},[35,2055,2056],{"class":299}," 3",[35,2058,406],{"class":232},[35,2060,100],{"class":299},[35,2062,1966],{"class":232},[35,2064,732],{"class":45},[35,2066,406],{"class":232},[35,2068,2069],{"class":45},"\"Amount\"",[35,2071,406],{"class":232},[35,2073,2074],{"class":45},"\"Driver column\"",[35,2076,2077],{"class":232},"], head)\n",[35,2079,2080,2082,2085,2087,2089],{"class":37,"line":496},[35,2081,685],{"class":228},[35,2083,2084],{"class":232}," i, (pool, amount) ",[35,2086,691],{"class":228},[35,2088,1987],{"class":299},[35,2090,2091],{"class":232},"(pool_amounts.items()):\n",[35,2093,2094,2097,2099,2102,2104,2106,2109,2112],{"class":37,"line":1090},[35,2095,2096],{"class":232},"    r ",[35,2098,287],{"class":228},[35,2100,2101],{"class":299}," len",[35,2103,1071],{"class":232},[35,2105,1074],{"class":228},[35,2107,2108],{"class":299}," 4",[35,2110,2111],{"class":228}," +",[35,2113,2114],{"class":232}," i\n",[35,2116,2117,2119,2121],{"class":37,"line":1101},[35,2118,2005],{"class":232},[35,2120,100],{"class":299},[35,2122,2123],{"class":232},", pool)\n",[35,2125,2126,2129,2131],{"class":37,"line":1114},[35,2127,2128],{"class":232},"    inp.write_number(r, ",[35,2130,472],{"class":299},[35,2132,2133],{"class":232},", amount, money)\n",[35,2135,2136,2138,2140],{"class":37,"line":1125},[35,2137,2005],{"class":232},[35,2139,812],{"class":299},[35,2141,2142],{"class":232},", driver_of[pool])\n",[35,2144,2145,2148,2150,2152,2154,2156,2159],{"class":37,"line":1130},[35,2146,2147],{"class":232},"inp.set_column(",[35,2149,100],{"class":299},[35,2151,406],{"class":232},[35,2153,1216],{"class":299},[35,2155,406],{"class":232},[35,2157,2158],{"class":299},"14",[35,2160,303],{"class":232},[35,2162,2163],{"class":37,"line":1145},[35,2164,259],{"emptyLinePlaceholder":258},[35,2166,2167,2170,2172,2174,2177],{"class":37,"line":1157},[35,2168,2169],{"class":232},"out ",[35,2171,287],{"class":228},[35,2173,1918],{"class":232},[35,2175,2176],{"class":45},"\"Direct method\"",[35,2178,303],{"class":232},[35,2180,2181,2184,2186,2188,2190,2192,2194,2196,2198,2200,2203,2205,2207,2210],{"class":37,"line":1187},[35,2182,2183],{"class":232},"out.write_row(",[35,2185,100],{"class":299},[35,2187,406],{"class":232},[35,2189,100],{"class":299},[35,2191,1966],{"class":232},[35,2193,579],{"class":45},[35,2195,619],{"class":232},[35,2197,1074],{"class":228},[35,2199,901],{"class":299},[35,2201,2202],{"class":232},"(pool_amounts) ",[35,2204,1074],{"class":228},[35,2206,694],{"class":232},[35,2208,2209],{"class":45},"\"Total\"",[35,2211,2077],{"class":232},[35,2213,2215,2218,2220,2222],{"class":37,"line":2214},25,[35,2216,2217],{"class":232},"n ",[35,2219,287],{"class":228},[35,2221,2101],{"class":299},[35,2223,2224],{"class":232},"(operating)\n",[35,2226,2228,2230,2232,2234,2236,2238,2240,2242,2244],{"class":37,"line":2227},26,[35,2229,685],{"class":228},[35,2231,1982],{"class":232},[35,2233,691],{"class":228},[35,2235,1987],{"class":299},[35,2237,1990],{"class":232},[35,2239,1993],{"class":293},[35,2241,287],{"class":228},[35,2243,472],{"class":299},[35,2245,2000],{"class":232},[35,2247,2249,2252,2254],{"class":37,"line":2248},27,[35,2250,2251],{"class":232},"    out.write(r, ",[35,2253,100],{"class":299},[35,2255,2010],{"class":232},[35,2257,2259,2261,2264,2266,2268,2271,2273,2275,2277],{"class":37,"line":2258},28,[35,2260,765],{"class":228},[35,2262,2263],{"class":232}," c, pool ",[35,2265,691],{"class":228},[35,2267,1987],{"class":299},[35,2269,2270],{"class":232},"(pool_amounts, ",[35,2272,1993],{"class":293},[35,2274,287],{"class":228},[35,2276,472],{"class":299},[35,2278,2000],{"class":232},[35,2280,2282,2285,2287,2290,2292,2294],{"class":37,"line":2281},29,[35,2283,2284],{"class":232},"        dcol ",[35,2286,287],{"class":228},[35,2288,2289],{"class":232}," xl_col_to_name(",[35,2291,472],{"class":299},[35,2293,2111],{"class":228},[35,2295,2296],{"class":232}," cols.index(driver_of[pool]))\n",[35,2298,2300,2303,2305,2308,2310,2313,2315,2317,2319,2322,2324,2327,2329,2331,2333,2336,2338,2340,2342,2345,2347,2349],{"class":37,"line":2299},30,[35,2301,2302],{"class":232},"        amount_cell ",[35,2304,287],{"class":228},[35,2306,2307],{"class":45}," \"Inputs!\"",[35,2309,2111],{"class":228},[35,2311,2312],{"class":232}," xl_rowcol_to_cell(n ",[35,2314,1074],{"class":228},[35,2316,2108],{"class":299},[35,2318,2111],{"class":228},[35,2320,2321],{"class":232}," c ",[35,2323,376],{"class":228},[35,2325,2326],{"class":299}," 1",[35,2328,406],{"class":232},[35,2330,472],{"class":299},[35,2332,406],{"class":232},[35,2334,2335],{"class":293},"row_abs",[35,2337,287],{"class":228},[35,2339,1883],{"class":299},[35,2341,406],{"class":232},[35,2343,2344],{"class":293},"col_abs",[35,2346,287],{"class":228},[35,2348,1883],{"class":299},[35,2350,303],{"class":232},[35,2352,2354,2357,2360,2363,2366,2369,2372,2375,2377,2380,2383,2386,2388,2390,2392,2395,2397,2399,2401,2404,2406,2408,2410,2413,2415,2417,2419,2421,2423,2426],{"class":37,"line":2353},31,[35,2355,2356],{"class":232},"        out.write_formula(r, c, ",[35,2358,2359],{"class":228},"f",[35,2361,2362],{"class":45},"\"=ROUND(",[35,2364,2365],{"class":1755},"{",[35,2367,2368],{"class":232},"amount_cell",[35,2370,2371],{"class":1755},"}",[35,2373,2374],{"class":45},"*Inputs!",[35,2376,2365],{"class":1755},[35,2378,2379],{"class":232},"dcol",[35,2381,2382],{"class":1755},"}{",[35,2384,2385],{"class":232},"r ",[35,2387,1074],{"class":228},[35,2389,2326],{"class":299},[35,2391,2371],{"class":1755},[35,2393,2394],{"class":45},"\u002FSUM(Inputs!",[35,2396,2365],{"class":1755},[35,2398,2379],{"class":232},[35,2400,2371],{"class":1755},[35,2402,2403],{"class":45},"$2:",[35,2405,2365],{"class":1755},[35,2407,2379],{"class":232},[35,2409,2371],{"class":1755},[35,2411,2412],{"class":45},"$",[35,2414,2365],{"class":1755},[35,2416,2217],{"class":232},[35,2418,1074],{"class":228},[35,2420,2326],{"class":299},[35,2422,2371],{"class":1755},[35,2424,2425],{"class":45},"),2)\"",[35,2427,2428],{"class":232},", money)\n",[35,2430,2432,2435,2437,2439,2441,2443,2445,2447,2450,2452,2454,2456,2458,2460,2463,2465,2468,2470,2473,2475,2477,2479,2481,2483,2486],{"class":37,"line":2431},32,[35,2433,2434],{"class":232},"    out.write_formula(r, ",[35,2436,2049],{"class":299},[35,2438,2202],{"class":232},[35,2440,1074],{"class":228},[35,2442,2326],{"class":299},[35,2444,406],{"class":232},[35,2446,2359],{"class":228},[35,2448,2449],{"class":45},"\"=SUM(B",[35,2451,2365],{"class":1755},[35,2453,2385],{"class":232},[35,2455,1074],{"class":228},[35,2457,2326],{"class":299},[35,2459,2371],{"class":1755},[35,2461,2462],{"class":45},":",[35,2464,2365],{"class":1755},[35,2466,2467],{"class":232},"xl_col_to_name(",[35,2469,2049],{"class":299},[35,2471,2472],{"class":232},"(pool_amounts))",[35,2474,2382],{"class":1755},[35,2476,2385],{"class":232},[35,2478,1074],{"class":228},[35,2480,2326],{"class":299},[35,2482,2371],{"class":1755},[35,2484,2485],{"class":45},")\"",[35,2487,2428],{"class":232},[35,2489,2491,2494,2496,2498,2500,2502,2504,2506],{"class":37,"line":2490},33,[35,2492,2493],{"class":232},"out.write(n ",[35,2495,1074],{"class":228},[35,2497,2326],{"class":299},[35,2499,406],{"class":232},[35,2501,100],{"class":299},[35,2503,406],{"class":232},[35,2505,2209],{"class":45},[35,2507,2508],{"class":232},", head)\n",[35,2510,2512,2514,2516,2518,2521,2523,2525,2527,2529,2531,2533,2536],{"class":37,"line":2511},34,[35,2513,685],{"class":228},[35,2515,2321],{"class":232},[35,2517,691],{"class":228},[35,2519,2520],{"class":299}," range",[35,2522,723],{"class":232},[35,2524,472],{"class":299},[35,2526,406],{"class":232},[35,2528,2049],{"class":299},[35,2530,2202],{"class":232},[35,2532,1074],{"class":228},[35,2534,2535],{"class":299}," 2",[35,2537,2000],{"class":232},[35,2539,2541,2544,2546,2548,2551,2553,2556,2558,2561,2563,2566,2568,2570,2572,2574,2576,2578,2580,2582],{"class":37,"line":2540},35,[35,2542,2543],{"class":232},"    out.write_formula(n ",[35,2545,1074],{"class":228},[35,2547,2326],{"class":299},[35,2549,2550],{"class":232},", c, ",[35,2552,2359],{"class":228},[35,2554,2555],{"class":45},"\"=SUM(",[35,2557,2365],{"class":1755},[35,2559,2560],{"class":232},"xl_col_to_name(c)",[35,2562,2371],{"class":1755},[35,2564,2565],{"class":45},"2:",[35,2567,2365],{"class":1755},[35,2569,2560],{"class":232},[35,2571,2382],{"class":1755},[35,2573,2217],{"class":232},[35,2575,1074],{"class":228},[35,2577,2326],{"class":299},[35,2579,2371],{"class":1755},[35,2581,2485],{"class":45},[35,2583,2428],{"class":232},[35,2585,2587,2590,2592,2594,2597,2599,2601],{"class":37,"line":2586},36,[35,2588,2589],{"class":232},"out.set_column(",[35,2591,100],{"class":299},[35,2593,406],{"class":232},[35,2595,2596],{"class":299},"5",[35,2598,406],{"class":232},[35,2600,2158],{"class":299},[35,2602,303],{"class":232},[35,2604,2606],{"class":37,"line":2605},37,[35,2607,259],{"emptyLinePlaceholder":258},[35,2609,2611,2614,2616,2618,2620],{"class":37,"line":2610},38,[35,2612,2613],{"class":232},"sd ",[35,2615,287],{"class":228},[35,2617,1918],{"class":232},[35,2619,1437],{"class":45},[35,2621,303],{"class":232},[35,2623,2625,2628,2630,2632,2634,2636,2639,2641,2644,2647,2649,2651,2653,2656],{"class":37,"line":2624},39,[35,2626,2627],{"class":232},"sd.write(",[35,2629,100],{"class":299},[35,2631,406],{"class":232},[35,2633,100],{"class":299},[35,2635,406],{"class":232},[35,2637,2638],{"class":45},"\"Order: \"",[35,2640,2111],{"class":228},[35,2642,2643],{"class":45}," \" → \"",[35,2645,2646],{"class":232},".join(",[35,2648,870],{"class":299},[35,2650,1175],{"class":232},[35,2652,1074],{"class":228},[35,2654,2655],{"class":45}," \". Each service department allocates to operating departments and to service departments later in the order.\"",[35,2657,303],{"class":232},[35,2659,2661,2664,2666,2668,2670,2672,2674,2676,2678,2680,2682,2684,2686],{"class":37,"line":2660},40,[35,2662,2663],{"class":232},"sd.write_row(",[35,2665,812],{"class":299},[35,2667,406],{"class":232},[35,2669,100],{"class":299},[35,2671,1966],{"class":232},[35,2673,579],{"class":45},[35,2675,619],{"class":232},[35,2677,1074],{"class":228},[35,2679,986],{"class":299},[35,2681,2111],{"class":228},[35,2683,694],{"class":232},[35,2685,2209],{"class":45},[35,2687,2077],{"class":232},[35,2689,2691,2693,2695,2697,2699,2702,2704,2706,2708],{"class":37,"line":2690},41,[35,2692,685],{"class":228},[35,2694,1982],{"class":232},[35,2696,691],{"class":228},[35,2698,1987],{"class":299},[35,2700,2701],{"class":232},"(step.index, ",[35,2703,1993],{"class":293},[35,2705,287],{"class":228},[35,2707,1511],{"class":299},[35,2709,2000],{"class":232},[35,2711,2713,2716,2718],{"class":37,"line":2712},42,[35,2714,2715],{"class":232},"    sd.write(r, ",[35,2717,100],{"class":299},[35,2719,2010],{"class":232},[35,2721,2723,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743],{"class":37,"line":2722},43,[35,2724,765],{"class":228},[35,2726,2263],{"class":232},[35,2728,691],{"class":228},[35,2730,1987],{"class":299},[35,2732,723],{"class":232},[35,2734,870],{"class":299},[35,2736,406],{"class":232},[35,2738,1993],{"class":293},[35,2740,287],{"class":228},[35,2742,472],{"class":299},[35,2744,2000],{"class":232},[35,2746,2748,2751,2753],{"class":37,"line":2747},44,[35,2749,2750],{"class":232},"        sd.write_number(r, c, ",[35,2752,300],{"class":299},[35,2754,2755],{"class":232},"(step.loc[d, pool]), money)\n",[35,2757,2759,2762,2764,2766,2768,2770,2772,2774,2776,2778,2780,2782,2784,2786,2788,2790,2793,2795,2797,2799,2801,2803,2805],{"class":37,"line":2758},45,[35,2760,2761],{"class":232},"    sd.write_formula(r, ",[35,2763,2049],{"class":299},[35,2765,723],{"class":232},[35,2767,870],{"class":299},[35,2769,1175],{"class":232},[35,2771,1074],{"class":228},[35,2773,2326],{"class":299},[35,2775,406],{"class":232},[35,2777,2359],{"class":228},[35,2779,2449],{"class":45},[35,2781,2365],{"class":1755},[35,2783,2385],{"class":232},[35,2785,1074],{"class":228},[35,2787,2326],{"class":299},[35,2789,2371],{"class":1755},[35,2791,2792],{"class":45},":E",[35,2794,2365],{"class":1755},[35,2796,2385],{"class":232},[35,2798,1074],{"class":228},[35,2800,2326],{"class":299},[35,2802,2371],{"class":1755},[35,2804,2485],{"class":45},[35,2806,2428],{"class":232},[35,2808,2810,2813,2815,2817,2819,2821,2823],{"class":37,"line":2809},46,[35,2811,2812],{"class":232},"sd.set_column(",[35,2814,100],{"class":299},[35,2816,406],{"class":232},[35,2818,2596],{"class":299},[35,2820,406],{"class":232},[35,2822,2158],{"class":299},[35,2824,303],{"class":232},[35,2826,2828],{"class":37,"line":2827},47,[35,2829,2830],{"class":232},"wb.close()\n",[35,2832,2834,2836,2838,2841],{"class":37,"line":2833},48,[35,2835,454],{"class":299},[35,2837,723],{"class":232},[35,2839,2840],{"class":45},"\"written\"",[35,2842,303],{"class":232},[10,2844,2845,2846,2849],{},"The formula version uses Excel's ",[32,2847,2848],{},"ROUND"," per cell, so it can differ from the pool total by a cent, and here it does: recalculated, the IT column adds up to 52,499.99, because Operations' share rounds to 6,273.58 where the largest-remainder allocation gave it the missing cent, 6,273.59. That is the reason to post the Python figures and keep the formulas as an explanation. The note in the step-down sheet records the order, because without it the numbers cannot be reproduced.",[20,2851,2853],{"id":2852},"common-pitfalls","Common pitfalls",[2855,2856,2857,2865,2871,2877,2883],"ul",{},[2858,2859,2860,2864],"li",{},[2861,2862,2863],"strong",{},"Rounding that does not tie out."," Round each share independently and totals drift by cents; use largest-remainder allocation.",[2858,2866,2867,2870],{},[2861,2868,2869],{},"Undocumented order."," Step-down results depend on the order of service departments; record it with the report.",[2858,2872,2873,2876],{},[2861,2874,2875],{},"Allocating to the department itself."," A service department's own driver share is excluded when it allocates its costs.",[2858,2878,2879,2882],{},[2861,2880,2881],{},"Stale drivers."," Floor plans and device counts change; date the driver table and refresh it each period.",[2858,2884,2885,2888],{},[2861,2886,2887],{},"Drivers that do not drive cost."," Revenue-based allocations penalise growth and hide which departments actually consume the service.",[20,2890,2892],{"id":2891},"conclusion","Conclusion",[10,2894,2895],{},"Pick one driver per cost pool that reflects what makes the cost rise, split each pool with largest-remainder rounding so it ties out to the cent, and choose between the direct method and the step-down method, which passes service departments' costs through each other in a documented order. Compare the methods, show fully loaded costs by operating department, and write an Excel workbook whose inputs and formulas let finance trace every number.",[20,2897,2899],{"id":2898},"frequently-asked-questions","Frequently asked questions",[10,2901,2902,2905],{},[2861,2903,2904],{},"How do I allocate costs by percentage in pandas?","\nDivide each department's driver by the total driver to get its share, multiply by the cost pool, and round with a largest-remainder method so the rounded amounts still add up to the pool.",[10,2907,2908,2911],{},[2861,2909,2910],{},"What is the difference between the direct and step-down methods?","\nThe direct method allocates service department costs only to operating departments. The step-down method allocates service departments one at a time, including to service departments later in the sequence, so their use of each other is partly recognised.",[10,2913,2914,2917],{},[2861,2915,2916],{},"Why don't my allocated amounts add up to the total?","\nBecause each amount was rounded independently. Round down to the cent, then give the leftover cents to the departments with the largest remainders.",[10,2919,2920,2923],{},[2861,2921,2922],{},"What drivers should I use for overhead allocation?","\nUse a measure that causes the cost: floor area for rent, devices or users for IT, headcount for HR, transactions for finance. Document the choice and review it yearly.",[20,2925,2927],{"id":2926},"related","Related",[2855,2929,2930,2936,2943,2950,2957],{},[2858,2931,2932,2933,2935],{},"Up one level: ",[14,2934,17],{"href":16}," — the rest of the finance reports.",[2858,2937,2938,2942],{},[14,2939,2941],{"href":2940},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-profit-and-loss-statement-from-a-general-ledger\u002F","Build a Profit and Loss Statement from a General Ledger"," — the statement these costs land in.",[2858,2944,2945,2949],{},[14,2946,2948],{"href":2947},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-budget-vs-actual-variance-report\u002F","Build a Budget vs Actual Variance Report"," — comparing allocated costs with budget.",[2858,2951,2952,2956],{},[14,2953,2955],{"href":2954},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-headcount-and-attrition-report\u002F","Build a Headcount and Attrition Report"," — the source of the headcount driver.",[2858,2958,2959,2963],{},[14,2960,2962],{"href":2961},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fcalculate-percent-of-total-per-group-in-pandas\u002F","Calculate Percent of Total per Group in pandas"," — the share calculation on its own.",[2965,2966,2967],"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 .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}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":30,"searchDepth":242,"depth":242,"links":2969},[2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981],{"id":22,"depth":242,"text":23},{"id":72,"depth":242,"text":73},{"id":212,"depth":242,"text":213},{"id":541,"depth":242,"text":542},{"id":851,"depth":242,"text":852},{"id":1367,"depth":242,"text":1368},{"id":1667,"depth":242,"text":1668},{"id":1795,"depth":242,"text":1796},{"id":2852,"depth":242,"text":2853},{"id":2891,"depth":242,"text":2892},{"id":2898,"depth":242,"text":2899},{"id":2926,"depth":242,"text":2927},"2026-09-29","Spread rent, IT, HR and finance costs over the departments that use them: choose a driver per cost pool, calculate shares, allocate with rounding that still adds up to the cent, compare the direct method with the step-down method for service departments, and write an allocation workbook with formulas finance can audit.","md",[2986,2988,2990,2992],{"q":2904,"a":2987},"Divide each department's driver by the total driver to get its share, multiply by the cost pool, and round with a largest-remainder method so the rounded amounts still add up to the pool.",{"q":2910,"a":2989},"The direct method allocates service department costs only to operating departments. The step-down method allocates service departments one at a time, including to service departments later in the sequence, so their use of each other is partly recognised.",{"q":2916,"a":2991},"Because each amount was rounded independently. Round down to the cent, then give the leftover cents to the departments with the largest remainders.",{"q":2922,"a":2993},"Use a measure that causes the cost: floor area for rent, devices or users for IT, headcount for HR, transactions for finance. Document the choice and review it yearly.","allocate shared costs across departments",null,{"breadcrumb":2997},[2998,3000,3003],{"name":2999,"item":344},"Home",{"name":3001,"item":3002},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":3004,"item":16},"Building Finance and Operations Reports in Excel with Python","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments",{"title":3007,"description":3008},"Allocate Shared Costs to Departments in Python (Step-Down)","Allocate overhead cost pools to departments with pandas: drivers such as floor area and headcount, largest-remainder rounding so totals tie out, direct vs step-down allocation of service departments, department P&L, Excel with formulas.","allocate-shared-costs-across-departments","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments\u002Findex",[3012,3013],"report-layouts","pivots-and-summaries","how-to","oKqVCPKkig_XvwbqgXUDua48mlJWxpTeAo4Xpd8m79o",[3017,3020],{"title":3004,"path":3018,"stem":3019,"children":-1},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Findex",{"title":3021,"path":3022,"stem":3023,"children":-1},"Build a Bank Reconciliation Report with Python and Excel","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bank-reconciliation-report","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bank-reconciliation-report\u002Findex",[3025,3026],{"path":3018,"title":3004},{"path":3027,"title":3001},"\u002Fautomating-reporting-workflows",[],[3030,3034,3037,3040,3043,3046],{"path":3031,"title":3032,"kind":3033},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards","Building Multi-Sheet Excel Dashboards","guide",{"path":3035,"title":3036,"kind":3014},"\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":3038,"title":3039,"kind":3014},"\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":3041,"title":3042,"kind":3014},"\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":3044,"title":3045,"kind":3014},"\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":3047,"title":3048,"kind":3014},"\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",1790972119188]