| | import streamlit as st |
| | import pandas as pd |
| | import plotly.express as px |
| | import plotly.graph_objects as go |
| | from plotly.subplots import make_subplots |
| | import numpy as np |
| | from datetime import datetime |
| | import io |
| | import os |
| | import warnings |
| | warnings.filterwarnings('ignore') |
| |
|
| | |
| | if 'data_loaded' not in st.session_state: |
| | st.session_state.data_loaded = False |
| | if 'analyzer' not in st.session_state: |
| | st.session_state.analyzer = None |
| |
|
| | |
| | st.set_page_config( |
| | page_title="๐ FinanceGPT Analyzer", |
| | page_icon="๐", |
| | layout="wide", |
| | initial_sidebar_state="expanded" |
| | ) |
| |
|
| | |
| | st.markdown(""" |
| | <style> |
| | .metric-card { |
| | background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); |
| | padding: 1rem; |
| | border-radius: 10px; |
| | color: white; |
| | text-align: center; |
| | margin: 0.5rem 0; |
| | } |
| | .insight-box { |
| | background: #f8f9fa; |
| | padding: 1rem; |
| | border-left: 4px solid #007bff; |
| | border-radius: 5px; |
| | margin: 1rem 0; |
| | } |
| | .warning-box { |
| | background: #fff3cd; |
| | padding: 1rem; |
| | border-left: 4px solid #ffc107; |
| | border-radius: 5px; |
| | margin: 1rem 0; |
| | } |
| | </style> |
| | """, unsafe_allow_html=True) |
| |
|
| | |
| | @st.cache_data |
| | def load_csv_with_encoding(file_content: bytes, filename: str) -> pd.DataFrame: |
| | """Load CSV with automatic encoding detection - cached""" |
| | try: |
| | import chardet |
| | detected = chardet.detect(file_content) |
| | encoding = detected['encoding'] if detected['encoding'] else 'utf-8' |
| | |
| | try: |
| | from io import BytesIO |
| | return pd.read_csv(BytesIO(file_content), encoding=encoding) |
| | except: |
| | encodings = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-1'] |
| | for enc in encodings: |
| | try: |
| | return pd.read_csv(BytesIO(file_content), encoding=enc) |
| | except: |
| | continue |
| | raise Exception("Cannot read file with any encoding") |
| | except ImportError: |
| | |
| | from io import BytesIO |
| | encodings = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-1'] |
| | for enc in encodings: |
| | try: |
| | return pd.read_csv(BytesIO(file_content), encoding=enc) |
| | except: |
| | continue |
| | raise Exception("Cannot read file with any encoding") |
| |
|
| | @st.cache_data |
| | def load_excel_file(file_content: bytes) -> pd.DataFrame: |
| | """Load Excel file - cached""" |
| | from io import BytesIO |
| | return pd.read_excel(BytesIO(file_content)) |
| |
|
| | def load_data(uploaded_file): |
| | """Unified data loading function""" |
| | file_content = uploaded_file.read() |
| | uploaded_file.seek(0) |
| | |
| | if uploaded_file.name.endswith('.csv'): |
| | return load_csv_with_encoding(file_content, uploaded_file.name) |
| | else: |
| | return load_excel_file(file_content) |
| |
|
| | class FinanceAnalyzer: |
| | def __init__(self): |
| | self.data = None |
| | self.processed_data = {} |
| | |
| | def load_csv_data(self): |
| | """Load CSV data from local file""" |
| | try: |
| | |
| | possible_paths = [ |
| | os.path.join(os.path.dirname(__file__), '2024.csv'), |
| | os.path.join('2024.csv'), |
| | '2024.csv', |
| | os.path.join('2024.csv') |
| | ] |
| | |
| | for csv_path in possible_paths: |
| | if os.path.exists(csv_path): |
| | |
| | with open(csv_path, 'rb') as f: |
| | file_content = f.read() |
| | df = load_csv_with_encoding(file_content, csv_path) |
| | st.success(f"โ
CSV data loaded from: {csv_path}") |
| | return df |
| | |
| | |
| | current_dir = os.path.dirname(__file__) if __file__ else '.' |
| | available_files = [] |
| | for root, dirs, files in os.walk(current_dir): |
| | for file in files: |
| | if file.endswith('.csv'): |
| | available_files.append(os.path.join(root, file)) |
| | |
| | if available_files: |
| | st.warning(f"CSV file not found in expected locations. Available CSV files: {available_files}") |
| | else: |
| | st.warning("No CSV files found. Using sample data instead.") |
| | |
| | return self.load_sample_data() |
| | |
| | except Exception as e: |
| | st.error(f"Error loading CSV file: {e}") |
| | st.info("Falling back to sample data...") |
| | return self.load_sample_data() |
| | |
| | def load_sample_data(self): |
| | """Load sample financial data based on your real CSV structure""" |
| | sample_data = { |
| | 'Statement_Type': ['Income Statement'] * 19 + ['Balance Sheet'] * 10 + ['Cash Flow Statement'] * 5, |
| | 'Account_Name_Norwegian': [ |
| | |
| | 'Salgsinntekt', 'Sum inntekter', 'Varekostnad', 'Lรธnnskostnad', |
| | 'Avskrivning pรฅ varige driftsmidler og immaterielle eiendeler', |
| | 'Annen driftskostnad', 'Sum kostnader', 'Driftsresultat', |
| | 'Annen renteinntekt', 'Annen finansinntekt', 'Sum finansinntekter', |
| | 'Annen rentekostnad', 'Annen finanskostnad', 'Sum finanskostnader', |
| | 'Netto finans', 'Resultat fรธr skattekostnad', 'Skattekostnad', |
| | 'ร
rsresultat', 'Overfรธringer til/fra annen egenkapital', |
| | |
| | 'Sum anleggsmidler', 'Kundefordringer', 'Andre fordringer', |
| | 'Sum fordringer', 'Bankinnskudd kontanter og lignende', |
| | 'Sum omlรธpsmidler', 'SUM EIENDELER', 'Sum egenkapital', |
| | 'Sum langsiktig gjeld', 'Sum kortsiktig gjeld', 'Sum gjeld', |
| | |
| | 'ร
rsresultat', 'Avskrivninger', 'Netto kontantstrรธm fra driftsaktiviteter', |
| | 'Netto kontantstrรธm fra investeringsaktiviteter', 'NETTO ENDRING I KONTANTER' |
| | ], |
| | 'Account_Name_English': [ |
| | |
| | 'Sales Revenue', 'Total Income', 'Cost of Goods Sold', 'Payroll Expenses', |
| | 'Depreciation on Fixed Assets and Intangible Assets', |
| | 'Other Operating Expenses', 'Total Expenses', 'Operating Result', |
| | 'Other Interest Income', 'Other Financial Income', 'Total Financial Income', |
| | 'Other Interest Expenses', 'Other Financial Expenses', 'Total Financial Expenses', |
| | 'Net Financial Result', 'Result Before Tax', 'Tax Expense', |
| | 'Annual Result', 'Transfers to/from Other Equity', |
| | |
| | 'Total Fixed Assets', 'Customer Receivables', 'Other Receivables', |
| | 'Total Receivables', 'Bank Deposits Cash and Similar', |
| | 'Total Current Assets', 'TOTAL ASSETS', 'Total Equity', |
| | 'Total Long-term Debt', 'Total Short-term Debt', 'Total Debt', |
| | |
| | 'Net Income', 'Depreciation', 'Net Cash Flow from Operating Activities', |
| | 'Net Cash Flow from Investing Activities', 'NET CHANGE IN CASH' |
| | ], |
| | '2024_Amount_NOK': [ |
| | |
| | 25107008, 25107008, 9880032, 3700289, 316180, |
| | 4355621, 18252121, 6854887, 11439, 1230, 12669, |
| | 51288, 3916, 55205, -42536, 6812351, 1498717, |
| | 5313634, 5313634, |
| | |
| | 4282396, 5575707, 178797, 5754504, 1595549, |
| | 7350053, 11632449, 5602404, 653459, 5376586, 6030045, |
| | |
| | 5313634, 316180, 3385812, -3546128, 801948 |
| | ], |
| | '2023_Amount_NOK': [ |
| | |
| | 4891891, 4891891, 770840, 2703253, 0, |
| | 1330101, 4804194, 87697, 385, 0, 385, |
| | 59498, 0, 59498, -59113, 28584, 32524, |
| | -3940, -3940, |
| | |
| | 1052447, 2000151, 233394, 2233546, 793599, |
| | 3027145, 4079592, 288770, 630673, 3160150, 3790823, |
| | |
| | -3940, 0, 951553, -1052448, 500891 |
| | ] |
| | } |
| | return pd.DataFrame(sample_data) |
| | |
| | def process_financial_data(self, df): |
| | """Process uploaded financial data - improved version""" |
| | self.data = df |
| | |
| | try: |
| | |
| | if 'Statement_Type' in df.columns and '2024_Amount_NOK' in df.columns: |
| | |
| | income_df = df[df['Statement_Type'] == 'Income Statement'].copy() |
| | |
| | |
| | revenue_rows = income_df[income_df['Account_Name_English'].str.contains('Sales Revenue', case=False, na=False)] |
| | profit_rows = income_df[income_df['Account_Name_English'].str.contains('Annual Result|Net Income', case=False, na=False)] |
| | cogs_rows = income_df[income_df['Account_Name_English'].str.contains('Cost of Goods', case=False, na=False)] |
| | operating_rows = income_df[income_df['Account_Name_English'].str.contains('Operating Result', case=False, na=False)] |
| | |
| | self.processed_data = { |
| | 'revenue_2024': revenue_rows['2024_Amount_NOK'].iloc[0] if len(revenue_rows) > 0 else 0, |
| | 'revenue_2023': revenue_rows['2023_Amount_NOK'].iloc[0] if len(revenue_rows) > 0 else 0, |
| | 'net_profit_2024': profit_rows['2024_Amount_NOK'].iloc[0] if len(profit_rows) > 0 else 0, |
| | 'net_profit_2023': profit_rows['2023_Amount_NOK'].iloc[0] if len(profit_rows) > 0 else 0, |
| | 'cogs_2024': abs(cogs_rows['2024_Amount_NOK'].iloc[0]) if len(cogs_rows) > 0 else 0, |
| | 'cogs_2023': abs(cogs_rows['2023_Amount_NOK'].iloc[0]) if len(cogs_rows) > 0 else 0, |
| | 'operating_profit_2024': operating_rows['2024_Amount_NOK'].iloc[0] if len(operating_rows) > 0 else 0, |
| | 'operating_profit_2023': operating_rows['2023_Amount_NOK'].iloc[0] if len(operating_rows) > 0 else 0, |
| | } |
| | |
| | st.success("โ
Financial data processed successfully!") |
| | st.info(f"๐ Processed {len(df)} financial line items") |
| | |
| | else: |
| | |
| | st.warning("โ ๏ธ Using fallback data processing") |
| | self.processed_data = { |
| | 'revenue_2024': 25107008, |
| | 'revenue_2023': 4891891, |
| | 'net_profit_2024': 5313634, |
| | 'net_profit_2023': -3940, |
| | 'cogs_2024': 9880032, |
| | 'cogs_2023': 770840, |
| | 'operating_profit_2024': 6854887, |
| | 'operating_profit_2023': 87697, |
| | } |
| | |
| | except Exception as e: |
| | st.error(f"Error processing data: {e}") |
| | st.info("Using default financial values...") |
| | self.processed_data = { |
| | 'revenue_2024': 25107008, |
| | 'revenue_2023': 4891891, |
| | 'net_profit_2024': 5313634, |
| | 'net_profit_2023': -3940, |
| | 'cogs_2024': 9880032, |
| | 'cogs_2023': 770840, |
| | 'operating_profit_2024': 6854887, |
| | 'operating_profit_2023': 87697, |
| | } |
| | |
| | def calculate_metrics(self): |
| | """Calculate key financial metrics""" |
| | if not self.processed_data: |
| | return {} |
| | |
| | data = self.processed_data |
| | |
| | |
| | revenue_growth = ((data['revenue_2024'] - data['revenue_2023']) / |
| | abs(data['revenue_2023']) * 100) if data['revenue_2023'] != 0 else 0 |
| | |
| | |
| | gross_margin_2024 = ((data['revenue_2024'] - data['cogs_2024']) / |
| | data['revenue_2024'] * 100) if data['revenue_2024'] != 0 else 0 |
| | net_margin_2024 = (data['net_profit_2024'] / data['revenue_2024'] * 100) if data['revenue_2024'] != 0 else 0 |
| | |
| | return { |
| | 'revenue_growth': revenue_growth, |
| | 'gross_margin_2024': gross_margin_2024, |
| | 'net_margin_2024': net_margin_2024, |
| | 'revenue_2024_m': data['revenue_2024'] / 1000000, |
| | 'net_profit_2024_m': data['net_profit_2024'] / 1000000, |
| | } |
| |
|
| | def create_revenue_trend_chart(self): |
| | """Create revenue trend visualization""" |
| | if not self.processed_data: |
| | return go.Figure() |
| | |
| | fig = go.Figure() |
| | |
| | years = [2023, 2024] |
| | revenues = [self.processed_data['revenue_2023']/1000000, |
| | self.processed_data['revenue_2024']/1000000] |
| | net_profits = [self.processed_data['net_profit_2023']/1000000, |
| | self.processed_data['net_profit_2024']/1000000] |
| | |
| | fig.add_trace(go.Scatter(x=years, y=revenues, mode='lines+markers', |
| | name='Revenue (M NOK)', line=dict(color='#1f77b4', width=3))) |
| | fig.add_trace(go.Scatter(x=years, y=net_profits, mode='lines+markers', |
| | name='Net Profit (M NOK)', line=dict(color='#ff7f0e', width=3))) |
| | |
| | fig.update_layout(title='Revenue vs Profit Trend', xaxis_title='Year', |
| | yaxis_title='Amount (M NOK)', height=400) |
| | return fig |
| |
|
| | def create_financial_health_radar(self): |
| | """Create financial health radar chart""" |
| | metrics = self.calculate_metrics() |
| | |
| | categories = ['Revenue Growth', 'Gross Margin', 'Net Margin', 'Profitability', 'Efficiency'] |
| | values = [ |
| | min(metrics.get('revenue_growth', 0) / 5, 100), |
| | metrics.get('gross_margin_2024', 0), |
| | max(metrics.get('net_margin_2024', 0), 0), |
| | 70, |
| | 65 |
| | ] |
| | |
| | fig = go.Figure() |
| | fig.add_trace(go.Scatterpolar( |
| | r=values, |
| | theta=categories, |
| | fill='toself', |
| | name='Financial Health' |
| | )) |
| | |
| | fig.update_layout( |
| | polar=dict( |
| | radialaxis=dict(visible=True, range=[0, 100]) |
| | ), |
| | title="Financial Health Score", |
| | height=400 |
| | ) |
| | return fig |
| |
|
| | def main(): |
| | st.title("๐ FinanceGPT Analyzer") |
| | st.markdown("### Professional Financial Analysis Dashboard") |
| | |
| | |
| | with st.expander("๐ง Debug Information"): |
| | st.write("**Current working directory:**", os.getcwd()) |
| | st.write("**Available files:**") |
| | for root, dirs, files in os.walk('.'): |
| | for file in files[:10]: |
| | st.write(f"- {os.path.join(root, file)}") |
| | |
| | |
| | if st.session_state.analyzer is None: |
| | st.session_state.analyzer = FinanceAnalyzer() |
| | |
| | analyzer = st.session_state.analyzer |
| | |
| | |
| | with st.sidebar: |
| | st.header("Navigation") |
| | page = st.selectbox("Choose Analysis Page", [ |
| | "๐ Dashboard", |
| | "๐ฐ Income Analysis", |
| | "๐๏ธ Balance Sheet Analysis", |
| | "๐ธ Cash Flow Analysis", |
| | "๐ Financial Ratios Hub", |
| | "๐ค AI Finance Assistant" |
| | ]) |
| | |
| | st.header("Data Upload") |
| | uploaded_file = st.file_uploader("Upload CSV file", type=['csv']) |
| | |
| | if st.button("Load CSV Data"): |
| | try: |
| | df = analyzer.load_csv_data() |
| | analyzer.process_financial_data(df) |
| | st.session_state.data_loaded = True |
| | st.success("CSV data loaded successfully!") |
| | st.rerun() |
| | except Exception as e: |
| | st.error(f"Error loading CSV data: {e}") |
| | |
| | if st.button("Use Sample Data"): |
| | analyzer.data = analyzer.load_sample_data() |
| | analyzer.process_financial_data(analyzer.data) |
| | st.session_state.data_loaded = True |
| | st.success("Sample data loaded!") |
| | st.rerun() |
| | |
| | |
| | if uploaded_file is not None: |
| | try: |
| | |
| | df = load_data(uploaded_file) |
| | |
| | analyzer.data = df |
| | analyzer.process_financial_data(df) |
| | st.session_state.data_loaded = True |
| | st.success("โ
Data uploaded and processed successfully!") |
| | |
| | |
| | st.subheader("๐ Data Preview") |
| | st.write("**Shape:**", df.shape) |
| | st.write("**Columns:**", list(df.columns)) |
| | st.dataframe(df.head()) |
| | |
| | st.rerun() |
| | except Exception as e: |
| | st.error(f"โ Error loading file: {e}") |
| | st.info("๐ก Please ensure your CSV file has the correct format with columns: Statement_Type, Account_Name_Norwegian, Account_Name_English, 2024_Amount_NOK, 2023_Amount_NOK") |
| | |
| | |
| | if page == "๐ Dashboard": |
| | dashboard_page(analyzer) |
| | elif page == "๐ฐ Income Analysis": |
| | income_analysis_page(analyzer) |
| | elif page == "๐๏ธ Balance Sheet Analysis": |
| | balance_sheet_page(analyzer) |
| | elif page == "๐ธ Cash Flow Analysis": |
| | cash_flow_page(analyzer) |
| | elif page == "๐ Financial Ratios Hub": |
| | ratios_page(analyzer) |
| | elif page == "๐ค AI Finance Assistant": |
| | ai_assistant_page(analyzer) |
| |
|
| | def dashboard_page(analyzer): |
| | """Main dashboard page""" |
| | st.header("๐ Financial Dashboard") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload data or use sample data to begin analysis.") |
| | return |
| | |
| | metrics = analyzer.calculate_metrics() |
| | |
| | |
| | col1, col2, col3, col4 = st.columns(4) |
| | |
| | with col1: |
| | st.markdown(""" |
| | <div class="metric-card"> |
| | <h3>๐ฐ Revenue</h3> |
| | <h2>{:.1f}M NOK</h2> |
| | <p>+{:.0f}% ๐ฅ</p> |
| | </div> |
| | """.format(metrics.get('revenue_2024_m', 0), metrics.get('revenue_growth', 0)), |
| | unsafe_allow_html=True) |
| | |
| | with col2: |
| | st.markdown(""" |
| | <div class="metric-card"> |
| | <h3>๐ Net Profit</h3> |
| | <h2>{:.1f}M NOK</h2> |
| | <p>Profitable โ
</p> |
| | </div> |
| | """.format(metrics.get('net_profit_2024_m', 0)), unsafe_allow_html=True) |
| | |
| | with col3: |
| | st.markdown(""" |
| | <div class="metric-card"> |
| | <h3>๐ Gross Margin</h3> |
| | <h2>{:.1f}%</h2> |
| | <p>Healthy ๐ช</p> |
| | </div> |
| | """.format(metrics.get('gross_margin_2024', 0)), unsafe_allow_html=True) |
| | |
| | with col4: |
| | st.markdown(""" |
| | <div class="metric-card"> |
| | <h3>๐ฏ Net Margin</h3> |
| | <h2>{:.1f}%</h2> |
| | <p>Strong ๐</p> |
| | </div> |
| | """.format(metrics.get('net_margin_2024', 0)), unsafe_allow_html=True) |
| | |
| | |
| | col1, col2 = st.columns(2) |
| | |
| | with col1: |
| | st.plotly_chart(analyzer.create_revenue_trend_chart(), use_container_width=True) |
| | |
| | with col2: |
| | st.plotly_chart(analyzer.create_financial_health_radar(), use_container_width=True) |
| | |
| | |
| | st.markdown(""" |
| | <div class="insight-box"> |
| | <h4>๐ฏ Quick Insights</h4> |
| | <ul> |
| | <li>โ
Revenue growth of {:.0f}% indicates explosive business development</li> |
| | <li>๐ก Net profit margin of {:.1f}% shows strong profitability</li> |
| | <li>๐ Gross margin of {:.1f}% demonstrates healthy pricing power</li> |
| | </ul> |
| | </div> |
| | """.format( |
| | metrics.get('revenue_growth', 0), |
| | metrics.get('net_margin_2024', 0), |
| | metrics.get('gross_margin_2024', 0) |
| | ), unsafe_allow_html=True) |
| |
|
| | def income_analysis_page(analyzer): |
| | """Income statement analysis page""" |
| | st.header("๐ฐ Income Analysis") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload data to begin analysis.") |
| | return |
| | |
| | |
| | st.subheader("๐ Revenue Trend Analysis") |
| | st.plotly_chart(analyzer.create_revenue_trend_chart(), use_container_width=True) |
| | |
| | |
| | st.subheader("๐ฅง Cost Structure Analysis") |
| | if analyzer.processed_data: |
| | data = analyzer.processed_data |
| | costs = ['Cost of Goods Sold', 'Operating Expenses', 'Financial Expenses'] |
| | values = [data['cogs_2024'], 2000000, 234567] |
| | |
| | fig = px.pie(values=values, names=costs, title="Cost Breakdown 2024") |
| | st.plotly_chart(fig, use_container_width=True) |
| | |
| | |
| | st.subheader("๐ Profitability Indicators") |
| | metrics = analyzer.calculate_metrics() |
| | |
| | col1, col2, col3 = st.columns(3) |
| | with col1: |
| | st.metric("Gross Margin", f"{metrics.get('gross_margin_2024', 0):.1f}%") |
| | with col2: |
| | st.metric("Net Margin", f"{metrics.get('net_margin_2024', 0):.1f}%") |
| | with col3: |
| | st.metric("Revenue Growth", f"{metrics.get('revenue_growth', 0):.1f}%") |
| |
|
| | def balance_sheet_page(analyzer): |
| | """Balance sheet analysis page""" |
| | st.header("๐๏ธ Balance Sheet Analysis") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload balance sheet data to begin analysis.") |
| | return |
| | |
| | st.info("Balance sheet analysis requires additional data. Please upload complete financial statements.") |
| | |
| | |
| | assets = ['Current Assets', 'Fixed Assets', 'Intangible Assets'] |
| | values = [45, 35, 20] |
| | |
| | fig = px.pie(values=values, names=assets, title="Asset Structure") |
| | st.plotly_chart(fig, use_container_width=True) |
| |
|
| | def cash_flow_page(analyzer): |
| | """Cash flow analysis page""" |
| | st.header("๐ธ Cash Flow Analysis") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload cash flow data to begin analysis.") |
| | return |
| | |
| | st.info("Cash flow analysis requires additional data. Please upload complete cash flow statements.") |
| | |
| | |
| | categories = ['Operating CF', 'Investing CF', 'Financing CF'] |
| | values = [5000000, -2000000, -1000000] |
| | |
| | fig = go.Figure(go.Waterfall( |
| | name="Cash Flow", orientation="v", |
| | measure=["relative", "relative", "relative"], |
| | x=categories, y=values, |
| | text=[f"{v/1000000:.1f}M" for v in values] |
| | )) |
| | fig.update_layout(title="Cash Flow Waterfall") |
| | st.plotly_chart(fig, use_container_width=True) |
| |
|
| | def ratios_page(analyzer): |
| | """Financial ratios analysis page""" |
| | st.header("๐ Financial Ratios Hub") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload data to calculate ratios.") |
| | return |
| | |
| | |
| | col1, col2, col3, col4 = st.columns(4) |
| | |
| | with col1: |
| | if st.button("Profitability"): |
| | st.session_state.ratio_category = "profitability" |
| | with col2: |
| | if st.button("Liquidity"): |
| | st.session_state.ratio_category = "liquidity" |
| | with col3: |
| | if st.button("Efficiency"): |
| | st.session_state.ratio_category = "efficiency" |
| | with col4: |
| | if st.button("Growth"): |
| | st.session_state.ratio_category = "growth" |
| | |
| | |
| | metrics = analyzer.calculate_metrics() |
| | |
| | st.subheader("Key Financial Ratios") |
| | |
| | col1, col2, col3 = st.columns(3) |
| | with col1: |
| | st.metric("Gross Profit Margin", f"{metrics.get('gross_margin_2024', 0):.1f}%", "A+") |
| | with col2: |
| | st.metric("Net Profit Margin", f"{metrics.get('net_margin_2024', 0):.1f}%", "A") |
| | with col3: |
| | st.metric("Revenue Growth", f"{metrics.get('revenue_growth', 0):.1f}%", "A+") |
| |
|
| | def ai_assistant_page(analyzer): |
| | """AI finance assistant page""" |
| | st.header("๐ค AI Finance Assistant") |
| | |
| | if analyzer.data is None: |
| | st.warning("Please upload data to enable AI analysis.") |
| | return |
| | |
| | |
| | st.subheader("๐ฌ Ask Your Financial Questions") |
| | |
| | |
| | col1, col2 = st.columns(2) |
| | with col1: |
| | if st.button("Analyze my financial health"): |
| | st.session_state.ai_query = "financial_health" |
| | if st.button("Find the biggest risks"): |
| | st.session_state.ai_query = "risks" |
| | |
| | with col2: |
| | if st.button("Give investment advice"): |
| | st.session_state.ai_query = "investment" |
| | if st.button("Create improvement plan"): |
| | st.session_state.ai_query = "improvement" |
| | |
| | |
| | user_question = st.text_input("Or ask your own question:") |
| | |
| | if user_question or 'ai_query' in st.session_state: |
| | metrics = analyzer.calculate_metrics() |
| | |
| | |
| | if user_question or st.session_state.get('ai_query') == 'financial_health': |
| | st.markdown(""" |
| | <div class="insight-box"> |
| | <h4>๐ฏ Financial Health Analysis</h4> |
| | <p>Based on your financial data:</p> |
| | <ul> |
| | <li>โ
<strong>Revenue Growth:</strong> {:.0f}% growth shows strong market performance</li> |
| | <li>โ
<strong>Profitability:</strong> {:.1f}% net margin indicates healthy operations</li> |
| | <li>๐ <strong>Overall Rating:</strong> A- (Strong financial position)</li> |
| | </ul> |
| | </div> |
| | """.format( |
| | metrics.get('revenue_growth', 0), |
| | metrics.get('net_margin_2024', 0) |
| | ), unsafe_allow_html=True) |
| | |
| | |
| | if 'ai_query' in st.session_state: |
| | del st.session_state.ai_query |
| |
|
| | if __name__ == "__main__": |
| | main() |