<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_candidates(candsfile, snrmin=0, snrmax=999, returnstate=False):
 """ Reads candidate file and returns data as python object. candsfile is pkl file (for now) with (1) state dict and (2) cands object. cands object can either be a dictionary or tuple of two numpy arrays. Return tuple of two numpy arrays (location, properties). returned values can be filtered by snrmin and snrmax (on absolute value). returnstate will instead return (loc, prop, state). """


    # read in pickle file of candidates
    assert os.path.exists(candsfile)

    try:
        with open(candsfile, 'rb') as pkl:
            d = pickle.load(pkl)
            cands = pickle.load(pkl)
    except IOError:
        logger.error('Trouble parsing candsfile')
        loc = np.array([])
        prop = np.array([])
        if returnstate:
            return (loc, prop, d)
        else:
            return (loc, prop)

    if 'snr2' in d['features']:
        snrcol = d['features'].index('snr2')
    elif 'snr1' in d['features']:
        snrcol = d['features'].index('snr1')

    # old style. here for backwards compatibility
    if isinstance(cands, dict):
        loc = []; prop = []
        for kk in sorted(cands.keys()):
            if ((np.abs(cands[kk][snrcol]) > snrmin) and (np.abs(cands[kk][snrcol]) < snrmax)):
                loc.append( list(kk) )
                prop.append( list(cands[kk]) )
        loc = np.array(loc)
        prop = np.array(prop)

    # new style
    elif isinstance(cands, tuple):
        loc, prop = cands
        assert isinstance(loc, np.ndarray) and isinstance(prop, np.ndarray), 'if cands object is tuple, contents must be two ndarrays'
        if not len(loc):
            if returnstate:
                return (loc, prop, d)
            else:
                return (loc, prop)

        snrsel = np.where( (np.abs(prop[:, snrcol]) > snrmin) & (np.abs(prop[:, snrcol]) < snrmax) )
        loc = loc[snrsel]
        prop = prop[snrsel]

    else:
        logger.error('Cands object (in cands file) must be dict or tuple(np.array, np.array).')

    # if segment or scan pkl, insert scan number as first col and modify d
    if 'scan' not in d['featureind']:
        scanarr = d['scan'] * np.ones(len(loc), dtype=int)
        loc = np.concatenate( (scanarr[:,None], loc), axis=1)
        d['featureind'].insert(0, 'scan')

    logger.info('Read %d candidates from %s.' % (len(loc), candsfile))

    if returnstate:
        return loc, prop, d
    else:
        return loc, prop