nodes: 0, module; 1, function_definition; 2, function_name:roller; 3, parameters; 4, block; 5, identifier:timestamps; 6, identifier:contract_dates; 7, identifier:get_weights; 8, dictionary_splat_pattern; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, comment:# for loop speedup only validate inputs the first function call to; 15, comment:# get_weights(); 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, for_statement; 21, expression_statement; 22, return_statement; 23, identifier:kwargs; 24, comment:"""
      Calculate weight allocations to tradeable instruments for generic futures
      at a set of timestamps for a given root generic.
  
      Paramters
      ---------
      timestamps: iterable
          Sorted iterable of of pandas.Timestamps to calculate weights for
      contract_dates: pandas.Series
          Series with index of tradeable contract names and pandas.Timestamps
          representing the last date of the roll as values, sorted by values.
          Index must be unique and values must be strictly monotonic.
      get_weights: function
          A function which takes in a timestamp, contract_dates, validate_inputs
          and **kwargs. Returns a list of tuples consisting of the generic
          instrument name, the tradeable contract as a string, the weight on this
          contract as a float and the date as a pandas.Timestamp.
      kwargs: keyword arguments
          Arguements to pass to get_weights
  
      Return
      ------
      A pandas.DataFrame with columns representing generics and a MultiIndex of
      date and contract. Values represent weights on tradeables for each generic.
  
      Examples
      --------
      >>> import pandas as pd
      >>> import mapping.mappings as mappings
      >>> cols = pd.MultiIndex.from_product([["CL1", "CL2"], ['front', 'back']])
      >>> idx = [-2, -1, 0]
      >>> trans = pd.DataFrame([[1.0, 0.0, 1.0, 0.0], [0.5, 0.5, 0.5, 0.5],
      ...                       [0.0, 1.0, 0.0, 1.0]], index=idx, columns=cols)
      >>> contract_dates = pd.Series([pd.Timestamp('2016-10-20'),
      ...                             pd.Timestamp('2016-11-21'),
      ...                             pd.Timestamp('2016-12-20')],
      ...                            index=['CLX16', 'CLZ16', 'CLF17'])
      >>> ts = pd.DatetimeIndex([pd.Timestamp('2016-10-18'),
      ...                        pd.Timestamp('2016-10-19'),
      ...                        pd.Timestamp('2016-10-19')])
      >>> wts = mappings.roller(ts, contract_dates, mappings.static_transition,
      ...                       transition=trans)
      """; 25, assignment; 26, assignment; 27, call; 28, assignment; 29, assignment; 30, assignment; 31, call; 32, assignment; 33, identifier:ts; 34, subscript; 35, block; 36, assignment; 37, identifier:weights; 38, identifier:timestamps; 39, call; 40, identifier:contract_dates; 41, call; 42, identifier:_check_contract_dates; 43, argument_list; 44, identifier:weights; 45, list; 46, identifier:validate_inputs; 47, True; 48, identifier:ts; 49, subscript; 50, attribute; 51, argument_list; 52, identifier:validate_inputs; 53, False; 54, identifier:timestamps; 55, slice; 56, expression_statement; 57, identifier:weights; 58, call; 59, identifier:sorted; 60, argument_list; 61, attribute; 62, argument_list; 63, identifier:contract_dates; 64, identifier:timestamps; 65, integer:0; 66, identifier:weights; 67, identifier:extend; 68, call; 69, integer:1; 70, call; 71, identifier:aggregate_weights; 72, argument_list; 73, identifier:timestamps; 74, identifier:contract_dates; 75, identifier:sort_values; 76, identifier:get_weights; 77, argument_list; 78, attribute; 79, argument_list; 80, identifier:weights; 81, identifier:ts; 82, identifier:contract_dates; 83, keyword_argument; 84, dictionary_splat; 85, identifier:weights; 86, identifier:extend; 87, call; 88, identifier:validate_inputs; 89, identifier:validate_inputs; 90, identifier:kwargs; 91, identifier:get_weights; 92, argument_list; 93, identifier:ts; 94, identifier:contract_dates; 95, keyword_argument; 96, dictionary_splat; 97, identifier:validate_inputs; 98, identifier:validate_inputs; 99, identifier:kwargs
code: def roller(timestamps, contract_dates, get_weights, **kwargs):
      """
      Calculate weight allocations to tradeable instruments for generic futures
      at a set of timestamps for a given root generic.
  
      Paramters
      ---------
      timestamps: iterable
          Sorted iterable of of pandas.Timestamps to calculate weights for
      contract_dates: pandas.Series
          Series with index of tradeable contract names and pandas.Timestamps
          representing the last date of the roll as values, sorted by values.
          Index must be unique and values must be strictly monotonic.
      get_weights: function
          A function which takes in a timestamp, contract_dates, validate_inputs
          and **kwargs. Returns a list of tuples consisting of the generic
          instrument name, the tradeable contract as a string, the weight on this
          contract as a float and the date as a pandas.Timestamp.
      kwargs: keyword arguments
          Arguements to pass to get_weights
  
      Return
      ------
      A pandas.DataFrame with columns representing generics and a MultiIndex of
      date and contract. Values represent weights on tradeables for each generic.
  
      Examples
      --------
      >>> import pandas as pd
      >>> import mapping.mappings as mappings
      >>> cols = pd.MultiIndex.from_product([["CL1", "CL2"], ['front', 'back']])
      >>> idx = [-2, -1, 0]
      >>> trans = pd.DataFrame([[1.0, 0.0, 1.0, 0.0], [0.5, 0.5, 0.5, 0.5],
      ...                       [0.0, 1.0, 0.0, 1.0]], index=idx, columns=cols)
      >>> contract_dates = pd.Series([pd.Timestamp('2016-10-20'),
      ...                             pd.Timestamp('2016-11-21'),
      ...                             pd.Timestamp('2016-12-20')],
      ...                            index=['CLX16', 'CLZ16', 'CLF17'])
      >>> ts = pd.DatetimeIndex([pd.Timestamp('2016-10-18'),
      ...                        pd.Timestamp('2016-10-19'),
      ...                        pd.Timestamp('2016-10-19')])
      >>> wts = mappings.roller(ts, contract_dates, mappings.static_transition,
      ...                       transition=trans)
      """
      timestamps = sorted(timestamps)
      contract_dates = contract_dates.sort_values()
      _check_contract_dates(contract_dates)
      weights = []
      # for loop speedup only validate inputs the first function call to
      # get_weights()
      validate_inputs = True
      ts = timestamps[0]
      weights.extend(get_weights(ts, contract_dates,
                                 validate_inputs=validate_inputs, **kwargs))
      validate_inputs = False
      for ts in timestamps[1:]:
          weights.extend(get_weights(ts, contract_dates,
                                     validate_inputs=validate_inputs, **kwargs))
  
      weights = aggregate_weights(weights)
      return weights