openfree commited on
Commit
0cd8b82
Β·
verified Β·
1 Parent(s): f6f4ad9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -22
app.py CHANGED
@@ -5,6 +5,9 @@ from datetime import datetime
5
  import plotly.graph_objects as go
6
  import re
7
  from urllib.parse import urlparse
 
 
 
8
 
9
  class StartupValuationCalculator:
10
  def __init__(self):
@@ -79,6 +82,111 @@ class StartupValuationCalculator:
79
  }
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  def calculate_berkus_score(self, berkus_data):
83
  """λ²„ν¬μŠ€ λ°©λ²•μœΌλ‘œ 평가 (μ΅œλŒ€ $2.5M)"""
84
  scores = {}
@@ -104,7 +212,7 @@ class StartupValuationCalculator:
104
 
105
  # 3. μš°μˆ˜ν•œ νŒ€ (Quality Team)
106
  team_score = min(100,
107
- berkus_data["team_experience"] * 20 +
108
  berkus_data["domain_expertise"] * 15 +
109
  berkus_data["startup_experience"] * 15
110
  )
@@ -133,7 +241,7 @@ class StartupValuationCalculator:
133
  adjustments = {}
134
 
135
  # 각 μš”μ†Œλ³„ μ‘°μ • λΉ„μœ¨ 계산 (0.5 ~ 1.5)
136
- adjustments["team"] = scorecard_data["team_strength"] / 100 # 0-100 -> 0-1
137
  adjustments["market_size"] = scorecard_data["market_opportunity"] / 100
138
  adjustments["product"] = scorecard_data["product_stage"] / 100
139
  adjustments["competition"] = scorecard_data["competitive_advantage"] / 100
@@ -332,7 +440,7 @@ def create_ui():
332
  calculator = StartupValuationCalculator()
333
 
334
  def process_valuation(
335
- language,
336
  # κΈ°λ³Έ 정보
337
  company_name, founded_year, industry, stage, revenue_type,
338
  # 맀좜 정보
@@ -351,7 +459,9 @@ def create_ui():
351
  # 데이터 μ€€λΉ„
352
  data = {
353
  "company_name": company_name,
 
354
  "industry": industry,
 
355
  "revenue_type": revenue_type,
356
  "monthly_revenue": monthly_revenue * 1000,
357
  "growth_rate": growth_rate,
@@ -465,6 +575,25 @@ def create_ui():
465
  ## πŸƒ {t['financial_health']}
466
  - **Cash Runway**: {results['runway']:.1f} months
467
  - **Monthly Burn Rate**: ${burn_rate}K
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  """
469
 
470
  # 차트 생성
@@ -497,23 +626,29 @@ def create_ui():
497
 
498
  # Gradio UI
499
  with gr.Blocks(title="Startup Valuation Calculator", theme=gr.themes.Soft()) as demo:
500
- # μ–Έμ–΄ 선택
501
- language = gr.Radio(
502
- choices=[("ν•œκ΅­μ–΄", "ko"), ("English", "en")],
503
- value="ko",
504
- label="Language / μ–Έμ–΄",
505
- type="value"
506
- )
507
-
508
  gr.Markdown("""
509
- # πŸ¦„ μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ μžλ™ν™” μ‹œμŠ€ν…œ v3.0
510
- ### λ²„ν¬μŠ€ 방법과 μŠ€μ½”μ–΄μΉ΄λ“œ 방법을 ν¬ν•¨ν•œ μ’…ν•© 평가
511
  """)
512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
  with gr.Tab("κΈ°λ³Έ 정보 / Basic Info"):
514
  with gr.Row():
515
  company_name = gr.Textbox(label="νšŒμ‚¬λͺ… / Company Name", value="우리 μŠ€νƒ€νŠΈμ—…")
516
- founded_year = gr.Slider(2015, 2024, value=2022, step=1, label="섀립연도 / Founded Year")
517
 
518
  with gr.Row():
519
  industry = gr.Dropdown(
@@ -550,7 +685,7 @@ def create_ui():
550
 
551
  gr.Markdown("### πŸ‘₯ νŒ€ μ—­λŸ‰ / Team Quality")
552
  with gr.Row():
553
- team_experience = gr.Slider(0, 5, value=3, step=1,
554
  label="νŒ€ 평균 κ²½λ ₯(λ…„) / Average Experience (years)")
555
  domain_expertise = gr.Slider(0, 5, value=3, step=1,
556
  label="도메인 μ „λ¬Έμ„± / Domain Expertise (1-5)")
@@ -573,6 +708,7 @@ def create_ui():
573
 
574
  with gr.Tab("μŠ€μ½”μ–΄μΉ΄λ“œ 평가 / Scorecard"):
575
  gr.Markdown("### 각 μš”μ†Œλ₯Ό 동일 μŠ€ν…Œμ΄μ§€ 평균 λŒ€λΉ„ 평가 (50 = 평균)")
 
576
 
577
  team_strength = gr.Slider(0, 100, value=60, step=5,
578
  label="νŒ€ μ—­λŸ‰ / Team Strength")
@@ -636,7 +772,7 @@ def create_ui():
636
  evaluate_btn.click(
637
  process_valuation,
638
  inputs=[
639
- language,
640
  company_name, founded_year, industry, stage, revenue_type,
641
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
642
  retention_rate, new_customers, monthly_marketing, monthly_sales,
@@ -655,13 +791,13 @@ def create_ui():
655
  with gr.Row():
656
  gr.Button("초기 μŠ€νƒ€νŠΈμ—… / Early Startup").click(
657
  lambda: [
658
- "ko", "ν…Œν¬ μŠ€νƒ€νŠΈμ—…", 2023, "AI/λ”₯ν…Œν¬", "MVP/베타", "κ΅¬λ…ν˜• (SaaS)",
659
  0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 50,
660
- 80, 7, "베타 버전", 2, 4, 1, 1, 2, 3, False, 0, 70,
661
  70, 65, 55, 60, 45, 50, 50
662
  ],
663
  outputs=[
664
- language, company_name, founded_year, industry, stage, revenue_type,
665
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
666
  retention_rate, new_customers, monthly_marketing, monthly_sales,
667
  cash_balance, burn_rate,
@@ -675,13 +811,13 @@ def create_ui():
675
 
676
  gr.Button("μ„±μž₯ 단계 / Growth Stage").click(
677
  lambda: [
678
- "en", "SaaS Corp", 2021, "SaaS - B2B", "μ„±μž₯ 단계", "κ΅¬λ…ν˜• (SaaS)",
679
  100, 150, 200, 75, 2, 90, 40, 30, 20, 2000, 120,
680
- 90, 9, "μΆœμ‹œ 버전", 5, 5, 3, 5, 5, 20, True, 8, 95,
681
  85, 80, 75, 70, 65, 75, 60
682
  ],
683
  outputs=[
684
- language, company_name, founded_year, industry, stage, revenue_type,
685
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
686
  retention_rate, new_customers, monthly_marketing, monthly_sales,
687
  cash_balance, burn_rate,
 
5
  import plotly.graph_objects as go
6
  import re
7
  from urllib.parse import urlparse
8
+ import requests
9
+ import json
10
+ import os
11
 
12
  class StartupValuationCalculator:
13
  def __init__(self):
 
82
  }
83
  }
84
 
85
+ def call_llm_api(self, prompt, api_key):
86
+ """LLM APIλ₯Ό ν˜ΈμΆœν•˜μ—¬ κ³ κΈ‰ 뢄석 μˆ˜ν–‰"""
87
+ if not api_key:
88
+ return None
89
+
90
+ url = "https://api.fireworks.ai/inference/v1/chat/completions"
91
+
92
+ payload = {
93
+ "model": "accounts/fireworks/models/qwen3-235b-a22b-instruct-2507",
94
+ "max_tokens": 4096,
95
+ "top_p": 1,
96
+ "top_k": 40,
97
+ "presence_penalty": 0,
98
+ "frequency_penalty": 0,
99
+ "temperature": 0.6,
100
+ "messages": [
101
+ {
102
+ "role": "system",
103
+ "content": "You are an expert startup valuation analyst and strategic advisor with deep knowledge of venture capital, financial analysis, and business strategy."
104
+ },
105
+ {
106
+ "role": "user",
107
+ "content": prompt
108
+ }
109
+ ]
110
+ }
111
+
112
+ headers = {
113
+ "Accept": "application/json",
114
+ "Content-Type": "application/json",
115
+ "Authorization": f"Bearer {api_key}"
116
+ }
117
+
118
+ try:
119
+ response = requests.post(url, headers=headers, data=json.dumps(payload))
120
+ if response.status_code == 200:
121
+ return response.json()['choices'][0]['message']['content']
122
+ else:
123
+ return None
124
+ except:
125
+ return None
126
+
127
+ def generate_strategic_report(self, data, results, language, api_key):
128
+ """LLM을 μ‚¬μš©ν•˜μ—¬ μ „λž΅μ  λ³΄κ³ μ„œ 생성"""
129
+
130
+ if language == "ko":
131
+ prompt = f"""
132
+ λ‹€μŒ μŠ€νƒ€νŠΈμ—…μ˜ κ°€μΉ˜ν‰κ°€ κ²°κ³Όλ₯Ό λΆ„μ„ν•˜κ³  μ „λž΅μ  쑰언을 ν¬ν•¨ν•œ 상세 λ³΄κ³ μ„œλ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”:
133
+
134
+ νšŒμ‚¬ 정보:
135
+ - νšŒμ‚¬λͺ…: {data['company_name']}
136
+ - 섀립년도: {data['founded_year']}
137
+ - μ‚°μ—…: {data['industry']}
138
+ - 사업 단계: {data['stage']}
139
+
140
+ 평가 κ²°κ³Ό:
141
+ - μ΅œμ’… κΈ°μ—…κ°€μΉ˜: ${results['final_valuation']/1000000:.2f}M
142
+ - λ²„ν¬μŠ€ 평가: ${results['berkus_valuation']/1000000:.2f}M
143
+ - ARR: ${results['arr']/1000000:.2f}M
144
+ - μ„±μž₯λ₯ : {data['growth_rate']}%
145
+ - LTV/CAC: {results['ltv_cac_ratio']:.1f}
146
+ - λŸ°μ›¨μ΄: {results['runway']:.1f}κ°œμ›”
147
+ - μŠ€μ½”μ–΄μΉ΄λ“œ μ μˆ˜λ“€: {results['scorecard_adjustments']}
148
+
149
+ λ‹€μŒμ„ ν¬ν•¨ν•˜μ—¬ μž‘μ„±ν•΄μ£Όμ„Έμš”:
150
+ 1. κ°€μΉ˜ν‰κ°€ 결과의 타당성 뢄석
151
+ 2. 동쒅업계 λŒ€λΉ„ 포지셔닝
152
+ 3. μ£Όμš” 강점과 κ°œμ„  ν•„μš” μ˜μ—­
153
+ 4. ν–₯ν›„ 6-12κ°œμ›” μ „λž΅μ  μš°μ„ μˆœμœ„
154
+ 5. μžκΈˆμ‘°λ‹¬ μ „λž΅ 및 적정 쑰달 규λͺ¨
155
+ 6. μ£Όμš” λ¦¬μŠ€ν¬μ™€ μ™„ν™” λ°©μ•ˆ
156
+ 7. 핡심 KPI와 λ§ˆμΌμŠ€ν†€ μ œμ•ˆ
157
+ """
158
+ else:
159
+ prompt = f"""
160
+ Please analyze the following startup valuation results and provide a comprehensive strategic report:
161
+
162
+ Company Information:
163
+ - Company Name: {data['company_name']}
164
+ - Founded: {data['founded_year']}
165
+ - Industry: {data['industry']}
166
+ - Stage: {data['stage']}
167
+
168
+ Valuation Results:
169
+ - Final Valuation: ${results['final_valuation']/1000000:.2f}M
170
+ - Berkus Valuation: ${results['berkus_valuation']/1000000:.2f}M
171
+ - ARR: ${results['arr']/1000000:.2f}M
172
+ - Growth Rate: {data['growth_rate']}%
173
+ - LTV/CAC: {results['ltv_cac_ratio']:.1f}
174
+ - Runway: {results['runway']:.1f} months
175
+ - Scorecard Scores: {results['scorecard_adjustments']}
176
+
177
+ Please include:
178
+ 1. Valuation validity analysis
179
+ 2. Industry positioning
180
+ 3. Key strengths and improvement areas
181
+ 4. Strategic priorities for next 6-12 months
182
+ 5. Fundraising strategy and optimal round size
183
+ 6. Key risks and mitigation strategies
184
+ 7. Core KPIs and milestone recommendations
185
+ """
186
+
187
+ llm_response = self.call_llm_api(prompt, api_key)
188
+ return llm_response
189
+
190
  def calculate_berkus_score(self, berkus_data):
191
  """λ²„ν¬μŠ€ λ°©λ²•μœΌλ‘œ 평가 (μ΅œλŒ€ $2.5M)"""
192
  scores = {}
 
212
 
213
  # 3. μš°μˆ˜ν•œ νŒ€ (Quality Team)
214
  team_score = min(100,
215
+ min(berkus_data["team_experience"], 10) * 10 + # μ΅œλŒ€ 10λ…„κΉŒμ§€λ§Œ κ°€μ‚°
216
  berkus_data["domain_expertise"] * 15 +
217
  berkus_data["startup_experience"] * 15
218
  )
 
241
  adjustments = {}
242
 
243
  # 각 μš”μ†Œλ³„ μ‘°μ • λΉ„μœ¨ 계산 (0.5 ~ 1.5)
244
+ adjustments["team"] = scorecard_data["team_strength"] / 100
245
  adjustments["market_size"] = scorecard_data["market_opportunity"] / 100
246
  adjustments["product"] = scorecard_data["product_stage"] / 100
247
  adjustments["competition"] = scorecard_data["competitive_advantage"] / 100
 
440
  calculator = StartupValuationCalculator()
441
 
442
  def process_valuation(
443
+ api_key, language,
444
  # κΈ°λ³Έ 정보
445
  company_name, founded_year, industry, stage, revenue_type,
446
  # 맀좜 정보
 
459
  # 데이터 μ€€λΉ„
460
  data = {
461
  "company_name": company_name,
462
+ "founded_year": founded_year,
463
  "industry": industry,
464
+ "stage": stage,
465
  "revenue_type": revenue_type,
466
  "monthly_revenue": monthly_revenue * 1000,
467
  "growth_rate": growth_rate,
 
575
  ## πŸƒ {t['financial_health']}
576
  - **Cash Runway**: {results['runway']:.1f} months
577
  - **Monthly Burn Rate**: ${burn_rate}K
578
+ """
579
+
580
+ # LLM 기반 μ „λž΅μ  뢄석 μΆ”κ°€
581
+ strategic_report = None
582
+ if api_key and api_key.strip():
583
+ strategic_report = calculator.generate_strategic_report(data, results, language, api_key)
584
+
585
+ if strategic_report:
586
+ if language == "ko":
587
+ valuation_text += f"""
588
+ ## πŸ€– AI μ „λž΅μ  뢄석
589
+
590
+ {strategic_report}
591
+ """
592
+ else:
593
+ valuation_text += f"""
594
+ ## πŸ€– AI Strategic Analysis
595
+
596
+ {strategic_report}
597
  """
598
 
599
  # 차트 생성
 
626
 
627
  # Gradio UI
628
  with gr.Blocks(title="Startup Valuation Calculator", theme=gr.themes.Soft()) as demo:
 
 
 
 
 
 
 
 
629
  gr.Markdown("""
630
+ # πŸ¦„ μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ μžλ™ν™” μ‹œμŠ€ν…œ v3.5
631
+ ### AI 기반 μ „λž΅μ  뢄석을 ν¬ν•¨ν•œ μ’…ν•© 평가 μ‹œμŠ€ν…œ
632
  """)
633
 
634
+ # API 킀와 μ–Έμ–΄ 선택
635
+ with gr.Row():
636
+ api_key = gr.Textbox(
637
+ label="Fireworks API Key (선택사항 - AI λΆ„μ„μš©)",
638
+ placeholder="AI μ „λž΅μ  뢄석을 μ›ν•˜μ‹œλ©΄ API ν‚€λ₯Ό μž…λ ₯ν•˜μ„Έμš”",
639
+ type="password"
640
+ )
641
+ language = gr.Radio(
642
+ choices=[("ν•œκ΅­μ–΄", "ko"), ("English", "en")],
643
+ value="ko",
644
+ label="Language / μ–Έμ–΄",
645
+ type="value"
646
+ )
647
+
648
  with gr.Tab("κΈ°λ³Έ 정보 / Basic Info"):
649
  with gr.Row():
650
  company_name = gr.Textbox(label="νšŒμ‚¬λͺ… / Company Name", value="우리 μŠ€νƒ€νŠΈμ—…")
651
+ founded_year = gr.Slider(2000, 2025, value=2022, step=1, label="섀립연도 / Founded Year")
652
 
653
  with gr.Row():
654
  industry = gr.Dropdown(
 
685
 
686
  gr.Markdown("### πŸ‘₯ νŒ€ μ—­λŸ‰ / Team Quality")
687
  with gr.Row():
688
+ team_experience = gr.Slider(0, 30, value=5, step=1,
689
  label="νŒ€ 평균 κ²½λ ₯(λ…„) / Average Experience (years)")
690
  domain_expertise = gr.Slider(0, 5, value=3, step=1,
691
  label="도메인 μ „λ¬Έμ„± / Domain Expertise (1-5)")
 
708
 
709
  with gr.Tab("μŠ€μ½”μ–΄μΉ΄λ“œ 평가 / Scorecard"):
710
  gr.Markdown("### 각 μš”μ†Œλ₯Ό 동일 μŠ€ν…Œμ΄μ§€ 평균 λŒ€λΉ„ 평가 (50 = 평균)")
711
+ gr.Markdown("### Rate each factor compared to same-stage average (50 = average)")
712
 
713
  team_strength = gr.Slider(0, 100, value=60, step=5,
714
  label="νŒ€ μ—­λŸ‰ / Team Strength")
 
772
  evaluate_btn.click(
773
  process_valuation,
774
  inputs=[
775
+ api_key, language,
776
  company_name, founded_year, industry, stage, revenue_type,
777
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
778
  retention_rate, new_customers, monthly_marketing, monthly_sales,
 
791
  with gr.Row():
792
  gr.Button("초기 μŠ€νƒ€νŠΈμ—… / Early Startup").click(
793
  lambda: [
794
+ "", "ko", "ν…Œν¬ μŠ€νƒ€νŠΈμ—…", 2023, "AI/λ”₯ν…Œν¬", "MVP/베타", "κ΅¬λ…ν˜• (SaaS)",
795
  0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 50,
796
+ 80, 7, "베타 버전", 3, 4, 1, 1, 2, 3, False, 0, 70,
797
  70, 65, 55, 60, 45, 50, 50
798
  ],
799
  outputs=[
800
+ api_key, language, company_name, founded_year, industry, stage, revenue_type,
801
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
802
  retention_rate, new_customers, monthly_marketing, monthly_sales,
803
  cash_balance, burn_rate,
 
811
 
812
  gr.Button("μ„±μž₯ 단계 / Growth Stage").click(
813
  lambda: [
814
+ "", "en", "SaaS Corp", 2021, "SaaS - B2B", "μ„±μž₯ 단계", "κ΅¬λ…ν˜• (SaaS)",
815
  100, 150, 200, 75, 2, 90, 40, 30, 20, 2000, 120,
816
+ 90, 9, "μΆœμ‹œ 버전", 8, 5, 3, 5, 5, 20, True, 8, 95,
817
  85, 80, 75, 70, 65, 75, 60
818
  ],
819
  outputs=[
820
+ api_key, language, company_name, founded_year, industry, stage, revenue_type,
821
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
822
  retention_rate, new_customers, monthly_marketing, monthly_sales,
823
  cash_balance, burn_rate,