Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -48,7 +48,7 @@ def generate_plot(planned_cost, actual_spend, forecast_cost):
|
|
| 48 |
fig, ax = plt.subplots(figsize=(8, 6))
|
| 49 |
categories = ['Planned Cost', 'Actual Spend', 'Forecasted Cost']
|
| 50 |
values = [planned_cost, actual_spend, forecast_cost]
|
| 51 |
-
ax.bar(categories, values, color=['#1f77b4', '#ff7f0e', '#2ca02c'])
|
| 52 |
ax.set_title("Budget Overview", fontsize=14, pad=15)
|
| 53 |
ax.set_ylabel("Amount ($)", fontsize=12)
|
| 54 |
ax.tick_params(axis='x', rotation=45)
|
|
@@ -64,7 +64,6 @@ def generate_plot(planned_cost, actual_spend, forecast_cost):
|
|
| 64 |
buf_gradio = io.BytesIO()
|
| 65 |
plt.savefig(buf_gradio, format='png', bbox_inches='tight', dpi=100)
|
| 66 |
buf_gradio.seek(0)
|
| 67 |
-
# Convert BytesIO to PIL Image for Gradio
|
| 68 |
gradio_image = Image.open(buf_gradio)
|
| 69 |
|
| 70 |
# Save plot to a temporary file for PDF generation
|
|
@@ -147,7 +146,8 @@ def predict_risk(planned_cost, actual_spend, category, cement_index, labor_index
|
|
| 147 |
|
| 148 |
# Placeholder for risk calculation logic (simplified for demo)
|
| 149 |
total_risk = 1 if actual_spend > planned_cost else 0
|
| 150 |
-
|
|
|
|
| 151 |
insights = "High risk of overrun" if total_risk == 1 else "Low risk of overrun"
|
| 152 |
status = "Critical" if total_risk == 1 else "Healthy"
|
| 153 |
top_causes = []
|
|
@@ -159,7 +159,7 @@ def predict_risk(planned_cost, actual_spend, category, cement_index, labor_index
|
|
| 159 |
top_causes.append("Labor Index Deviation")
|
| 160 |
top_causes = ", ".join(top_causes) if top_causes else "None"
|
| 161 |
|
| 162 |
-
logger.debug(f"Calculation results: total_risk={total_risk}, forecast_cost={forecast_cost}, "
|
| 163 |
f"insights={insights}, status={status}, top_causes={top_causes}")
|
| 164 |
|
| 165 |
# Prepare data for Salesforce
|
|
@@ -170,7 +170,7 @@ def predict_risk(planned_cost, actual_spend, category, cement_index, labor_index
|
|
| 170 |
"Cement_Index__c": cement_index,
|
| 171 |
"Labor_Index__c": labor_index,
|
| 172 |
"Project_Phase__c": project_phase,
|
| 173 |
-
"Risk_Score__c": total_risk * 100,
|
| 174 |
"Forecasted_Cost__c": forecast_cost,
|
| 175 |
"Insights__c": insights,
|
| 176 |
"Status__c": status
|
|
@@ -221,12 +221,13 @@ def predict_risk(planned_cost, actual_spend, category, cement_index, labor_index
|
|
| 221 |
# Generate Excel file
|
| 222 |
excel_file = generate_excel(planned_cost, actual_spend, forecast_cost, total_risk, insights, status, top_causes, forecast_cost_eur)
|
| 223 |
|
| 224 |
-
# Format the output for Gradio
|
| 225 |
risk_level = "High" if total_risk == 1 else "Low"
|
| 226 |
output_text = (
|
| 227 |
f"Risk Summary\n"
|
| 228 |
f"----------------------------------------\n"
|
| 229 |
-
f"Risk Level: {risk_level}
|
|
|
|
| 230 |
f"Status: {status}\n"
|
| 231 |
f"Insights: {insights} due to {top_causes.lower()}.\n\n"
|
| 232 |
f"Forecast Chart\n"
|
|
@@ -243,28 +244,46 @@ def predict_risk(planned_cost, actual_spend, category, cement_index, labor_index
|
|
| 243 |
)
|
| 244 |
return output_text, chart_image, pdf_file, excel_file
|
| 245 |
|
| 246 |
-
# Gradio interface
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
gr.
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
|
| 268 |
# Launch the app
|
| 269 |
if __name__ == "__main__":
|
| 270 |
-
|
|
|
|
| 48 |
fig, ax = plt.subplots(figsize=(8, 6))
|
| 49 |
categories = ['Planned Cost', 'Actual Spend', 'Forecasted Cost']
|
| 50 |
values = [planned_cost, actual_spend, forecast_cost]
|
| 51 |
+
ax.bar(categories, values, color=['#1f77b4', '#ff7f0e', '#2ca02c'])
|
| 52 |
ax.set_title("Budget Overview", fontsize=14, pad=15)
|
| 53 |
ax.set_ylabel("Amount ($)", fontsize=12)
|
| 54 |
ax.tick_params(axis='x', rotation=45)
|
|
|
|
| 64 |
buf_gradio = io.BytesIO()
|
| 65 |
plt.savefig(buf_gradio, format='png', bbox_inches='tight', dpi=100)
|
| 66 |
buf_gradio.seek(0)
|
|
|
|
| 67 |
gradio_image = Image.open(buf_gradio)
|
| 68 |
|
| 69 |
# Save plot to a temporary file for PDF generation
|
|
|
|
| 146 |
|
| 147 |
# Placeholder for risk calculation logic (simplified for demo)
|
| 148 |
total_risk = 1 if actual_spend > planned_cost else 0
|
| 149 |
+
risk_percentage = total_risk * 100 # Convert to percentage (0% or 100%)
|
| 150 |
+
forecast_cost = planned_cost * 2
|
| 151 |
insights = "High risk of overrun" if total_risk == 1 else "Low risk of overrun"
|
| 152 |
status = "Critical" if total_risk == 1 else "Healthy"
|
| 153 |
top_causes = []
|
|
|
|
| 159 |
top_causes.append("Labor Index Deviation")
|
| 160 |
top_causes = ", ".join(top_causes) if top_causes else "None"
|
| 161 |
|
| 162 |
+
logger.debug(f"Calculation results: total_risk={total_risk}, risk_percentage={risk_percentage}, forecast_cost={forecast_cost}, "
|
| 163 |
f"insights={insights}, status={status}, top_causes={top_causes}")
|
| 164 |
|
| 165 |
# Prepare data for Salesforce
|
|
|
|
| 170 |
"Cement_Index__c": cement_index,
|
| 171 |
"Labor_Index__c": labor_index,
|
| 172 |
"Project_Phase__c": project_phase,
|
| 173 |
+
"Risk_Score__c": total_risk * 100,
|
| 174 |
"Forecasted_Cost__c": forecast_cost,
|
| 175 |
"Insights__c": insights,
|
| 176 |
"Status__c": status
|
|
|
|
| 221 |
# Generate Excel file
|
| 222 |
excel_file = generate_excel(planned_cost, actual_spend, forecast_cost, total_risk, insights, status, top_causes, forecast_cost_eur)
|
| 223 |
|
| 224 |
+
# Format the output for Gradio with enhanced summary and risk percentage
|
| 225 |
risk_level = "High" if total_risk == 1 else "Low"
|
| 226 |
output_text = (
|
| 227 |
f"Risk Summary\n"
|
| 228 |
f"----------------------------------------\n"
|
| 229 |
+
f"Risk Level: {risk_level}\n"
|
| 230 |
+
f"Risk Percentage: {risk_percentage}%\n"
|
| 231 |
f"Status: {status}\n"
|
| 232 |
f"Insights: {insights} due to {top_causes.lower()}.\n\n"
|
| 233 |
f"Forecast Chart\n"
|
|
|
|
| 244 |
)
|
| 245 |
return output_text, chart_image, pdf_file, excel_file
|
| 246 |
|
| 247 |
+
# Custom Gradio Blocks interface
|
| 248 |
+
with gr.Blocks(title="Budget Overrun Risk Estimator") as demo:
|
| 249 |
+
gr.Markdown("# Budget Overrun Risk Estimator")
|
| 250 |
+
gr.Markdown("Enter project details to estimate budget overrun risk. All numeric fields are required.")
|
| 251 |
+
|
| 252 |
+
with gr.Row():
|
| 253 |
+
with gr.Column():
|
| 254 |
+
planned_cost_input = gr.Textbox(label="Planned Cost", placeholder="Enter planned cost (e.g., 1200000)")
|
| 255 |
+
actual_spend_input = gr.Textbox(label="Actual Spend", placeholder="Enter actual spend (e.g., 5000000)")
|
| 256 |
+
category_input = gr.Dropdown(label="Category", choices=["Civil", "Electrical", "Plumbing", "Finishing", "Others"], value="Plumbing")
|
| 257 |
+
cement_index_input = gr.Textbox(label="Cement Index", placeholder="Enter cement index (e.g., 120)")
|
| 258 |
+
labor_index_input = gr.Textbox(label="Labor Index", placeholder="Enter labor index (e.g., 30)")
|
| 259 |
+
project_phase_input = gr.Dropdown(label="Project Phase", choices=["Planning", "Execution", "Closure"], value="Planning")
|
| 260 |
+
|
| 261 |
+
with gr.Row():
|
| 262 |
+
clear_button = gr.Button("Clear")
|
| 263 |
+
submit_button = gr.Button("Submit", variant="primary")
|
| 264 |
+
|
| 265 |
+
with gr.Column():
|
| 266 |
+
output_text = gr.Textbox(label="Prediction Results")
|
| 267 |
+
output_chart = gr.Image(label="Forecast Chart")
|
| 268 |
+
output_pdf = gr.File(label="Download Local PDF Report")
|
| 269 |
+
output_excel = gr.File(label="Download Excel Report")
|
| 270 |
+
|
| 271 |
+
# Clear button functionality
|
| 272 |
+
clear_button.click(
|
| 273 |
+
fn=lambda: ("", "", "Plumbing", "", "", "Planning", "", None, None, None),
|
| 274 |
+
outputs=[
|
| 275 |
+
planned_cost_input, actual_spend_input, category_input, cement_index_input,
|
| 276 |
+
labor_index_input, project_phase_input, output_text, output_chart, output_pdf, output_excel
|
| 277 |
+
]
|
| 278 |
+
)
|
| 279 |
+
|
| 280 |
+
# Submit button functionality
|
| 281 |
+
submit_button.click(
|
| 282 |
+
fn=predict_risk,
|
| 283 |
+
inputs=[planned_cost_input, actual_spend_input, category_input, cement_index_input, labor_index_input, project_phase_input],
|
| 284 |
+
outputs=[output_text, output_chart, output_pdf, output_excel]
|
| 285 |
+
)
|
| 286 |
|
| 287 |
# Launch the app
|
| 288 |
if __name__ == "__main__":
|
| 289 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|