nodes: 0, module; 1, function_definition; 2, function_name:calls_sorted; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, function_definition; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, comment:# TODO: ugh, this is ugly.  Test to find the optimal way to sort; 12, comment:# while still ending up with a list; 13, return_statement; 14, comment:"""
          calls sorted in z
          """; 15, function_name:_z; 16, parameters; 17, block; 18, assignment; 19, assignment; 20, assignment; 21, call; 22, identifier:call; 23, if_statement; 24, identifier:calls; 25, attribute; 26, identifier:zs; 27, call; 28, identifier:sorted_inds; 29, call; 30, attribute; 31, argument_list; 32, call; 33, block; 34, elif_clause; 35, else_clause; 36, identifier:self; 37, identifier:_calls; 38, attribute; 39, argument_list; 40, attribute; 41, argument_list; 42, identifier:_call; 43, identifier:make_callgroup; 44, call; 45, identifier:isinstance; 46, argument_list; 47, return_statement; 48, boolean_operator; 49, block; 50, comment:# put it at the back; 51, block; 52, identifier:np; 53, identifier:array; 54, list_comprehension; 55, identifier:zs; 56, identifier:argsort; 57, attribute; 58, argument_list; 59, attribute; 60, attribute; 61, call; 62, call; 63, call; 64, return_statement; 65, return_statement; 66, call; 67, for_in_clause; 68, subscript; 69, identifier:tolist; 70, attribute; 71, identifier:value; 72, identifier:np; 73, identifier:ndarray; 74, attribute; 75, argument_list; 76, identifier:isinstance; 77, argument_list; 78, identifier:isinstance; 79, argument_list; 80, attribute; 81, unary_operator; 82, identifier:_z; 83, argument_list; 84, identifier:c; 85, identifier:calls; 86, call; 87, identifier:sorted_inds; 88, identifier:call; 89, identifier:z; 90, identifier:np; 91, identifier:mean; 92, call; 93, attribute; 94, identifier:float; 95, attribute; 96, identifier:int; 97, attribute; 98, identifier:value; 99, attribute; 100, identifier:c; 101, attribute; 102, argument_list; 103, attribute; 104, argument_list; 105, attribute; 106, identifier:value; 107, attribute; 108, identifier:value; 109, identifier:call; 110, identifier:z; 111, identifier:np; 112, identifier:inf; 113, identifier:np; 114, identifier:array; 115, identifier:calls; 116, attribute; 117, identifier:flatten; 118, identifier:call; 119, identifier:z; 120, identifier:call; 121, identifier:z; 122, attribute; 123, identifier:value; 124, identifier:call; 125, identifier:z
code: def calls_sorted(self):
          """
          calls sorted in z
          """
          def _z(call):
              if isinstance(call.z.value, np.ndarray):
                  return np.mean(call.z.value.flatten())
              elif isinstance(call.z.value, float) or isinstance(call.z.value, int):
                  return call.z.value
              else:
                  # put it at the back
                  return -np.inf
  
          calls = self._calls
          zs = np.array([_z(c) for c in calls])
          sorted_inds = zs.argsort()
          # TODO: ugh, this is ugly.  Test to find the optimal way to sort
          # while still ending up with a list
          return _call.make_callgroup(np.array(calls)[sorted_inds].tolist())