To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote the number of pianos as \(P\) and the number of guitars as \(G\).

The objective is to maximize profit. The profit per piano sold is $300, and the profit per guitar sold is $200. So, the total profit can be represented as \(300P + 200G\).

We have two main constraints:
1. **Space Constraint**: Each piano takes 8 sq ft of space, and each guitar takes 3 sq ft of space. The store has 100 sq ft of space available. This can be represented as \(8P + 3G \leq 100\).
2. **Budget Constraint**: A piano costs $500, and a guitar costs $300. The store has a budget of $8000. This constraint is represented as \(500P + 300G \leq 8000\).

Additionally, we have the constraint that at least 30% of items in stock must be guitars. If \(T = P + G\) represents the total number of items, then this constraint can be written as \(G \geq 0.3T\) or \(G \geq 0.3(P + G)\), which simplifies to \(G \geq 0.3P + 0.3G\), and further simplifies to \(0.7G \geq 0.3P\).

Now, let's represent these constraints and the objective function in a standard form that can be translated into Gurobi code.

```python
from gurobipy import *

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

# Define decision variables
pianos = m.addVar(name='pianos', vtype=GRB.INTEGER, lb=0)
guitars = m.addVar(name='guitars', vtype=GRB.INTEGER, lb=0)

# Objective function: Maximize profit
m.setObjective(300*pianos + 200*guitars, GRB.MAXIMIZE)

# Constraints
m.addConstr(8*pianos + 3*guitars <= 100, name='space_constraint')
m.addConstr(500*pianos + 300*guitars <= 8000, name='budget_constraint')
m.addConstr(0.7*guitars >= 0.3*pianos, name='guitar_percentage_constraint')

# Optimize the model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: {pianos.varName} = {pianos.x}, {guitars.varName} = {guitars.x}")
else:
    print("No optimal solution found")
```