<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _make_sj_out_dict(fns, jxns=None, define_sample_name=None):
 """Read multiple sj_outs, return dict with keys as sample names and values as sj_out dataframes. Parameters fns : list of strs of filenames or file handles List of filename of the SJ.out.tab files to read in jxns : set If provided, only keep junctions in this set. define_sample_name : function that takes string as input Function mapping filename to sample name. For instance, you may have the sample name in the path and use a regex to extract it. The sample names will be used as the column names. If this is not provided, the columns will be named as the input files. Returns ------- sj_outD : dict Dict whose keys are sample names and values are sj_out dataframes """

    if define_sample_name == None:
        define_sample_name = lambda x: x
    else:
        assert len(set([define_sample_name(x) for x in fns])) == len(fns)
    sj_outD = dict()

    for fn in fns:
        sample = define_sample_name(fn)
        df = read_sj_out_tab(fn)
        # Remove any junctions that don't have any uniquely mapped junction
        # reads.  Even if a junction passes the cutoff in other samples, we are
        # only concerned with unique counts.
        df = df[df.unique_junction_reads > 0]
        index = (df.chrom + ':' + df.start.astype(str) + '-' 
                 +  df.end.astype(str))
        assert len(index) == len(set(index))
        df.index = index
        # If jxns is provided, only keep those.
        if jxns:
            df = df.ix[set(df.index) & jxns]
        sj_outD[sample] = df

    return sj_outD