def get_data (self, ts_list, symbol_list, data_item, verbose=False, bIncDelist=False):
        '''
        Read data into a DataFrame, but check to see if it is in a cache first.
        @param ts_list: List of timestamps for which the data values are needed. Timestamps must be sorted.
        @param symbol_list: The list of symbols for which the data values are needed
        @param data_item: The data_item needed. Like open, close, volume etc.  May be a list, in which case a list of DataFrame is returned.
        @param bIncDelist: If true, delisted securities will be included.
        @note: If a symbol is not found then a message is printed. All the values in the column for that stock will be NaN. Execution then 
        continues as usual. No errors are raised at the moment.
        '''

        # Construct hash -- filename where data may be already
        #
        # The idea here is to create a filename from the arguments provided.
        # We then check to see if the filename exists already, meaning that
        # the data has already been created and we can just read that file.

        ls_syms_copy = copy.deepcopy(symbol_list)

        # Create the hash for the symbols
        hashsyms = 0
        for i in symbol_list:
            hashsyms = (hashsyms + hash(i)) % 10000000

        # Create the hash for the timestamps
        hashts = 0

        # print "test point 1: " + str(len(ts_list))
        # spyfile=os.environ['QSDATA'] + '/Processed/Norgate/Stocks/US/NYSE Arca/SPY.pkl'
        for i in ts_list:
            hashts = (hashts + hash(i)) % 10000000
        hashstr = 'qstk-' + str (self.source)+'-' +str(abs(hashsyms)) + '-' + str(abs(hashts)) \
            + '-' + str(hash(str(data_item))) #  + '-' + str(hash(str(os.path.getctime(spyfile))))

        # get the directory for scratch files from environment
        # try:
        #     scratchdir = os.environ['QSSCRATCH']
        # except KeyError:
        #     #self.rootdir = "/hzr71/research/QSData"
        #     raise KeyError("Please be sure to set the value for QSSCRATCH in config.sh or local.sh")

        # final complete filename
        cachefilename = self.scratchdir + '/' + hashstr + '.pkl'
        if verbose:
            print "cachefilename is: " + cachefilename

        # now eather read the pkl file, or do a hardread
        readfile = False  # indicate that we have not yet read the file

        #check if the cachestall variable is defined.
        # try:
        #     catchstall=dt.timedelta(hours=int(os.environ['CACHESTALLTIME']))
        # except:
        #     catchstall=dt.timedelta(hours=1)
        cachestall = dt.timedelta(hours=self.cachestalltime)

        # Check if the file is older than the cachestalltime
        if os.path.exists(cachefilename):
            if ((dt.datetime.now() - dt.datetime.fromtimestamp(os.path.getmtime(cachefilename))) < cachestall):
                if verbose:
                    print "cache hit"
                try:
                    cachefile = open(cachefilename, "rb")
                    start = time.time() # start timer
                    retval = pkl.load(cachefile)
                    elapsed = time.time() - start # end timer
                    readfile = True # remember success
                    cachefile.close()
                except __HOLE__:
                    if verbose:
                        print "error reading cache: " + cachefilename
                        print "recovering..."
                except EOFError:
                    if verbose:
                        print "error reading cache: " + cachefilename
                        print "recovering..."
        if (readfile!=True):
            if verbose:
                print "cache miss"
                print "beginning hardread"
            start = time.time() # start timer
            if verbose:
                print "data_item(s): " + str(data_item)
                print "symbols to read: " + str(symbol_list)
            retval = self.get_data_hardread(ts_list, 
                symbol_list, data_item, verbose, bIncDelist)
            elapsed = time.time() - start # end timer
            if verbose:
                print "end hardread"
                print "saving to cache"
            try:
                cachefile = open(cachefilename,"wb")
                pkl.dump(retval, cachefile, -1)
                os.chmod(cachefilename,0666)
            except IOError:
                print "error writing cache: " + cachefilename
            if verbose:
                print "end saving to cache"
            if verbose:
                print "reading took " + str(elapsed) + " seconds"

        if type(retval) == type([]):
            for i, df_single in enumerate(retval):
                retval[i] = df_single.reindex(columns=ls_syms_copy)
        else:
            retval = retval.reindex(columns=ls_syms_copy)
        return retval
dataset/ETHPy150Open QuantSoftware/QuantSoftwareToolkit/QSTK/qstkutil/DataAccess.py/DataAccess.get_data