def _do_stddev(args, bIgnoreEmpty=True):
    '''
    get variance/standard deviation wrt sample/population space,
    for the contents of a matrix of cells.
    It also returns the number of cells involved.
    '''
    start,end = args.split(':')
    bCellAddr, (sR,sC) = parse.celladdr_valid(start)
    if not bCellAddr:
        return None, None
    bCellAddr, (eR,eC) = parse.celladdr_valid(end)
    if not bCellAddr:
        return None, None
    avg = do_avg(args)
    total = 0
    cnt = 0
    for r in range(sR, eR+1):
        for c in range(sC, eC+1):
            if ((me['data'].get((r,c)) == None) and bIgnoreEmpty):
                continue
            total += (cellval.nvalue_key((r,c)) - avg)**2
            cnt += 1
    varp = total/cnt
    stdevp = sqrt(varp)
    try:
        var = total/(cnt-1)
        stdev = sqrt(var)
    except:
        var = None
        stdev = None
    return varp, stdevp, var, stdev, cnt
def _cellrange_to_list(lRange, bIgnoreEmpty=True):
    bCellAddr, (sR,sC) = parse.celladdr_valid(lRange[0])
    if not bCellAddr:
        return False, []
    bCellAddr, (eR,eC) = parse.celladdr_valid(lRange[2])
    if not bCellAddr:
        return False, []
    lOut = []
    for r in range(sR, eR+1):
        for c in range(sC, eC+1):
            if ((me['data'].get((r,c)) == None) and bIgnoreEmpty):
                continue
            lOut.append(cellval.nvalue_key((r,c)))
    return True, lOut
Beispiel #3
0
def goto_cell(stdscr, args):
    bCellAddr, (r, c) = parse.celladdr_valid(args)
    if bCellAddr:
        if r > me['numRows']:
            r = me['numRows']
        if c > me['numCols']:
            c = me['numCols']
        _goto_cell(stdscr, r, c)
def _do_minmax(args, bIgnoreEmpty=True):
    '''
    Find the min and max from the matrix of cells.
    '''
    start,end = args.split(':')
    bCellAddr, (sR,sC) = parse.celladdr_valid(start)
    if not bCellAddr:
        return None, None, None
    bCellAddr, (eR,eC) = parse.celladdr_valid(end)
    if not bCellAddr:
        return None, None, None
    lItems = []
    for r in range(sR, eR+1):
        for c in range(sC, eC+1):
            if ((me['data'].get((r,c)) == None) and bIgnoreEmpty):
                continue
            lItems.append(cellval.nvalue_key((r,c)))
    tMin = min(lItems)
    tMax = max(lItems)
    return tMin, tMax, len(lItems)
def _do_prod(args, bIgnoreEmpty=True):
    '''
    Multiply the contents of a matrix of cells.
    It also returns the number of cells involved.
    '''
    start,end = args.split(':')
    bCellAddr, (sR,sC) = parse.celladdr_valid(start)
    if not bCellAddr:
        return None, None
    bCellAddr, (eR,eC) = parse.celladdr_valid(end)
    if not bCellAddr:
        return None, None
    prod = 1
    cnt = 0
    for r in range(sR, eR+1):
        for c in range(sC, eC+1):
            if ((me['data'].get((r,c)) == None) and bIgnoreEmpty):
                continue
            prod *= cellval.nvalue_key((r,c))
            cnt += 1
    return prod, cnt
def _nvalue_saddr_or_str(sAddrOr):
    '''
    If passed a cell address in AlphaNum notation,
        Return the corresponding cells numeric value
    Else return the passed string back again.
    '''
    bCellAddr, cellKey = parse.celladdr_valid(sAddrOr)
    if bCellAddr:
        val = nvalue_key(cellKey)
        #print("_nvalue_saddr_or_str:{}:{}:{}".format(sAddrOr, cellKey, val), file=GLOGFILE)
        return val
    return sAddrOr
def _do_sum(args, bIgnoreEmpty=True):
    '''
    sum up contents of a matrix of cells.
    It also returns the number of cells involved.
    bIgnoreEmpty can be used to control whether empty cells are considered or not.
    '''
    start,end = args.split(':')
    bCellAddr, (sR,sC) = parse.celladdr_valid(start)
    if not bCellAddr:
        return None, None
    bCellAddr, (eR,eC) = parse.celladdr_valid(end)
    if not bCellAddr:
        return None, None
    total = 0
    cnt = 0
    for r in range(sR, eR+1):
        for c in range(sC, eC+1):
            if ((me['data'].get((r,c)) == None) and bIgnoreEmpty):
                continue
            total += cellval.nvalue_key((r,c))
            cnt += 1
    return total, cnt
def do_rcmd(scr, cmd, args):
    '''
    RCommands demuxer.

    It converts cell markers, if any, to cell addresses.
    Gets the cell keys for the given cell addresses.
    '''
    cstatusbar(scr, ['[status: rcmd processing ...]'])
    bDone = False
    try:
        print("rcmd:{} {}".format(cmd, args), file=GERRFILE)
        # Handle Markers
        lTokens, lTTypes = parse.get_tokens(args, 0, ['@', '-', '+'])
        sAdjustedArgs = ""
        for i in range(len(lTTypes)):
            if (lTTypes[i] == parse.TokenType.AlphaNum) and (lTokens[i][0]
                                                             == '@'):
                markerId = lTokens[i][2:]
                key = _get_marker(markerId)
                sAdjustedArgs += "{} ".format(cell_key2addr(key))
            else:
                sAdjustedArgs += "{} ".format(lTokens[i])
        # Handle cell addresses
        lCAddr, lPos = parse.get_celladdrs(sAdjustedArgs)
        lKeys = []
        for cAddr in lCAddr:
            bCellAddr, key = parse.celladdr_valid(cAddr)
            if not bCellAddr:
                return False
            lKeys.append(key)
            print("rcmd:btw:{} {}".format(cAddr, key), file=GERRFILE)
        # Execute the commands
        numKeys = len(lKeys)
        if numKeys == 3:  # If 3 cell addresses, then its assumed to be srcStart, srcENd and dstStart, so generate dstEnd from srcRange
            lKeys.append((lKeys[2][0] + (lKeys[1][0] - lKeys[0][0]),
                          lKeys[2][1] + (lKeys[1][1] - lKeys[0][1])))
        if cmd == "rcopy":
            bDone = _do_rcopy(scr, lKeys[0], lKeys[1], lKeys[2], lKeys[3])
        elif cmd == "rcopyasis":
            bDone = _do_rcopy(scr, lKeys[0], lKeys[1], lKeys[2], lKeys[3],
                              False)
        elif cmd == "rclear":
            bDone = _do_rclear(scr, lKeys[0], lKeys[1])
        elif cmd == "rclearerr":
            bDone = _do_rclear_err(scr, lKeys[0], lKeys[1])
        elif cmd == "rgennums":
            tokens, types = parse.get_tokens(sAdjustedArgs, lPos[-1],
                                             ['-', '+'])
            bDone = _do_rgennums(scr, lKeys[0], lKeys[1], tokens[1:])
        if bDone:
            me['dirty'] = True
        if cmd.startswith("rsearch"):
            tokens, types = parse.get_tokens(sAdjustedArgs, lPos[-1],
                                             ['-', '+'])
            bDone, bReplaced = _do_rsearch(scr, cmd, lKeys[0], lKeys[1],
                                           tokens[1:])
            if bReplaced:
                me['dirty'] = True
    except:
        traceback.print_exc(file=GERRFILE)
        bDone = False
    cstatusbar(scr, ['                             '])
    if not bDone:
        dlg(scr,
            ["Failed:{} {}".format(cmd, args), "Press any key to continue..."])
def cell_updated(cellKey, sContent, clearCache=True, clearedSet=None):
    '''
    Update the fw and reverse links associated with each cell

    NOTE: For now it maintains a expanded list of cells. TO keep the
    logic which depends on this at other places simple and stupid.

    clearedSet can be used to ensure that calc cache clearing can be done
    efficiently for spreadsheets involving very-very-long chains of
    cell-to-cell interdependencies. Also when a bunch of cells are
    updated from the same context like say during insert / delete of
    rows / cols, the clearedSet helps to avoid trying to clear calc cache
    of same dependent cells more than once, across multiple calls to
    cell_updated.

    In normal use one should call cell_updated with a empty clearedSet.
    Think carefully before using cell_updated without clearedSet.
    '''
    global TIMECAP1, TIMECAP2, TIMECAP3, TOKENCAP1
    origCellFwdLink = me['fwdLinks'].get(cellKey)
    cellFwdLink = set()
    # Handle the new content of the cell
    #T1 = time.time()
    if sContent == None:
        sContent = ""
    if sContent.strip().startswith('='):
        lCellAddrs = parse.get_celladdrs_incranges(sContent)
        #print("DBUG2:syncdCellUpdated:{}:{}".format(sContent.strip(), lCellAddrs), file=GERRFILE)
        #lCellAddrs = parse.get_celladdrs_incranges_internal(sContent)
        #print(lCellAddrs, file=GERRFILE)
    else:
        lCellAddrs = []
    TOKENCAP1 += len(lCellAddrs)
    #T2 = time.time()
    #TIMECAP1 += (T2-T1)
    for cellAddrPlus in lCellAddrs:
        if (len(cellAddrPlus) == 1):
            bCellAddr, key = parse.celladdr_valid(cellAddrPlus[0])
            if not bCellAddr:
                print("WARN:syncdCellUpdated:{}:{}={}".format(
                    sContent, cellAddrPlus[0], key),
                      file=GERRFILE)
                continue
            cellFwdLink.add(key)
            cell_revlink_add(key, cellKey)
        elif (len(cellAddrPlus) == 2):
            bCellAddr, key1 = parse.celladdr_valid(cellAddrPlus[0])
            if not bCellAddr:
                print("WARN:syncdCellUpdated:{}:{}={}".format(
                    sContent, cellAddrPlus[0], key1),
                      file=GERRFILE)
                continue
            bCellAddr, key2 = parse.celladdr_valid(cellAddrPlus[1])
            if not bCellAddr:
                print("WARN:syncdCellUpdated:{}:{}={}".format(
                    sContent, cellAddrPlus[1], key2),
                      file=GERRFILE)
                continue
            for r in range(key1[0], key2[0] + 1):
                for c in range(key1[1], key2[1] + 1):
                    cellFwdLink.add((r, c))
                    cell_revlink_add((r, c), cellKey)
    #T3 = time.time()
    #TIMECAP2 += (T3-T2)
    # Handle cells removed from the =expression
    if origCellFwdLink != None:
        droppedCells = origCellFwdLink.difference(cellFwdLink)
    else:
        droppedCells = set()
    if len(cellFwdLink) > 0:
        me['fwdLinks'][cellKey] = cellFwdLink
    else:
        if origCellFwdLink != None:
            me['fwdLinks'].pop(cellKey)
    for cell in droppedCells:
        cell_revlink_discard(cell, cellKey)
    # Clear cell calc cache for all dependents
    if clearCache:
        cdata_clear_revlinks(cellKey, clearedSet)