Compute the moving average of  YCOL'th column of each sample point
in  DATA. In particular, for each element  I in  DATA,
this function extracts up to  WIDTH*2+1 elements, consisting of
 I itself,  WIDTH elements before  I, and  WIDTH
elements after  I. It then computes the mean of the  YCOL'th
column of these elements, and it composes a two-element sample
consisting of  XCOL'th element and the mean.

>>> data = [[10,20], [20,30], [30,50], [40,70], [50,5]]
... chart_data.moving_average(data, 0, 1, 1)
[(10, 25.0), (20, 33.333333333333336), (30, 50.0), (40, 41.666666666666664), (50, 37.5)]

  The above value actually represents:

[(10, (20+30)/2), (20, (20+30+50)/3), (30, (30+50+70)/3), 
  (40, (50+70+5)/3), (50, (70+5)/2)]

def moving_average(data, xcol, ycol, width):
    """Compute the moving average of  YCOL'th column of each sample point
in  DATA. In particular, for each element  I in  DATA,
this function extracts up to  WIDTH*2+1 elements, consisting of
 I itself,  WIDTH elements before  I, and  WIDTH
elements after  I. It then computes the mean of the  YCOL'th
column of these elements, and it composes a two-element sample
consisting of  XCOL'th element and the mean.

>>> data = [[10,20], [20,30], [30,50], [40,70], [50,5]]
... chart_data.moving_average(data, 0, 1, 1)
[(10, 25.0), (20, 33.333333333333336), (30, 50.0), (40, 41.666666666666664), (50, 37.5)]

  The above value actually represents:

[(10, (20+30)/2), (20, (20+30+50)/3), (30, (30+50+70)/3), 
  (40, (50+70+5)/3), (50, (70+5)/2)]

"""

    out = []
    try:
        for i in range(len(data)):
            n = 0
            total = 0
            for j in range(i - width, i + width + 1):
                if j >= 0 and j < len(data):
                    total += data[j][ycol]
                    n += 1
            out.append((data[i][xcol], float(total) / n))
    except IndexError:
        raise IndexError("bad data: %s,xcol=%d,ycol=%d,width=%d" % (data, xcol, ycol, width))

    return out