Search code examples
pythoncurve-fittingpylintscipy-optimize

Possible unbalanced tuple unpacking with sequence in scipy optimization curve_fit


I got error from pylint from my code. I don't know how to fix that. can you please help me?

The code is here:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# Define the two points
x1, y1 = 4, 0
x2, y2 = 15, 1

# Define the square root function
def sqrt_func(x, a, b):
    return a * np.sqrt(x - x1) + y1

# Fit the curve to the two points
popt, pcov = curve_fit(sqrt_func, [x1, x2], [y1, y2])

# Generate intermediate x values between 4 and 15
x_values = np.linspace(4, 15, num=100)

# Use the fitted curve to calculate y values
y_values = sqrt_func(x_values, *popt)

# Plot the curve and the two points
plt.plot(x_values, y_values)
plt.scatter([x1, x2], [y1, y2])
plt.show()

in this bellow line I have this error: ** Possible unbalanced tuple unpacking with sequence defined at line 885 of scipy.optimize._minpack_py: left side has 2 labels, right side has 5 values **

popt, pcov = curve_fit(sqrt_func, [x1, x2], [y1, y2])

Solution

  • Here's the relevant source code part:

    
    def curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False,
                  check_finite=None, bounds=(-np.inf, np.inf), method=None,
                  jac=None, *, full_output=False, nan_policy=None,
                  **kwargs):
        ... # a lot of code here
        
        if full_output:
            return popt, pcov, infodict, errmsg, ier
        else:
            return popt, pcov
    

    pylint analyses the body and understands that curve_fit can return a 2-tuple or 5-tuple, but fails to infer the relationship with full_output input parameter. We're more capable then pylint and can read the definition to find out that the return type is always 2-tuple in your case, and so pylint gave a false positive. You can add a comment to explain the ignorance reason and to suppress the error message, like this:

    # with full_output = False, always returns a 2-tuple
    # pylint: disable-next=unbalanced-tuple-unpacking
    popt, pcov = curve_fit(sqrt_func, [x1, x2], [y1, y2])  
    

    Note that I'm using pylint: disable-next, see this question for reasons to prefer it to pylint: ignore in many cases.