To solve this optimization problem, we will first define the decision variables, the objective function, and the constraints based on the given information.

Let's denote:
- \(x_s\) as the number of packets of sardines to buy,
- \(x_t\) as the number of packets of tuna to buy.

The objective is to minimize the total cost. Given that each packet of sardines costs $15 and each packet of tuna costs $18, the objective function can be written as:
\[ \text{Minimize} \quad 15x_s + 18x_t \]

The constraints are based on the nutritional requirements:
1. Total fat: \(4x_s + 6x_t \geq 800\)
2. Essential fatty acids: \(12x_s + 10x_t \geq 1200\)
3. Protein: \(10x_s + 7x_t \geq 700\)

Additionally, the number of packets cannot be negative:
\[ x_s \geq 0, \quad x_t \geq 0 \]

Now, let's translate this into Gurobi code in Python:

```python
from gurobipy import *

# Create a new model
m = Model("Aquarium_Feeding")

# Define the decision variables
x_s = m.addVar(vtype=GRB.CONTINUOUS, name="sardines")
x_t = m.addVar(vtype=GRB.CONTINUOUS, name="tuna")

# Set the objective function
m.setObjective(15*x_s + 18*x_t, GRB.MINIMIZE)

# Add constraints
m.addConstr(4*x_s + 6*x_t >= 800, "fat")
m.addConstr(12*x_s + 10*x_t >= 1200, "essential_fatty_acids")
m.addConstr(10*x_s + 7*x_t >= 700, "protein")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Sardines: {x_s.x}")
    print(f"Tuna: {x_t.x}")
    print(f"Total Cost: {m.objVal}")
else:
    print("No optimal solution found")
```