Search code examples
pythoncode-duplicationcontrol-flow

avoiding code duplication in Python code redux


This is a followup to an earlier question. I got some good suggestions for that, so I thought I would try my luck again.

from itertools import takewhile

if K is None:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]'
else:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i < K

af=open('a')
bf=open('b', 'w')
cf=open('c', 'w')

i = 0
if K is None:
    for line in takewhile(illuminacond, af):
        line_split=line.split(',')
        pid=line_split[1][0:3]
        out = line_split[1] + ',' + line_split[2] + ',' + line_split[3][1] + line_split[3][3] + ',' \
                                  + line_split[15] + ',' + line_split[9] + ',' + line_split[10]
        if pid!='cnv' and pid!='hCV' and pid!='cnv':
            i = i+1
            bf.write(out.strip('"')+'\n')
            cf.write(line)
else:
    for line in takewhile(illuminacond, af):
        line_split=line.split(',')
        pid=line_split[1][0:3]
        out = line_split[1] + ',' + line_split[2] + ',' + line_split[3][1] + line_split[3][3] + ',' \
                            + line_split[15] + ',' + line_split[9] + ',' + line_split[10]
        if pid!='cnv' and pid!='hCV' and pid!='cnv':
            i = i+1
            bf.write(out.strip('"')+'\n')

Is it possible to compactify this code? If I have some stuff in common in two loops like this, one obvious possibility is to just factor out the common code, but here, eww. The annoying thing is that the only difference here is the writing to c.

Brief summary of code: If K is not None, then loop over K lines of a and write to both b and c. Otherwise, loop over all of a and just write to b.


Solution

  • One check, one loop, no classes, psyco-optimizable.

    from itertools import takewhile
    
    if K is None:
        illuminacond = lambda x: x.split(',')[0] != '[Controls]'
        def action(cf, line): cf.write(line)
    else:
        illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i < K
        def action(cf, line): pass
    
    af=open('a')
    bf=open('b', 'w')
    cf=open('c', 'w')
    
    i = 0
    for line in takewhile(illuminacond, af):
        line_split=line.split(',')
        pid=line_split[1][0:3]
        out = line_split[1] + ',' + line_split[2] + ',' + line_split[3][1] + line_split[3][3] + ',' \
                                  + line_split[15] + ',' + line_split[9] + ',' + line_split[10]
        if pid!='cnv' and pid!='hCV' and pid!='cnv':
            i = i+1
            bf.write(out.strip('"')+'\n')
            action(cf, line)