<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def Normalize(self, period, start_time, stop_time, mode=NORMALIZE_MODE_GAUGE):
 """Normalize the series to have a fixed period over a fixed time range. Supports two modes, depending on the type of data: NORMALIZE_MODE_GAUGE: support gauge values. If multiple original data points lie within an output interval, the output value is an average of the original data point. if no original data points lie within an output interval, the output value is None. NORMALIZE_MODE_COUNTER: supports counter values. Assumes that the sequence is already increasing (typically, MakeIncreasing will have been called). Each output value is the largest value seen during or before the corresponding output interval. Args: period: The desired time between points. Should be an rdfvalue.Duration or a count of microseconds. start_time: The first timestamp will be at start_time. Should be an rdfvalue.RDFDatetime or a count of microseconds since epoch. stop_time: The last timestamp will be at stop_time - period. Should be an rdfvalue.RDFDatetime or a count of microseconds since epoch. mode: The type of normalization to perform. May be NORMALIZE_MODE_GAUGE or NORMALIZE_MODE_COUNTER. Raises: RuntimeError: In case the sequence timestamps are misordered. """

    period = self._NormalizeTime(period)
    start_time = self._NormalizeTime(start_time)
    stop_time = self._NormalizeTime(stop_time)
    if not self.data:
      return

    self.FilterRange(start_time, stop_time)

    grouped = {}
    for value, timestamp in self.data:
      offset = timestamp - start_time
      shifted_offset = offset - (offset % period)
      grouped.setdefault(shifted_offset, []).append(value)

    self.data = []
    last_value = None
    for offset in range(0, stop_time - start_time, period):
      g = grouped.get(offset)
      if mode == NORMALIZE_MODE_GAUGE:
        v = None
        if g:
          v = sum(g) / len(g)
        self.data.append([v, offset + start_time])
      else:
        if g:
          for v in g:
            if v < last_value:
              raise RuntimeError("Next value must not be smaller.")
            last_value = v
        self.data.append([last_value, offset + start_time])