Returns a generator that produces (x, y) tuples in a diamond shape.
    It is easier to predict the size of the diamond that this function
    produces, as opposed to creatinga 4-sided polygon with `polygon()`
    and rotating it 45 degrees.

    The `left` and `top` arguments are the x and y coordinates for the topleft corner of the square.

    The width and height of the diamond will be `2 * radius + 1`.

    If `filled` is `True`, the interior points are also returned.

    In this example diamond shape, the D characters represent the
    drawn diamond, the . characters represent the "outside spaces",
    and the ' characters represent the "inside spaces".
    (The radius of this example diamond is 3.)

    ...D
    ..D'D
    .D'''D
    D'''''D
    .D'''D
    ..D'D
    ...D

    >>> list(diamond(0, 0, 3))
    [(4, 0), (3, 1), (5, 1), (2, 2), (6, 2), (1, 3), (7, 3), (2, 4), (6, 4), (3, 5), (5, 5), (4, 6)]
    >>> drawPoints(diamond(0, 0, 3))
    ,,,O,,,
    ,,O,O,,
    ,O,,,O,
    O,,,,,O
    ,O,,,O,
    ,,O,O,,
    ,,,O,,,
    >>> drawPoints(diamond(0, 0, 3, filled=True))
    ,,,O,,,
    ,,OOO,,
    ,OOOOO,
    OOOOOOO
    ,OOOOO,
    ,,OOO,,
    ,,,O,,,

def diamond(x, y, radius, filled=False, thickness=1):
    """
    Returns a generator that produces (x, y) tuples in a diamond shape.
    It is easier to predict the size of the diamond that this function
    produces, as opposed to creatinga 4-sided polygon with `polygon()`
    and rotating it 45 degrees.

    The `left` and `top` arguments are the x and y coordinates for the topleft corner of the square.

    The width and height of the diamond will be `2 * radius + 1`.

    If `filled` is `True`, the interior points are also returned.

    In this example diamond shape, the D characters represent the
    drawn diamond, the . characters represent the "outside spaces",
    and the ' characters represent the "inside spaces".
    (The radius of this example diamond is 3.)

    ...D
    ..D'D
    .D'''D
    D'''''D
    .D'''D
    ..D'D
    ...D

    >>> list(diamond(0, 0, 3))
    [(4, 0), (3, 1), (5, 1), (2, 2), (6, 2), (1, 3), (7, 3), (2, 4), (6, 4), (3, 5), (5, 5), (4, 6)]
    >>> drawPoints(diamond(0, 0, 3))
    ,,,O,,,
    ,,O,O,,
    ,O,,,O,
    O,,,,,O
    ,O,,,O,
    ,,O,O,,
    ,,,O,,,
    >>> drawPoints(diamond(0, 0, 3, filled=True))
    ,,,O,,,
    ,,OOO,,
    ,OOOOO,
    OOOOOOO
    ,OOOOO,
    ,,OOO,,
    ,,,O,,,
    """

    if thickness != 1:
        raise NotImplementedError('The pybresenham module is under development and the filled, thickness, and endcap parameters are not implemented. You can contribute at https://github.com/asweigart/pybresenham')

    outsideSpaces = radius
    insideSpaces = 1 # We'll only start incrementing insidesSpaces on the 2nd row.

    for row in range(radius * 2 + 1):
        # Yield the leftside point in this row.
        yield (outsideSpaces + 1 + x, row + y)

        if row != 0 and row != radius * 2:
            # (The first and last rows only have one point per row.)

            if filled:
                # Yield all the interior spaces in this row.
                for interiorx in range(outsideSpaces + 2 + x, outsideSpaces + insideSpaces + 2 + x):
                    yield (interiorx, row + y) # No need for "+ x" here, we did that in the range() call.

            # Yield the rightside point in this row.
            yield (outsideSpaces + insideSpaces + 2 + x, row + y)

        # Modify outsideSpaces/insideSpaces as we move down the rows.
        if row < radius:
            outsideSpaces -= 1
            if row != 0:
                insideSpaces += 2
        else:
            outsideSpaces += 1
            insideSpaces -= 2