Popular recipes by Dan McDougall http://code.activestate.com/recipes/users/4169722/2014-05-25T16:23:55-07:00ActiveState Code Recipeslreplace() and rreplace(): Replace the beginning and ends of a strings (Python) 2010-06-04T02:18:48-07:00Dan McDougallhttp://code.activestate.com/recipes/users/4169722/http://code.activestate.com/recipes/577252-lreplace-and-rreplace-replace-the-beginning-and-en/ <p style="color: grey"> Python recipe 577252 by <a href="/recipes/users/4169722/">Dan McDougall</a> (<a href="/recipes/tags/regex/">regex</a>, <a href="/recipes/tags/replace/">replace</a>, <a href="/recipes/tags/string/">string</a>). </p> <p>Python newbies will often make the following mistake (I certainly have =):</p> <pre class="prettyprint"><code>&gt;&gt;&gt; test = """this is a test: ... tis the season for mistakes.""" &gt;&gt;&gt; for line in test.split('\n'): ... print line.lstrip('this') ... is a test the season for mistakes. </code></pre> <p>The mistake is assuming that lstrip() (or rstrip()) strips a string (whole) when it actually strips all of the provided characters in the given string. Python actually comes with no function to strip a string from the left-hand or right-hand side of a string so I wrote this (very simple) recipe to solve that problem. Here's the usage:</p> <pre class="prettyprint"><code>&gt;&gt;&gt; test = """this is a test: ... tis the season for mistakes.""" &gt;&gt;&gt; for line in test.split('\n'): ... print lreplace('this', '', line) ... is a test tis the season for mistakes. </code></pre> <p>I really wish Python had these functions built into the string object. I think it would be a useful addition to the standard library. It would also be nicer to type this:</p> <pre class="prettyprint"><code>line.lreplace('this', '') </code></pre> <p>Instead of this:</p> <pre class="prettyprint"><code>lreplace('this','',line) </code></pre> Convert strings like '5d' and '60s' to timedelta objects (Python) 2011-10-06T14:06:54-07:00Dan McDougallhttp://code.activestate.com/recipes/users/4169722/http://code.activestate.com/recipes/577894-convert-strings-like-5d-and-60s-to-timedelta-objec/ <p style="color: grey"> Python recipe 577894 by <a href="/recipes/users/4169722/">Dan McDougall</a> (<a href="/recipes/tags/datetime/">datetime</a>, <a href="/recipes/tags/timedelta/">timedelta</a>). </p> <p>I wrote this little function for <code>[Gate One](http://vimeo.com/24857127)</code> (a web-based terminal emulator/SSH client)... It converts strings in the format of &lt;num&gt;&lt;character&gt; into timedelta objects. It's not rocket science but maybe it'll save someone a few keystrokes :). Besides that, it comes with a really nice Sphinx-ready (reStructuredText) docstring with complete doctests.</p> Method-based URL dispatcher for the Tornado web server (Python) 2009-11-20T11:51:47-08:00Dan McDougallhttp://code.activestate.com/recipes/users/4169722/http://code.activestate.com/recipes/576958-method-based-url-dispatcher-for-the-tornado-web-se/ <p style="color: grey"> Python recipe 576958 by <a href="/recipes/users/4169722/">Dan McDougall</a> (<a href="/recipes/tags/dispatcher/">dispatcher</a>, <a href="/recipes/tags/shortcuts/">shortcuts</a>, <a href="/recipes/tags/subclass/">subclass</a>, <a href="/recipes/tags/tornado/">tornado</a>, <a href="/recipes/tags/url/">url</a>, <a href="/recipes/tags/web/">web</a>). Revision 5. </p> <p>The MethodDispatcher is a subclass of <a href="http://www.tornadoweb.org/">tornado</a>.web.RequestHandler that will use the methods contained in subclasses of MethodDispatcher to handle requests. In other words, instead of having to make a new RequestHandler class for every URL in your application you can subclass MethodDispatcher and use the methods contained therein <em>as</em> your URLs.</p> <p>The MethodDispatcher also adds the convenience of automatically passing arguments to your class methods. So there is no need to use Tornado's get_argument() method.</p> <h5><strong>Example</strong></h5> <p>To demonstrate the advantages of using MethodDispatcher I'll present a standard Tornado app with multiple URLs and re-write it using MethodDispatcher...</p> <h5><strong>The standard Tornado way</strong></h5> <pre class="prettyprint"><code>class Foo(tornado.web.RequestHandler): def get(self): self.write('foo') class Bar(tornado.web.RequestHandler): def get(self): self.write('bar') class SimonSays(tornado.web.RequestHandler): def get(self): say = self.get_argument("say") self.write('Simon says, %s' % `say`) application = tornado.web.Application([ (r"/foo", Foo), (r"/bar", Bar), (r"/simonsays", SimonSays), ]) </code></pre> <h5><strong>The MethodDispatcher way</strong></h5> <pre class="prettyprint"><code>class FooBar(MethodDispatcher): def foo(self): self.write("foo") def bar(self): self.write("bar") def simonsays(self, say): self.write("Simon Says, %s" % `say`) application = tornado.web.Application([ (r"/.*", FooBar) ]) </code></pre> <h5><strong>Notes</strong></h5> <p>As you can see from the above example, using the MethodDispatcher can significantly reduce the complexity of Tornado applications. Here's some other things to keep in mind when using the MethodDispatcher:</p> <ul> <li>MethodDispatcher will ignore any methods that begin with an underscore (_). This prevents builtins and private methods from being exposed to the web.</li> <li>The '/' path is special: It always maps to self.index().</li> <li>MethodDispatcher does not require that your methods distinquish between GET and POST requests. Whether a GET or POST is performed the matching method will be called with any passed arguments or POSTed data. Because of the way this works you should not use get() and post() in your MethodDispatcher subclasses unless you want to override this functionality.</li> <li>When an argument is passed with a single value (/simonsays?say=hello) the value passed to the argument will be de-listed. In other words, it will be passed to your method like so: {'say': 'hello'}. This overrides the default Tornado behavior which would return the value as a list: {'say': ['hello']}. If more than one value is passed MethodDispatcher will use the default behavior.</li> </ul> Python code minifier (Python) 2014-05-25T16:23:55-07:00Dan McDougallhttp://code.activestate.com/recipes/users/4169722/http://code.activestate.com/recipes/576704-python-code-minifier/ <p style="color: grey"> Python recipe 576704 by <a href="/recipes/users/4169722/">Dan McDougall</a> (<a href="/recipes/tags/bz2/">bz2</a>, <a href="/recipes/tags/bzip2/">bzip2</a>, <a href="/recipes/tags/comments/">comments</a>, <a href="/recipes/tags/compression/">compression</a>, <a href="/recipes/tags/docstring/">docstring</a>, <a href="/recipes/tags/embedded/">embedded</a>, <a href="/recipes/tags/gzip/">gzip</a>, <a href="/recipes/tags/minify/">minify</a>, <a href="/recipes/tags/pack/">pack</a>, <a href="/recipes/tags/regex/">regex</a>, <a href="/recipes/tags/zlib/">zlib</a>). Revision 16. </p> <p><strong>Update 05/25/2014:</strong> Pyminifier 2.0 has been released and now lives on Github: <a href="https://github.com/liftoff/pyminifier" rel="nofollow">https://github.com/liftoff/pyminifier</a> (docs are here: <a href="http://liftoff.github.io/pyminifier/" rel="nofollow">http://liftoff.github.io/pyminifier/</a>). The code below is very out-of-date but will be left alone for historical purposes.</p> <p>Python Minifier: Reduces the size of Python code for use on embedded platforms. Performs the following:</p> <ol> <li>Removes docstrings.</li> <li>Removes comments.</li> <li>Removes blank lines.</li> <li>Minimizes code indentation.</li> <li>Joins multiline pairs of parentheses, braces, and brackets (and removes extraneous whitespace within).</li> <li>Preserves shebangs and encoding info (e.g. "# -<em>- coding: utf-8 -</em>-")</li> <li><strong>NEW:</strong> Optionally, produces a bzip2 or gzip-compressed self-extracting python script containing the minified source for ultimate minification.</li> </ol> <p><strong>Update 09/23/2010:</strong> Version 1.4.1: Fixed an indentation bug when operators such as @ and open parens started a line.</p> <p><strong>Update 09/18/2010:</strong> Version 1.4:</p> <ul> <li>Added some command line options to save the result to an output file.</li> <li>Added the ability to save the result as a bzip2 or gzip-compressed self-extracting python script (which is kinda neat--try it!).</li> <li>Updated some of the docstrings to provide more examples of what each function does.</li> </ul> <p><strong>Update 06/02/2010:</strong> Version 1.3: Rewrote several functions to use Python's built-in tokenizer module (which I just discovered despite being in Python since version 2.2). This negated the requirement for pyparsing and improved performance by an order of magnitude. It also fixed some pretty serious bugs with dedent() and reduce_operators().</p> <p>PLEASE POST A COMMENT IF YOU ENCOUNTER A BUG!</p> Serve static web content from within a gzipped tarball to save space using CherryPy (Python) 2009-03-31T18:24:06-07:00Dan McDougallhttp://code.activestate.com/recipes/users/4169722/http://code.activestate.com/recipes/576706-serve-static-web-content-from-within-a-gzipped-tar/ <p style="color: grey"> Python recipe 576706 by <a href="/recipes/users/4169722/">Dan McDougall</a> (<a href="/recipes/tags/cherrypy/">cherrypy</a>, <a href="/recipes/tags/compression/">compression</a>, <a href="/recipes/tags/embedded/">embedded</a>, <a href="/recipes/tags/gzip/">gzip</a>, <a href="/recipes/tags/html/">html</a>, <a href="/recipes/tags/http/">http</a>, <a href="/recipes/tags/network/">network</a>, <a href="/recipes/tags/routes/">routes</a>, <a href="/recipes/tags/web/">web</a>, <a href="/recipes/tags/web_server/">web_server</a>). </p> <p>This code lets you store all of your static website content inside a gzipped tarball while transparently serving it to HTTP clients on-demand. Perfect for embedded systems where space is limited.</p>