docs: def sort_strings(strings, sort_order=None, reverse=False, case_sensitive=False, sort_order_first=True):
      """Sort a list of strings according to the provided sorted list of string prefixes
  
      TODO:
          - Provide an option to use `.startswith()` rather than a fixed prefix length (will be much slower)
  
      Arguments:
          sort_order_first (bool): Whether strings in sort_order should always preceed "unknown" strings
          sort_order (sequence of str): Desired ordering as a list of prefixes to the strings
              If sort_order strings have varying length, the max length will determine the prefix length compared
          reverse (bool): whether to reverse the sort orded. Passed through to `sorted(strings, reverse=reverse)`
          case_senstive (bool): Whether to sort in lexographic rather than alphabetic order
           and whether the prefixes  in sort_order are checked in a case-sensitive way
  
      Examples:
          >>> sort_strings(['morn32', 'morning', 'unknown', 'date', 'dow', 'doy', 'moy'],
          ...              ('dat', 'dow', 'moy', 'dom', 'doy', 'mor'))
          ['date', 'dow', 'moy', 'doy', 'morn32', 'morning', 'unknown']
          >>> sort_strings(['morn32', 'morning', 'unknown', 'less unknown', 'lucy', 'date', 'dow', 'doy', 'moy'],
          ...              ('dat', 'dow', 'moy', 'dom', 'doy', 'mor'), reverse=True)
          ['unknown', 'lucy', 'less unknown', 'morning', 'morn32', 'doy', 'moy', 'dow', 'date']
  
          Strings whose prefixes don't exist in `sort_order` sequence can be interleaved into the
          sorted list in lexical order by setting `sort_order_first=False`
          >>> sort_strings(['morn32', 'morning', 'unknown', 'lucy', 'less unknown', 'date', 'dow', 'doy', 'moy'],
          ...              ('dat', 'dow', 'moy', 'dom', 'moy', 'mor'),
          ...              sort_order_first=False)  # doctest: +NORMALIZE_WHITESPACE
          ['date', 'dow', 'doy', 'less unknown', 'lucy', 'moy', 'morn32', 'morning', 'unknown']
      """
      if not case_sensitive:
          sort_order = tuple(s.lower() for s in sort_order)
          strings = tuple(s.lower() for s in strings)
      prefix_len = max(len(s) for s in sort_order)
  
      def compare(a, b, prefix_len=prefix_len):
          if prefix_len:
              if a[:prefix_len] in sort_order:
                  if b[:prefix_len] in sort_order:
                      comparison = sort_order.index(a[:prefix_len]) - sort_order.index(b[:prefix_len])
                      comparison = int(comparison / abs(comparison or 1))
                      if comparison:
                          return comparison * (-2 * reverse + 1)
                  elif sort_order_first:
                      return -1 * (-2 * reverse + 1)
              # b may be in sort_order list, so it should be first
              elif sort_order_first and b[:prefix_len] in sort_order:
                  return -2 * reverse + 1
          return (-1 * (a < b) + 1 * (a > b)) * (-2 * reverse + 1)
  
      return sorted(strings, key=functools.cmp_to_key(compare))