nodes: 0, module; 1, function_definition; 2, function_name:naturalize_person; 3, parameters; 4, block; 5, identifier:self; 6, identifier:string; 7, expression_statement; 8, expression_statement; 9, comment:# Add lowercase versions:; 10, expression_statement; 11, comment:# If a name has a capitalised particle in we use that to sort.; 12, comment:# So 'Le Carre, John' but 'Carre, John le'.; 13, expression_statement; 14, expression_statement; 15, comment:# Smith; 16, expression_statement; 17, comment:# Fred James; 18, expression_statement; 19, comment:# Jr; 20, expression_statement; 21, expression_statement; 22, if_statement; 23, if_statement; 24, if_statement; 25, comment:# In case this name has any numbers in it.; 26, expression_statement; 27, return_statement; 28, comment:"""
          Attempt to make a version of the string that has the surname, if any,
          at the start.
  
          'John, Brown' to 'Brown, John'
          'Sir John Brown Jr' to 'Brown, Sir John Jr'
          'Prince' to 'Prince'
  
          string -- The string to change.
          """; 29, assignment; 30, assignment; 31, assignment; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, comparison_operator:parts[-1] in suffixes; 38, comment:# Remove suffixes entirely, as we'll add them back on the end.; 39, block; 40, comparison_operator:len(parts) > 1; 41, block; 42, identifier:suffix; 43, comment:# Add it back on.; 44, block; 45, assignment; 46, identifier:sort_string; 47, identifier:suffixes; 48, list; 49, identifier:suffixes; 50, binary_operator:suffixes + [s.lower() for s in suffixes]; 51, identifier:particles; 52, list; 53, identifier:surname; 54, string; 55, identifier:names; 56, string; 57, identifier:suffix; 58, string; 59, identifier:sort_string; 60, identifier:string; 61, identifier:parts; 62, call; 63, subscript; 64, identifier:suffixes; 65, expression_statement; 66, expression_statement; 67, comment:# Remove suffix from parts; 68, expression_statement; 69, call; 70, integer:1; 71, if_statement; 72, comment:# From 'David Foster Wallace' to 'Wallace, David Foster':; 73, expression_statement; 74, expression_statement; 75, identifier:sort_string; 76, call; 77, string; 78, string; 79, string; 80, string; 81, string; 82, string; 83, string; 84, string; 85, string; 86, identifier:suffixes; 87, list_comprehension; 88, string; 89, string; 90, string; 91, string; 92, string; 93, string; 94, attribute; 95, argument_list; 96, identifier:parts; 97, unary_operator; 98, assignment; 99, assignment; 100, assignment; 101, identifier:len; 102, argument_list; 103, comparison_operator:parts[-2] in particles; 104, comment:# From ['Alan', 'Barry', 'Le', 'Carré']; 105, comment:# to   ['Alan', 'Barry', 'Le Carré']:; 106, block; 107, assignment; 108, assignment; 109, attribute; 110, argument_list; 111, string_content:Jr; 112, string_content:Jr.; 113, string_content:Sr; 114, string_content:Sr.; 115, string_content:I; 116, string_content:II; 117, string_content:III; 118, string_content:IV; 119, string_content:V; 120, call; 121, for_in_clause; 122, string_content:Le; 123, string_content:La; 124, string_content:Von; 125, string_content:Van; 126, string_content:Du; 127, string_content:De; 128, identifier:string; 129, identifier:split; 130, string; 131, integer:1; 132, identifier:suffix; 133, subscript; 134, identifier:parts; 135, subscript; 136, identifier:sort_string; 137, call; 138, identifier:parts; 139, subscript; 140, identifier:particles; 141, expression_statement; 142, identifier:sort_string; 143, call; 144, identifier:sort_string; 145, call; 146, identifier:self; 147, identifier:_naturalize_numbers; 148, identifier:sort_string; 149, attribute; 150, argument_list; 151, identifier:s; 152, identifier:suffixes; 153, string_content:; 154, identifier:parts; 155, unary_operator; 156, identifier:parts; 157, slice; 158, attribute; 159, argument_list; 160, identifier:parts; 161, unary_operator; 162, assignment; 163, attribute; 164, argument_list; 165, attribute; 166, argument_list; 167, identifier:s; 168, identifier:lower; 169, integer:1; 170, integer:0; 171, unary_operator; 172, string; 173, identifier:join; 174, identifier:parts; 175, integer:2; 176, identifier:parts; 177, binary_operator:parts[0:-2] + [ ' '.join(parts[-2:]) ]; 178, string; 179, identifier:format; 180, subscript; 181, call; 182, string; 183, identifier:format; 184, identifier:sort_string; 185, identifier:suffix; 186, integer:1; 187, string_content:; 188, subscript; 189, list; 190, string_content:{}, {}; 191, identifier:parts; 192, unary_operator; 193, attribute; 194, argument_list; 195, string_content:{} {}; 196, identifier:parts; 197, slice; 198, call; 199, integer:1; 200, string; 201, identifier:join; 202, subscript; 203, integer:0; 204, unary_operator; 205, attribute; 206, argument_list; 207, string_content:; 208, identifier:parts; 209, slice; 210, integer:2; 211, string; 212, identifier:join; 213, subscript; 214, unary_operator; 215, string_content:; 216, identifier:parts; 217, slice; 218, integer:1; 219, unary_operator; 220, integer:2
code: def naturalize_person(self, string):
          """
          Attempt to make a version of the string that has the surname, if any,
          at the start.
  
          'John, Brown' to 'Brown, John'
          'Sir John Brown Jr' to 'Brown, Sir John Jr'
          'Prince' to 'Prince'
  
          string -- The string to change.
          """
          suffixes = [
                      'Jr', 'Jr.', 'Sr', 'Sr.',
                      'I', 'II', 'III', 'IV', 'V',
                      ]
          # Add lowercase versions:
          suffixes = suffixes + [s.lower() for s in suffixes]
  
          # If a name has a capitalised particle in we use that to sort.
          # So 'Le Carre, John' but 'Carre, John le'.
          particles = [
                      'Le', 'La',
                      'Von', 'Van',
                      'Du', 'De',
                      ]
  
          surname = '' # Smith
          names = ''   # Fred James
          suffix = ''  # Jr
  
          sort_string = string
          parts = string.split(' ')
  
          if parts[-1] in suffixes:
              # Remove suffixes entirely, as we'll add them back on the end.
              suffix = parts[-1]
              parts = parts[0:-1] # Remove suffix from parts
              sort_string = ' '.join(parts)
  
          if len(parts) > 1:
  
              if parts[-2] in particles:
                  # From ['Alan', 'Barry', 'Le', 'Carré']
                  # to   ['Alan', 'Barry', 'Le Carré']:
                  parts = parts[0:-2] + [ ' '.join(parts[-2:]) ]
  
              # From 'David Foster Wallace' to 'Wallace, David Foster':
              sort_string = '{}, {}'.format(parts[-1], ' '.join(parts[:-1]))
  
          if suffix:
              # Add it back on.
              sort_string = '{} {}'.format(sort_string, suffix)
  
          # In case this name has any numbers in it.
          sort_string = self._naturalize_numbers(sort_string)
  
          return sort_string