I wrote this bit of python intending it to become some module to replace excel mapping programs like MapForce. Right now it only does columns to columns. So the number of rows in always equals the number of rows out.
To declare a map, use a python defaultdict(list)
object
from collections import defaultdict
demoCmd = defaultdict(list)
demoCmd = {
'A': [mapOper.mapVal, 'Hello, World'],
'B': [mapOper.mapSum, 0, 1, 2],
'C': [mapOper.mapAss, 3, 4, 5],
'D': [mapOper.mapProd, [mapOper.mapSum, 1, 0], 0, 1],
'E': 5
}
The keys are the destination columns name or index. Integers can be used as keys but they must be zero offset. Strings are converted to zero offset integers. The Lists are the functions mapping to that column. It's in LISP style [function arg1, arg2, etc]
, where integers are column indexes (zero offset) and strings are raw values. And you can nest the lists like in 'D'
.
mapOper
is just a file containing some commonly used functions. Some of them I don't think I need to include eg
def mapSum(*valueList):
filter(None, valueList)
return sum(valueList)
Anyways the main engine is this
def evalOpList(opList, fromSheet, row):
if type(opList) is str: # treat arg as a value
return opList
elif type(opList) is int: # treat arg as index
return fromSheet.cell(row, opList).value
else: # its another function
args = list()
itOpList = iter(opList)
next(itOpList)
args = [evalOpList(it, fromSheet, row) for it in itOpList]
return opList[0](*args)
def interpColMap(mapCmd, fmSheet, toSheet, rTop=0, rBot=0, rToTop=0):
if rBot < 0:
rBot = fmSheet.nrows
MapCmdConvert(mapCmd)
assert rTop < rBot and rToTop >= 0
for row in range(rTop, rBot):
for key in list(mapCmd.keys()):
toSheet.write(row, key, evalOpList(mapCmd[key], fmSheet, row))
And you call it like this
colMapper.interpColMap(demoCmd, fws, tws)
Where fws
is an worksheet from xlrd
to map from and tws
is a workbook from xlwt
to map to.
I have already tested it some and it works. It's just that coming from C++ this seems very odd style. Only two function make up my program and no classes. I also have the problem of having all int
s be indexes and all str
s be values. This means I can't do += 1
to a column without doing [int, '1']
. And I don't even know if that would work.
It's just a very unique style and I need to know if it's too convoluted or not.