code: def find_fingering(self, notes, max_distance=4, not_strings=[]):
          
          if notes is None:
              return []
          if len(notes) == 0:
              return []
          first = notes[0]
          notes = notes[1:]
          frets = self.find_frets(first)
          result = []
          for (string, fret) in enumerate(frets):
              if fret is not None and string not in not_strings:
                  if len(notes) > 0:
                      # recursively find fingerings for
                      # remaining notes
                      r = self.find_fingering(notes, max_distance, not_strings
                               + [string])
                      if r != []:
                          for f in r:
                              result.append([(string, fret)] + f)
                  else:
                      result.append([(string, fret)])
  
          # filter impossible fingerings and sort
          res = []
          for r in result:
              (min, max) = (1000, -1)
              frets = 0
              for (string, fret) in r:
                  if fret > max:
                      max = fret
                  if fret < min and fret != 0:
                      min = fret
                  frets += fret
              if 0 <= max - min < max_distance or min == 1000 or max == -1:
                  res.append((frets, r))
          return [r for (_, r) in sorted(res)]
docs: Return a list [(string, fret)] of possible fingerings for
          'notes'.
  
          The notes parameter should be a list of strings or Notes or a
          NoteContainer; max_distance denotes the maximum distance between
          frets; not_strings can be used to disclude certain strings and is
          used internally to recurse.
  
          Example:
          >>> t = tunings.StringTuning('test', 'test', ['A-3', 'E-4', 'A-5'])
          >>> t.find_fingering(['E-4', 'B-4'])
          [[(0, 7), (1, 7)], [(1, 0), (0, 14)]]