| name | cwicr-cost-calculator |
| description | Calculate construction costs using DDC CWICR resource-based methodology. Break down costs into labor, materials, equipment with transparent pricing. |
| homepage | https://datadrivenconstruction.io |
| metadata | {"openclaw":{"emoji":"💰","os":["darwin","linux","win32"],"homepage":"https://datadrivenconstruction.io","requires":{"bins":["python3"]}}} |
CWICR Cost Calculator
Business Case
Problem Statement
Traditional cost estimation often produces "black box" estimates with hidden markups. Stakeholders need:
- Transparent cost breakdowns
- Traceable pricing logic
- Auditable calculations
- Resource-level detail
Solution
Resource-based cost calculation using CWICR methodology that separates physical norms (labor hours, material quantities) from volatile prices, enabling transparent and auditable estimates.
Business Value
- Full transparency - Every cost component visible
- Auditable - Traceable calculation logic
- Flexible - Update prices without changing norms
- Accurate - Based on 55,000+ validated work items
Technical Implementation
Prerequisites
pip install pandas numpy
Python Implementation
import pandas as pd
import numpy as np
from typing import Dict, Any, List, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum
from datetime import datetime
class CostComponent(Enum):
"""Cost breakdown components."""
LABOR = "labor"
MATERIAL = "material"
EQUIPMENT = "equipment"
OVERHEAD = "overhead"
PROFIT = "profit"
TOTAL = "total"
class CostStatus(Enum):
"""Cost calculation status."""
CALCULATED = "calculated"
ESTIMATED = "estimated"
MISSING_DATA = "missing_data"
ERROR = "error"
@dataclass
class CostBreakdown:
"""Detailed cost breakdown for a work item."""
work_item_code: str
description: str
unit: str
quantity: float
labor_cost: float = 0.0
material_cost: float = 0.0
equipment_cost: float =
overhead_cost: =
profit_cost: =
unit_price: =
total_cost: =
labor_hours: =
labor_rate: =
resources: [[, ]] = field(default_factory=)
status: CostStatus = CostStatus.CALCULATED
() -> [, ]:
{
: .work_item_code,
: .description,
: .unit,
: .quantity,
: .labor_cost,
: .material_cost,
: .equipment_cost,
: .overhead_cost,
: .profit_cost,
: .total_cost,
: .status.value
}
:
total_cost:
labor_total:
material_total:
equipment_total:
overhead_total:
profit_total:
item_count:
currency:
calculated_at: datetime
breakdown_by_category: [, ] = field(default_factory=)
:
DEFAULT_OVERHEAD_RATE =
DEFAULT_PROFIT_RATE =
():
.data = cwicr_data
.overhead_rate = overhead_rate .DEFAULT_OVERHEAD_RATE
.profit_rate = profit_rate .DEFAULT_PROFIT_RATE
.currency = currency
._index_data()
():
.data.columns:
._code_index = .data.set_index()
:
._code_index =
() -> CostBreakdown:
._code_index work_item_code ._code_index.index:
item = ._code_index.loc[work_item_code]
:
matches = .data[
.data[]..contains(work_item_code, =, na=)
]
matches.empty:
CostBreakdown(
work_item_code=work_item_code,
description=,
unit=,
quantity=quantity,
status=CostStatus.MISSING_DATA
)
item = matches.iloc[]
labor_unit = (item.get(, ) )
material_unit = (item.get(, ) )
equipment_unit = (item.get(, ) )
price_overrides:
price_overrides:
labor_norm = (item.get(, ) )
labor_unit = labor_norm * price_overrides[]
price_overrides:
material_unit *= price_overrides[]
price_overrides:
equipment_unit *= price_overrides[]
labor_cost = labor_unit * quantity
material_cost = material_unit * quantity
equipment_cost = equipment_unit * quantity
direct_cost = labor_cost + material_cost + equipment_cost
overhead_cost = direct_cost * .overhead_rate
profit_cost = (direct_cost + overhead_cost) * .profit_rate
total_cost = direct_cost + overhead_cost + profit_cost
unit_price = total_cost / quantity quantity >
CostBreakdown(
work_item_code=work_item_code,
description=(item.get(, )),
unit=(item.get(, )),
quantity=quantity,
labor_cost=labor_cost,
material_cost=material_cost,
equipment_cost=equipment_cost,
overhead_cost=overhead_cost,
profit_cost=profit_cost,
unit_price=unit_price,
total_cost=total_cost,
labor_hours=(item.get(, ) ) * quantity,
labor_rate=(item.get(, ) ),
status=CostStatus.CALCULATED
)
() -> CostSummary:
breakdowns = []
item items:
code = item.get() item.get()
qty = item.get(, )
overrides = item.get()
breakdown = .calculate_item_cost(code, qty, overrides)
breakdowns.append(breakdown)
labor_total = (b.labor_cost b breakdowns)
material_total = (b.material_cost b breakdowns)
equipment_total = (b.equipment_cost b breakdowns)
overhead_total = (b.overhead_cost b breakdowns)
profit_total = (b.profit_cost b breakdowns)
total_cost = (b.total_cost b breakdowns)
breakdown_by_category = {}
group_by_category:
b breakdowns:
category = b.work_item_code.split()[] b.work_item_code
category breakdown_by_category:
breakdown_by_category[category] =
breakdown_by_category[category] += b.total_cost
CostSummary(
total_cost=total_cost,
labor_total=labor_total,
material_total=material_total,
equipment_total=equipment_total,
overhead_total=overhead_total,
profit_total=profit_total,
item_count=(breakdowns),
currency=.currency,
calculated_at=datetime.now(),
breakdown_by_category=breakdown_by_category
)
() -> pd.DataFrame:
results = []
_, row qto_df.iterrows():
code = row[code_column]
qty = row[quantity_column]
breakdown = .calculate_item_cost(code, qty)
result = breakdown.to_dict()
col qto_df.columns:
col result:
result[] = row[col]
results.append(result)
pd.DataFrame(results)
() -> pd.DataFrame:
adjusted = base_costs.copy()
adjusted.columns region_factors:
adjusted[] *= region_factors[]
adjusted.columns region_factors:
adjusted[] *= region_factors[]
adjusted.columns region_factors:
adjusted[] *= region_factors[]
adjusted[] = (
adjusted.get(, ) +
adjusted.get(, ) +
adjusted.get(, )
)
adjusted[] = adjusted[] * ( + .overhead_rate) * ( + .profit_rate)
adjusted
() -> [, ]:
{
: estimate2.total_cost - estimate1.total_cost,
: (
(estimate2.total_cost - estimate1.total_cost) /
estimate1.total_cost * estimate1.total_cost >
),
: estimate2.labor_total - estimate1.labor_total,
: estimate2.material_total - estimate1.material_total,
: estimate2.equipment_total - estimate1.equipment_total,
: estimate2.item_count - estimate1.item_count
}
:
():
.calculator = calculator
() -> [, ]:
summary = .calculator.calculate_estimate(items)
{
: datetime.now().isoformat(),
: summary.currency,
: (summary.total_cost, ),
: {
: (summary.labor_total, ),
: (summary.material_total, ),
: (summary.equipment_total, ),
: (summary.overhead_total, ),
: (summary.profit_total, )
},
: {
: (summary.labor_total / summary.total_cost * , ) summary.total_cost > ,
: (summary.material_total / summary.total_cost * , ) summary.total_cost > ,
: (summary.equipment_total / summary.total_cost * , ) summary.total_cost > ,
},
: summary.item_count,
: summary.breakdown_by_category
}
() -> pd.DataFrame:
results = []
item items:
code = item.get() item.get()
qty = item.get(, )
breakdown = .calculator.calculate_item_cost(code, qty)
results.append(breakdown.to_dict())
df = pd.DataFrame(results)
totals = df[[, , ,
, , ]].()
totals[] =
totals[] =
df = pd.concat([df, pd.DataFrame([totals])], ignore_index=)
df
() -> :
calc = CWICRCostCalculator(cwicr_data)
breakdown = calc.calculate_item_cost(work_item_code, quantity)
breakdown.total_cost
() -> [, ]:
calc = CWICRCostCalculator(cwicr_data)
report = CostReportGenerator(calc)
report.generate_summary_report(items)
Quick Start
import pandas as pd
from cwicr_data_loader import CWICRDataLoader
loader = CWICRDataLoader()
cwicr = loader.load("ddc_cwicr_en.parquet")
calc = CWICRCostCalculator(cwicr)
breakdown = calc.calculate_item_cost("CONC-001", quantity=150)
print(f"Total: ${breakdown.total_cost:,.2f}")
print(f" Labor: ${breakdown.labor_cost:,.2f}")
print(f" Material: ${breakdown.material_cost:,.2f}")
print(f" Equipment: ${breakdown.equipment_cost:,.2f}")
Common Use Cases
1. Project Estimate
items = [
{'work_item_code': 'CONC-001', 'quantity': 150},
{'work_item_code': 'EXCV-002', 'quantity': 200},
{'work_item_code': 'REBAR-003', 'quantity': 15000}
]
summary = calc.calculate_estimate(items)
print(f"Project Total: ${summary.total_cost:,.2f}")
2. QTO Integration
qto = pd.read_excel("quantities.xlsx")
costs = calc.calculate_from_qto(qto,
code_column='work_item',
quantity_column='quantity'
)
print(costs[['description', 'quantity', 'total_cost']])
3. Regional Adjustment
berlin_factors = {
'labor': 1.15,
'material': 0.95,
'equipment': 1.0
}
adjusted = calc.apply_regional_factors(costs, berlin_factors)
Resources