human
Write me a the Python program you requested given the following:
I am working on the file "03_reinforcement_learning_basic.ipynb".
The first task is:
Because the action space is discrete, we only need to take the sign of the linear regression output. In this case the weights can be sampled uniformly in [-1, 1]. However, if we want to use the bias term, it should be sampled according to the boundaries of the observation space (?)
Can you write Python program for it?
assistant
#Here is the Python program you requested.

# generate model weights: [n_models, n_params]
models = 2 * np.random.random([N_MODELS, env.observation_space.shape[0]]) - 1 # uniform in [-1, +1]

class LinearAgent(object):
    def __init__(self, weights=None):
        self._weights = weights
        
    @property
    def weights(self):
        return self._weights

    @weights.setter
    def weights(self, new_weights):
        self._weights = new_weights
        
    def action(self, state):
        a = np.dot(self._weights, state)
        return int(a > 0)

def play_episode(env, agent, max_steps=MAX_STEPS):
    observations = []
    rewards = []
    o = env.reset()
    for t in range(max_steps):
        a = agent.action(o)
        o, r, done, info = env.step(a)
        rewards.append(r)
        observations.append(o)
        if done:
            break
    return observations, rewards

def evaluate_agent(env, agent, n_experiments=20, max_steps=MAX_STEPS):
    episode_rewards = []
    for e in range(n_experiments):
        observations, rewards = play_episode(env, agent, max_steps)
        
        avg_reward = np.array(rewards).sum() / max_steps
        episode_rewards.append(avg_reward)
    
    episode_rewards = np.array(episode_rewards)
    return episode_rewards.sum(), episode_rewards.mean()

model_metrics = np.zeros((models.shape[0], 2)) # total and mean reward for each model
for i, m in tqdm(enumerate(models)):
    agent = LinearAgent(m)
    model_metrics[i, :] = evaluate_agent(env, agent)

%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('ggplot')

plt.hist(model_metrics[:,1], bins=50)
plt.title('Distribution of expected cumulative reward')
plt.xlabel('mean reward')
plt.show()

print('% of successful models', (model_metrics[:,1] == 1.0).mean())