## Symbolic Representation

Let's denote the variables as follows:
- $x_1$: kg of Granny Smith apples
- $x_2$: kg of McIntosh apples

The objective is to maximize profit, given that the profit per kg of Granny Smith apples is $2 and per kg of McIntosh apples is $1. Therefore, the objective function is:

Maximize: $2x_1 + x_2$

The constraints based on the problem description are:
- At most 100 kg of Granny Smith apples: $x_1 \leq 100$
- At most 120 kg of McIntosh apples: $x_2 \leq 120$
- At least 25 kg of Granny Smith apples: $x_1 \geq 25$
- At least 50 kg of McIntosh apples: $x_2 \geq 50$
- Cleaning machine availability: $3x_1 + 3x_2 \leq 15$

## Symbolic Representation in JSON Format

```json
{
    'sym_variables': [('x1', 'kg of Granny Smith apples'), ('x2', 'kg of McIntosh apples')],
    'objective_function': '2*x1 + x2',
    'constraints': [
        'x1 <= 100',
        'x2 <= 120',
        'x1 >= 25',
        'x2 >= 50',
        '3*x1 + 3*x2 <= 15'
    ]
}
```

## Gurobi Code in Python

```python
import gurobipy as gp

# Create a new model
model = gp.Model("AppleFarm")

# Define variables
x1 = model.addVar(lb=25, ub=100, name="GrannySmith")
x2 = model.addVar(lb=50, ub=120, name="McIntosh")

# Objective function: maximize profit
model.setObjective(2*x1 + x2, gp.GRB.MAXIMIZE)

# Constraints
model.addConstr(x1 <= 100, name="GrannySmithLimit")
model.addConstr(x2 <= 120, name="McIntoshLimit")
model.addConstr(x1 >= 25, name="GrannySmithMin")
model.addConstr(x2 >= 50, name="McIntoshMin")
model.addConstr(3*x1 + 3*x2 <= 15, name="CleaningMachineLimit")

# Solve the model
model.optimize()

# Print the solution
if model.status == gp.GRB.OPTIMAL:
    print("Optimal Solution:")
    print(f"Granny Smith apples: {x1.varValue} kg")
    print(f"McIntosh apples: {x2.varValue} kg")
    print(f"Max Profit: ${model.objVal}")
else:
    print("No optimal solution found.")
```