0

I've got a problem with this file. When I launch it I get an error on line 24.

UnboundLocal Error : local variable 'file_out' referenced before assignment.

Any suggestion on how to correct it will be greatly appreciated. I have to say that I'm a complete noob on python and didn't write this by myself.

#!/usr/local/python

import sys, getopt
import os

usage="python correct_mol2.py -i 2qab_ligand.mol2 -o 2qab_ligand_new.mol2\n"

def main(argv):

    try:
        opts,args = getopt.getopt(sys.argv[1:],'hi:o:')
    except getopt.GetoptError:
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print usage
            sys.exit()
        elif opt == '-i':
                file_in = arg
        elif opt == '-o':
            file_out = arg
    x=0
    fout=file("%s"%file_out,"w")
    for line in file(file_in):
#       print line
        if line.find("@<TRIPOS>BOND") >= 0:
            x=0
        if x==0:
            fout.write(line)
        if x==1:
            if line[47:49] == '35' :
                fout.write(line[:47]+"Br"+line[49:])
                continue
            if line[47:49] == '17' :
                fout.write(line[:47]+"Cl"+line[49:])
                continue
            if line[47:48] == '9' :
                fout.write(line[:47]+"F"+line[48:])
                continue
            if (line[47] == 'H' and line[48] ==' ') or line[47] == 'F' or line[47:49] == 'Br' or line[47:49] == 'Cl' :
                fout.write(line)
                continue
            else:
                fout.write(line[:48]+"."+line[48:54]+line[55:])
        if line.find("@<TRIPOS>ATOM") >= 0:
            x=1
    fout.close()

main(sys.argv)
Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997

1 Answers1

1

The file_out argument is only set if the -o argument is set.

You need to perhaps set a default before the for opt, arg in opts: loop:

file_out = 'default_filename'

If -o is meant to be a mandatory option, you'll need to explicitly test for the option being absent.

Other comments on your code:

  • Use argparse instead; optparse has been deprecated, it's successor is far more flexible and versatile.

  • file_out is, when set, already a string. No need to use string formatting on it; you can pass it straight to open() (rather than file(), also deprecated). If you use the file object as a context manager then it'll be closed for you automatically:

    with open(file_out, "w") as fout, open(file_in) as fin:
        for line in fin:
    
  • You can use the file object as an iterator, meaning you can advance the file object and get more lines in the for loop as your parsing state changes. Use this to detect Tripos MOL2 records.

    Tripos MOL2 data records use tabs or spaces to separate the lines; split your line into columns, then pick out the specific column to map replacement values for. That's a lot less fragile than slicing the lines to specific columns:

    map = {'35': 'Br', '17': 'Cl', '9': 'F'}
    # when we encounter a mapped value, make it easier on ourselves
    # and map those back to themselves
    map.update((v: v) for v in map.values())
    
    section = None
    for line in fin:
        if line[0] == '@':
            # new section
            section = line.strip().rpartition('>')[-1]
            fout.write(line)
            continue
    
        if section != 'ATOM':
            fout.write(line)
            continue
    
        # parse the ATOM section
        for line in fin:
            if line[0] == '@':  # section end, we are done
                section = line.strip().rpartition('>')[-1]
                fout.write(line)
                break
    
            # atom data lines are whitespace separated
            row = line.split()
    
            # I'm assuming column 7 is the value you are replacing; adjust as required
            row[7] = map.get(row[7], '.')
    
            # re-join line with tabs, write out
            fout.write('\t'.join(row) + '\n')
    
Community
  • 1
  • 1
Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
  • Thank you very much for your detailed response. The main problem is that I really don't understand programming. I don’t really know what to replace and how. I’m ashamed to ask you but can you rewrite the script so I only have to copy it and make it work? I’m a scientist in medicinal chemistry so it will help my research focused on cancer. – Xavier Drozak Sep 01 '14 at 07:34
  • @XavierDrozak: I only made an educated guess as to what might be done to improve your code. I cannot re-write your code entirely for you; I don't have the access to the data you have, nor am I in a position to test things for you. Find someone who can program or can teach you to program close by, in a setting better suited for mentoring. I am available as in online mentorship programs (see my profile). Good luck! – Martijn Pieters Sep 01 '14 at 07:47