Untitled
unknown
plain_text
9 days ago
4.1 kB
2
Indexable
Never
import math from typing import Tuple, Dict, Optional # Constants DAYS_IN_MONTH = 30.4 MIN_OFFER_THRESHOLD = 1800 MIN_OFFER_AMOUNT = 2000 MAX_OFFER_AMOUNT = 250000 ROUNDING_BASE = 1000 # Grade parameters GRADE_PARAMS = { 'A3': {'max_swipe_percentage': 0.15, 'factor_rate': 1.16, 'expected_payback_days': 250}, 'B3': {'max_swipe_percentage': 0.175, 'factor_rate': 1.16, 'expected_payback_days': 215}, 'C3': {'max_swipe_percentage': 0.175, 'factor_rate': 1.17, 'expected_payback_days': 195}, 'D3': {'max_swipe_percentage': 0.175, 'factor_rate': 1.19, 'expected_payback_days': 185}, 'E3': {'max_swipe_percentage': 0.175, 'factor_rate': 1.12, 'expected_payback_days': 140} } def validate_inputs(monthly_revenue: float, fico: int, yib: float) -> None: """Validate input parameters.""" if monthly_revenue <= 0: raise ValueError("Monthly revenue must be positive") if not (300 <= fico <= 850): raise ValueError("FICO score must be between 300 and 850") if yib < 0: raise ValueError("Years in business must be non-negative") def determine_grade(fico: int, yib: float) -> Optional[str]: """Determine the grade based on FICO score and years in business.""" if fico < 500: return 'E3' elif 500 <= fico < 580: return 'D3' elif 580 <= fico < 670: return 'C3' if yib >= 3 else 'D3' elif 670 <= fico < 740: return 'B3' if yib >= 3 else 'C3' elif fico >= 740: return 'A3' if yib >= 3 else 'D3' return None # This case should not occur given our validation, but it's here for completeness def calculate_offer_estimate(monthly_revenue: float, grade: str) -> float: """Calculate the initial offer estimate.""" params = GRADE_PARAMS[grade] return (monthly_revenue / DAYS_IN_MONTH) * params['expected_payback_days'] * params['max_swipe_percentage'] / params['factor_rate'] def adjust_offer(offer_estimate: float) -> int: """Adjust the offer based on business rules.""" if MIN_OFFER_THRESHOLD <= offer_estimate < MIN_OFFER_AMOUNT: return MIN_OFFER_AMOUNT return min(MAX_OFFER_AMOUNT, math.ceil(offer_estimate / ROUNDING_BASE) * ROUNDING_BASE) def calculate_offer(monthly_revenue: float, fico: int, yib: float) -> Tuple[Optional[str], Optional[int]]: """Calculate the final offer based on monthly revenue, FICO score, and years in business.""" validate_inputs(monthly_revenue, fico, yib) grade = determine_grade(fico, yib) if grade is None: return None, None # Indicate that no offer can be made offer_estimate = calculate_offer_estimate(monthly_revenue, grade) final_offer = adjust_offer(offer_estimate) return grade, final_offer # Define the test scenarios test_scenarios = [ {"monthly_revenue": 11500, "fico": 750, "yib": 1, "expected": "$11,000.00"}, # Sample A {"monthly_revenue": 11500, "fico": 570, "yib": 5, "expected": "$11,000.00"}, # Sample B {"monthly_revenue": 11500, "fico": 690, "yib": 5, "expected": "$13,000.00"}, # Sample C {"monthly_revenue": 11500, "fico": 490, "yib": 5, "expected": "$9,000.00"}, # Sample D {"monthly_revenue": 11500, "fico": 580, "yib": 2.5, "expected": "N/A"}, # New scenario ] # Run the scenarios through the function and print the results for i, scenario in enumerate(test_scenarios, 1): try: grade, final_offer = calculate_offer(scenario["monthly_revenue"], scenario["fico"], scenario["yib"]) print(f"Scenario {i}:") print(f" Monthly Revenue: ${scenario['monthly_revenue']:,.2f}") print(f" FICO: {scenario['fico']}") print(f" Years in Business: {scenario['yib']}") if grade is not None and final_offer is not None: print(f" Matched Grade: {grade}") print(f" Calculated Offer: ${final_offer:,.2f}") else: print(" Result: N/A (No offer available)") print(f" Expected Offer: {scenario['expected']}") except ValueError as e: print(f"Scenario {i}: Error - {e}") print("-----------")
Leave a Comment