def indexify_fn(self, fn, 
                   axis,
                   array_args, 
                   cartesian_product = False,
                   output = None, 
                   index_offsets = None):
    """
    Take a function whose last k values are slices through input data 
    and transform it into a function which explicitly extracts its arguments
    """  
    array_args = tuple(array_args)
    
    array_arg_types = tuple(get_types(array_args))

    closure_args = self.closure_elts(fn)
    closure_arg_types = tuple(get_types(closure_args))
    n_closure_args = len(closure_args)
    fn = self.get_fn(fn)
    
    axes = self.normalize_axes(array_args, axis)
    
    
    key = (  fn.cache_key, 
             axes,
             closure_arg_types, 
             array_arg_types, 
             output is None,  
             cartesian_product, 
             index_offsets, 
           )

    def mk_closure():
      new_fn = self._indexed_fn_cache[key] 
      if output is None:
        return self.closure(new_fn, closure_args + array_args)
      else:
        return self.closure(new_fn, (output, ) + closure_args + array_args)
    
    if key in self._indexed_fn_cache:
      result = mk_closure()
      return result 
    
    if cartesian_product:
      # if we're doing a cartesian product then each argument may need 
      # a different number of indices depending on whether it's a scalar
      # and when its axis is None or given as an int 
      n_indices = 0
      for axis, arg_t in zip(axes, array_arg_types):
        if axis is None:
          n_indices += self.rank(arg_t)
        elif isinstance(arg_t, ArrayT):
          n_indices += 1
    else:
      # if we're doing an element-wise map, 
      # then either the axes are all None, in which case 
      # we need indices for the largest arg
      # or, we're just picking off one slice from 
      # every argument 
      if any(axis is None for axis in axes):
        assert all(axis is None for axis in axes), "Incompatible axes %s" % axes 
        n_indices = max_rank(array_arg_types)
      else:
        assert all(isinstance(axis, (int,long)) for axis in axes), axes % "Invalid axes %s" 
        n_indices = 1
        
    #index_input_type = Int64 if n_indices == 1 else repeat_tuple(Int64, n_arrays) 
    index_input_types = (Int64,) * n_indices  
    
    if output is None:
      inner_input_types = closure_arg_types + array_arg_types + index_input_types
      new_return_type = fn.return_type 
    else:
      inner_input_types = (output.type,) + closure_arg_types +  array_arg_types + index_input_types
      new_return_type = NoneType 
    
    input_names = []
    if output is not None:
      if output is Var:
        local_output_name = names.refresh(output.name)
      else:
        local_output_name = names.fresh("local_output")
      input_names.append(local_output_name) 
    
    for old_input_name in fn.arg_names:
      input_names.append(names.refresh(old_input_name)) 
    
    
    input_names.extend(self.fresh_index_names(n_indices))
      
    
    new_fn_name = self.fresh_fn_name("idx_", fn)
    
    new_fn, builder, input_vars = build_fn(inner_input_types, 
                                           new_return_type,
                                           name = new_fn_name,  
                                           input_names = input_names)

    index_input_vars = input_vars[-n_indices:]
    if output is None:
      output_var = None
      closure_arg_vars = input_vars[:n_closure_args]
      array_arg_vars = input_vars[n_closure_args:-n_indices]
    else:
      output_var = input_vars[0]
      closure_arg_vars = input_vars[1:n_closure_args+1]
      array_arg_vars = input_vars[n_closure_args+1:-n_indices]
    
    slice_values = \
      self.get_slices(builder, array_arg_vars, axes, index_input_vars, 
                      cartesian_product, index_offsets)


    elt_result = builder.call(fn, tuple(closure_arg_vars) + tuple(slice_values))
    if output is None: 
      builder.return_(elt_result)
    else:
      if len(index_input_vars) > 1:
        builder.setidx(output_var, builder.tuple(index_input_vars), elt_result)
      else:
        builder.setidx(output_var, index_input_vars[0], elt_result)
      builder.return_(none)
    
    new_fn.created_by = self.fn.created_by 
    new_fn.transform_history = self.fn.transform_history 
    self._indexed_fn_cache[key] = new_fn
    return mk_closure()
dataset/ETHPy150Open iskandr/parakeet/parakeet/transforms/indexify_adverbs.py/IndexifyAdverbs.indexify_fn/swapped operands of `%`