import random


def generate_data(m = 2, b = 7, stdev = 20, num_examples = 20):
    """
    Return some 'fake' data consisting of a cloud of points scattered about the line y = mx + b
    (which is y = 2x + 7 by default).

    The x-values of the points are chosen randomly and uniformly from the interval [0,40].
    The y-values are chosen by adding to mx+b an error sampled from N(0, 20) (which is the nor-
    mal distribution with mean 0 and standard deviation stdev(=20 by default)).

    The x-values are returned as a list of lists of the form xs = [[x_1], [x_2], ... ].
    The y-values are returned as a list of lists of the form ys = [[y_1], [y_2], ... ].

    Args:
        m: The slope of the line used to generate the point cloud.
        b: The intercept of that line.
        stdev:  The standard deviation of the normal distribution used generate the errors.
        num_examples: The number of points in the cloud.

    Returns:
        xs, ys: These are both lists of lists.
    """
    xs = []  # this list will hold the x-values
    ys = []  # this one will hold the y-values

    for i in range(num_examples):

        # Append an x-value drawn uniformly from the interval [0,40].
        x = random.uniform(0,40)
        xs.append([x])

        # Append the corresponding point on the line plus some error.
        ys.append([m * x + b + random.normalvariate(0,stdev)])

    return xs, ys