code: def multi_curve_fit(xs, ys, verbose):
      
      #functions = {exponential: p0_exponential, reciprocal: p0_reciprocal, single_reciprocal: p0_single_reciprocal}
      functions = {
          exponential: p0_exponential,
          reciprocal: p0_reciprocal,
          #single_reciprocal: p0_single_reciprocal,
          simple_reciprocal: p0_simple_reciprocal,
          simple_2reciprocal: p0_simple_2reciprocal,
          simple_4reciprocal: p0_simple_4reciprocal,
          simple_5reciprocal: p0_simple_5reciprocal
      }
      from scipy.optimize import curve_fit
      fit_results = {}
      best = ['', np.inf]
      for function in functions:
          try:
              weights = get_weights(xs, ys)
              popt, pcov = curve_fit(function, xs, ys, functions[function](xs, ys), maxfev=8000, sigma=weights)
              pcov = []
              m = measure(function, xs, ys, popt, weights)
              fit_results.update({function: {'measure': m, 'popt': popt, 'pcov': pcov}})
              for f in fit_results:
                  if fit_results[f]['measure'] <= best[1]:
                      best = f, fit_results[f]['measure']
              if verbose:
                  print(str(function), m)
          except RuntimeError:
              print('no fit found for ', function)
  
      return fit_results[best[0]]['popt'], fit_results[best[0]]['pcov'], best
docs: fit multiple functions to the x, y data, return the best fit