Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -29,25 +29,130 @@ class StartupValuationCalculator:
|
|
| 29 |
"200%+": 1.5
|
| 30 |
}
|
| 31 |
|
| 32 |
-
#
|
| 33 |
-
self.
|
| 34 |
-
"
|
| 35 |
-
"
|
| 36 |
-
"
|
| 37 |
-
"
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
-
#
|
| 41 |
-
self.
|
| 42 |
-
"
|
| 43 |
-
"
|
| 44 |
-
"
|
| 45 |
-
"
|
| 46 |
-
"
|
| 47 |
-
"
|
| 48 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
}
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
def calculate_arr(self, monthly_revenue, revenue_type):
|
| 52 |
"""μ λ§€μΆμ μ°κ° λ°λ³΅ λ§€μΆ(ARR)λ‘ λ³ν"""
|
| 53 |
if revenue_type == "ꡬλ
ν (SaaS)":
|
|
@@ -75,129 +180,82 @@ class StartupValuationCalculator:
|
|
| 75 |
return 999
|
| 76 |
return cac / (arpu * (gross_margin / 100))
|
| 77 |
|
| 78 |
-
def
|
| 79 |
-
"""
|
| 80 |
-
|
| 81 |
-
"ltv_cac_ratio": min(100, (ltv_cac_ratio / 3) * 100) if ltv_cac_ratio > 0 else 0,
|
| 82 |
-
"gross_margin": min(100, gross_margin * 1.25),
|
| 83 |
-
"retention": retention_rate,
|
| 84 |
-
"payback": max(0, 100 - (payback_months / 24) * 100) if payback_months < 999 else 0
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
total_score = sum(scores[key] * self.unit_economics_weights[key] for key in scores)
|
| 88 |
-
return total_score
|
| 89 |
-
|
| 90 |
-
def evaluate_domain(self, domains):
|
| 91 |
-
"""λλ©μΈ κ°μΉ νκ°"""
|
| 92 |
-
if not domains:
|
| 93 |
-
return 0
|
| 94 |
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
-
#
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
else:
|
| 108 |
-
|
| 109 |
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
score = 0
|
| 122 |
-
score += patent_filed * 15 # μΆμ νΉνλΉ 15μ
|
| 123 |
-
score += patent_granted * 30 # λ±λ‘ νΉνλΉ 30μ
|
| 124 |
-
return min(100, score)
|
| 125 |
-
|
| 126 |
-
def evaluate_papers(self, papers):
|
| 127 |
-
"""λ
Όλ¬Έ κ°μΉ νκ°"""
|
| 128 |
-
if not papers:
|
| 129 |
-
return 0
|
| 130 |
-
|
| 131 |
-
paper_count = len([p.strip() for p in papers.split('\n') if p.strip()])
|
| 132 |
-
score = paper_count * 20 # λ
Όλ¬ΈλΉ 20μ
|
| 133 |
-
|
| 134 |
-
# μ£Όμ νν/μ λ ν€μλ 체ν¬
|
| 135 |
-
prestigious_keywords = ['Nature', 'Science', 'IEEE', 'ACM', 'CVPR', 'NeurIPS', 'ICML']
|
| 136 |
-
for keyword in prestigious_keywords:
|
| 137 |
-
if keyword.lower() in papers.lower():
|
| 138 |
-
score += 10
|
| 139 |
-
|
| 140 |
-
return min(100, score)
|
| 141 |
-
|
| 142 |
-
def evaluate_github(self, github_url, github_stars):
|
| 143 |
-
"""GitHub μ μ₯μ νκ°"""
|
| 144 |
-
if not github_url:
|
| 145 |
-
return 0
|
| 146 |
-
|
| 147 |
-
score = 0
|
| 148 |
-
if github_stars >= 1000:
|
| 149 |
-
score = 80
|
| 150 |
-
elif github_stars >= 500:
|
| 151 |
-
score = 60
|
| 152 |
-
elif github_stars >= 100:
|
| 153 |
-
score = 40
|
| 154 |
-
elif github_stars >= 50:
|
| 155 |
-
score = 20
|
| 156 |
else:
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
#
|
| 166 |
-
if
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
# λ°μ¬ νμ
|
| 174 |
-
score += min(30, phd_count * 10)
|
| 175 |
|
| 176 |
-
#
|
| 177 |
-
|
|
|
|
|
|
|
| 178 |
|
| 179 |
-
|
| 180 |
-
|
|
|
|
|
|
|
|
|
|
| 181 |
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
def calculate_ip_score(self, ip_data):
|
| 185 |
-
"""μ§μ μ¬μ° μ’
ν© μ μ κ³μ°"""
|
| 186 |
-
scores = {
|
| 187 |
-
"patents": self.evaluate_patents(ip_data["patent_filed"], ip_data["patent_granted"]),
|
| 188 |
-
"papers": self.evaluate_papers(ip_data["papers"]),
|
| 189 |
-
"domains": self.evaluate_domain(ip_data["domains"]),
|
| 190 |
-
"trademarks": min(100, ip_data["trademarks"] * 20),
|
| 191 |
-
"github": self.evaluate_github(ip_data["github_url"], ip_data["github_stars"]),
|
| 192 |
-
"awards": min(100, ip_data["awards"] * 25),
|
| 193 |
-
"team": self.evaluate_team(
|
| 194 |
-
ip_data["team_size"], ip_data["phd_count"],
|
| 195 |
-
ip_data["serial_entrepreneurs"], ip_data["big_tech_experience"]
|
| 196 |
-
)
|
| 197 |
-
}
|
| 198 |
|
| 199 |
-
|
| 200 |
-
return total_score, scores
|
| 201 |
|
| 202 |
def get_growth_category(self, growth_rate):
|
| 203 |
"""μ±μ₯λ₯ μΉ΄ν
κ³ λ¦¬ κ²°μ """
|
|
@@ -212,128 +270,60 @@ class StartupValuationCalculator:
|
|
| 212 |
else:
|
| 213 |
return "200%+"
|
| 214 |
|
| 215 |
-
def
|
| 216 |
-
"""
|
| 217 |
-
# ARR κ³μ°
|
| 218 |
-
arr = self.calculate_arr(data["monthly_revenue"], data["revenue_type"])
|
| 219 |
-
|
| 220 |
-
# λ¨μκ²½μ κ³μ°
|
| 221 |
-
ltv = self.calculate_ltv(data["arpu"], data["gross_margin"], data["monthly_churn"])
|
| 222 |
-
cac = self.calculate_cac(data["monthly_marketing"], data["monthly_sales"], data["new_customers"])
|
| 223 |
-
ltv_cac_ratio = ltv / cac if cac > 0 else 0
|
| 224 |
-
payback = self.calculate_payback(cac, data["arpu"], data["gross_margin"])
|
| 225 |
-
|
| 226 |
-
# λ¨μκ²½μ μ μ
|
| 227 |
-
ue_score = self.get_unit_economics_score(
|
| 228 |
-
ltv_cac_ratio, data["gross_margin"], data["retention_rate"], payback
|
| 229 |
-
)
|
| 230 |
-
|
| 231 |
-
# IP μμ° μ μ
|
| 232 |
-
ip_score, ip_breakdown = self.calculate_ip_score(ip_data)
|
| 233 |
-
|
| 234 |
-
# μ’
ν© μ μ (λ¨μκ²½μ 60%, IP 40%)
|
| 235 |
-
combined_score = ue_score * 0.6 + ip_score * 0.4
|
| 236 |
-
|
| 237 |
-
# κΈ°λ³Έ λ©ν°ν μ ν
|
| 238 |
-
multiples = self.industry_multiples[data["industry"]]
|
| 239 |
-
if combined_score >= 80:
|
| 240 |
-
base_multiple = multiples["high"]
|
| 241 |
-
elif combined_score >= 50:
|
| 242 |
-
base_multiple = multiples["mid"]
|
| 243 |
-
else:
|
| 244 |
-
base_multiple = multiples["low"]
|
| 245 |
-
|
| 246 |
-
# μ±μ₯λ₯ μ‘°μ
|
| 247 |
-
growth_adj = self.growth_adjustments[self.get_growth_category(data["growth_rate"])]
|
| 248 |
-
adjusted_multiple = base_multiple * growth_adj
|
| 249 |
-
|
| 250 |
-
# μ€ν
μ΄μ§ μ‘°μ
|
| 251 |
-
stage_adj = {
|
| 252 |
-
"MVP/λ² ν": 0.7,
|
| 253 |
-
"μ΄κΈ° λ§€μΆ": 0.85,
|
| 254 |
-
"μ±μ₯ λ¨κ³": 1.0,
|
| 255 |
-
"μμ΅μ± ν보": 1.2
|
| 256 |
-
}
|
| 257 |
-
|
| 258 |
-
# IP μμ° ν리미μ (μ΅λ 20%)
|
| 259 |
-
ip_premium = 1 + (ip_score / 100 * 0.2)
|
| 260 |
-
|
| 261 |
-
final_multiple = adjusted_multiple * stage_adj[data["stage"]] * ip_premium
|
| 262 |
-
|
| 263 |
-
# μ΅μ’
κ°μΉνκ°
|
| 264 |
-
valuation = arr * final_multiple
|
| 265 |
-
|
| 266 |
-
# λ°μ¨μ΄ κ³μ°
|
| 267 |
-
runway = data["cash_balance"] / data["burn_rate"] if data["burn_rate"] > 0 else 999
|
| 268 |
-
|
| 269 |
-
return {
|
| 270 |
-
"valuation": valuation,
|
| 271 |
-
"arr": arr,
|
| 272 |
-
"multiple": final_multiple,
|
| 273 |
-
"ltv": ltv,
|
| 274 |
-
"cac": cac,
|
| 275 |
-
"ltv_cac_ratio": ltv_cac_ratio,
|
| 276 |
-
"payback": payback,
|
| 277 |
-
"ue_score": ue_score,
|
| 278 |
-
"ip_score": ip_score,
|
| 279 |
-
"ip_breakdown": ip_breakdown,
|
| 280 |
-
"combined_score": combined_score,
|
| 281 |
-
"runway": runway
|
| 282 |
-
}
|
| 283 |
-
|
| 284 |
-
def create_comparison_chart(self, valuation, industry, arr):
|
| 285 |
-
"""λμ’
μ
κ³ λΉκ΅ μ°¨νΈ μμ±"""
|
| 286 |
-
multiples = self.industry_multiples[industry]
|
| 287 |
-
|
| 288 |
fig = go.Figure()
|
| 289 |
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
|
|
|
|
|
|
| 294 |
|
| 295 |
-
# λ§λ κ·Έλν
|
| 296 |
fig.add_trace(go.Bar(
|
| 297 |
-
x=
|
| 298 |
-
y=
|
| 299 |
-
text=[f"${
|
| 300 |
-
f"${high_val/1000000:.1f}M", f"${valuation/1000000:.1f}M"],
|
| 301 |
textposition="outside",
|
| 302 |
-
marker_color=["
|
| 303 |
))
|
| 304 |
|
|
|
|
| 305 |
fig.update_layout(
|
| 306 |
-
title=
|
| 307 |
-
yaxis_title="
|
| 308 |
showlegend=False,
|
| 309 |
height=400
|
| 310 |
)
|
| 311 |
|
| 312 |
return fig
|
| 313 |
|
| 314 |
-
def
|
| 315 |
-
"""
|
| 316 |
-
categories = list(
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
r=values,
|
| 322 |
-
theta=categories,
|
| 323 |
-
fill='toself',
|
| 324 |
-
name='IP μμ° μ μ'
|
| 325 |
-
)
|
| 326 |
-
])
|
| 327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
fig.update_layout(
|
| 329 |
polar=dict(
|
| 330 |
radialaxis=dict(
|
| 331 |
visible=True,
|
| 332 |
range=[0, 100]
|
| 333 |
-
)
|
| 334 |
-
),
|
| 335 |
showlegend=False,
|
| 336 |
-
title=
|
| 337 |
)
|
| 338 |
|
| 339 |
return fig
|
|
@@ -342,26 +332,26 @@ def create_ui():
|
|
| 342 |
calculator = StartupValuationCalculator()
|
| 343 |
|
| 344 |
def process_valuation(
|
|
|
|
|
|
|
| 345 |
company_name, founded_year, industry, stage, revenue_type,
|
|
|
|
| 346 |
monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
|
| 347 |
retention_rate, new_customers, monthly_marketing, monthly_sales,
|
|
|
|
| 348 |
cash_balance, burn_rate,
|
| 349 |
-
#
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
|
|
|
|
|
|
| 354 |
):
|
| 355 |
-
# μ
λ ₯κ° κ²μ¦
|
| 356 |
-
if monthly_revenue <= 0:
|
| 357 |
-
return "μ λ§€μΆμ μ
λ ₯ν΄μ£ΌμΈμ.", None, None, None
|
| 358 |
-
|
| 359 |
# λ°μ΄ν° μ€λΉ
|
| 360 |
data = {
|
| 361 |
"company_name": company_name,
|
| 362 |
-
"founded_year": founded_year,
|
| 363 |
"industry": industry,
|
| 364 |
-
"stage": stage,
|
| 365 |
"revenue_type": revenue_type,
|
| 366 |
"monthly_revenue": monthly_revenue * 1000,
|
| 367 |
"growth_rate": growth_rate,
|
|
@@ -376,285 +366,330 @@ def create_ui():
|
|
| 376 |
"burn_rate": burn_rate * 1000
|
| 377 |
}
|
| 378 |
|
| 379 |
-
|
| 380 |
-
"
|
| 381 |
-
"
|
| 382 |
-
"
|
| 383 |
-
"
|
| 384 |
-
"
|
| 385 |
-
"
|
| 386 |
-
"github_stars": github_stars,
|
| 387 |
-
"awards": awards,
|
| 388 |
"partnerships": partnerships,
|
| 389 |
-
"
|
| 390 |
-
"
|
| 391 |
-
"
|
| 392 |
-
"
|
| 393 |
-
"
|
| 394 |
-
|
| 395 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
}
|
| 397 |
|
| 398 |
# κ°μΉνκ° κ³μ°
|
| 399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
|
| 401 |
# κ²°κ³Ό ν¬λ§·ν
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
## π μ£Όμ μ§ν
|
| 406 |
-
- **κΈ°μ
κ°μΉ**: ${results['valuation']/1000000:.1f}M (β©{results['valuation']/1000000*1300:.0f}μ΅)
|
| 407 |
-
- **ARR**: ${results['arr']/1000000:.1f}M
|
| 408 |
-
- **μ μ© λ©ν°ν**: {results['multiple']:.1f}x
|
| 409 |
|
| 410 |
-
##
|
| 411 |
-
- **
|
| 412 |
-
-
|
| 413 |
-
-
|
| 414 |
-
- **Payback Period**: {results['payback']:.1f}κ°μ
|
| 415 |
-
- **λ¨μκ²½μ μ μ**: {results['ue_score']:.0f}/100
|
| 416 |
-
|
| 417 |
-
## π― μ§μ μ¬μ° λ° λ¬΄νμμ°
|
| 418 |
-
- **IP μμ° μ μ**: {results['ip_score']:.0f}/100
|
| 419 |
-
- **μ’
ν© μ μ**: {results['combined_score']:.0f}/100
|
| 420 |
|
| 421 |
-
|
| 422 |
-
-
|
| 423 |
-
-
|
| 424 |
-
-
|
| 425 |
-
-
|
| 426 |
-
-
|
| 427 |
-
-
|
| 428 |
-
|
|
|
|
|
|
|
|
|
|
| 429 |
|
| 430 |
-
##
|
| 431 |
-
-
|
| 432 |
-
-
|
|
|
|
| 433 |
|
| 434 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
"""
|
| 436 |
-
# μΈμ¬μ΄νΈ μΆκ°
|
| 437 |
-
if results['ltv_cac_ratio'] < 1:
|
| 438 |
-
valuation_text += "- β οΈ LTV/CAC λΉμ¨μ΄ 1 λ―Έλ§μ
λλ€. λ§μΌν
ν¨μ¨μ± κ°μ μ΄ νμν©λλ€.\n"
|
| 439 |
-
elif results['ltv_cac_ratio'] > 3:
|
| 440 |
-
valuation_text += "- β
μ°μν LTV/CAC λΉμ¨μ 보μ΄κ³ μμ΅λλ€.\n"
|
| 441 |
-
|
| 442 |
-
if results['runway'] < 12:
|
| 443 |
-
valuation_text += "- β οΈ λ°μ¨μ΄κ° 12κ°μ λ―Έλ§μ
λλ€. μΆκ° μκΈμ‘°λ¬μ κ³ λ €νμΈμ.\n"
|
| 444 |
-
|
| 445 |
-
if gross_margin < 60:
|
| 446 |
-
valuation_text += "- π λ§€μΆμ΄μ΄μ΅λ₯ κ°μ μ¬μ§κ° μμ΅λλ€. (μ
κ³ νκ· : 70-80%)\n"
|
| 447 |
-
|
| 448 |
-
if results['ip_score'] > 70:
|
| 449 |
-
valuation_text += "- π κ°λ ₯ν IP ν¬νΈν΄λ¦¬μ€λ₯Ό 보μ νκ³ μμ΄ κ°μΉνκ°μ ν리미μμ΄ μ μ©λμμ΅λλ€.\n"
|
| 450 |
|
| 451 |
-
#
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
|
| 456 |
-
#
|
| 457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 458 |
|
| 459 |
-
#
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
-
return valuation_text, comparison_chart,
|
| 468 |
|
| 469 |
# Gradio UI
|
| 470 |
-
with gr.Blocks(title="
|
| 471 |
-
|
| 472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
|
| 474 |
-
|
| 475 |
-
|
|
|
|
| 476 |
""")
|
| 477 |
|
| 478 |
-
with gr.Tab("κΈ°λ³Έ μ 보"):
|
| 479 |
with gr.Row():
|
| 480 |
-
company_name = gr.Textbox(label="νμ¬λͺ
", value="μ°λ¦¬ μ€ννΈμ
")
|
| 481 |
-
founded_year = gr.Slider(2015, 2024, value=2022, step=1, label="μ€λ¦½μ°λ")
|
| 482 |
|
| 483 |
with gr.Row():
|
| 484 |
industry = gr.Dropdown(
|
| 485 |
choices=list(calculator.industry_multiples.keys()),
|
| 486 |
value="SaaS - B2B",
|
| 487 |
-
label="μ°μ
λΆλ₯"
|
| 488 |
)
|
| 489 |
stage = gr.Radio(
|
| 490 |
choices=["MVP/λ² ν", "μ΄κΈ° λ§€μΆ", "μ±μ₯ λ¨κ³", "μμ΅μ± ν보"],
|
| 491 |
value="μ΄κΈ° λ§€μΆ",
|
| 492 |
-
label="μ¬μ
λ¨κ³"
|
| 493 |
)
|
| 494 |
|
| 495 |
revenue_type = gr.Radio(
|
| 496 |
choices=["ꡬλ
ν (SaaS)", "κ±°λμμλ£ν", "μΌνμ± νλ§€"],
|
| 497 |
value="ꡬλ
ν (SaaS)",
|
| 498 |
-
label="μμ΅ λͺ¨λΈ"
|
| 499 |
)
|
| 500 |
|
| 501 |
-
with gr.Tab("
|
| 502 |
-
gr.Markdown("###
|
| 503 |
with gr.Row():
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
|
|
|
| 507 |
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
gr.Markdown("### π₯ κ³ κ° μ§ν")
|
| 515 |
-
with gr.Row():
|
| 516 |
-
retention_rate = gr.Slider(0, 100, value=85, step=5,
|
| 517 |
-
label="μκ° κ³ κ° μ μ§μ¨ (%)")
|
| 518 |
-
monthly_churn = gr.Slider(0, 20, value=3, step=0.5,
|
| 519 |
-
label="μ μ΄νλ₯ (%)")
|
| 520 |
|
| 521 |
-
gr.Markdown("###
|
| 522 |
with gr.Row():
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
with gr.Row():
|
| 530 |
-
patent_filed = gr.Number(label="μΆμ νΉν μ", value=2)
|
| 531 |
-
patent_granted = gr.Number(label="λ±λ‘ νΉν μ", value=1)
|
| 532 |
-
trademarks = gr.Number(label="μνκΆ μ", value=1)
|
| 533 |
-
|
| 534 |
-
papers = gr.Textbox(
|
| 535 |
-
label="λ°ν λ
Όλ¬Έ (ν μ€μ νλμ©, URL ν¬ν¨ κ°λ₯)",
|
| 536 |
-
lines=3,
|
| 537 |
-
placeholder="μ: https://arxiv.org/abs/2301.12345 - AI Model Optimization\nICML 2023 - Novel Approach to Machine Learning"
|
| 538 |
-
)
|
| 539 |
|
| 540 |
-
gr.Markdown("###
|
| 541 |
-
|
| 542 |
-
label="
|
| 543 |
-
|
| 544 |
-
|
| 545 |
|
|
|
|
| 546 |
with gr.Row():
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
|
|
|
|
|
|
|
|
|
|
| 552 |
|
| 553 |
-
gr.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
with gr.Row():
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
gr.Markdown("### π₯ ν ꡬμ±")
|
| 560 |
with gr.Row():
|
| 561 |
-
|
| 562 |
-
|
|
|
|
| 563 |
|
| 564 |
with gr.Row():
|
| 565 |
-
|
| 566 |
-
|
|
|
|
|
|
|
| 567 |
|
| 568 |
-
gr.Markdown("### π± λΈλλ λ° μ¬μ©μ κΈ°λ°")
|
| 569 |
with gr.Row():
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
|
| 574 |
-
with gr.Tab("μ¬λ¬΄ νν©"):
|
| 575 |
-
gr.Markdown("### πΈ νκΈ μν©
|
| 576 |
with gr.Row():
|
| 577 |
-
cash_balance = gr.Number(label="νκΈ μκ³ ($K)", value=1000)
|
| 578 |
-
burn_rate = gr.Number(label="μ λ²λ μ΄νΈ ($K)", value=80)
|
| 579 |
|
| 580 |
# νκ° μ€ν λ²νΌ
|
| 581 |
-
evaluate_btn = gr.Button("π κ°μΉνκ° μ€ν", variant="primary", size="lg")
|
| 582 |
|
| 583 |
# κ²°κ³Ό μΆλ ₯
|
| 584 |
with gr.Row():
|
| 585 |
with gr.Column(scale=2):
|
| 586 |
-
valuation_output = gr.Markdown(label="νκ° κ²°κ³Ό")
|
| 587 |
with gr.Column(scale=1):
|
| 588 |
-
|
| 589 |
|
| 590 |
with gr.Row():
|
| 591 |
-
comparison_chart = gr.Plot(label="
|
| 592 |
-
|
| 593 |
|
| 594 |
# μ΄λ²€νΈ μ°κ²°
|
| 595 |
evaluate_btn.click(
|
| 596 |
process_valuation,
|
| 597 |
inputs=[
|
|
|
|
| 598 |
company_name, founded_year, industry, stage, revenue_type,
|
| 599 |
monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
|
| 600 |
retention_rate, new_customers, monthly_marketing, monthly_sales,
|
| 601 |
cash_balance, burn_rate,
|
| 602 |
-
|
| 603 |
-
|
| 604 |
-
|
| 605 |
-
|
|
|
|
| 606 |
],
|
| 607 |
-
outputs=[valuation_output, comparison_chart,
|
| 608 |
)
|
| 609 |
|
| 610 |
-
# μμ λ°μ΄ν°
|
| 611 |
-
gr.Markdown("### π μμ
|
| 612 |
with gr.Row():
|
| 613 |
-
gr.Button("
|
| 614 |
lambda: [
|
| 615 |
-
"
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
"aitech.com, aitech.ai", 5, 2,
|
| 620 |
-
"NeurIPS 2023 - Novel AI Architecture\nhttps://arxiv.org/abs/2023.12345", 3,
|
| 621 |
-
"https://github.com/aitech/core", 500, 3, 5,
|
| 622 |
-
15, 3, 2, 4,
|
| 623 |
-
10, 50, 100
|
| 624 |
],
|
| 625 |
outputs=[
|
| 626 |
-
company_name, founded_year, industry, stage, revenue_type,
|
| 627 |
monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
|
| 628 |
retention_rate, new_customers, monthly_marketing, monthly_sales,
|
| 629 |
cash_balance, burn_rate,
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
|
|
|
| 634 |
]
|
| 635 |
)
|
| 636 |
|
| 637 |
-
gr.Button("
|
| 638 |
lambda: [
|
| 639 |
-
"
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
"biohealth.com, biohealth.health", 8, 4,
|
| 644 |
-
"Nature Medicine 2023 - Breakthrough in Drug Discovery\nScience 2023 - Novel Biomarker", 5,
|
| 645 |
-
"https://github.com/biohealth/research", 200, 5, 3,
|
| 646 |
-
25, 8, 1, 3,
|
| 647 |
-
15, 5, 30
|
| 648 |
],
|
| 649 |
outputs=[
|
| 650 |
-
company_name, founded_year, industry, stage, revenue_type,
|
| 651 |
monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
|
| 652 |
retention_rate, new_customers, monthly_marketing, monthly_sales,
|
| 653 |
cash_balance, burn_rate,
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
|
|
|
|
| 658 |
]
|
| 659 |
)
|
| 660 |
|
|
|
|
| 29 |
"200%+": 1.5
|
| 30 |
}
|
| 31 |
|
| 32 |
+
# λ²ν¬μ€ λ°©λ² μΉ΄ν
κ³ λ¦¬λ³ μ΅λκ° ($500K each)
|
| 33 |
+
self.berkus_max_values = {
|
| 34 |
+
"sound_idea": 500000,
|
| 35 |
+
"prototype": 500000,
|
| 36 |
+
"quality_team": 500000,
|
| 37 |
+
"strategic_relationships": 500000,
|
| 38 |
+
"product_rollout": 500000
|
| 39 |
}
|
| 40 |
|
| 41 |
+
# μ€μ½μ΄μΉ΄λ κ°μ€μΉ
|
| 42 |
+
self.scorecard_weights = {
|
| 43 |
+
"team": 0.30,
|
| 44 |
+
"market_size": 0.25,
|
| 45 |
+
"product": 0.15,
|
| 46 |
+
"competition": 0.10,
|
| 47 |
+
"marketing": 0.10,
|
| 48 |
+
"need_for_funding": 0.05,
|
| 49 |
+
"other": 0.05
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
# μΈμ΄λ³ ν
μ€νΈ
|
| 53 |
+
self.translations = {
|
| 54 |
+
"ko": {
|
| 55 |
+
"title": "π¦ μ€ννΈμ
κ°μΉνκ° μλν μμ€ν
v3.0",
|
| 56 |
+
"subtitle": "λ²ν¬μ€ λ°©λ²κ³Ό μ€μ½μ΄μΉ΄λ λ°©λ²μ ν¬ν¨ν μ’
ν© νκ°",
|
| 57 |
+
"valuation_result": "κ°μΉνκ° κ²°κ³Ό",
|
| 58 |
+
"company_value": "κΈ°μ
κ°μΉ",
|
| 59 |
+
"arr": "μ°κ° λ°λ³΅ λ§€μΆ",
|
| 60 |
+
"multiple": "μ μ© λ©ν°ν",
|
| 61 |
+
"unit_economics": "λ¨μκ²½μ ",
|
| 62 |
+
"berkus_score": "λ²ν¬μ€ νκ°",
|
| 63 |
+
"scorecard_score": "μ€μ½μ΄μΉ΄λ νκ°",
|
| 64 |
+
"financial_health": "μ¬λ¬΄ 건μ μ±",
|
| 65 |
+
"insights": "νκ° μΈμ¬μ΄νΈ"
|
| 66 |
+
},
|
| 67 |
+
"en": {
|
| 68 |
+
"title": "π¦ Startup Valuation System v3.0",
|
| 69 |
+
"subtitle": "Comprehensive valuation with Berkus and Scorecard methods",
|
| 70 |
+
"valuation_result": "Valuation Result",
|
| 71 |
+
"company_value": "Company Value",
|
| 72 |
+
"arr": "Annual Recurring Revenue",
|
| 73 |
+
"multiple": "Applied Multiple",
|
| 74 |
+
"unit_economics": "Unit Economics",
|
| 75 |
+
"berkus_score": "Berkus Score",
|
| 76 |
+
"scorecard_score": "Scorecard Score",
|
| 77 |
+
"financial_health": "Financial Health",
|
| 78 |
+
"insights": "Valuation Insights"
|
| 79 |
+
}
|
| 80 |
}
|
| 81 |
|
| 82 |
+
def calculate_berkus_score(self, berkus_data):
|
| 83 |
+
"""λ²ν¬μ€ λ°©λ²μΌλ‘ νκ° (μ΅λ $2.5M)"""
|
| 84 |
+
scores = {}
|
| 85 |
+
total = 0
|
| 86 |
+
|
| 87 |
+
# 1. 건μ ν μμ΄λμ΄ (Sound Idea)
|
| 88 |
+
idea_score = min(100, berkus_data["idea_validation"] + berkus_data["market_research"] * 10)
|
| 89 |
+
scores["sound_idea"] = self.berkus_max_values["sound_idea"] * (idea_score / 100)
|
| 90 |
+
|
| 91 |
+
# 2. νλ‘ν νμ
(Prototype)
|
| 92 |
+
prototype_score = 0
|
| 93 |
+
if berkus_data["prototype_stage"] == "μμ":
|
| 94 |
+
prototype_score = 0
|
| 95 |
+
elif berkus_data["prototype_stage"] == "컨μ
/λͺ©μ
":
|
| 96 |
+
prototype_score = 30
|
| 97 |
+
elif berkus_data["prototype_stage"] == "μλ νλ‘ν νμ
":
|
| 98 |
+
prototype_score = 60
|
| 99 |
+
elif berkus_data["prototype_stage"] == "λ² ν λ²μ ":
|
| 100 |
+
prototype_score = 80
|
| 101 |
+
elif berkus_data["prototype_stage"] == "μΆμ λ²μ ":
|
| 102 |
+
prototype_score = 100
|
| 103 |
+
scores["prototype"] = self.berkus_max_values["prototype"] * (prototype_score / 100)
|
| 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 |
+
)
|
| 111 |
+
scores["quality_team"] = self.berkus_max_values["quality_team"] * (team_score / 100)
|
| 112 |
+
|
| 113 |
+
# 4. μ λ΅μ κ΄κ³ (Strategic Relationships)
|
| 114 |
+
relationship_score = min(100,
|
| 115 |
+
berkus_data["partnerships"] * 15 +
|
| 116 |
+
berkus_data["advisors"] * 10 +
|
| 117 |
+
berkus_data["pilot_customers"] * 25
|
| 118 |
+
)
|
| 119 |
+
scores["strategic_relationships"] = self.berkus_max_values["strategic_relationships"] * (relationship_score / 100)
|
| 120 |
+
|
| 121 |
+
# 5. μ ν μΆμ/νλ§€ (Product Rollout)
|
| 122 |
+
if berkus_data["sales_started"]:
|
| 123 |
+
rollout_score = min(100, 50 + berkus_data["customer_validation"] * 10)
|
| 124 |
+
else:
|
| 125 |
+
rollout_score = berkus_data["launch_readiness"]
|
| 126 |
+
scores["product_rollout"] = self.berkus_max_values["product_rollout"] * (rollout_score / 100)
|
| 127 |
+
|
| 128 |
+
total = sum(scores.values())
|
| 129 |
+
return total, scores
|
| 130 |
+
|
| 131 |
+
def calculate_scorecard_valuation(self, scorecard_data, base_valuation):
|
| 132 |
+
"""μ€μ½μ΄μΉ΄λ λ°©λ²μΌλ‘ μ‘°μ λ κ°μΉνκ°"""
|
| 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
|
| 140 |
+
adjustments["marketing"] = scorecard_data["marketing_channels"] / 100
|
| 141 |
+
adjustments["need_for_funding"] = scorecard_data["funding_efficiency"] / 100
|
| 142 |
+
adjustments["other"] = scorecard_data["other_factors"] / 100
|
| 143 |
+
|
| 144 |
+
# κ°μ€ νκ· κ³μ°
|
| 145 |
+
weighted_score = 0
|
| 146 |
+
for factor, weight in self.scorecard_weights.items():
|
| 147 |
+
# κ° μ μλ₯Ό 0.5 ~ 1.5 λ²μλ‘ λ³ν (50μ μ΄ 1.0)
|
| 148 |
+
adjusted_score = 0.5 + (adjustments[factor])
|
| 149 |
+
weighted_score += adjusted_score * weight
|
| 150 |
+
|
| 151 |
+
# κΈ°λ³Έ κ°μΉνκ°μ μ‘°μ λΉμ¨ μ μ©
|
| 152 |
+
adjusted_valuation = base_valuation * weighted_score
|
| 153 |
+
|
| 154 |
+
return adjusted_valuation, adjustments, weighted_score
|
| 155 |
+
|
| 156 |
def calculate_arr(self, monthly_revenue, revenue_type):
|
| 157 |
"""μ λ§€μΆμ μ°κ° λ°λ³΅ λ§€μΆ(ARR)λ‘ λ³ν"""
|
| 158 |
if revenue_type == "ꡬλ
ν (SaaS)":
|
|
|
|
| 180 |
return 999
|
| 181 |
return cac / (arpu * (gross_margin / 100))
|
| 182 |
|
| 183 |
+
def calculate_valuation(self, data, berkus_data, scorecard_data, use_revenue_multiple=True):
|
| 184 |
+
"""μ’
ν© κ°μΉνκ° κ³μ°"""
|
| 185 |
+
results = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
+
# 1. λ²ν¬μ€ λ°©λ² νκ°
|
| 188 |
+
berkus_valuation, berkus_scores = self.calculate_berkus_score(berkus_data)
|
| 189 |
+
results["berkus_valuation"] = berkus_valuation
|
| 190 |
+
results["berkus_scores"] = berkus_scores
|
| 191 |
|
| 192 |
+
# 2. λ§€μΆ κΈ°λ° νκ° (λ§€μΆμ΄ μλ κ²½μ°)
|
| 193 |
+
if data["monthly_revenue"] > 0 and use_revenue_multiple:
|
| 194 |
+
# ARR κ³μ°
|
| 195 |
+
arr = self.calculate_arr(data["monthly_revenue"], data["revenue_type"])
|
| 196 |
+
|
| 197 |
+
# λ¨μκ²½μ κ³μ°
|
| 198 |
+
ltv = self.calculate_ltv(data["arpu"], data["gross_margin"], data["monthly_churn"])
|
| 199 |
+
cac = self.calculate_cac(data["monthly_marketing"], data["monthly_sales"], data["new_customers"])
|
| 200 |
+
ltv_cac_ratio = ltv / cac if cac > 0 else 0
|
| 201 |
+
payback = self.calculate_payback(cac, data["arpu"], data["gross_margin"])
|
| 202 |
|
| 203 |
+
# λ©ν°ν κ²°μ
|
| 204 |
+
multiples = self.industry_multiples[data["industry"]]
|
| 205 |
+
growth_category = self.get_growth_category(data["growth_rate"])
|
| 206 |
+
growth_adj = self.growth_adjustments[growth_category]
|
| 207 |
+
|
| 208 |
+
# κΈ°λ³Έ λ©ν°ν μ ν
|
| 209 |
+
if ltv_cac_ratio >= 3:
|
| 210 |
+
base_multiple = multiples["high"]
|
| 211 |
+
elif ltv_cac_ratio >= 1.5:
|
| 212 |
+
base_multiple = multiples["mid"]
|
| 213 |
else:
|
| 214 |
+
base_multiple = multiples["low"]
|
| 215 |
|
| 216 |
+
adjusted_multiple = base_multiple * growth_adj
|
| 217 |
+
|
| 218 |
+
# λ§€μΆ κΈ°λ° κ°μΉνκ°
|
| 219 |
+
revenue_valuation = arr * adjusted_multiple
|
| 220 |
+
|
| 221 |
+
results["arr"] = arr
|
| 222 |
+
results["ltv"] = ltv
|
| 223 |
+
results["cac"] = cac
|
| 224 |
+
results["ltv_cac_ratio"] = ltv_cac_ratio
|
| 225 |
+
results["payback"] = payback
|
| 226 |
+
results["multiple"] = adjusted_multiple
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
else:
|
| 228 |
+
revenue_valuation = 0
|
| 229 |
+
results["arr"] = 0
|
| 230 |
+
results["ltv"] = 0
|
| 231 |
+
results["cac"] = 0
|
| 232 |
+
results["ltv_cac_ratio"] = 0
|
| 233 |
+
results["payback"] = 0
|
| 234 |
+
results["multiple"] = 0
|
| 235 |
+
|
| 236 |
+
# 3. κΈ°λ³Έ κ°μΉνκ° κ²°μ (λ²ν¬μ€ vs λ§€μΆ κΈ°λ°)
|
| 237 |
+
if revenue_valuation > berkus_valuation * 1.5:
|
| 238 |
+
base_valuation = revenue_valuation
|
| 239 |
+
valuation_method = "revenue_multiple"
|
| 240 |
+
else:
|
| 241 |
+
base_valuation = max(berkus_valuation, revenue_valuation)
|
| 242 |
+
valuation_method = "berkus"
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
+
# 4. μ€μ½μ΄μΉ΄λ μ‘°μ
|
| 245 |
+
final_valuation, scorecard_adjustments, weighted_score = self.calculate_scorecard_valuation(
|
| 246 |
+
scorecard_data, base_valuation
|
| 247 |
+
)
|
| 248 |
|
| 249 |
+
results["base_valuation"] = base_valuation
|
| 250 |
+
results["final_valuation"] = final_valuation
|
| 251 |
+
results["valuation_method"] = valuation_method
|
| 252 |
+
results["scorecard_adjustments"] = scorecard_adjustments
|
| 253 |
+
results["scorecard_multiplier"] = weighted_score
|
| 254 |
|
| 255 |
+
# 5. λ°μ¨μ΄ κ³μ°
|
| 256 |
+
results["runway"] = data["cash_balance"] / data["burn_rate"] if data["burn_rate"] > 0 else 999
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
|
| 258 |
+
return results
|
|
|
|
| 259 |
|
| 260 |
def get_growth_category(self, growth_rate):
|
| 261 |
"""μ±μ₯λ₯ μΉ΄ν
κ³ λ¦¬ κ²°μ """
|
|
|
|
| 270 |
else:
|
| 271 |
return "200%+"
|
| 272 |
|
| 273 |
+
def create_valuation_comparison_chart(self, results, language="ko"):
|
| 274 |
+
"""νκ° λ°©λ²λ³ λΉκ΅ μ°¨νΈ"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
fig = go.Figure()
|
| 276 |
|
| 277 |
+
methods = ["Berkus", "Revenue Multiple", "Scorecard Adjusted"]
|
| 278 |
+
values = [
|
| 279 |
+
results["berkus_valuation"],
|
| 280 |
+
results["base_valuation"] if results["valuation_method"] == "revenue_multiple" else 0,
|
| 281 |
+
results["final_valuation"]
|
| 282 |
+
]
|
| 283 |
|
|
|
|
| 284 |
fig.add_trace(go.Bar(
|
| 285 |
+
x=methods,
|
| 286 |
+
y=values,
|
| 287 |
+
text=[f"${v/1000000:.2f}M" for v in values],
|
|
|
|
| 288 |
textposition="outside",
|
| 289 |
+
marker_color=["lightblue", "lightgreen", "darkblue"]
|
| 290 |
))
|
| 291 |
|
| 292 |
+
title = "νκ° λ°©λ²λ³ κΈ°μ
κ°μΉ λΉκ΅" if language == "ko" else "Valuation by Method"
|
| 293 |
fig.update_layout(
|
| 294 |
+
title=title,
|
| 295 |
+
yaxis_title="Valuation (USD)",
|
| 296 |
showlegend=False,
|
| 297 |
height=400
|
| 298 |
)
|
| 299 |
|
| 300 |
return fig
|
| 301 |
|
| 302 |
+
def create_scorecard_radar_chart(self, adjustments, language="ko"):
|
| 303 |
+
"""μ€μ½μ΄μΉ΄λ μμλ³ μ μ λ μ΄λ μ°¨νΈ"""
|
| 304 |
+
categories = list(adjustments.keys())
|
| 305 |
+
if language == "ko":
|
| 306 |
+
categories_display = ["ν", "μμ₯κ·λͺ¨", "μ ν", "κ²½μλ ₯", "λ§μΌν
", "μκΈν¨μ¨", "κΈ°ν"]
|
| 307 |
+
else:
|
| 308 |
+
categories_display = ["Team", "Market", "Product", "Competition", "Marketing", "Funding", "Other"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
|
| 310 |
+
values = [adjustments[cat] * 100 for cat in categories]
|
| 311 |
+
|
| 312 |
+
fig = go.Figure(data=go.Scatterpolar(
|
| 313 |
+
r=values,
|
| 314 |
+
theta=categories_display,
|
| 315 |
+
fill='toself'
|
| 316 |
+
))
|
| 317 |
+
|
| 318 |
+
title = "μ€μ½μ΄μΉ΄λ νκ° μμ" if language == "ko" else "Scorecard Factors"
|
| 319 |
fig.update_layout(
|
| 320 |
polar=dict(
|
| 321 |
radialaxis=dict(
|
| 322 |
visible=True,
|
| 323 |
range=[0, 100]
|
| 324 |
+
)),
|
|
|
|
| 325 |
showlegend=False,
|
| 326 |
+
title=title
|
| 327 |
)
|
| 328 |
|
| 329 |
return fig
|
|
|
|
| 332 |
calculator = StartupValuationCalculator()
|
| 333 |
|
| 334 |
def process_valuation(
|
| 335 |
+
language,
|
| 336 |
+
# κΈ°λ³Έ μ 보
|
| 337 |
company_name, founded_year, industry, stage, revenue_type,
|
| 338 |
+
# λ§€μΆ μ 보
|
| 339 |
monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
|
| 340 |
retention_rate, new_customers, monthly_marketing, monthly_sales,
|
| 341 |
+
# μ¬λ¬΄ μ 보
|
| 342 |
cash_balance, burn_rate,
|
| 343 |
+
# λ²ν¬μ€ λ°©λ² μ
λ ₯
|
| 344 |
+
idea_validation, market_research, prototype_stage, team_experience,
|
| 345 |
+
domain_expertise, startup_experience, partnerships, advisors,
|
| 346 |
+
pilot_customers, sales_started, customer_validation, launch_readiness,
|
| 347 |
+
# μ€μ½μ΄μΉ΄λ μ
λ ₯
|
| 348 |
+
team_strength, market_opportunity, product_stage, competitive_advantage,
|
| 349 |
+
marketing_channels, funding_efficiency, other_factors
|
| 350 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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,
|
|
|
|
| 366 |
"burn_rate": burn_rate * 1000
|
| 367 |
}
|
| 368 |
|
| 369 |
+
berkus_data = {
|
| 370 |
+
"idea_validation": idea_validation,
|
| 371 |
+
"market_research": market_research,
|
| 372 |
+
"prototype_stage": prototype_stage,
|
| 373 |
+
"team_experience": team_experience,
|
| 374 |
+
"domain_expertise": domain_expertise,
|
| 375 |
+
"startup_experience": startup_experience,
|
|
|
|
|
|
|
| 376 |
"partnerships": partnerships,
|
| 377 |
+
"advisors": advisors,
|
| 378 |
+
"pilot_customers": pilot_customers,
|
| 379 |
+
"sales_started": sales_started,
|
| 380 |
+
"customer_validation": customer_validation,
|
| 381 |
+
"launch_readiness": launch_readiness
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
scorecard_data = {
|
| 385 |
+
"team_strength": team_strength,
|
| 386 |
+
"market_opportunity": market_opportunity,
|
| 387 |
+
"product_stage": product_stage,
|
| 388 |
+
"competitive_advantage": competitive_advantage,
|
| 389 |
+
"marketing_channels": marketing_channels,
|
| 390 |
+
"funding_efficiency": funding_efficiency,
|
| 391 |
+
"other_factors": other_factors
|
| 392 |
}
|
| 393 |
|
| 394 |
# κ°μΉνκ° κ³μ°
|
| 395 |
+
use_revenue = monthly_revenue > 0
|
| 396 |
+
results = calculator.calculate_valuation(data, berkus_data, scorecard_data, use_revenue)
|
| 397 |
+
|
| 398 |
+
# μΈμ΄λ³ ν
μ€νΈ
|
| 399 |
+
t = calculator.translations[language]
|
| 400 |
|
| 401 |
# κ²°κ³Ό ν¬λ§·ν
|
| 402 |
+
if language == "ko":
|
| 403 |
+
valuation_text = f"""
|
| 404 |
+
# π {company_name} {t['valuation_result']}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 405 |
|
| 406 |
+
## π μ’
ν© νκ°
|
| 407 |
+
- **{t['company_value']}**: ${results['final_valuation']/1000000:.2f}M
|
| 408 |
+
- **νκ° λ°©λ²**: {'λ§€μΆ λ©ν°ν' if results['valuation_method'] == 'revenue_multiple' else 'λ²ν¬μ€ λ°©λ²'} + μ€μ½μ΄μΉ΄λ μ‘°μ
|
| 409 |
+
- **μ€μ½μ΄μΉ΄λ μ‘°μ λ°°μ**: {results['scorecard_multiplier']:.2f}x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 410 |
|
| 411 |
+
## π― {t['berkus_score']} (μ΅λ $2.5M)
|
| 412 |
+
- **μ΄ νκ°μ‘**: ${results['berkus_valuation']/1000000:.2f}M
|
| 413 |
+
- 건μ ν μμ΄λμ΄: ${results['berkus_scores']['sound_idea']/1000:.0f}K
|
| 414 |
+
- νλ‘ν νμ
: ${results['berkus_scores']['prototype']/1000:.0f}K
|
| 415 |
+
- μ°μν ν: ${results['berkus_scores']['quality_team']/1000:.0f}K
|
| 416 |
+
- μ λ΅μ κ΄κ³: ${results['berkus_scores']['strategic_relationships']/1000:.0f}K
|
| 417 |
+
- μ ν μΆμ: ${results['berkus_scores']['product_rollout']/1000:.0f}K
|
| 418 |
+
"""
|
| 419 |
+
else:
|
| 420 |
+
valuation_text = f"""
|
| 421 |
+
# π {company_name} {t['valuation_result']}
|
| 422 |
|
| 423 |
+
## π Summary
|
| 424 |
+
- **{t['company_value']}**: ${results['final_valuation']/1000000:.2f}M
|
| 425 |
+
- **Method**: {'Revenue Multiple' if results['valuation_method'] == 'revenue_multiple' else 'Berkus Method'} + Scorecard
|
| 426 |
+
- **Scorecard Multiplier**: {results['scorecard_multiplier']:.2f}x
|
| 427 |
|
| 428 |
+
## π― {t['berkus_score']} (Max $2.5M)
|
| 429 |
+
- **Total**: ${results['berkus_valuation']/1000000:.2f}M
|
| 430 |
+
- Sound Idea: ${results['berkus_scores']['sound_idea']/1000:.0f}K
|
| 431 |
+
- Prototype: ${results['berkus_scores']['prototype']/1000:.0f}K
|
| 432 |
+
- Quality Team: ${results['berkus_scores']['quality_team']/1000:.0f}K
|
| 433 |
+
- Strategic Relationships: ${results['berkus_scores']['strategic_relationships']/1000:.0f}K
|
| 434 |
+
- Product Rollout: ${results['berkus_scores']['product_rollout']/1000:.0f}K
|
| 435 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
|
| 437 |
+
# λ§€μΆ κΈ°λ° νκ° μΆκ° (λ§€μΆμ΄ μλ κ²½μ°)
|
| 438 |
+
if use_revenue and results['arr'] > 0:
|
| 439 |
+
if language == "ko":
|
| 440 |
+
valuation_text += f"""
|
| 441 |
+
## π° λ§€μΆ κΈ°λ° νκ°
|
| 442 |
+
- **ARR**: ${results['arr']/1000000:.2f}M
|
| 443 |
+
- **μ μ© λ©ν°ν**: {results['multiple']:.1f}x
|
| 444 |
+
- **LTV/CAC**: {results['ltv_cac_ratio']:.1f}x
|
| 445 |
+
- **Payback**: {results['payback']:.1f}κ°μ
|
| 446 |
+
"""
|
| 447 |
+
else:
|
| 448 |
+
valuation_text += f"""
|
| 449 |
+
## π° Revenue-based Valuation
|
| 450 |
+
- **ARR**: ${results['arr']/1000000:.2f}M
|
| 451 |
+
- **Multiple**: {results['multiple']:.1f}x
|
| 452 |
+
- **LTV/CAC**: {results['ltv_cac_ratio']:.1f}x
|
| 453 |
+
- **Payback**: {results['payback']:.1f} months
|
| 454 |
+
"""
|
| 455 |
|
| 456 |
+
# μ¬λ¬΄ 건μ μ±
|
| 457 |
+
if language == "ko":
|
| 458 |
+
valuation_text += f"""
|
| 459 |
+
## π {t['financial_health']}
|
| 460 |
+
- **νκΈ λ°μ¨μ΄**: {results['runway']:.1f}κ°μ
|
| 461 |
+
- **μκ° λ²λ μ΄νΈ**: ${burn_rate}K
|
| 462 |
+
"""
|
| 463 |
+
else:
|
| 464 |
+
valuation_text += f"""
|
| 465 |
+
## π {t['financial_health']}
|
| 466 |
+
- **Cash Runway**: {results['runway']:.1f} months
|
| 467 |
+
- **Monthly Burn Rate**: ${burn_rate}K
|
| 468 |
+
"""
|
| 469 |
|
| 470 |
+
# μ°¨νΈ μμ±
|
| 471 |
+
comparison_chart = calculator.create_valuation_comparison_chart(results, language)
|
| 472 |
+
scorecard_chart = calculator.create_scorecard_radar_chart(results['scorecard_adjustments'], language)
|
| 473 |
+
|
| 474 |
+
# μμΈ ν
μ΄λΈ
|
| 475 |
+
if language == "ko":
|
| 476 |
+
methods_df = pd.DataFrame({
|
| 477 |
+
"νκ° λ°©λ²": ["λ²ν¬μ€ λ°©λ²", "λ§€μΆ λ©ν°ν", "μ€μ½μ΄μΉ΄λ μ‘°μ ", "μ΅μ’
νκ°"],
|
| 478 |
+
"νκ°μ‘": [
|
| 479 |
+
f"${results['berkus_valuation']/1000000:.2f}M",
|
| 480 |
+
f"${results['base_valuation']/1000000:.2f}M" if results['valuation_method'] == 'revenue_multiple' else "N/A",
|
| 481 |
+
f"{results['scorecard_multiplier']:.2f}x",
|
| 482 |
+
f"${results['final_valuation']/1000000:.2f}M"
|
| 483 |
+
]
|
| 484 |
+
})
|
| 485 |
+
else:
|
| 486 |
+
methods_df = pd.DataFrame({
|
| 487 |
+
"Method": ["Berkus Method", "Revenue Multiple", "Scorecard Adjustment", "Final Valuation"],
|
| 488 |
+
"Value": [
|
| 489 |
+
f"${results['berkus_valuation']/1000000:.2f}M",
|
| 490 |
+
f"${results['base_valuation']/1000000:.2f}M" if results['valuation_method'] == 'revenue_multiple' else "N/A",
|
| 491 |
+
f"{results['scorecard_multiplier']:.2f}x",
|
| 492 |
+
f"${results['final_valuation']/1000000:.2f}M"
|
| 493 |
+
]
|
| 494 |
+
})
|
| 495 |
|
| 496 |
+
return valuation_text, comparison_chart, scorecard_chart, methods_df
|
| 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(
|
| 520 |
choices=list(calculator.industry_multiples.keys()),
|
| 521 |
value="SaaS - B2B",
|
| 522 |
+
label="μ°μ
λΆλ₯ / Industry"
|
| 523 |
)
|
| 524 |
stage = gr.Radio(
|
| 525 |
choices=["MVP/λ² ν", "μ΄κΈ° λ§€μΆ", "μ±μ₯ λ¨κ³", "μμ΅μ± ν보"],
|
| 526 |
value="μ΄κΈ° λ§€μΆ",
|
| 527 |
+
label="μ¬μ
λ¨κ³ / Stage"
|
| 528 |
)
|
| 529 |
|
| 530 |
revenue_type = gr.Radio(
|
| 531 |
choices=["ꡬλ
ν (SaaS)", "κ±°λμμλ£ν", "μΌνμ± νλ§€"],
|
| 532 |
value="ꡬλ
ν (SaaS)",
|
| 533 |
+
label="μμ΅ λͺ¨λΈ / Revenue Model"
|
| 534 |
)
|
| 535 |
|
| 536 |
+
with gr.Tab("λ²ν¬μ€ νκ° / Berkus Method"):
|
| 537 |
+
gr.Markdown("### π‘ μμ΄λμ΄ κ²μ¦ / Idea Validation")
|
| 538 |
with gr.Row():
|
| 539 |
+
idea_validation = gr.Slider(0, 100, value=70, step=10,
|
| 540 |
+
label="μμ΄λμ΄ κ²μ¦ μμ€ / Idea Validation Level (%)")
|
| 541 |
+
market_research = gr.Slider(0, 10, value=5, step=1,
|
| 542 |
+
label="μμ₯ μ‘°μ¬ κΉμ΄ / Market Research Depth (1-10)")
|
| 543 |
|
| 544 |
+
gr.Markdown("### π§ νλ‘ν νμ
/ Prototype")
|
| 545 |
+
prototype_stage = gr.Radio(
|
| 546 |
+
choices=["μμ", "컨μ
/λͺ©μ
", "μλ νλ‘ν νμ
", "λ² ν λ²μ ", "μΆμ λ²μ "],
|
| 547 |
+
value="λ² ν λ²μ ",
|
| 548 |
+
label="νλ‘ν νμ
λ¨κ³ / Prototype Stage"
|
| 549 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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)")
|
| 557 |
+
startup_experience = gr.Slider(0, 5, value=2, step=1,
|
| 558 |
+
label="μ€ννΈμ
κ²½ν / Startup Experience (1-5)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 559 |
|
| 560 |
+
gr.Markdown("### π€ μ λ΅μ κ΄κ³ / Strategic Relationships")
|
| 561 |
+
with gr.Row():
|
| 562 |
+
partnerships = gr.Number(label="μ λ΅μ ννΈλμ μ / Strategic Partnerships", value=2)
|
| 563 |
+
advisors = gr.Number(label="κ³ λ¬Έ/λ©ν μ / Advisors/Mentors", value=3)
|
| 564 |
+
pilot_customers = gr.Number(label="νμΌλΏ κ³ κ° μ / Pilot Customers", value=5)
|
| 565 |
|
| 566 |
+
gr.Markdown("### π μ ν μΆμ / Product Rollout")
|
| 567 |
with gr.Row():
|
| 568 |
+
sales_started = gr.Checkbox(label="λ§€μΆ λ°μ μμ / Sales Started", value=True)
|
| 569 |
+
customer_validation = gr.Slider(0, 10, value=5, step=1,
|
| 570 |
+
label="κ³ κ° κ²μ¦ μμ€ / Customer Validation (1-10)")
|
| 571 |
+
launch_readiness = gr.Slider(0, 100, value=80, step=10,
|
| 572 |
+
label="μΆμ μ€λΉλ / Launch Readiness (%)")
|
| 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")
|
| 579 |
+
market_opportunity = gr.Slider(0, 100, value=70, step=5,
|
| 580 |
+
label="μμ₯ κΈ°ν / Market Opportunity")
|
| 581 |
+
product_stage = gr.Slider(0, 100, value=65, step=5,
|
| 582 |
+
label="μ ν μμ±λ / Product Maturity")
|
| 583 |
+
competitive_advantage = gr.Slider(0, 100, value=55, step=5,
|
| 584 |
+
label="κ²½μ μ°μ / Competitive Advantage")
|
| 585 |
+
marketing_channels = gr.Slider(0, 100, value=50, step=5,
|
| 586 |
+
label="λ§μΌν
/νλ§€ / Marketing & Sales")
|
| 587 |
+
funding_efficiency = gr.Slider(0, 100, value=60, step=5,
|
| 588 |
+
label="μκΈ ν¨μ¨μ± / Funding Efficiency")
|
| 589 |
+
other_factors = gr.Slider(0, 100, value=50, step=5,
|
| 590 |
+
label="κΈ°ν μμ / Other Factors")
|
| 591 |
+
|
| 592 |
+
with gr.Tab("λ§€μΆ μ 보 / Revenue (Optional)"):
|
| 593 |
+
gr.Markdown("### π° λ§€μΆμ΄ μλ κ²½μ°λ§ μ
λ ₯ / Only if you have revenue")
|
| 594 |
with gr.Row():
|
| 595 |
+
monthly_revenue = gr.Number(label="μ λ§€μΆ / Monthly Revenue ($K)", value=0)
|
| 596 |
+
growth_rate = gr.Slider(0, 300, value=0, step=10,
|
| 597 |
+
label="μ°κ° μ±μ₯λ₯ / Annual Growth Rate (%)")
|
| 598 |
+
|
|
|
|
| 599 |
with gr.Row():
|
| 600 |
+
arpu = gr.Number(label="ARPU ($)", value=0)
|
| 601 |
+
gross_margin = gr.Slider(0, 100, value=0, step=5,
|
| 602 |
+
label="λ§€μΆμ΄μ΄μ΅λ₯ / Gross Margin (%)")
|
| 603 |
|
| 604 |
with gr.Row():
|
| 605 |
+
retention_rate = gr.Slider(0, 100, value=0, step=5,
|
| 606 |
+
label="κ³ κ° μ μ§μ¨ / Retention Rate (%)")
|
| 607 |
+
monthly_churn = gr.Slider(0, 20, value=0, step=0.5,
|
| 608 |
+
label="μ μ΄νλ₯ / Monthly Churn (%)")
|
| 609 |
|
|
|
|
| 610 |
with gr.Row():
|
| 611 |
+
new_customers = gr.Number(label="μ μ κ· κ³ κ° / New Customers/Month", value=0)
|
| 612 |
+
monthly_marketing = gr.Number(label="μ λ§μΌν
λΉμ© / Marketing Cost ($K)", value=0)
|
| 613 |
+
monthly_sales = gr.Number(label="μ μμ
λΉμ© / Sales Cost ($K)", value=0)
|
| 614 |
|
| 615 |
+
with gr.Tab("μ¬λ¬΄ νν© / Financials"):
|
| 616 |
+
gr.Markdown("### πΈ νκΈ μν© / Cash Position ($K)")
|
| 617 |
with gr.Row():
|
| 618 |
+
cash_balance = gr.Number(label="νκΈ μκ³ / Cash Balance ($K)", value=1000)
|
| 619 |
+
burn_rate = gr.Number(label="μ λ²λ μ΄νΈ / Monthly Burn Rate ($K)", value=80)
|
| 620 |
|
| 621 |
# νκ° μ€ν λ²νΌ
|
| 622 |
+
evaluate_btn = gr.Button("π κ°μΉνκ° μ€ν / Run Valuation", variant="primary", size="lg")
|
| 623 |
|
| 624 |
# κ²°κ³Ό μΆλ ₯
|
| 625 |
with gr.Row():
|
| 626 |
with gr.Column(scale=2):
|
| 627 |
+
valuation_output = gr.Markdown(label="νκ° κ²°κ³Ό / Results")
|
| 628 |
with gr.Column(scale=1):
|
| 629 |
+
methods_table = gr.DataFrame(label="νκ° λ°©λ² λΉκ΅ / Method Comparison")
|
| 630 |
|
| 631 |
with gr.Row():
|
| 632 |
+
comparison_chart = gr.Plot(label="νκ° λ°©λ² λΉκ΅ / Valuation Comparison")
|
| 633 |
+
scorecard_chart = gr.Plot(label="μ€μ½μ΄μΉ΄λ λΆμ / Scorecard Analysis")
|
| 634 |
|
| 635 |
# μ΄λ²€νΈ μ°κ²°
|
| 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,
|
| 643 |
cash_balance, burn_rate,
|
| 644 |
+
idea_validation, market_research, prototype_stage, team_experience,
|
| 645 |
+
domain_expertise, startup_experience, partnerships, advisors,
|
| 646 |
+
pilot_customers, sales_started, customer_validation, launch_readiness,
|
| 647 |
+
team_strength, market_opportunity, product_stage, competitive_advantage,
|
| 648 |
+
marketing_channels, funding_efficiency, other_factors
|
| 649 |
],
|
| 650 |
+
outputs=[valuation_output, comparison_chart, scorecard_chart, methods_table]
|
| 651 |
)
|
| 652 |
|
| 653 |
+
# μμ λ°μ΄ν°
|
| 654 |
+
gr.Markdown("### π μμ λ°μ΄ν° / Example Data")
|
| 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,
|
| 668 |
+
idea_validation, market_research, prototype_stage, team_experience,
|
| 669 |
+
domain_expertise, startup_experience, partnerships, advisors,
|
| 670 |
+
pilot_customers, sales_started, customer_validation, launch_readiness,
|
| 671 |
+
team_strength, market_opportunity, product_stage, competitive_advantage,
|
| 672 |
+
marketing_channels, funding_efficiency, other_factors
|
| 673 |
]
|
| 674 |
)
|
| 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,
|
| 688 |
+
idea_validation, market_research, prototype_stage, team_experience,
|
| 689 |
+
domain_expertise, startup_experience, partnerships, advisors,
|
| 690 |
+
pilot_customers, sales_started, customer_validation, launch_readiness,
|
| 691 |
+
team_strength, market_opportunity, product_stage, competitive_advantage,
|
| 692 |
+
marketing_channels, funding_efficiency, other_factors
|
| 693 |
]
|
| 694 |
)
|
| 695 |
|