# Complete DOCPLEX implementation

from docplex.mp.model import Model

def optimize_investments():
    """Optimize investment allocation to maximize expected return."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="investment_optimization")
    
    # Data from the problem statement
    expected_return_rates = [0.12, 0.18, 0.22]
    money_requested = [20000, 25000, 30000]
    total_budget = 60000
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(expected_return_rates) == len(money_requested), "Array length mismatch"
    safe_range = range(min(len(expected_return_rates), len(money_requested)))  # Safe indexing
    
    # 2. VARIABLES
    # Variable dictionaries for investments
    investments = {i: mdl.continuous_var(name=f"x_{i}", lb=0) for i in safe_range}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total expected return
    objective = mdl.sum(expected_return_rates[i] * investments[i] for i in safe_range)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Total budget constraint
    total_investment = mdl.sum(investments[i] for i in safe_range)
    mdl.add_constraint(total_investment <= total_budget, ctname="total_budget")
    
    # Individual investment constraints
    for i in safe_range:
        mdl.add_constraint(investments[i] <= money_requested[i], ctname=f"max_investment_{i}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value:.2f}")
        for i in safe_range:
            value = solution.get_value(investments[i])
            if value > 1e-6:
                print(f"Investment in entrepreneur {i+1}: {value:.2f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
optimize_investments()