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

- Decision Variables:
  - \(x_s\): The number of storefront signs produced.
  - \(x_t\): The number of street signs produced.

- Objective Function:
  - Maximize profit: \(400x_s + 120x_t\)

- Constraints:
  - Cutting time constraint: \(2x_s + x_t \leq 100\)
  - Printing time constraint: \(1x_s + 0.5x_t \leq 50\)
  - Assembly time constraint: \(2x_s + 0.8x_t \leq 60\)
  - Non-negativity constraints: \(x_s \geq 0, x_t \geq 0\)

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

```python
from gurobipy import *

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

# Define the decision variables
x_s = m.addVar(vtype=GRB.CONTINUOUS, name="storefront_signs", lb=0)
x_t = m.addVar(vtype=GRB.CONTINUOUS, name="street_signs", lb=0)

# Set the objective function
m.setObjective(400*x_s + 120*x_t, GRB.MAXIMIZE)

# Add constraints
m.addConstr(2*x_s + x_t <= 100, name="cutting_time")
m.addConstr(x_s + 0.5*x_t <= 50, name="printing_time")
m.addConstr(2*x_s + 0.8*x_t <= 60, name="assembly_time")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Number of storefront signs: {x_s.x}")
    print(f"Number of street signs: {x_t.x}")
    print(f"Maximum profit: ${400*x_s.x + 120*x_t.x:.2f}")
else:
    print("No optimal solution found.")
```