<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Python string interpolation trick</title>
	<atom:link href="http://www.bramz.net/2008/12/07/python-string-interpolation-trick/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bramz.net/2008/12/07/python-string-interpolation-trick/</link>
	<description>home page of Bram de Greve, aka Bramz: ramblings about programming, photography and other stuff.</description>
	<lastBuildDate>Thu, 27 Oct 2011 18:27:44 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Bramz</title>
		<link>http://www.bramz.net/2008/12/07/python-string-interpolation-trick/comment-page-1/#comment-2017</link>
		<dc:creator>Bramz</dc:creator>
		<pubDate>Sat, 21 Nov 2009 16:05:08 +0000</pubDate>
		<guid isPermaLink="false">http://www.bramz.net/?p=222#comment-2017</guid>
		<description>Hi Luc,

You&#039;re welcome.  That&#039;s neat application you&#039;ve shown there.  Here&#039;s a few ideas on taking this a little bit further.  

&lt;strong&gt;disclaimer&lt;/strong&gt;: none of the following ideas use string interpolation so it is a bit off-topic =)

You can get a cleaner syntax in your predicate strings by feeding &lt;code&gt;d&lt;/code&gt; directly to the &lt;code&gt;eval&lt;/code&gt; function.  That way you can use your field names as identifiers in &lt;code&gt;eval_string&lt;/code&gt;.  Like so:

&lt;pre&gt;def eval_vars(eval_string, fields, rec, echo = False):
	d = dict(zip(fields, rec))
	if echo:
		print eval_string, d, eval(eval_string, d)
	try:
		return eval(eval_string, d)
	except:
		return False

eval_vars(&#039;WAARDE &gt; 50.0&#039;, a, b, True)
eval_vars(&#039;POSTCODE[:2] == &quot;90&quot;&#039;, a, b, True)
eval_vars(&#039;POSTCODE == &quot;9000&quot;&#039;, a, b, True)
eval_vars(&#039;INTEGER == 17&#039;, a, b, True)
eval_vars(&#039;INTEGER == 17 and POSTCODE[:2] == &quot;90&quot;&#039;, a, c, True)
eval_vars(&#039;(INTEGER in range(5,16) or INTEGER in range(20,25)) &#039;
	&#039;and POSTCODE[:2] == &quot;90&quot;&#039;, a, d, True)
eval_vars(&#039;(INTEGER in range(5,16) or INTEGER in range(20,25)) &#039;
	&#039;and POSTCODE[:2] == &quot;90&quot;&#039;, a, e, True)&lt;/pre&gt;

You might notice another small improvement in building &lt;code&gt;d&lt;/code&gt; itself.  &lt;code&gt;dict&lt;/code&gt; accepts a sequence of (key, value) pairs, so you can &lt;code&gt;zip&lt;/code&gt; the field names and the valules.

Another way of doing all this, is using lambda expressions instead of strings.  This might be cleaner if you are embedding the predicates in the python code, but you can&#039;t pull them from let&#039;s say a text box anymore.  Constructing &lt;code&gt;d&lt;/code&gt; becomes somewhat harder, as you must only keep the fields that are really arguments.

&lt;pre&gt;def eval_vars(predicate, fields, rec):
	arg_names = predicate.__code__.co_varnames[
		:predicate.__code__.co_argcount]
	d = dict((k, v) for k, v in zip(fields, rec)
		if k in arg_names)
	return predicate(**d)

print eval_vars(lambda WAARDE: WAARDE &gt; 50.0, a, b)
print eval_vars(lambda POSTCODE: POSTCODE[:2] == &quot;90&quot;, a, b)
print eval_vars(lambda POSTCODE: POSTCODE == &quot;9000&quot;, a, b)
print eval_vars(lambda INTEGER: INTEGER == 17, a, b)
print eval_vars(lambda INTEGER, POSTCODE: INTEGER == 17 and
	POSTCODE[:2] == &quot;90&quot;, a, c)
print eval_vars(lambda INTEGER, POSTCODE:
	(INTEGER in range(5,16) or INTEGER in range(20,25)) and
	POSTCODE[:2] == &quot;90&quot;, a, d)
print eval_vars(lambda INTEGER, POSTCODE:
	(INTEGER in range(5,16) or INTEGER in range(20,25)) and
	POSTCODE[:2] == &quot;90&quot;, a, e)&lt;/pre&gt;

Cheers,
Bram</description>
		<content:encoded><![CDATA[<p>Hi Luc,</p>
<p>You&#8217;re welcome.  That&#8217;s neat application you&#8217;ve shown there.  Here&#8217;s a few ideas on taking this a little bit further.  </p>
<p><strong>disclaimer</strong>: none of the following ideas use string interpolation so it is a bit off-topic =)</p>
<p>You can get a cleaner syntax in your predicate strings by feeding <code>d</code> directly to the <code>eval</code> function.  That way you can use your field names as identifiers in <code>eval_string</code>.  Like so:</p>
<pre>def eval_vars(eval_string, fields, rec, echo = False):
	d = dict(zip(fields, rec))
	if echo:
		print eval_string, d, eval(eval_string, d)
	try:
		return eval(eval_string, d)
	except:
		return False

eval_vars('WAARDE &gt; 50.0', a, b, True)
eval_vars('POSTCODE[:2] == "90"', a, b, True)
eval_vars('POSTCODE == "9000"', a, b, True)
eval_vars('INTEGER == 17', a, b, True)
eval_vars('INTEGER == 17 and POSTCODE[:2] == "90"', a, c, True)
eval_vars('(INTEGER in range(5,16) or INTEGER in range(20,25)) '
	'and POSTCODE[:2] == "90"', a, d, True)
eval_vars('(INTEGER in range(5,16) or INTEGER in range(20,25)) '
	'and POSTCODE[:2] == "90"', a, e, True)</pre>
<p>You might notice another small improvement in building <code>d</code> itself.  <code>dict</code> accepts a sequence of (key, value) pairs, so you can <code>zip</code> the field names and the valules.</p>
<p>Another way of doing all this, is using lambda expressions instead of strings.  This might be cleaner if you are embedding the predicates in the python code, but you can&#8217;t pull them from let&#8217;s say a text box anymore.  Constructing <code>d</code> becomes somewhat harder, as you must only keep the fields that are really arguments.</p>
<pre>def eval_vars(predicate, fields, rec):
	arg_names = predicate.__code__.co_varnames[
		:predicate.__code__.co_argcount]
	d = dict((k, v) for k, v in zip(fields, rec)
		if k in arg_names)
	return predicate(**d)

print eval_vars(lambda WAARDE: WAARDE > 50.0, a, b)
print eval_vars(lambda POSTCODE: POSTCODE[:2] == "90", a, b)
print eval_vars(lambda POSTCODE: POSTCODE == "9000", a, b)
print eval_vars(lambda INTEGER: INTEGER == 17, a, b)
print eval_vars(lambda INTEGER, POSTCODE: INTEGER == 17 and
	POSTCODE[:2] == "90", a, c)
print eval_vars(lambda INTEGER, POSTCODE:
	(INTEGER in range(5,16) or INTEGER in range(20,25)) and
	POSTCODE[:2] == "90", a, d)
print eval_vars(lambda INTEGER, POSTCODE:
	(INTEGER in range(5,16) or INTEGER in range(20,25)) and
	POSTCODE[:2] == "90", a, e)</pre>
<p>Cheers,<br />
Bram</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: luc</title>
		<link>http://www.bramz.net/2008/12/07/python-string-interpolation-trick/comment-page-1/#comment-2005</link>
		<dc:creator>luc</dc:creator>
		<pubDate>Tue, 17 Nov 2009 10:19:44 +0000</pubDate>
		<guid isPermaLink="false">http://www.bramz.net/?p=222#comment-2005</guid>
		<description>Hoi,

Used this technique to make a evaluation function for record processing. 

1. write evaluation function as string interpollation, use field names as vars
2. feed field list
3. feed value list

Need to use str() for correct string processing in the eval function...


def eval_vars(eval_string, fields, rec, echo = False):
    # evaluate expression
    d = {}
    for f, x in zip(fields, rec):
        d[f]=x
        
    e_string = eval_string % d
    if echo:
        print e_string, eval(e_string)
    try:
        return eval(e_string)
    except:
        return False

a = [&#039;POSTCODE&#039;, &#039;WAARDE&#039;,&#039;INTEGER&#039;]
b = [&#039;9000&#039; , 45.23, 17]
c = [&#039;9315&#039;,  65.2 , 17]
d = [&#039;9031&#039;,  62.5 , 23]
e = [&#039;9031&#039;,  62.5 , 17]


eval_vars(&#039;%(WAARDE)f &gt; 50.0&#039;, a, b, True)
eval_vars(&#039;&quot;%(POSTCODE)s&quot;[:2] == str(90)&#039;, a, b, True)
eval_vars(&#039;str(%(POSTCODE)s) == str(9000)&#039;, a, b, True)
eval_vars(&#039;str(%(POSTCODE)s)[:2] == str(90)&#039;, a, b, True)
eval_vars(&#039;%(INTEGER)i == 17&#039;, a, b, True)
eval_vars(&#039;%(INTEGER)i == 17 and str(%(POSTCODE)s)[:2] == str(90)&#039;, a, c, True)
eval_vars(&#039;(%(INTEGER)i in range(5,16) or %(INTEGER)i in range(20,25)) and str(%(POSTCODE)s)[:2] == str(90)&#039;, a, d, True)
eval_vars(&#039;(%(INTEGER)i in range(5,16) or %(INTEGER)i in range(20,25)) and str(%(POSTCODE)s)[:2] == str(90)&#039;, a, e, True)

I can write any query on any dataset now...

Feeding a dictionary would be shorter, but loading large datasets as lists saves a lot of time and memory.

Thanks for the idea....

Luc</description>
		<content:encoded><![CDATA[<p>Hoi,</p>
<p>Used this technique to make a evaluation function for record processing. </p>
<p>1. write evaluation function as string interpollation, use field names as vars<br />
2. feed field list<br />
3. feed value list</p>
<p>Need to use str() for correct string processing in the eval function&#8230;</p>
<p>def eval_vars(eval_string, fields, rec, echo = False):<br />
    # evaluate expression<br />
    d = {}<br />
    for f, x in zip(fields, rec):<br />
        d[f]=x</p>
<p>    e_string = eval_string % d<br />
    if echo:<br />
        print e_string, eval(e_string)<br />
    try:<br />
        return eval(e_string)<br />
    except:<br />
        return False</p>
<p>a = ['POSTCODE', 'WAARDE','INTEGER']<br />
b = ['9000' , 45.23, 17]<br />
c = ['9315',  65.2 , 17]<br />
d = ['9031',  62.5 , 23]<br />
e = ['9031',  62.5 , 17]</p>
<p>eval_vars(&#8216;%(WAARDE)f &gt; 50.0&#8242;, a, b, True)<br />
eval_vars(&#8216;&#8221;%(POSTCODE)s&#8221;[:2] == str(90)&#8217;, a, b, True)<br />
eval_vars(&#8216;str(%(POSTCODE)s) == str(9000)&#8217;, a, b, True)<br />
eval_vars(&#8216;str(%(POSTCODE)s)[:2] == str(90)&#8217;, a, b, True)<br />
eval_vars(&#8216;%(INTEGER)i == 17&#8242;, a, b, True)<br />
eval_vars(&#8216;%(INTEGER)i == 17 and str(%(POSTCODE)s)[:2] == str(90)&#8217;, a, c, True)<br />
eval_vars(&#8216;(%(INTEGER)i in range(5,16) or %(INTEGER)i in range(20,25)) and str(%(POSTCODE)s)[:2] == str(90)&#8217;, a, d, True)<br />
eval_vars(&#8216;(%(INTEGER)i in range(5,16) or %(INTEGER)i in range(20,25)) and str(%(POSTCODE)s)[:2] == str(90)&#8217;, a, e, True)</p>
<p>I can write any query on any dataset now&#8230;</p>
<p>Feeding a dictionary would be shorter, but loading large datasets as lists saves a lot of time and memory.</p>
<p>Thanks for the idea&#8230;.</p>
<p>Luc</p>
]]></content:encoded>
	</item>
</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
