Kkjutt000 commited on
Commit
adc5545
Β·
verified Β·
1 Parent(s): a26acbd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -90
app.py CHANGED
@@ -1,97 +1,138 @@
1
  import gradio as gr
2
  import numpy as np
3
  import plotly.graph_objects as go
4
- import plotly.express as px
5
- import pandas as pd
6
- from plotly.subplots import make_subplots
7
 
8
- # Manual TVM functions (no external finance libs)
9
- def npv(rate, cashflows):
10
- total = 0.0
11
- for i, cf in enumerate(cashflows):
12
- total += cf / (1 + rate) ** i
13
- return total
14
-
15
- def irr(cashflows, iterations=100):
16
- rate = 0.1
17
- for _ in range(iterations):
18
- npv_val = npv(rate, cashflows)
19
- npv_deriv = sum(-i * cf / (1 + rate) ** (i + 1) for i, cf in enumerate(cashflows) if cf != 0)
20
- if abs(npv_deriv) < 1e-8:
21
- break
22
- rate -= npv_val / npv_deriv
23
- return max(0, rate)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- class ChemEngTVM:
26
- def __init__(self):
27
- self.inflation = 0.03
 
28
 
29
- def calculate(self, capex, opex_fixed, opex_var, revenue, plant_life, marr, salvage_pct, inflation_pct):
30
- capex = float(capex)
31
- opex_fixed, opex_var, revenue = map(float, [opex_fixed, opex_var, revenue])
32
- plant_life, marr, salvage_pct, inflation_pct = map(float, [plant_life, marr, salvage_pct, inflation_pct])
33
- marr /= 100
34
- salvage_pct /= 100
35
- inflation_pct /= 100
36
-
37
- # Generate cash flows
38
- cashflows = [-capex]
39
- for year in range(1, int(plant_life) + 1):
40
- opex_total = (opex_fixed + opex_var) * (1 + inflation_pct) ** year
41
- rev = revenue * (1 + inflation_pct) ** year
42
- net_cf = rev - opex_total
43
- cashflows.append(net_cf)
44
- cashflows[-1] += capex * salvage_pct
45
-
46
- # Calculate metrics
47
- npv_val = npv(marr, cashflows)
48
- irr_val = irr(cashflows) * 100
 
 
 
 
49
 
50
- # Payback period
51
- cum_cf = np.cumsum(cashflows)
52
- payback = next((i for i, x in enumerate(cum_cf) if x >= 0), plant_life)
53
-
54
- # Create visualizations
55
- years = np.arange(len(cashflows))
56
-
57
- # Cash flow chart
58
- fig_cf = go.Figure()
59
- fig_cf.add_trace(go.Bar(x=years[1:], y=cashflows[1:],
60
- name="Annual Cash Flow", marker_color='#1f77b4'))
61
- fig_cf.add_trace(go.Scatter(x=years, y=cum_cf,
62
- mode='lines+markers', name="Cumulative CF",
63
- line=dict(color='red', width=4)))
64
- fig_cf.add_hline(y=0, line_dash="dash", line_color="gray")
65
- fig_cf.update_layout(
66
- title="πŸ§ͺ Chemical Plant Cash Flow Analysis",
67
- xaxis_title="Year", yaxis_title="Cash Flow ($)",
68
- height=400, showlegend=True
69
- )
70
-
71
- # Sensitivity analysis
72
- rev_range = np.linspace(revenue*0.6, revenue*1.4, 15)
73
- npv_range = []
74
- for r in rev_range:
75
- temp_cf = [-capex]
76
- for y in range(1, int(plant_life)+1):
77
- opex_t = (opex_fixed + opex_var) * (1 + inflation_pct)**y
78
- rev_t = r * (1 + inflation_pct)**y
79
- temp_cf.append(rev_t - opex_t)
80
- temp_cf[-1] += capex * salvage_pct
81
- npv_range.append(npv(marr, temp_cf))
82
-
83
- fig_sens = px.line(x=rev_range/1e6, y=np.array(npv_range)/1e6,
84
- labels={'x':'Revenue ($M)', 'y':'NPV ($M)'},
85
- title="πŸ“ˆ NPV Sensitivity to Revenue")
86
- fig_sens.add_hline(y=0, line_dash="dash", line_color="red")
87
-
88
- # Results table
89
- df = pd.DataFrame({
90
- 'Year': years,
91
- 'Cash Flow': np.round(cashflows, 0),
92
- 'Cumulative': np.round(cum_cf, 0)
93
- })
94
-
95
- # Format results
96
- results = f"""
97
- ## 🎯 **Economic Summary**
 
1
  import gradio as gr
2
  import numpy as np
3
  import plotly.graph_objects as go
 
 
 
4
 
5
+ def calculate_chemeng_tvm(capex, revenue, opex_fixed, opex_var, plant_life, marr_pct, salvage_pct, inflation_pct):
6
+ capex = float(capex)
7
+ revenue = float(revenue)
8
+ opex_fixed = float(opex_fixed)
9
+ opex_var = float(opex_var)
10
+ plant_life = int(plant_life)
11
+ marr = float(marr_pct) / 100
12
+ salvage = float(salvage_pct) / 100
13
+ inflation = float(inflation_pct) / 100
14
+
15
+ # Generate cash flows
16
+ cashflows = [-capex]
17
+ for year in range(1, plant_life + 1):
18
+ opex_total = (opex_fixed + opex_var) * (1 + inflation) ** year
19
+ rev = revenue * (1 + inflation) ** year
20
+ net_cf = rev - opex_total
21
+ cashflows.append(net_cf)
22
+ cashflows[-1] += capex * salvage
23
+
24
+ # NPV Calculation
25
+ npv_val = sum(cf / (1 + marr)**i for i, cf in enumerate(cashflows))
26
+
27
+ # IRR Approximation (Newton-Raphson)
28
+ irr_guess = 0.1
29
+ for _ in range(50):
30
+ npv_est = sum(cf / (1 + irr_guess)**i for i, cf in enumerate(cashflows))
31
+ deriv = sum(-i * cf / (1 + irr_guess)**(i+1) for i, cf in enumerate(cashflows))
32
+ if abs(deriv) < 1e-10: break
33
+ irr_guess -= npv_est / deriv
34
+ irr_val = max(0, irr_guess * 100)
35
+
36
+ # Payback Period
37
+ cum_cf = [0]
38
+ for cf in cashflows[1:]:
39
+ cum_cf.append(cum_cf[-1] + cf)
40
+ payback = next((i for i, total in enumerate(cum_cf) if total >= 0), plant_life)
41
+
42
+ # Results HTML
43
+ results_html = f"""
44
+ <div style='font-family: Arial; padding: 20px;'>
45
+ <h2 style='color: #1f77b4;'>πŸ§ͺ Chemical Engineering Economics</h2>
46
+ <table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>
47
+ <tr style='background: #f0f8ff;'>
48
+ <th style='border: 1px solid #ddd; padding: 12px;'>Metric</th>
49
+ <th style='border: 1px solid #ddd; padding: 12px; text-align: right;'>Value</th>
50
+ </tr>
51
+ <tr>
52
+ <td style='border: 1px solid #ddd; padding: 12px;'><b>πŸ’Ž NPV</b></td>
53
+ <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>
54
+ </tr>
55
+ <tr style='background: #f9f9f9;'>
56
+ <td style='border: 1px solid #ddd; padding: 12px;'><b>⚑ IRR</b></td>
57
+ <td style='border: 1px solid #ddd; padding: 12px; text-align: right; font-size: 18px;'>{irr_val:.1f}%</td>
58
+ </tr>
59
+ <tr>
60
+ <td style='border: 1px solid #ddd; padding: 12px;'><b>⏱️ Payback</b></td>
61
+ <td style='border: 1px solid #ddd; padding: 12px; text-align: right;'>{payback:.1f} years</td>
62
+ </tr>
63
+ <tr style='background: #f9f9f9;'>
64
+ <td style='border: 1px solid #ddd; padding: 12px;'><b>πŸ“Š Profitability Index</b></td>
65
+ <td style='border: 1px solid #ddd; padding: 12px; text-align: right;'>{abs(npv_val/capex)*100:.1f}%</td>
66
+ </tr>
67
+ </table>
68
+ <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'};'>
69
+ <b>Status: {'βœ… PROJECT VIABLE (NPV > 0)' if npv_val > 0 else '⚠️ REVIEW REQUIRED'}</b>
70
+ </div>
71
+ </div>
72
+ """
73
+
74
+ # Cash Flow Chart
75
+ years = list(range(len(cashflows)))
76
+ fig = go.Figure()
77
+ fig.add_trace(go.Bar(x=years[1:], y=cashflows[1:],
78
+ name="Annual Cash Flow", marker_color='#1f77b4'))
79
+ fig.add_trace(go.Scatter(x=years, y=cum_cf,
80
+ mode='lines+markers', name="Cumulative CF",
81
+ line=dict(color='#ff4444', width=4)))
82
+ fig.add_hline(y=0, line_dash="dash", line_color="gray", annotation_text="Breakeven")
83
+ fig.update_layout(
84
+ title="πŸ’Έ Chemical Plant Cash Flow Analysis",
85
+ xaxis_title="Year", yaxis_title="Cash Flow ($)",
86
+ height=400, showlegend=True,
87
+ font=dict(size=12)
88
+ )
89
+
90
+ return results_html, fig.to_html(full_html=False, div_id="cashflow-chart")
91
 
92
+ # Gradio Interface
93
+ with gr.Blocks(title="ChemEng TVM Calculator") as demo:
94
+ gr.Markdown("# πŸ§ͺ Chemical Engineering TVM Calculator")
95
+ gr.Markdown("**CAPEX β€’ OPEX β€’ NPV β€’ IRR β€’ Plant Investment Analysis**")
96
 
97
+ with gr.Row():
98
+ with gr.Column(scale=1):
99
+ gr.Markdown("### πŸ“Š Chemical Plant Inputs")
100
+
101
+ gr.Markdown("**πŸ’° Investment & Revenue**")
102
+ with gr.Row():
103
+ capex_input = gr.Number(value=10000000, label="CAPEX ($)", precision=0)
104
+ revenue_input = gr.Number(value=5000000, label="Revenue/Year ($)", precision=0)
105
+
106
+ gr.Markdown("**🏭 Operating Costs**")
107
+ with gr.Row():
108
+ opex_fixed_input = gr.Number(value=1500000, label="Fixed OPEX ($)", precision=0)
109
+ opex_var_input = gr.Number(value=2000000, label="Variable OPEX ($)", precision=0)
110
+
111
+ gr.Markdown("**πŸ“… Economic Parameters**")
112
+ with gr.Row():
113
+ plant_life_input = gr.Slider(5, 30, value=15, step=1, label="Plant Life (years)")
114
+ marr_input = gr.Slider(8, 20, value=12, step=1, label="MARR (%)")
115
+
116
+ with gr.Row():
117
+ salvage_input = gr.Slider(0, 20, value=10, step=1, label="Salvage Value (%)")
118
+ inflation_input = gr.Slider(1, 8, value=3, step=0.5, label="Inflation (%)")
119
+
120
+ calculate_btn = gr.Button("πŸ”¬ RUN ECONOMIC ANALYSIS", variant="primary", size="lg")
121
 
122
+ with gr.Column(scale=2):
123
+ results_output = gr.HTML()
124
+ chart_output = gr.HTML()
125
+
126
+ # Connect button to function
127
+ calculate_btn.click(
128
+ calculate_chemeng_tvm,
129
+ inputs=[capex_input, revenue_input, opex_fixed_input, opex_var_input,
130
+ plant_life_input, marr_input, salvage_input, inflation_input],
131
+ outputs=[results_output, chart_output]
132
+ )
133
+
134
+ gr.Markdown("---")
135
+ gr.Markdown("*Professional tool for Chemical Engineers | Powered by Gradio*")
136
+
137
+ # Launch (Hugging Face auto-runs this)
138
+ demo.launch()