docs: def _get_methods_that_calculate_outputs(inputs, outputs, methods):
      '''
      Given iterables of input variable names, output variable names,
      and a methods dictionary, returns the subset of the methods dictionary
      that can be calculated, doesn't calculate something we already have,
      and only contains equations that might help calculate the outputs from
      the inputs.
      '''
      # Get a list of everything that we can possibly calculate
      # This is useful in figuring out whether we can calculate arguments
      intermediates = get_calculatable_quantities(inputs, methods)
      # Initialize our return dictionary
      return_methods = {}
      # list so that we can append arguments that need to be output for
      # some of the paths
      outputs = list(outputs)
      # keep track of when to exit the while loop
      keep_going = True
      while keep_going:
          # If there are no updates in a pass, the loop will exit
          keep_going = False
          for output in outputs:
              try:
                  output_dict = return_methods[output]
              except:
                  output_dict = {}
              for args, func in methods[output].items():
                  # only check the method if we're not already returning it
                  if args not in output_dict.keys():
                      # Initialize a list of intermediates needed to use
                      # this method, to add to outputs if we find we can
                      # use it.
                      needed = []
                      for arg in args:
                          if arg in inputs:
                              # we have this argument
                              pass
                          elif arg in outputs:
                              # we may need to calculate one output using
                              # another output
                              pass
                          elif arg in intermediates:
                              if arg not in outputs:
                                  # don't need to add to needed if it's already
                                  # been put in outputs
                                  needed.append(arg)
                          else:
                              # Can't do this func
                              break
                      else:  # did not break, can calculate this
                          output_dict[args] = func
                          if len(needed) > 0:
                              # We added an output, so need another loop
                              outputs.extend(needed)
                              keep_going = True
              if len(output_dict) > 0:
                  return_methods[output] = output_dict
      return return_methods