def calculate_upper_bounds(x_s, y_s):
    """
        Calculate upper bounds of total timesteps and average episodic
        return per iteration.

        Parameters:
            x_s - A list of lists of total timesteps so far per seed.
            y_s - A list of lists of average episodic return per seed.

        Return: 
            Upper bounds of both x_s and y_s
    """
    # x_low is upper bound of timesteps so far, y is upper bound of average episodic reward
    x_high, y_high = x_s[0], y_s[0]

    # Find upper bound amongst all trials per iteration
    for xs, ys in zip(x_s[1:], y_s[1:]):
        x_high = [x if x > x_high[i] else x_high[i] for i, x in enumerate(xs)]
        y_high = [y if y > y_high[i] else y_high[i] for i, y in enumerate(ys)]
    return x_high, y_high
Calculate upper bounds of total timesteps and average episodic
return per iteration.

Parameters:
x_s - A list of lists of total timesteps so far per seed.
y_s - A list of lists of average episodic return per seed.

Return:
Upper bounds of both x_s and y_s
part4/make_graph.py