File size: 6,258 Bytes
0dabc69 5455d26 0dabc69 adc5545 5455d26 adc5545 5455d26 adc5545 5455d26 adc5545 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | import gradio as gr
import numpy as np
import plotly.graph_objects as go
def calculate_chemeng_tvm(capex, revenue, opex_fixed, opex_var, plant_life, marr_pct, salvage_pct, inflation_pct):
capex = float(capex)
revenue = float(revenue)
opex_fixed = float(opex_fixed)
opex_var = float(opex_var)
plant_life = int(plant_life)
marr = float(marr_pct) / 100
salvage = float(salvage_pct) / 100
inflation = float(inflation_pct) / 100
# Generate cash flows
cashflows = [-capex]
for year in range(1, plant_life + 1):
opex_total = (opex_fixed + opex_var) * (1 + inflation) ** year
rev = revenue * (1 + inflation) ** year
net_cf = rev - opex_total
cashflows.append(net_cf)
cashflows[-1] += capex * salvage
# NPV Calculation
npv_val = sum(cf / (1 + marr)**i for i, cf in enumerate(cashflows))
# IRR Approximation (Newton-Raphson)
irr_guess = 0.1
for _ in range(50):
npv_est = sum(cf / (1 + irr_guess)**i for i, cf in enumerate(cashflows))
deriv = sum(-i * cf / (1 + irr_guess)**(i+1) for i, cf in enumerate(cashflows))
if abs(deriv) < 1e-10: break
irr_guess -= npv_est / deriv
irr_val = max(0, irr_guess * 100)
# Payback Period
cum_cf = [0]
for cf in cashflows[1:]:
cum_cf.append(cum_cf[-1] + cf)
payback = next((i for i, total in enumerate(cum_cf) if total >= 0), plant_life)
# Results HTML
results_html = f"""
<div style='font-family: Arial; padding: 20px;'>
<h2 style='color: #1f77b4;'>π§ͺ Chemical Engineering Economics</h2>
<table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>
<tr style='background: #f0f8ff;'>
<th style='border: 1px solid #ddd; padding: 12px;'>Metric</th>
<th style='border: 1px solid #ddd; padding: 12px; text-align: right;'>Value</th>
</tr>
<tr>
<td style='border: 1px solid #ddd; padding: 12px;'><b>π NPV</b></td>
<td style='border: 1px solid #ddd; padding: 12px; text-align: right; font-size: 18px; color: {'green' if npv_val > 0 else 'red'};'>${npv_val:,.0f}</td>
</tr>
<tr style='background: #f9f9f9;'>
<td style='border: 1px solid #ddd; padding: 12px;'><b>β‘ IRR</b></td>
<td style='border: 1px solid #ddd; padding: 12px; text-align: right; font-size: 18px;'>{irr_val:.1f}%</td>
</tr>
<tr>
<td style='border: 1px solid #ddd; padding: 12px;'><b>β±οΈ Payback</b></td>
<td style='border: 1px solid #ddd; padding: 12px; text-align: right;'>{payback:.1f} years</td>
</tr>
<tr style='background: #f9f9f9;'>
<td style='border: 1px solid #ddd; padding: 12px;'><b>π Profitability Index</b></td>
<td style='border: 1px solid #ddd; padding: 12px; text-align: right;'>{abs(npv_val/capex)*100:.1f}%</td>
</tr>
</table>
<div style='background: {'#d4edda' if npv_val > 0 else '#f8d7da'}; padding: 15px; border-radius: 8px; border-left: 5px solid {'#28a745' if npv_val > 0 else '#dc3545'};'>
<b>Status: {'β
PROJECT VIABLE (NPV > 0)' if npv_val > 0 else 'β οΈ REVIEW REQUIRED'}</b>
</div>
</div>
"""
# Cash Flow Chart
years = list(range(len(cashflows)))
fig = go.Figure()
fig.add_trace(go.Bar(x=years[1:], y=cashflows[1:],
name="Annual Cash Flow", marker_color='#1f77b4'))
fig.add_trace(go.Scatter(x=years, y=cum_cf,
mode='lines+markers', name="Cumulative CF",
line=dict(color='#ff4444', width=4)))
fig.add_hline(y=0, line_dash="dash", line_color="gray", annotation_text="Breakeven")
fig.update_layout(
title="πΈ Chemical Plant Cash Flow Analysis",
xaxis_title="Year", yaxis_title="Cash Flow ($)",
height=400, showlegend=True,
font=dict(size=12)
)
return results_html, fig.to_html(full_html=False, div_id="cashflow-chart")
# Gradio Interface
with gr.Blocks(title="ChemEng TVM Calculator") as demo:
gr.Markdown("# π§ͺ Chemical Engineering TVM Calculator")
gr.Markdown("**CAPEX β’ OPEX β’ NPV β’ IRR β’ Plant Investment Analysis**")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### π Chemical Plant Inputs")
gr.Markdown("**π° Investment & Revenue**")
with gr.Row():
capex_input = gr.Number(value=10000000, label="CAPEX ($)", precision=0)
revenue_input = gr.Number(value=5000000, label="Revenue/Year ($)", precision=0)
gr.Markdown("**π Operating Costs**")
with gr.Row():
opex_fixed_input = gr.Number(value=1500000, label="Fixed OPEX ($)", precision=0)
opex_var_input = gr.Number(value=2000000, label="Variable OPEX ($)", precision=0)
gr.Markdown("**π
Economic Parameters**")
with gr.Row():
plant_life_input = gr.Slider(5, 30, value=15, step=1, label="Plant Life (years)")
marr_input = gr.Slider(8, 20, value=12, step=1, label="MARR (%)")
with gr.Row():
salvage_input = gr.Slider(0, 20, value=10, step=1, label="Salvage Value (%)")
inflation_input = gr.Slider(1, 8, value=3, step=0.5, label="Inflation (%)")
calculate_btn = gr.Button("π¬ RUN ECONOMIC ANALYSIS", variant="primary", size="lg")
with gr.Column(scale=2):
results_output = gr.HTML()
chart_output = gr.HTML()
# Connect button to function
calculate_btn.click(
calculate_chemeng_tvm,
inputs=[capex_input, revenue_input, opex_fixed_input, opex_var_input,
plant_life_input, marr_input, salvage_input, inflation_input],
outputs=[results_output, chart_output]
)
gr.Markdown("---")
gr.Markdown("*Professional tool for Chemical Engineers | Powered by Gradio*")
# Launch (Hugging Face auto-runs this)
demo.launch() |