## Problem Description and Formulation

The art gallery sells two types of items: paintings and photo prints. The goal is to maximize profit given certain constraints.

- A painting takes 7 sq ft of wall space, and a photo print takes 4 sq ft.
- The gallery has 200 sq ft of wall space available.
- A painting costs $400, and a photo print costs $200.
- The gallery has a budget of $7000.
- At least 20% of the items in stock must be photo prints.
- The profit per painting sold is $330, and the profit per photo print sold is $170.

## Decision Variables

Let \(P\) be the number of paintings and \(PH\) be the number of photo prints.

## Objective Function

Maximize profit: \(330P + 170PH\).

## Constraints

1. Wall space constraint: \(7P + 4PH \leq 200\).
2. Budget constraint: \(400P + 200PH \leq 7000\).
3. Percentage of photo prints constraint: \(PH \geq 0.20(P + PH)\) or \(0.80PH \geq 0.20P\) or \(4PH \geq P\).
4. Non-negativity constraints: \(P \geq 0, PH \geq 0\).
5. Integer constraints: \(P, PH\) are integers.

## Gurobi Code

```python
import gurobi

def solve_gallery_problem():
    # Create a new model
    model = gurobi.Model()

    # Define decision variables
    P = model.addVar(name="paintings", vtype=gurobi.GRB.INTEGER)
    PH = model.addVar(name="photo_prints", vtype=gurobi.GRB.INTEGER)

    # Objective function: Maximize profit
    model.setObjective(330 * P + 170 * PH, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(7 * P + 4 * PH <= 200, name="wall_space")
    model.addConstr(400 * P + 200 * PH <= 7000, name="budget")
    model.addConstr(P - 4 * PH <= 0, name="photo_prints_percentage")

    # Non-negativity constraints are inherently handled by defining variables without bounds

    # Solve the model
    model.optimize()

    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution found.")
        print(f"Number of paintings: {P.varValue}")
        print(f"Number of photo prints: {PH.varValue}")
        print(f"Max Profit: {model.objVal}")
    elif model.status == gurobi.GRB.INFEASIBLE:
        print("The model is infeasible.")
    else:
        print("The model has a non-optimal status.")

solve_gallery_problem()
```