<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Je t'embrasse &#187; Python</title>
	<atom:link href="http://www.jjinno.com/category/projects/python-projects/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jjinno.com</link>
	<description>Salutations from Silicon Valley, California</description>
	<lastBuildDate>Sun, 20 Jun 2010 21:29:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>An academic approach to &#8216;import&#8217;</title>
		<link>http://www.jjinno.com/2010/06/20/an-academic-approach-to-import/</link>
		<comments>http://www.jjinno.com/2010/06/20/an-academic-approach-to-import/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 21:29:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.jjinno.com/?p=119</guid>
		<description><![CDATA[As they say, Python is a language that does not force you to do things. Instead, it assumes the programmer to be a consenting adult who, knowingly or unknowingly has the power to bend and mold existing paradigms to fit whatever task is at hand. While this easy-peasy mindset sometimes can be an absolute asset, [...]]]></description>
			<content:encoded><![CDATA[<p>As they say, Python is a language that does not force you to do things.  Instead, it assumes the programmer to be a consenting adult who, knowingly or unknowingly has the power to bend and mold existing paradigms to fit whatever task is at hand.  While this easy-peasy mindset sometimes can be an absolute asset, it will inevitably (hopefully not more than once) lead you down the winding path of destruction.  Personally I feel that nothing in Python is quite as capable at dragging people down like the &#8220;import&#8221; statement.</p>
<p><strong>Standard Imports:</strong></p>
<pre class="brush: python;">import os
from os.path import isfile as isFile
from time import *</pre>
<p>Hopefully this is not the first time you&#8217;ve heard this, but you should avoid the asterisk on imports.  Unless you own the import (like a file with a bunch of common functions in it) then you can never be sure that a function defined within the import has not just blown away a function with the same name in your application.</p>
<p><strong>User-specific Imports:</strong><br />
But what about the following&#8230; (Linux only I believe)</p>
<pre class="brush: python;">import os
import sys
sys.path.append(os.path.join(os.environ['HOME'], 'scripts'))
import userScript</pre>
<p>This can be really helpful to provide some user-specific functionality.  Basically the username determines the home directory, and the home directory then provides you with a specific subdirectory of Python scripts.  If you log in as &#8220;root&#8221; you will get one set of functionality, whereas if you log in as &#8220;user&#8221; you will get a different set of functionality.</p>
<p>Watch out though, as environmental variables are very inaccurate.  Anybody and anything can change these variables, and can leave you depending on incorrect or invalid values.  One of the easiest ways to see this is by having a proper-daemon C/C++ application that calls a Python script.  When you log on as any user and execute the binary, you will see the expected results.  If you (via socket or RPC or whatever) call it remotely, the user defaults to the system, which unfortunately does not have certain environmental variables (like a &#8220;HOME&#8221; directory)&#8230; in other words, remote call = failure.</p>
<p><strong>Application-relative (not path-relative) Imports:</strong><br />
Here is another one that I have seen, but have rarely used.  Similarly to  the previous condition, it requires appending to the system path, but this time we are working with a relative directory.</p>
<pre class="brush: python;">import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import someClass</pre>
<p>There are two special things happening here.  First, we are extracting the direct relative path to the file containing this code.  If we were to run this through the interpreter, we would get an error because there is no &#8220;__file__&#8221;. Second, because &#8220;__file__&#8221; is always the relative path to the Python file, it doesn&#8217;t matter where you execute from, absolute path or not, you will always be referring to &#8220;..&#8221; from the Python file.  This is EXTREMELY useful if you need to create an application that can be run via both relative and absolute path.</p>
<p><strong>Path-agnostic Import Best Practices:</strong><br />
Although I have given multiple examples of how to get the system path to not care where you are executing from, I have for the most part found that the best practice with import paths is to use a configuration file.  Why did I just complicate the import process even more?  Well, lets take a look at the code:</p>
<pre class="brush: python;">import os
import sys
lines = open(os.path.join(os.path.dirname(__file__), &quot;config.cfg&quot;)).splitlines()
paths = [line.split(&quot;=&quot;)[1] for line in lines if &quot;path&quot; is line.split(&quot;=&quot;)[0]]
for path in paths: sys.path.append(path)
import customModule</pre>
<p>The benefit here is that now when you want to swap out &#8220;customModule&#8221; with a different version for testing, you dont need to move any directories, or rename any imports.  All you do is change the config file.  And yes, I did go a little overboard here, and allow you to add as many paths to the system path list as you want.  The other big benefit here is that since you are always specifying an absolute path in the configuration file, you are always guaranteed that the import will succeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jjinno.com/2010/06/20/an-academic-approach-to-import/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using a Property to get a Class name into an Attribute</title>
		<link>http://www.jjinno.com/2010/05/28/using-a-python-property-to-get-a-class-name-into-an-attribute/</link>
		<comments>http://www.jjinno.com/2010/05/28/using-a-python-property-to-get-a-class-name-into-an-attribute/#comments</comments>
		<pubDate>Fri, 28 May 2010 22:57:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.jjinno.com/?p=148</guid>
		<description><![CDATA[For one reason or another, I found myself in a slight predicament. I needed to get the name of my class into an attribute. Thanks to Google + KyLev I managed to procure a workable solution: class Problem(object): moduleIndex = 0 def __init__(self): self.__class__.moduleIndex = self.__class__.moduleIndex + 1 class Solution(object): moduleIndex = 0 moduleName = [...]]]></description>
			<content:encoded><![CDATA[<p>For one reason or another, I found myself in a slight predicament.  I needed to get the name of my class into an attribute.</p>
<p>Thanks to Google + <a href="http://www.kylev.com/2004/10/13/fun-with-python-properties/">KyLev</a> I managed to procure a workable solution:</p>
<pre class="brush: python;">class Problem(object):
    moduleIndex = 0
    def __init__(self):
        self.__class__.moduleIndex = self.__class__.moduleIndex + 1

class Solution(object):
    moduleIndex = 0
    moduleName = property(fget=lambda self: self.__class__.__name__)
    def __init__(self):
        self.__class__.moduleIndex = self.__class__.moduleIndex + 1
        print &quot;[%s] %s&quot;%(self.moduleIndex, self.moduleName)

if __name__ == &quot;__main__&quot;: t = Solution()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jjinno.com/2010/05/28/using-a-python-property-to-get-a-class-name-into-an-attribute/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating Network Addresses</title>
		<link>http://www.jjinno.com/2009/11/25/calculating-network-addresses/</link>
		<comments>http://www.jjinno.com/2009/11/25/calculating-network-addresses/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 06:30:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.jjinno.com/?p=112</guid>
		<description><![CDATA[I have frequently run up against the problem of generating network addresses (strictly speaking IPv4) but I am positive that the principles demonstrated below can carry over into IPv6. The biggest issue is that in calculating addresses, the best way to find the &#8220;Nth address from here&#8221; is to convert to decimal and add. Well [...]]]></description>
			<content:encoded><![CDATA[<p>I have frequently run up against the problem of generating network addresses (strictly speaking IPv4) but I am positive that the principles demonstrated below can carry over into IPv6.</p>
<p>The biggest issue is that in calculating addresses, the best way to find the &#8220;Nth address from here&#8221; is to convert to decimal and add. Well it&#8217;s not so difficult to convert 4 octets into a 32-bit binary number, and crunch that into a single decimal number, add &#8220;N&#8221;, convert back to binary, divide into octets, and convert back to decimal&#8230; but it takes forever.  So why take forever when you don&#8217;t need to.  The trick? Divide &#038; Conquer.</p>
<p>After walking through the theory, masks, addresses, ranges, compliments&#8230; I finally put together the following as a helper. Feel free to comment.</p>
<pre class="brush: python;">#!/usr/bin/env python

import re
import sys
from optparse import OptionParser

# ============================================================================
# Global Variables
# ============================================================================
use_string = &quot;usage: %prog&quot;
ver_string = &quot;v.0.1.0&quot;

# ============================================================================
# Global Functions
# ============================================================================
def is_ipv4(string):
    regex = r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$'
    i = re.finditer(regex,string)
    match = [m.groups() for m in i]
    if len(match) != 1: return False
    octets = match[0]
    for octet in octets:
        try: number = int(octet)
        except: return False
        if number &lt; 0 or number &gt; 255: return False
    return True

def dec2octets(number):
    original = number
    octets = 4
    answer = []
    remainder = 1
    while (remainder != 0):
        if octets == 0:
            raise Exception(&quot;'%s' is too large to be an IP.&quot;%original)
        octets = octets - 1
        value = number / (256**octets)
        remainder = number % (256**octets)
        answer.append(value)
        number = remainder
    while (len(answer) != 4): answer.append(0)
    return answer

def ip2list(ip):
    assert is_ipv4(ip)
    return [int(x) for x in ip.split('.')]

def ip2bin(ip):
    assert is_ipv4(ip)
    tmp = [[('0','1')[x&gt;&gt;j&amp;1] for j in xrange(7,-1,-1)] \
           for x in [int(x) for x in ip.split('.')]]
    return ''.join([''.join(x) for x in tmp])

def bin2dec(x):
    assert type(x) == type(&quot;&quot;)
    assert x.strip('01') == ''
    return int(x,2)

def numify(n):
    assert type(n) == type(1)
    if str(n)[-1] == &quot;1&quot;: return &quot;%sst&quot;%(n)
    elif str(n)[-1] == &quot;2&quot;: return &quot;%snd&quot;%(n)
    elif str(n)[-1] == &quot;3&quot;: return &quot;%srd&quot;%(n)
    else: return &quot;%sth&quot;%(n)

# ============================================================================
# Main Method
# ============================================================================
if __name__ == '__main__':
    parser = OptionParser(version=ver_string, usage=use_string)
    parser.add_option(&quot;-i&quot;,&quot;--ip&quot;,
                      action=&quot;store&quot;,
                      default=None,
                      dest=&quot;ipAddress&quot;,
                      help=(&quot;Use this to specify the IP address to use in &quot;
                            &quot;calculations. Alternatively, specify the IP address&quot;
                            &quot;in the 'x.x.x.x/N' form to specify both IP and &quot;
                            &quot;subnet mask.&quot;),
                      metavar=&quot;IPADDR&quot;,
                      )
    parser.add_option(&quot;-m&quot;,&quot;--mask&quot;,
                      action=&quot;store&quot;,
                      default=None,
                      dest=&quot;subnetMask&quot;,
                      help=(&quot;Use this to specify the subnet mask to use in &quot;
                            &quot;calculations.&quot;),
                      metavar=&quot;MASK&quot;,
                      )
    parser.add_option(&quot;-n&quot;,&quot;--find&quot;,
                      action=&quot;store&quot;,
                      default=0,
                      dest=&quot;lookFor&quot;,
                      help=(&quot;Use this to specify the IP address to &quot;
                            &quot;us in calculations&quot;),
                      metavar=&quot;VALUE&quot;,
                      )

    (options, args) = parser.parse_args()

    # ========================================================================
    # Massage input...
    # ========================================================================
    if (options.ipAddress != None and options.subnetMask != None):
        assert is_ipv4(options.ipAddress)
        assert is_ipv4(options.subnetMask)
        addr = ip2list(options.ipAddress)
        mask = ip2list(options.subnetMask)
        bits = ip2bin(options.subnetMask).count('1')
        comp = [255-x for x in mask]
        netw = [addr[x] &amp; mask[x] for x in range(len(addr))]
        cast = [comp[x] | netw[x] for x in range(len(comp))]
    elif (options.ipAddress != None and options.subnetMask == None):
        assert options.ipAddress.find('/') != -1
        (temp, bits) = options.ipAddress.split('/')
        assert is_ipv4(temp)
        assert int(bits) &lt; 32
        assert int(bits) &gt; 0
        addr = ip2list(temp)
        bits = int(bits)
        temp = &quot;&quot;.join([&quot;1&quot;]*bits)+&quot;&quot;.join([&quot;0&quot;]*(32-bits))
        mask = [bin2dec(temp[0:8]), bin2dec(temp[8:16]),
                bin2dec(temp[16:24]), bin2dec(temp[24:32])]
        comp = [255-x for x in mask]
        netw = [addr[x] &amp; mask[x] for x in range(len(addr))]
        cast = [comp[x] | netw[x] for x in range(len(comp))]
    elif (options.ipAddress == None and options.subnetMask != None):
        assert is_ipv4(options.subnetMask)
        addr = [0,0,0,0]
        mask = ip2list(options.subnetMask)
        bits = ip2bin(options.subnetMask).count('1')
        comp = [255-x for x in mask]
        netw = [addr[x] &amp; mask[x] for x in range(len(addr))]
        cast = [comp[x] | netw[x] for x in range(len(comp))]
    else: raise Exception(&quot;An IP or Subnet mask must be specified!&quot;)
    diff = dec2octets(int(options.lookFor))
    size = bin2dec(&quot;&quot;.join([&quot;1&quot;]*(32-bits)))-1

    # Is it valid? (aka. Is it in our specified range?)
    test = [diff[x] &amp; mask[x] for x in range(len(diff))]

    # ========================================================================
    # Massage output...
    # ========================================================================
    address = &quot;.&quot;.join([str(x) for x in addr])
    network = &quot;.&quot;.join([str(x) for x in netw])
    netmask = &quot;.&quot;.join([str(x) for x in mask])
    brdcast = &quot;.&quot;.join([str(x) for x in cast])
    print (&quot;There are %s addresses available in the %s/%s network &quot;
           &quot;range.&quot;%(size, network, bits))

    print (&quot;Network: %s  Netmask: %s  &quot;
           &quot;Broadcast: %s&quot;%(network, netmask, brdcast))

    if (int(options.lookFor) &lt;= 0): sys.exit()
    if (test == [0,0,0,0]):
        plus = &quot;.&quot;.join([str(netw[x] + diff[x]) for x in range(len(netw))])
        print (&quot;The %s address in the %s/%s network &quot;
               &quot;is %s&quot;%(numify(int(options.lookFor)), network, bits, plus))
    else:
        print (&quot;The %s address is beyond the %s addresses in the %s/%s &quot;
               &quot;network.&quot;%(numify(int(options.lookFor)),size,network,bits))</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jjinno.com/2009/11/25/calculating-network-addresses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RegEx &#8211; Lists &amp; Hashes with Escape Characters</title>
		<link>http://www.jjinno.com/2009/08/02/regular-expressions-matching-escape-characters-beyond/</link>
		<comments>http://www.jjinno.com/2009/08/02/regular-expressions-matching-escape-characters-beyond/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 00:52:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.jjinno.com/?p=65</guid>
		<description><![CDATA[I recently ran across a need to match escape characters within a regular expression. The key here is that you need to make use of a fun little RegEx feature called &#8220;Zero-Width, Negative, Look-Back Assertion&#8221;. Its a loaded title, but crams a LOT of functionality into a little space&#8230; None. This all stems from a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran across a need to match escape characters within a regular expression.  The key here is that you need to make use of a fun little RegEx feature called &#8220;Zero-Width, Negative, Look-Back Assertion&#8221;.  Its a loaded title, but crams a LOT of functionality into a little space&#8230; None.  This all stems from a <a href="http://www.python-forum.org/pythonforum/viewtopic.php?f=18&amp;t=14059">post</a> I made on Python-Forum&#8230;</p>
<p>Just FYI, so that nobody hassles me later, you need to include the Python Regular Expression module in order to use any of these examples.</p>
<pre class="brush: python;">import re</pre>
<p><strong>Problem #1:</strong> How do you represent an &#8220;escaped character&#8221; in a Regular Expression?<br />
<strong>Solution #1:</strong> Use positive look-back assertion on the existence of a single backslash prior to any character.</p>
<pre class="brush: python;">
text=r'\f\o\o'
regex = r'(.(?:(?&lt;=\\).))'
i = re.finditer(regex, text)
for m in i: print m.groups()
</pre>
<p><strong>Problem #2:</strong> It is not possible to put the previous regex inside a character set. So how then do you create a set of &#8220;escaped characters + non-terminators&#8221;?<br />
<strong>Solution #2:</strong> Use the &#8220;?&#8221; on each &#8220;character&#8221; in the set.</p>
<pre class="brush: python;">
text='{foo:bar}{a:\/foo\.bar}'
regex = r'(\{(?:(?:(?&lt;=\\).)?[^\{\}\[\]\/\.]?)+\})'
i = re.finditer(regex, text)
for m in i: print m.groups()
</pre>
<p><strong>Problem #3:</strong> How do you keep multiple occurrences from matching?<br />
<strong>Solution #3:</strong> Explicit match using anchors. In other words, use &#8220;^&#8221; and &#8220;$&#8221; to bound your matching appropriately.</p>
<pre class="brush: python;">
text='{a:\/foo\.bar}'
regex = r'^(\{(?:(?:(?&lt;=\\).)?[^\{\}\[\]\/\.]?)+\})$'
i = re.finditer(regex, text)
for m in i: print m.groups()
</pre>
<p><strong>Problem #4:</strong> How do you match practically any character that could occur within 2 bounding characters (like /regex/ in a sed-esque fashion)?<br />
<strong>Solution #4:</strong> Exactly like before, except now, the only character we cant have in the middle is one of the plain (non-escaped) bounding characters.</p>
<pre class="brush: python;">
text='/g[@#$%\/{foo:bar}\/^&amp;*()]/{a:\/foo\.bar}'
regex = r'(\/(?:(?:(?&lt;=\\).)?[^\/]?)+\/)'
i = re.finditer(regex, text)
for m in i: print m.groups()
</pre>
<p><strong>Problem #5:</strong> How do we avoid matching when two valid matches are split? Like &#8220;/foo/{a:b}/bar/&#8221;<br />
<strong>Solution #5:</strong> Explicitly define the possible combinations of each regex subsection</p>
<pre class="brush: python;">
text1='{a:\/foo\.bar}/foo\/bar/'
text2='/foo\/bar/{a:\/foo\.bar}'
regex=r'^(\{(?:(?:(?&lt;=\\).)?[^\{\}\[\]\/\.]?)+\})(\/(?:(?:(?&lt;=\\).)?[^\/]?)+\/)$'
i = re.finditer(regex, text1)
for m in i: print m.groups()
regex=r'^(\/(?:(?:(?&lt;=\\).)?[^\/]?)+\/)(\{(?:(?:(?&lt;=\\).)?[^\{\}\[\]\/\.]?)+\})$'
i = re.finditer(regex, text2)
for m in i: print m.groups()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jjinno.com/2009/08/02/regular-expressions-matching-escape-characters-beyond/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Highlight</title>
		<link>http://www.jjinno.com/2009/03/19/code-highlight/</link>
		<comments>http://www.jjinno.com/2009/03/19/code-highlight/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 06:39:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.jjinno.com/?p=48</guid>
		<description><![CDATA[Just a small test of a new code-highlighting feature. #!/usr/bin/env python def test(): try: print &#34;Trying something...&#34; int(&#34;foo&#34;) # Should cause an exception return &#34;TRY&#34; except: print &#34;Excepting something...&#34; return &#34;EXCEPT&#34; finally: print &#34;Finalizing something...&#34; return &#34;FINALLY&#34; return &#34;FUNCTION&#34; if __name__ == &#34;__main__&#34;: print test()]]></description>
			<content:encoded><![CDATA[<p>Just a small test of a new code-highlighting feature.</p>
<pre class="brush: python;">#!/usr/bin/env python
def test():
    try:
        print &quot;Trying something...&quot;
        int(&quot;foo&quot;) # Should cause an exception
        return &quot;TRY&quot;
    except:
        print &quot;Excepting something...&quot;
        return &quot;EXCEPT&quot;
    finally:
        print &quot;Finalizing something...&quot;
        return &quot;FINALLY&quot;
    return &quot;FUNCTION&quot;

if __name__ == &quot;__main__&quot;:
    print test()</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jjinno.com/2009/03/19/code-highlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
