class_docstr: Abstract base class for all attack classes.
class_docstr_tok: ["Abstract","base","class","for","all","attack","classes","."]
docstr: Construct the inputs to the attack graph to be used by generate_np.
  
  :param kwargs: Keyword arguments to generate_np.
  :return:
    Structural arguments
    Feedable arguments
    Output of `arg_type` describing feedable arguments
    A unique key
docstr_tok: ["Construct","the","inputs","to","the","attack","graph","to","be","used","by","generate_np",".",":","param","kwargs",":","Keyword","arguments","to","generate_np",".",":","return",":","Structural","arguments","Feedable","arguments","Output","of","`","arg_type","`","describing","feedable","arguments","A","unique","key"]
code: def construct_variables(self, kwargs):
      """
      Construct the inputs to the attack graph to be used by generate_np.
  
      :param kwargs: Keyword arguments to generate_np.
      :return:
        Structural arguments
        Feedable arguments
        Output of `arg_type` describing feedable arguments
        A unique key
      """
      if isinstance(self.feedable_kwargs, dict):
          warnings.warn(
              "Using a dict for `feedable_kwargs is deprecated."
              "Switch to using a tuple."
              "It is not longer necessary to specify the types "
              "of the arguments---we build a different graph "
              "for each received type."
              "Using a dict may become an error on or after "
              "2019-04-18."
          )
          feedable_names = tuple(sorted(self.feedable_kwargs.keys()))
      else:
          feedable_names = self.feedable_kwargs
          if not isinstance(feedable_names, tuple):
              raise TypeError(
                  "Attack.feedable_kwargs should be a tuple, but "
                  "for subclass "
                  + str(type(self))
                  + " it is "
                  + str(self.feedable_kwargs)
                  + " of type "
                  + str(type(self.feedable_kwargs))
              )
  
      # the set of arguments that are structural properties of the attack
      # if these arguments are different, we must construct a new graph
      fixed = dict(
          (k, v)
          for k, v in kwargs.items()
          if k in self.structural_kwargs
      )
  
      # the set of arguments that are passed as placeholders to the graph
      # on each call, and can change without constructing a new graph
      feedable = {
          k: v for k, v in kwargs.items() if k in feedable_names
      }
      for k in feedable:
          if isinstance(feedable[k], (float, int)):
              feedable[k] = np.array(feedable[k])
  
      for key in kwargs:
          if key not in fixed and key not in feedable:
              raise ValueError(
                  str(type(self)) + ": Undeclared argument: " + key
              )
  
      feed_arg_type = arg_type(feedable_names, feedable)
  
      if not all(
          isinstance(value, collections.Hashable)
          for value in fixed.values()
      ):
          # we have received a fixed value that isn't hashable
          # this means we can't cache this graph for later use,
          # and it will have to be discarded later
          hash_key = None
      else:
          # create a unique key for this set of fixed paramaters
          hash_key = tuple(sorted(fixed.items())) + tuple(
              [feed_arg_type]
          )
  
      return fixed, feedable, feed_arg_type, hash_key
  
file_path: cleverhans/cleverhans_v3.1.0/cleverhans/attacks/attack.py
imports: from abc import ABCMeta
  import collections
  import warnings
  import numpy
  import tensorflow
  from cleverhans.compat import reduce_max
  from cleverhans.model import Model
  from cleverhans import utils
label_desc: Use image node_id 5 for calling the Attack obj's underlying member method code with example usage: obj.construct_variables(kwargs) and returns: fixed,  feedable,  feed_arg_type,  hash_key