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

Let's denote:
- \(N\) as the number of newspaper ads,
- \(R\) as the number of radio ads,
- \(T\) as the number of television ads.

The objective is to maximize the total viewership. The expected viewership from each type of ad is given as follows: 5000 viewers for a newspaper ad, 1000 viewers for a radio ad, and 8000 viewers for a television ad. Therefore, the objective function can be written as:
\[ \text{Maximize} \quad 5000N + 1000R + 8000T \]

The constraints are:
1. **Budget Constraint**: The total cost of all ads must not exceed $100,000.
\[ 1200N + 500R + 2000T \leq 100,000 \]
2. **Radio Ads Limit**: No more than 10 radio ads can be run.
\[ R \leq 10 \]
3. **Television Ads Fraction**: At most a third of the total number of ads should be television ads.
\[ T \leq \frac{1}{3}(N + R + T) \]
4. **Newspaper Ads Fraction**: At least 20% of the ads should be newspaper ads.
\[ N \geq 0.2(N + R + T) \]

To implement this in Gurobi, we need to ensure all variables are non-negative since they represent quantities of ads.

Here is how you could express this problem in Python using Gurobi:

```python
from gurobipy import *

# Create a model
m = Model("Theta_Sandwich_Optimization")

# Decision variables
N = m.addVar(vtype=GRB.INTEGER, name="Newspaper_Ads")
R = m.addVar(vtype=GRB.INTEGER, name="Radio_Ads")
T = m.addVar(vtype=GRB.INTEGER, name="Television_Ads")

# Objective function: Maximize total viewership
m.setObjective(5000*N + 1000*R + 8000*T, GRB.MAXIMIZE)

# Constraints
# Budget constraint
m.addConstr(1200*N + 500*R + 2000*T <= 100000, name="Budget")

# Radio ads limit
m.addConstr(R <= 10, name="Radio_Ads_Limit")

# Television ads fraction
m.addConstr(T <= (1/3)*(N + R + T), name="Television_Ads_Fraction")

# Newspaper ads fraction
m.addConstr(N >= 0.2*(N + R + T), name="Newspaper_Ads_Fraction")

# Non-negativity constraints are implicitly handled by GRB.INTEGER with lower bound at 0

# Solve the model
m.optimize()

# Print results if optimal solution is found
if m.status == GRB.OPTIMAL:
    print(f"Optimal number of Newspaper Ads: {N.x}")
    print(f"Optimal number of Radio Ads: {R.x}")
    print(f"Optimal number of Television Ads: {T.x}")
else:
    print("No optimal solution found")
```