Posts: 28
Threads: 8
Joined: Aug 2018
good morning guys,
I need help:
I have done a program to obtain some data and then I have to append this data to the original file. My original file is something like this (with hundred more lines):
Verapamil,sub, COC1=C(OC)C=C(CCN©CCCC(C#N)(C©C)C2=CC(OC)=C(OC)C=C2)C=C1
Norverapamil,sub, COC1=CC=C(CCNCCCC(C#N)(C©C)C2=CC(OC)=C(OC)C=C2)C=C1OC
levofloxacin,sub, C[C@H]1COC2=C3N1C=C(C(O)=O)C(=O)C3=CC(F)=C2N1CCN©CC1
.
.
.
I need to take each third entry (in bold), process it to obtain a data and append this value to the original file, separated by comma.
I show you my program below. I am able to obtain the values and I see them on the screen but I don't find the way to append them to the original file. Could you help me with this, please?
import os
import subprocess
path_input = '/home/c.blanes/pgp/training.txt'
obabel = '/usr/bin/obabel '
f = open(path_input, 'r')
for line in f.readlines():
smiles = line.split(',')[2].strip('\n')
print(smiles)
launch = obabel + '-:\'%s\' -otxt --append TPSA'%(smiles)
print (launch)
subprocess.call(launch, shell=True)
Posts: 12,022
Threads: 484
Joined: Sep 2016
Nov-23-2018, 10:23 AM
(This post was last modified: Nov-23-2018, 10:24 AM by Larz60+.)
use mode 'a' to append to a file.
you should use the with construct as then you don't have to close the file, it's done automatically at end of operation (you actually forgot to close file in above example).
It's syntax is:
with open(filename, mode) as name:
for line in name.readlines():
... output can be written as part of same statement:
with open(path_input, 'r') as f_in, open(outname, 'a') as f_out:
...
Posts: 4,781
Threads: 76
Joined: Jan 2018
Nov-23-2018, 11:01 AM
(This post was last modified: Nov-23-2018, 11:03 AM by Gribouillis.)
clarablanes Wrote:I am able to obtain the values and I see them on the screen but I don't find the way to append them to the original file What exactly do you want to append to the original file? Is it the 'smiles', the 'launch' or the output of the calls to subprocess.call() ?
In any case, I strongly suggest that you write the desired ouptut to a temporary file first in order to avoid overwriting the initial file.
Posts: 28
Threads: 8
Joined: Aug 2018
Thank you Larz60+ and Gribouillis for your suggestions. Now the program writes in the original file although it is appending everything to the bottom of the file and I would like to append a number in each file.
About what Gribouillis suggests, the output I get in my screen is:
COC1=C(=C)......
63.95
COC1=CC.....
72.74
C[C@H]1CO...
75.01
CC1CN...
74.57
And want to append in the original file is 63.95 to the first line, 72.72 to the second line and so on, separated from the smiles with a comma, like the first two entries in each file, like this:
Verapamil,sub,COC1=C(OC)C=C(CCN©CCCC(C#N)(C©C)C2=CC(OC)=C(OC)C=C2)C=C1,63.95
Norverapamil,sub,COC1=CC=C(CCNCCCC(C#N)(C©C)C2=CC(OC)=C(OC)C=C2)C=C1OC,72.74
levofloxacin,sub,C[C@H]1COC2=C3N1C=C(C(O)=O)C(=O)C3=CC(F)=C2N1CCN©CC1,75.01
Below I show you what I have now (but it is appending all the orders to the bottom of the file):
Sorry that I can't explain better in English and thank you both very much.
import os
import subprocess
path_input = '/home/c.blanes/pgp/training.txt'
obabel = '/usr/bin/obabel '
with open(path_input, 'r') as f_in, open(path_input, 'a') as f_out:
for line in f_in.readlines():
smiles = line.split(',')[2].strip('\n')
print(smiles)
launch = obabel + '-:\'%s\' -otxt --append TPSA'%(smiles)
subprocess.call(launch, shell=True)
f_out.write(launch)
Posts: 12,022
Threads: 484
Joined: Sep 2016
Nov-23-2018, 05:07 PM
(This post was last modified: Nov-23-2018, 05:07 PM by Larz60+.)
Ah, sorry I didn't see that first time.
In this instance, you need to have an input and output file opened at the same time.
read a line from input, write out with additional content, read again, write again.
So the:
with open(path_input, 'r') as f_in, open(outname, 'a') as f_out: would apply.
so modify your code from:
import os
import subprocess
path_input = '/home/c.blanes/pgp/training.txt'
obabel = '/usr/bin/obabel '
with open(path_input, 'r') as f_in, open(path_input, 'a') as f_out:
for line in f_in.readlines():
smiles = line.split(',')[2].strip('\n')
print(smiles)
launch = obabel + '-:\'%s\' -otxt --append TPSA'%(smiles)
subprocess.call(launch, shell=True)
f_out.write(launch) to:
import os
import subprocess
path_input = '/home/c.blanes/pgp/training.txt'
# path_input = './src/training.txt'
path_output = './src/trainingNew.txt'
obabel = '/usr/bin/obabel '
with open(path_input, 'r') as f_in, open(path_output, 'w') as f_out:
for line in f_in.readlines():
# smiles = line.split(',')[2].strip('\n')
smiles = line.strip().split(',')[2]
print()
print(f"smiles: {smiles}")
launch = obabel + '-:\'%s\' -otxt --append TPSA'%(smiles)
print(f'launch: {launch}')
subprocess.call(launch, shell=True)
f_out.write(f'{launch}\n') Note that I strip line prior to the split. You had it reversed
also note that I add a newline when writing.
it is possible to read and write to the same file, but not as you have it in original code.
In order to do this, the entire file would have to be buffered in memory, otherwise the first write will corrupt the remaining data in file.
It's always easier and safer to write to a new file, and then rename after, or as an alternative, rename original file before reading and write out to a new file with original name.
Posts: 28
Threads: 8
Joined: Aug 2018
Dear Larz+60, my computer says that there is a syntax error. I think the problem is the server python version (2.7). There is also version3 but it keeps saying syntax error.
I am changing the expressions f'xxx: {xxx} with,
13 print(smiles)
16 print(launch)
19 f_out.write(launch)
but I'm not doing it right because my output does not look good.
What else should I do?
Thank you.
clara
Posts: 4,781
Threads: 76
Joined: Jan 2018
Nov-23-2018, 07:06 PM
(This post was last modified: Nov-23-2018, 07:08 PM by Gribouillis.)
I think you want something like this
import subprocess as sp
path_input = '/home/c.blanes/pgp/training.txt'
path_output = '/home/c.blanes/pgp/training-output.txt'
obabel = '/usr/bin/obabel '
def output_lines(f_in):
for line in f_in:
seq = line.rstrip().split(',')
smiles = seq[2]
result = sp.check_output([
obabel, "-:'%s'" % smiles,
'-otxt', '--append', 'TPSA']) # you don't need shell=True
yield ','.join(seq[:3]+[result.rstrip()]) + '\n'
if __name__ == '__main__':
with open(path_input, 'r') as f_in, open(path_output, 'w') as f_out:
f_out.writelines(output_lines(f_in))
Posts: 28
Threads: 8
Joined: Aug 2018
Well, I obtain a lot of errors this way:
Traceback (most recent call last):
File "prueba2.py", line 17, in <module>
f_out.writelines(output_lines(f_in))
File "prueba2.py", line 12, in output_lines
'-otxt', '--append', 'TPSA'])
File "/usr/lib/python3.5/subprocess.py", line 316, in check_output
**kwargs).stdout
File "/usr/lib/python3.5/subprocess.py", line 383, in run
with Popen(*popenargs, **kwargs) as process:
File "/usr/lib/python3.5/subprocess.py", line 676, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.5/subprocess.py", line 1282, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/obabel '
Posts: 4,781
Threads: 76
Joined: Jan 2018
Oh sorry, you need to remove the space character at the end of '/usr/bin/obabel '
Posts: 28
Threads: 8
Joined: Aug 2018
It is just what I need. THANK YOU VERY MUCH.
|