docs: def make_primitive_extrapolate_ends(cas_coords, smoothing_level=2):
      """Generates smoothed helix primitives and extrapolates lost ends.
  
      Notes
      -----
      From an input list of CA coordinates, the running average is
      calculated to form a primitive. The smoothing_level dictates how
      many times to calculate the running average. A higher
      smoothing_level generates a 'smoother' primitive - i.e. the
      points on the primitive more closely fit a smooth curve in R^3.
      Each time the smoothing level is increased by 1, a point is lost
      from either end of the primitive. To correct for this, the primitive
      is extrapolated at the ends to approximate the lost values. There
      is a trade-off then between the smoothness of the primitive and
      its accuracy at the ends.
  
  
      Parameters
      ----------
      cas_coords : list(numpy.array or float or tuple)
          Each element of the list must have length 3.
      smoothing_level : int
          Number of times to run the averaging.
  
      Returns
      -------
      final_primitive : list(numpy.array)
          Each array has length 3.
      """
      try:
          smoothed_primitive = make_primitive_smoothed(
              cas_coords, smoothing_level=smoothing_level)
      except ValueError:
          smoothed_primitive = make_primitive_smoothed(
              cas_coords, smoothing_level=smoothing_level - 1)
      # if returned smoothed primitive is too short, lower the smoothing
      # level and try again.
      if len(smoothed_primitive) < 3:
          smoothed_primitive = make_primitive_smoothed(
              cas_coords, smoothing_level=smoothing_level - 1)
      final_primitive = []
      for ca in cas_coords:
          prim_dists = [distance(ca, p) for p in smoothed_primitive]
          closest_indices = sorted([x[0] for x in sorted(
              enumerate(prim_dists), key=lambda k: k[1])[:3]])
          a, b, c = [smoothed_primitive[x] for x in closest_indices]
          ab_foot = find_foot(a, b, ca)
          bc_foot = find_foot(b, c, ca)
          ca_foot = (ab_foot + bc_foot) / 2
          final_primitive.append(ca_foot)
      return final_primitive