## Problem Description and Gurobi Code

### Problem Description

The problem is an optimization problem with the goal to minimize the objective function:

\[ 9.06 \times \text{hours worked by Hank} + 5.38 \times \text{hours worked by Bobby} + 9.94 \times \text{hours worked by Peggy} \]

subject to various constraints on work quality rating, likelihood to quit index, dollar cost per hour, organization score, and productivity rating.

### Gurobi Code

```python
import gurobi

# Define the model
m = gurobi.Model()

# Define the variables
hours_worked_by_Hank = m.addVar(name="hours_worked_by_Hank", lb=0)  # Fractional hours allowed
hours_worked_by_Bobby = m.addVar(name="hours_worked_by_Bobby", lb=0, integrality=gurobi.GRB.INTEGER)  # Non-fractional hours
hours_worked_by_Peggy = m.addVar(name="hours_worked_by_Peggy", lb=0)  # Fractional hours allowed

# Define the coefficients for the objective function
obj_coeffs = [9.06, 5.38, 9.94]

# Set the objective function
m.setObjective(obj_coeffs[0]*hours_worked_by_Hank + obj_coeffs[1]*hours_worked_by_Bobby + obj_coeffs[2]*hours_worked_by_Peggy, gurobi.GRB.MINIMIZE)

# Define the resources/attributes
resources = {
    'r0': {'description': 'work quality rating', 'upper_bound': 216, 'x0': 6.31, 'x1': 14.73, 'x2': 14.29},
    'r1': {'description': 'likelihood to quit index', 'upper_bound': 97, 'x0': 17.26, 'x1': 19.79, 'x2': 9.37},
    'r2': {'description': 'dollar cost per hour', 'upper_bound': 191, 'x0': 15.74, 'x1': 5.05, 'x2': 19.88},
    'r3': {'description': 'organization score', 'upper_bound': 153, 'x0': 9.25, 'x1': 16.92, 'x2': 2.08},
    'r4': {'description': 'productivity rating', 'upper_bound': 188, 'x0': 2.6, 'x1': 0.19, 'x2': 17.17}
}

# Add constraints
m.addConstr(resources['r0']['x0']*hours_worked_by_Hank + resources['r0']['x1']*hours_worked_by_Bobby >= 56, name="work_quality_rating_Hank_Bobby")
m.addConstr(resources['r0']['x0']*hours_worked_by_Hank + resources['r0']['x1']*hours_worked_by_Bobby + resources['r0']['x2']*hours_worked_by_Peggy >= 56, name="work_quality_rating_all")
m.addConstr(resources['r1']['x0']*hours_worked_by_Hank + resources['r1']['x1']*hours_worked_by_Bobby >= 27, name="likelihood_to_quit_index_Hank_Bobby")
m.addConstr(resources['r1']['x0']*hours_worked_by_Hank + resources['r1']['x1']*hours_worked_by_Bobby + resources['r1']['x2']*hours_worked_by_Peggy >= 27, name="likelihood_to_quit_index_all")
m.addConstr(resources['r2']['x1']*hours_worked_by_Bobby + resources['r2']['x2']*hours_worked_by_Peggy >= 30, name="dollar_cost_per_hour_Bobby_Peggy")
m.addConstr(resources['r2']['x0']*hours_worked_by_Hank + resources['r2']['x2']*hours_worked_by_Peggy >= 44, name="dollar_cost_per_hour_Hank_Peggy")
m.addConstr(resources['r2']['x0']*hours_worked_by_Hank + resources['r2']['x1']*hours_worked_by_Bobby + resources['r2']['x2']*hours_worked_by_Peggy >= 44, name="dollar_cost_per_hour_all")
m.addConstr(resources['r3']['x0']*hours_worked_by_Hank + resources['r3']['x2']*hours_worked_by_Peggy >= 22, name="organization_score_Hank_Peggy")
m.addConstr(resources['r3']['x1']*hours_worked_by_Bobby + resources['r3']['x2']*hours_worked_by_Peggy >= 42, name="organization_score_Bobby_Peggy")
m.addConstr(resources['r3']['x0']*hours_worked_by_Hank + resources['r3']['x1']*hours_worked_by_Bobby + resources['r3']['x2']*hours_worked_by_Peggy >= 42, name="organization_score_all")
m.addConstr(resources['r3']['x0']*hours_worked_by_Hank + resources['r3']['x2']*hours_worked_by_Peggy <= 77, name="organization_score_Hank_Peggy_upper")
m.addConstr(resources['r4']['x0']*hours_worked_by_Hank + resources['r4']['x1']*hours_worked_by_Bobby + resources['r4']['x2']*hours_worked_by_Peggy >= 49, name="productivity_rating_all")
m.addConstr(resources['r4']['x0']*hours_worked_by_Hank + resources['r4']['x2']*hours_worked_by_Peggy >= 38, name="productivity_rating_Hank_Peggy")
m.addConstr(resources['r4']['x0']*hours_worked_by_Hank + resources['r4']['x1']*hours_worked_by_Bobby + resources['r4']['x2']*hours_worked_by_Peggy <= 159, name="productivity_rating_all_upper")
m.addConstr(-6*hours_worked_by_Hank + 6*hours_worked_by_Bobby >= 0, name="Hank_Bobby_hours")

# Solve the model
m.optimize()

# Print the solution
if m.status == gurobi.GRB.OPTIMAL:
    print("Optimal Solution:")
    print(f"Hours worked by Hank: {hours_worked_by_Hank.varValue}")
    print(f"Hours worked by Bobby: {hours_worked_by_Bobby.varValue}")
    print(f"Hours worked by Peggy: {hours_worked_by_Peggy.varValue}")
    print(f"Objective Function Value: {m.objVal}")
else:
    print("No optimal solution found.")
```