On my prior post Jon and Jignesh both made the comment that using locals()
in string substitution provides for easier to read code – and is a great recommendation. What locals()
does is grab the object from the local environment, so in your string if you place %(MyObject)s
, and in the prior part of your code you have MyObject = "foo"
, it will substitute foo
into the string. Using the same prior code, here is an example:
BEGIN PROGRAM Python.
var = ["V1","V2","V3"]
lab = ["Var 1","Var 2","Var 3"]
for v,l in zip(var,lab):
spss.Submit("""
*Descriptive statistics.
FREQ %(v)s.
CORRELATIONS /VARIABLES=X1 X2 X3 %(v)s.
*Graph 1.
GRAPH /SCATTERPLOT(BIVAR)=X1 WITH %(v)s /TITLE = "%(l)s".
*Graph 2.
GRAPH /SCATTERPLOT(BIVAR)=X2 WITH %(v)s /TITLE = "%(l)s".
*Graph 3.
GRAPH /SCATTERPLOT(BIVAR)=X3 WITH %(v)s /TITLE = "%(l)s".
""" % (locals()))
END PROGRAM.
This ends up working in a similar fashion to the dictionary substitution I mentioned, just that Python makes the dictionary for you. Here is the same prior example using the dictionary with %
substitution:
BEGIN PROGRAM Python.
var = ["V1","V2","V3"]
lab = ["Var 1","Var 2","Var 3"]
MyDict = {"a":v, "b":l}
for v,l in zip(var,lab):
spss.Submit("""
*Descriptive statistics.
FREQ %(a)s.
CORRELATIONS /VARIABLES=X1 X2 X3 %(a)s.
*Graph 1.
GRAPH /SCATTERPLOT(BIVAR)=X1 WITH %(a)s /TITLE = "%(b)s".
*Graph 2.
GRAPH /SCATTERPLOT(BIVAR)=X2 WITH %(a)s /TITLE = "%(b)s".
*Graph 3.
GRAPH /SCATTERPLOT(BIVAR)=X3 WITH %(a)s /TITLE = "%(b)s".
""" % (MyDict) )
END PROGRAM.
And finally here is this example using a string template. It is basically self-explanatory.
*Using a string template.
BEGIN PROGRAM Python.
from string import Template
#Making template
c = Template("""*Descriptive statistics.
FREQ $var.
CORRELATIONS /VARIABLES=X1 X2 X3 $var.
*Graph 1.
GRAPH /SCATTERPLOT(BIVAR)=X1 WITH $var /TITLE = "$lab".
*Graph 2.
GRAPH /SCATTERPLOT(BIVAR)=X2 WITH $var /TITLE = "$lab".
*Graph 3.
GRAPH /SCATTERPLOT(BIVAR)=X3 WITH $var /TITLE = "$lab".
""")
#now looping over variables and labels
var = ["V1","V2","V3"]
lab = ["Var 1","Var 2","Var 3"]
for v,l in zip(var,lab):
spss.Submit(c.substitute(var=v,lab=l))
END PROGRAM.
The template solution is nice because it can make the code a bit more modular (i.e. you don’t have huge code blocks within a loop). The only annoyance I can see with this is that $
does come up in SPSS code on occasion with the few system defined variables, so it needs to be escaped with a second $
.
Albert-Jan
/ June 8, 2016And there is yet another mechanism in Python 3, f strings: https://www.python.org/dev/peps/pep-0498/