# Modify how a script prints the output?

I'm trying to print out all measured distances between a ligand and 2 residues (using PyMol), below is the script that I'm using. I only want to measure the distances between all the ligand's O & ND2 of N312, as well as all the ligand's N & OD2 of D113.

from pymol import stored
stored.a, stored.b, stored.c, stored.d = [],[],[],[]
cmd.iterate_state(1, "r55_01///UNL1/N*", "stored.a.append(ID)")
cmd.iterate_state(1, "r55_01///UNL1/O*", "stored.b.append(ID)")
cmd.iterate_state(1, "r55_01//R/ASP113/OD2", "stored.c.append(ID)")
cmd.iterate_state(1, "/r55_01//R/ASN312/ND2", "stored.d.append(ID)")

f=open("dst4.txt", 'w')

for a in stored.a:
for b in stored.b:
for c in stored.c:
for d in stored.d:
f.write( "distance from %s to %s is %s\n" % (a, c,
cmd.distance( "id %s" % a, "id %s" % c,cutoff=5,mode=2)))
f.write( "distance from %s to %s is %s\n" % (b, d,
cmd.distance( "id %s" % b, "id %s" % d,cutoff=5,mode=2)))

f.close()


The output file currently looks like this

distance from 9 to 1334 is 4.589359760284424
distance from 8 to 4204 is 3.1509475708007812
distance from 9 to 1334 is 4.589359760284424
distance from 15 to 4204 is 0.0
distance from 9 to 1334 is 4.589359760284424
distance from 17 to 4204 is 0.0
distance from 9 to 1334 is 4.589359760284424
distance from 20 to 4204 is 0.0
distance from 23 to 1334 is 0.0
distance from 8 to 4204 is 3.1509475708007812
distance from 23 to 1334 is 0.0
distance from 15 to 4204 is 0.0
distance from 23 to 1334 is 0.0
distance from 17 to 4204 is 0.0
distance from 23 to 1334 is 0.0
distance from 20 to 4204 is 0.0


I want my output to look more like this. Thanks in advance!

Lig_N D113 4.59
Lig_O N312 3.15


Let's simplify...

cmd.distance(xx,xxx) accepts two selector strings and is fine with and state 1. And best of all if you select multiple atoms it gives you the smallest distance!

So all you need to do is:

# measure
d_O = cmd.distance('UNL and element O', 'resi 312 and name ND2')
d_N = cmd.distance('UNL and element N', 'resi 113 and name OD2')
# write
f=open("dst4.txt", 'w')
f.write(f'Lig_N D113 {d_N:.2f}\n')
f.write(f'Lig_O N312 {d_O:.2f}\n')
f.close()


If you are using python 2 (if so do note pymol scripting is better in 3), then the second bit is

f=open("dst4.txt", 'w')
f.write('Lig_N D113 %.2f\n' % (d_N,))
f.write(f'Lig_O N312 %.2f\n' % (d_O,))
f.close()


## Unsolicited coding tips

A few unsolicited tips... Your original script is rather over-complicated and obfuscated and uncommented, so for better legibility why not do:

• cmd.iterate_state is always harder to follow than the for atom in get_model('xxxx').atoms synthax
• unless you are stuck with python 2, use f-strings not the %s sprintf style formatting
• the /x/x/x/x selector synthax is never as readable as the longer resi/resn/name selection algebra.

Code golf is always tempting, but it can result in future-you getting stuck as happened here...

• You're right about the unnecessary complication in my script haha... I adapted the script a bit and it works :D Thank you!
– Zoe
Jun 29 '20 at 13:13