# Complete GUROBIPY implementation - Retry Attempt 1

import gurobipy as gp
from gurobipy import GRB

def optimize_student_club_assignments():
    # 1. MODEL & DATA SETUP
    model = gp.Model("student_club_assignment")
    
    # Data from the problem statement
    preference_scores = {
        (1, 101): 8, (1, 102): 3,
        (2, 101): 5, (2, 103): 7,
        (3, 102): 6, (3, 103): 4
    }
    
    club_capacities = {
        101: 60,
        102: 40,
        103: 50
    }
    
    students = {1, 2, 3}
    clubs = {101, 102, 103}
    
    # Validate data completeness
    assert all((stu, club) in preference_scores for stu in students for club in clubs if (stu, club) in preference_scores), "Preference scores missing for some student-club pairs"
    
    # 2. VARIABLES
    x = model.addVars(students, clubs, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(preference_scores.get((i, j), 0) * x[i, j] for i in students for j in clubs), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Club Capacity Constraints
    model.addConstrs((gp.quicksum(x[i, j] for i in students) <= club_capacities[j] for j in clubs), name="capacity")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in students:
            for j in clubs:
                if x[i, j].x > 0.5:  # Binary variable, so check if it's 1
                    print(f"Student {i} assigned to Club {j}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

# Run the optimization
optimize_student_club_assignments()