To solve this problem, we need to formulate a linear programming model that captures the constraints and objectives described. The goal is to maximize the total score by deciding how many small balls (worth 5 points each) and large balls (worth 2 points each) to throw.

Let's denote:
- \(x_s\) as the number of small balls thrown,
- \(x_l\) as the number of large balls thrown.

The objective function, which we want to maximize, is given by:
\[ \text{Maximize} \quad 5x_s + 2x_l \]

Subject to the following constraints:
1. The total number of balls thrown cannot exceed 20: \( x_s + x_l \leq 20 \)
2. At least 6 small balls must be thrown: \( x_s \geq 6 \)
3. At least 5 large balls must be thrown: \( x_l \geq 5 \)
4. No more than 12 of either type can be thrown:
   - For small balls: \( x_s \leq 12 \)
   - For large balls: \( x_l \leq 12 \)

All variables are non-negative since we cannot throw a negative number of balls.

The Gurobi code in Python will reflect these constraints and the objective function. We use the `gurobipy` library to model and solve this linear programming problem.

```python
from gurobipy import *

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

# Define variables
x_s = m.addVar(name="small_balls", lb=6, ub=12)  # Number of small balls thrown
x_l = m.addVar(name="large_balls", lb=5, ub=12)  # Number of large balls thrown

# Set the objective function: Maximize the total score
m.setObjective(5*x_s + 2*x_l, GRB.MAXIMIZE)

# Add constraints
m.addConstr(x_s + x_l <= 20, name="total_balls")  # Total balls constraint

# Solve the model
m.optimize()

# Check if an optimal solution was found
if m.status == GRB.OPTIMAL:
    print(f"Optimal score: {m.objVal}")
    print(f"Throw {x_s.x} small balls and {x_l.x} large balls.")
else:
    print("No optimal solution found. The model may be infeasible.")

# Print the Gurobi model
m.printStats()
```