# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def optimize_journalist_event_assignment():
    """Optimize journalist assignments to maximize event attendance"""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("news_report")
    
    # Data: Event attendance and journalist-event pairs
    event_attendance = {1: 150, 2: 250, 3: 100}
    journalist_event_pairs = [(1, 1), (1, 2), (2, 2), (2, 3), (3, 1)]
    
    # Validate data lengths
    assert len(event_attendance) == 3, "Event attendance data length mismatch"
    
    # 2. VARIABLES
    # Binary decision variables for journalist-event assignments
    x = model.addVars(journalist_event_pairs, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total attendance at events covered by journalists
    model.setObjective(gp.quicksum(event_attendance[j] * x[i, j] for i, j in journalist_event_pairs), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Constraint: Each journalist can cover up to 2 events
    model.addConstrs((gp.quicksum(x[i, j] for j in event_attendance.keys() if (i, j) in journalist_event_pairs) <= 2 for i in range(1, 4)), name="journalist_event_limit")
    
    # Constraint: Each event can be covered by up to 2 journalists
    model.addConstrs((gp.quicksum(x[i, j] for i in range(1, 4) if (i, j) in journalist_event_pairs) <= 2 for j in event_attendance.keys()), name="event_journalist_limit")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i, j in journalist_event_pairs:
            if x[i, j].x > 1e-6:
                print(f"Journalist {i} covers Event {j}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
optimize_journalist_event_assignment()