Skip to main content سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill budget-variance-analyzerيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... datadrivenconstruction
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
فتح مستودع GitHub المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name budget-variance-analyzer description Analyze construction budget variances. Compare estimated vs actual costs, identify trends, forecast final costs, and generate variance reports for cost control. homepage https://datadrivenconstruction.io metadata {"openclaw":{"emoji":"💵","os":["darwin","linux","win32"],"homepage":"https://datadrivenconstruction.io","requires":{"bins":"[Truncated]"}}}
Budget Variance Analyzer
Overview
Analyze construction budget variances between estimated and actual costs. Track cost performance by category, identify concerning trends, forecast final costs, and provide actionable insights for cost control.
Variance Analysis Framework
┌─────────────────────────────────────────────────────────────────┐
│ BUDGET VARIANCE ANALYSIS │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Budget vs Actual = Variance → Forecast │
│ ────── ────── ──────── ──────── │
│ 📋 Original 💰 Spent 📊 Over/Under 🔮 EAC │
│ 📝 Revised 📈 Committed 📉 Trend 📋 ETC │
│ 🎯 Baseline 🧾 Invoiced ⚠️ Alerts 📊 VAC │
│ │
│ EAC = Estimate at Completion │
│ ETC = Estimate to Complete │
│ VAC = Variance at Completion │
│ │
└─────────────────────────────────────────────────────────────────┘
Technical Implementation
from dataclasses import dataclass, field
from typing import List , Dict , Optional , Tuple
from datetime import datetime, timedelta
from enum import Enum
import statistics
class CostCategory (Enum ):
LABOR = "labor"
MATERIALS = "materials"
EQUIPMENT = "equipment"
SUBCONTRACTOR = "subcontractor"
GENERAL_CONDITIONS = "general_conditions"
OVERHEAD = "overhead"
CONTINGENCY = "contingency"
FEE = "fee"
class VarianceStatus (Enum ):
ON_BUDGET = "on_budget"
UNDER_BUDGET = "under_budget"
OVER_BUDGET = "over_budget"
CRITICAL = "critical"
@dataclass
class CostCode :
code: str
description: str
category: CostCategory
original_budget: float
revised_budget: float = 0.0
committed: float = 0.0
actual: float = 0.0
forecast: float = 0.0
percent_complete: float = 0.0
@property
( ) -> :
.revised_budget .revised_budget .original_budget
( ) -> :
.budget - .actual
( ) -> :
( .variance / .budget * ) .budget
( ) -> :
.budget - .committed
( ) -> :
.percent_complete >= :
.forecast - .actual
( ) -> :
.budget - .forecast
:
date: datetime
cost_code:
actual:
committed:
forecast:
:
report_date: datetime
project_name:
total_budget:
total_actual:
total_committed:
total_forecast:
variance:
variance_percent:
eac:
etc:
vac:
variances_by_category: [ , ]
critical_items: [CostCode]
trend:
:
VARIANCE_THRESHOLDS = {
: ,
: ,
: - ,
: -
}
( ):
.project_name = project_name
.original_budget = original_budget
.cost_codes: [ , CostCode] = {}
.snapshots: [CostSnapshot] = []
.contingency_used =
( ) -> CostCode:
cost_code = CostCode(
code=code,
description=description,
category=category,
original_budget=budget,
revised_budget=budget,
forecast=budget
)
.cost_codes[code] = cost_code
cost_code
( ) -> :
count =
item items:
.add_cost_code(
item[ ],
item[ ],
CostCategory(item.get( , )),
item[ ]
)
count +=
count
( ) -> CostCode:
code .cost_codes:
ValueError( )
cost_code = .cost_codes[code]
cost_code.actual = actual
._record_snapshot(code)
cost_code
( ) -> CostCode:
code .cost_codes:
ValueError( )
cost_code = .cost_codes[code]
cost_code.committed = committed
committed > cost_code.forecast:
cost_code.forecast = committed
._record_snapshot(code)
cost_code
( ) -> CostCode:
code .cost_codes:
ValueError( )
cost_code = .cost_codes[code]
cost_code.forecast = forecast
percent_complete :
cost_code.percent_complete = percent_complete
._record_snapshot(code)
cost_code
( ) -> CostCode:
code .cost_codes:
ValueError( )
cost_code = .cost_codes[code]
cost_code.revised_budget = new_budget
cost_code.forecast = new_budget
cost_code
( ) -> :
.contingency_used += amount
target_code .cost_codes:
cc = .cost_codes[target_code]
cc.revised_budget += amount
.contingency_used
( ):
code .cost_codes:
cc = .cost_codes[code]
snapshot = CostSnapshot(
date=datetime.now(),
cost_code=code,
actual=cc.actual,
committed=cc.committed,
forecast=cc.forecast
)
.snapshots.append(snapshot)
( ) -> VarianceStatus:
variance_percent >= .VARIANCE_THRESHOLDS[ ]:
VarianceStatus.UNDER_BUDGET
variance_percent >= .VARIANCE_THRESHOLDS[ ]:
VarianceStatus.ON_BUDGET
variance_percent >= .VARIANCE_THRESHOLDS[ ]:
VarianceStatus.OVER_BUDGET
:
VarianceStatus.CRITICAL
( ) -> [ , ]:
by_category = {}
category CostCategory:
codes = [cc cc .cost_codes.values()
cc.category == category]
codes:
budget = (cc.budget cc codes)
actual = (cc.actual cc codes)
committed = (cc.committed cc codes)
forecast = (cc.forecast cc codes)
variance = budget - actual
variance_pct = (variance / budget * ) budget
by_category[category.value] = {
: budget,
: actual,
: committed,
: forecast,
: variance,
: variance_pct,
: .get_variance_status(variance_pct / ).value
}
by_category
( ) -> [CostCode]:
critical = []
cc .cost_codes.values():
variance_pct = cc.variance_percent /
variance_pct < threshold:
critical.append(cc)
(critical, key= x: x.variance_percent)
( ) -> :
total_budget = (cc.budget * cc.percent_complete /
cc .cost_codes.values())
total_actual = (cc.actual cc .cost_codes.values())
total_actual == :
total_budget / total_actual
( ) -> :
total_budget = (cc.budget cc .cost_codes.values())
total_actual = (cc.actual cc .cost_codes.values())
method == :
cpi = .calculate_cpi()
cpi == :
total_budget
total_actual + (total_budget - total_actual * cpi) / cpi
method == :
(cc.forecast cc .cost_codes.values())
method == :
( (cc.committed, cc.actual) cc .cost_codes.values())
total_budget
( ) -> :
code:
snapshots = [s s .snapshots s.cost_code == code]
:
snapshots = .snapshots
(snapshots) < :
{ : , : }
weekly_actuals = {}
s snapshots:
week = s.date.isocalendar()[ ]
week weekly_actuals:
weekly_actuals[week] = []
weekly_actuals[week].append(s.actual)
weeks = (weekly_actuals.keys())
(weeks) < :
{ : , : }
week_avgs = [statistics.mean(weekly_actuals[w]) w weeks]
n = (weeks)
x_mean = ( (n)) / n
y_mean = (week_avgs) / n
numerator = ((i - x_mean) * (week_avgs[i] - y_mean) i (n))
denominator = ((i - x_mean) ** i (n))
slope = numerator / denominator denominator
slope > :
trend =
slope > :
trend =
slope < - :
trend =
slope < :
trend =
:
trend =
{ : trend, : slope, : (snapshots)}
( ) -> VarianceReport:
total_budget = (cc.budget cc .cost_codes.values())
total_actual = (cc.actual cc .cost_codes.values())
total_committed = (cc.committed cc .cost_codes.values())
total_forecast = (cc.forecast cc .cost_codes.values())
variance = total_budget - total_actual
variance_pct = (variance / total_budget * ) total_budget
eac = .forecast_eac()
etc = eac - total_actual
vac = total_budget - eac
trend_analysis = .analyze_trend()
VarianceReport(
report_date=datetime.now(),
project_name= .project_name,
total_budget=total_budget,
total_actual=total_actual,
total_committed=total_committed,
total_forecast=total_forecast,
variance=variance,
variance_percent=variance_pct,
eac=eac,
etc=etc,
vac=vac,
variances_by_category= .analyze_by_category(),
critical_items= .identify_critical_items(),
trend=trend_analysis[ ]
)
( ) -> :
lines = [
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
]
cat, data report.variances_by_category.items():
status_icon = data[ ] == data[ ] ==
lines.append(
)
report.critical_items:
lines.extend([
,
,
,
,
])
cc report.critical_items[: ]:
lines.append(
)
.join(lines)
Quick Start
analyzer = BudgetVarianceAnalyzer("Office Tower" , 5000000 )
analyzer.add_cost_code("01-100" , "Project Management" , CostCategory.GENERAL_CONDITIONS, 150000 )
analyzer.add_cost_code("03-100" , "Concrete" , CostCategory.MATERIALS, 400000 )
analyzer.add_cost_code("05-100" , "Structural Steel" , CostCategory.SUBCONTRACTOR, 800000 )
analyzer.add_cost_code("15-100" , "Mechanical" , CostCategory.SUBCONTRACTOR, 600000 )
analyzer.add_cost_code("16-100" , "Electrical" , CostCategory.SUBCONTRACTOR, 450000 )
analyzer.update_actual("01-100" , 120000 )
analyzer.update_actual("03-100" , 380000 )
analyzer.update_actual("05-100" , 850000 )
analyzer.update_actual("15-100" , 300000 )
analyzer.update_actual("16-100" , 200000 )
analyzer.update_committed("05-100" , 900000 )
analyzer.update_forecast("05-100" , 920000 , percent_complete=85 )
cpi = analyzer.calculate_cpi()
print (f"Cost Performance Index: {cpi:.2 f} " )
critical = analyzer.identify_critical_items()
print (f"Critical items: " )
report = analyzer.generate_variance_report()
(analyzer.generate_report_markdown(report))
Requirements
pip install (no external dependencies)
def
budget
self
float
return
self
if
self
else
self
@property
def
variance
self
float
return
self
self
@property
def
variance_percent
self
float
return
self
self
100
if
self
else
0
@property
def
committed_variance
self
float
return
self
self
@property
def
estimate_to_complete
self
float
if
self
100
return
0
return
self
self
@property
def
variance_at_completion
self
float
return
self
self
@dataclass
class
CostSnapshot
str
float
float
float
@dataclass
class
VarianceReport
str
float
float
float
float
float
float
float
float
float
Dict
str
Dict
List
str
class
BudgetVarianceAnalyzer
"""Analyze construction budget variances."""
"under_budget"
0.05
"on_budget"
0.00
"over_budget"
0.05
"critical"
0.10
def
__init__
self, project_name: str , original_budget: float
self
self
self
Dict
str
self
List
self
0.0
def
add_cost_code
self, code: str , description: str ,
category: CostCategory, budget: float
"""Add cost code to budget."""
self
return
def
import_budget
self, items: List [Dict ]
int
"""Import budget from list of items."""
0
for
in
self
'code'
'description'
'category'
'other'
'budget'
1
return
def
update_actual
self, code: str , actual: float
"""Update actual cost for cost code."""
if
not
in
self
raise
f"Cost code {code} not found"
self
self
return
def
update_committed
self, code: str , committed: float
"""Update committed cost (contracts, POs)."""
if
not
in
self
raise
f"Cost code {code} not found"
self
if
self
return
def
update_forecast
self, code: str , forecast: float ,
percent_complete: float = None
"""Update forecast for cost code."""
if
not
in
self
raise
f"Cost code {code} not found"
self
if
is
not
None
self
return
def
revise_budget
self, code: str , new_budget: float ,
reason: str = ""
"""Revise budget for cost code."""
if
not
in
self
raise
f"Cost code {code} not found"
self
return
def
use_contingency
self, amount: float , target_code: str ,
reason: str = ""
float
"""Use contingency to cover variance."""
self
if
in
self
self
return
self
def
_record_snapshot
self, code: str
"""Record cost snapshot for trending."""
if
not
in
self
return
self
self
def
get_variance_status
self, variance_percent: float
"""Determine variance status."""
if
self
"under_budget"
return
elif
self
"over_budget"
return
elif
self
"critical"
return
else
return
def
analyze_by_category
self
Dict
str
Dict
"""Analyze variances by cost category."""
for
in
for
in
self
if
if
not
continue
sum
for
in
sum
for
in
sum
for
in
sum
for
in
100
if
else
0
"budget"
"actual"
"committed"
"forecast"
"variance"
"variance_percent"
"status"
self
100
return
def
identify_critical_items
self, threshold: float = -0.10
List
"""Identify cost codes with critical variance."""
for
in
self
100
if
return
sorted
lambda
def
calculate_cpi
self
float
"""Calculate Cost Performance Index."""
sum
100
for
in
self
sum
for
in
self
if
0
return
1.0
return
def
forecast_eac
self, method: str = "cpi"
float
"""Forecast Estimate at Completion."""
sum
for
in
self
sum
for
in
self
if
"cpi"
self
if
0
return
return
elif
"forecast"
return
sum
for
in
self
elif
"committed"
return
sum
max
for
in
self
return
def
analyze_trend
self, code: str = None
Dict
"""Analyze variance trend over time."""
if
for
in
self
if
else
self
if
len
2
return
"trend"
"insufficient_data"
"slope"
0
for
in
1
if
not
in
sorted
if
len
2
return
"trend"
"insufficient_data"
"slope"
0
for
in
len
sum
range
sum
sum
for
in
range
sum
2
for
in
range
if
else
0
if
1000
"increasing_rapidly"
elif
0
"increasing"
elif
1000
"decreasing_rapidly"
elif
0
"decreasing"
else
"stable"
return
"trend"
"slope"
"data_points"
len
def
generate_variance_report
self
"""Generate comprehensive variance report."""
sum
for
in
self
sum
for
in
self
sum
for
in
self
sum
for
in
self
100
if
else
0
self
self
return
self
self
self
"trend"
def
generate_report_markdown
self, report: VarianceReport
str
"""Generate markdown report."""
"# Budget Variance Report"
""
f"**Project:** {report.project_name} "
f"**Report Date:** {report.report_date.strftime('%Y-%m-%d' )} "
""
"## Executive Summary"
""
f"| Metric | Amount |"
f"|--------|--------|"
f"| Total Budget | ${report.total_budget:,.0 f} |"
f"| Actual to Date | ${report.total_actual:,.0 f} |"
f"| Committed | ${report.total_committed:,.0 f} |"
f"| **Variance** | **${report.variance:,.0 f} ({report.variance_percent:.1 f} %)** |"
""
"## Forecast"
""
f"| Metric | Amount |"
f"|--------|--------|"
f"| Estimate at Completion (EAC) | ${report.eac:,.0 f} |"
f"| Estimate to Complete (ETC) | ${report.etc:,.0 f} |"
f"| Variance at Completion (VAC) | ${report.vac:,.0 f} |"
f"| CPI | {self.calculate_cpi():.2 f} |"
f"| Trend | {report.trend} |"
""
"## By Category"
""
"| Category | Budget | Actual | Variance | Status |"
"|----------|--------|--------|----------|--------|"
for
in
"🟢"
if
"status"
"under_budget"
else
"🟡"
if
"status"
"on_budget"
else
"🔴"
f"| {cat} | ${data['budget' ]:,.0 f} | ${data['actual' ]:,.0 f} | "
f"${data['variance' ]:,.0 f} ({data['variance_percent' ]:.1 f} %) | {status_icon} |"
if
""
"## Critical Items (>10% Over Budget)"
""
"| Code | Description | Budget | Actual | Variance |"
"|------|-------------|--------|--------|----------|"
for
in
10
f"| {cc.code} | {cc.description[:25 ]} | ${cc.budget:,.0 f} | "
f"${cc.actual:,.0 f} | ${cc.variance:,.0 f} ({cc.variance_percent:.1 f} %) |"
return
"\n"
{len (critical)}
print