tag:blogger.com,1999:blog-4554162523689846152024-02-18T23:45:35.754-08:00HappyPythonMatt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-455416252368984615.post-20084201489766278952009-11-28T13:11:00.001-08:002009-11-28T13:11:31.692-08:00Generating SVG Output (from Graphviz) in your Django AppSo accomplishing new coding tasks can be a challenge with interruptions and I've had a lot of interruptions this week but I finally got there. And I'm thankful!<br /><br />I have an app that is storing data, meaning Django models for the uninitiated. What is in there doesn't matter, but it is something that is conducive to plotting with <a href="http://graphviz.org/">graphviz</a>. So the starting point is a string that is in the <a href="http://graphviz.org/Gallery/directed/unix.gv.txt">.dot format</a>. I have some code that makes queries to the database and I end up with a string.<br /><br />So there is a utility function that creates this string...<br /><pre><br />def make_svg_str:<br />#blah blah blah snip<br />dot_string += "}"<br />p = subprocess.Popen('/usr/bin/dot -Tsvg', shell=True,\<br />stdin=subprocess.PIPE, stdout=subprocess.PIPE)<br />(stdout,stderr) = p.communicate(dot_string)<br />return stdout<br /></pre><br />So I <i>almost</i> got this right the first time except that I forgot the stdout in Popen() which caused the output to go to stdout (and not be assigned to the string) so I saw the .xml in the dev web server logs.<br /><br />The graphviz string (dot_string) is being piped to the dot executable and then the function is returning the XML SVG as a string, and is obviously assigned to the stdout variable in the tuple.<br /><br />Now the tricky part within my views.py.<br /><br />My first mistake was using the <a href="http://docs.djangoproject.com/en/dev/howto/outputting-csv/">Django CSV</a> docs instead of the <a href="http://docs.djangoproject.com/en/dev/howto/outputting-pdf/#howto-outputting-pdf">PDF docs</a> because the latter is what we need. I also didn't remember that HttpResponse is a file-like object so we can can just write to it once we have the SVG text.<br /><pre><br />def svg(request):<br />f = Foo.objects.all()<br />response = HttpResponse(mimetype='image/svg+xml')<br />response['Content-Disposition'] = 'filename=somefilename.svg'<br />response.write(make_svg_str(f))<br />return response<br /></pre><br />So this will display your image within your browser (which is what I wanted) instead of downloading file if you the use the "attachment" in the Content-Disposition key.<br /><br />The name of the game is taking shortcuts that get the job done. I'm using the admin interface to provide a good-enough UI to enter the data and now I'm using Graphviz to visualize that data without having to spend a lot of time writing UIs or nasty JavaScript.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-51392007905809559392008-12-13T07:53:00.000-08:002008-12-13T07:55:40.145-08:00Google Protocol Buffers<a href="http://code.google.com/apis/protocolbuffers/docs/overview.html">Google Protocol Buffers</a> was mentioned on the Python LinkedIn Community. <br /><blockquote><br />Protocol buffers are a flexible, efficient, automated mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages. You can even update your data structure without breaking deployed programs that are compiled against the "old" format.<br /></blockquote><br /><br /><a href="http://code.google.com/apis/protocolbuffers/docs/reference/python/index.html">Here</a> is the Link to the Python API.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-55120293528985871242008-12-06T16:49:00.000-08:002008-12-06T16:55:20.055-08:00Talking 3.0<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/I8pyv9FiMcg&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/I8pyv9FiMcg&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /><br />I'm embarrassed to say I've hardly touched 2.6 let alone 3.0 but <a href="http://www.b-list.org/weblog/2008/dec/05/python-3000/">Let's talk about Python 3.0</a> has some interesting background on the limitations of Python 2.x as well as thoughts on process improvement<br /><blockquote><br />This is a startlingly good analogy for the way lots of corporations do things; once a particular process is entrenched (and especially after a couple rounds of employee turnover), there’s nobody left who remembers why the company does things this way. There’s nobody who stops to think about whether this is still a good way to do things, or whether it was even a good idea way back at the beginning. The process continues through nothing more than inertia, and anyone who suggests a change is likely to end up viciously attacked by monkeys. <br /></blockquote><br /><br />Of course CentOS5 still only comes with Python 2.4.3, which is what I'm stuck for much of my development unless is compile from scratch.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-15397448421862437102008-11-21T17:19:00.000-08:002008-11-21T17:21:42.889-08:00Back to my Labor Day AppOne of the best rules of programming is to leave your code alone if you are banging your head against a problem. <a href="http://happypython.blogspot.com/2008/09/rundown-on-django-upgrade-problems-and.html">When upgrading to 1.0</a> Well I finally fixed the issue with my admin interface. It helps if you put admin.py in the right directory!<br /><br />Within the app instead of the project.<br /><br />DOH!Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-31206256993599616432008-09-27T06:56:00.000-07:002008-09-27T06:59:10.049-07:00Func: Python Systems Management<a href="https://fedorahosted.org/func">Func: Fedora Unified Network Controller</a> looks pretty interesting.<br /><br /><blockquote><br />A lot of programs, systems, and tools need some way to communicate. Func provides a two-way authenticated system for generically doing these sort of things. You can build your own applications on top of it, and easily expand func by adding in additional modules, whether you want these to work through the func command line or by means of some other application. If you just want to use the func command line, that's great. If you want to build apps on the func tools, that's great too. If this sounds generically vague, it's only because it really is that expandable.<br /></blockquote><br /><br />With some examples<br /><br /><pre><br /># func target.example.org call hardware info<br /># func "*.example.org" call yumcmd update<br /># func "*" call moduleyouwrote functionname 1234 5678 firetruck acmelabs hike! <br /></pre>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-76127526692464257092008-09-21T14:10:00.000-07:002008-09-21T14:15:31.998-07:00Converting Subnet to CIDR in PythonA <a href="http://code.activestate.com/recipes/576483/">nice recipe</a>, here is the meat of an even faster version in the comments.<br /><pre><br />def calcDottedNetmask(mask):<br /> bits = 0xffffffff ^ (1 << 32 - mask) - 1<br /> return inet_ntoa(pack('>I', bits))<br /></pre><br /><br />Which also led me to <a href="http://code.google.com/p/netaddr/">the Python netaddr</a> project. Very cool!Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-76591504065167779132008-09-21T13:50:00.000-07:002008-09-21T14:04:03.614-07:00Rundown on Django 1.0 Upgrade Problems (and Solutions)I've been too swamped with my teaching lately to make much progress on a <a href="http://happypython.blogspot.com/2008/09/and-how-easy-is-django-csv.html">little app</a> I initially wrote in 0.96.2 and have been trying to port to 1.0.<br /><br />Besides some bonehead typos that wasted a lot of time, here are the summary of issues I've run across:<div><ol><li>Creation of the new admin.py</li><li>Modifications of urls.py</li><li>Conversion between max_length and maxlength in your modles</li></ol>I still don't have my admin interfaces working even though I've followed the exact steps, so I'm sure it is something else.<br /><br />The main problems related to the admin interface, but there are a number of resources I've run across including <a href="http://docs.djangoproject.com/en/dev/releases/1.0-porting-guide/">Porting your apps from Django 0.96 to 1.0</a> and <a href="http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges">the complete list of backward incompatible changes</a> and a <a href="http://www.djangosnippets.org/snippets/603/">conversion script</a> to create the new admin interface conversion.<br /><br /></div>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-12832358293752416932008-09-01T05:14:00.000-07:002008-09-01T05:23:06.509-07:00And how easy is Django CSV?I'm a few hours (and of course I already have a functional app) into converting a spreadsheet "database" we currently store on Sharepoint with a Django app and I was pleased to see how <a href="http://www.djangoproject.com/documentation/0.96/outputting_csv/">easy it was to do CSV dumps</a> of data. And it worked on the first time. Amazing.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-55749323141804073912008-05-11T06:35:00.000-07:002008-05-11T06:53:07.593-07:00And CherryPy Looks to be the Winner<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4lt75Gu3Mwbr87EYjbSn6ncgL4950W8mJ1oMcO4KuCvmyfKD7D6TTMk3X8Xrhel52xEw8dPhWuSVUQgcuHFZYR7FfaurYbYffAHjIWSymB3IOlONBIRhy3RjI13LC9eIra7kyu_mpfCo/s1600-h/cplogo.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4lt75Gu3Mwbr87EYjbSn6ncgL4950W8mJ1oMcO4KuCvmyfKD7D6TTMk3X8Xrhel52xEw8dPhWuSVUQgcuHFZYR7FfaurYbYffAHjIWSymB3IOlONBIRhy3RjI13LC9eIra7kyu_mpfCo/s400/cplogo.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5199116308241795474" /></a><br /><br />So I've been <a href="http://happypython.blogspot.com/2008/05/from-aspen-to-karrigell-and-webpy.html">looking for a pure Python lightweight HTTP server</a> for serving up a small django app.<br /><br />Here are the steps I used (assuming Django is already installed however you installed it) for Ubuntu Hardy LTS:<br /><br />1) Install <a href="http://www.cherrypy.org/">CherryPy</a> 3.x (I installed the <b>python-cherrypy3</b> package)<br /><br />2) Get <a href="http://www.xhtml.net/scripts/Django-CherryPy-server-DjangoCerise">DjangoCerise</a> and follow the docs. Documentation and these wrapper scripts were the make or break difference.<br /><br />3) Increase number of threads in th e SERVER_THREADS file. My crude app worked fine but the django admin interface was a bit sluggish.<br /><br />While it properly daemonizes (possibly because I screwed up the scripts) shutdown wasn't working for me and (quite obviously, in hindsight) unless you run the startup scripts as root (which I will be) once this app qoes into "production" it won't properly set the user to nobody.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-64254327763092324522008-05-10T19:14:00.000-07:002008-05-10T19:25:06.621-07:00From Aspen to Karrigell and web.pyBeen struggling to get <a href="http://www.zetadev.com/software/aspen/">Aspen</a> working with Django. My app works fine, still having issues with "static" apps, which are necessary for the media directory and I ran across two framworks I hadn't seen before.<br /><br />The first was <a href="http://karrigell.sourceforge.net/">Karrigell</a><br /><br /><blockquote><br />Karrigell is a flexible Python web framework, with a clear and intuitive syntax. It is independant from any database, ORM or templating engine, and lets the programmer choose between a variety of coding styles<br /><br />The package includes a powerful built-in web server, so there's no need to download, install and configure a separate one, and a pure-Python database engine, PyDbLite, which is used for the demos <br /></blockquote><br /><br />and another was <a href="http://webpy.org/">web.py</a> which is so barebones it is not worth quoting the website.<br /><br />I doubt I'll use either of these, in particular I'm not sure the point of using a web framework unless there is an ORM?Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-9332017490067211732008-04-25T06:28:00.000-07:002008-04-25T06:31:43.036-07:00No Model Inheritence in Django?Based on <a href="http://code.djangoproject.com/wiki/ModelInheritance">this wiki page on Model Inheritance</a> and this <a href="http://www.fadingred.org/blog/articles/2007/03/02/extending-djangos-model-class/">hack on extending models</a> (yuck) not looking too good. I would guess this "just works" in Rails, since I've just redesigned my database now would be the time to switch but I really want Django's admin interface.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com2tag:blogger.com,1999:blog-455416252368984615.post-17752977846418816432008-04-17T19:10:00.000-07:002008-04-17T19:13:38.990-07:00Not Too Happy with Django MigrationSo after playing around with <a href="http://code.google.com/p/dmigrate/">dmigration</a> and <a href="http://www.aswmc.com/dbmigration/">dbmigration</a> I'm probably going back to mucking with SQL (which I'm even less happy) or maybe hacking something together that meets my needs and actually works.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-21337182241773229892008-03-02T10:53:00.000-08:002008-03-02T10:57:00.993-08:00fun with ieeemacThis week I count have actually used <a href="http://pypi.python.org/pypi?%3Aaction=search&term=ieeemac&submit=search">ieeemac</a> when I was writing some scripts to automate packet generation using Click Router.<br /><br />But of course I was using Ruby so I couldn't take advantage of this.<br /><br /><span style="font-family: courier new;">>>> import ieeemac</span><br /><span style="font-family: courier new;">>>> import commands</span><br /><span style="font-family: courier new;">>>> o = commands.getoutput("ifconfig -a") </span><br /><span style="font-family: courier new;">>>> o</span><br /><span style="font-family: courier new;">'lo0: flags=8049<up,loopback,running,multicast> mtu 16384\n\tinet 127.0.0.1 netmask 0xff000000 \n\tinet6 ::1 prefixlen 128 \n\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 \ngif0: flags=8010<pointopoint,multicast> mtu 1280\nstf0: flags=0<> mtu 1280\nen0: flags=8863<up,broadcast,smart,running,simplex,multicast> mtu 1500\n\tether 00:11:24:45:4b:1a \n\tmedia: autoselect (none) status: inactive\n\tsupported media: none autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback>\nen1: flags=8863<up,broadcast,smart,running,simplex,multicast> mtu 1500\n\tinet6 fe80::211:24ff:fea4:9fc7%en1 prefixlen 64 scopeid 0x5 \n\tinet 192.168.1.103 netmask 0xffffff00 broadcast 192.168.1.255\n\tether 00:11:24:a4:9f:c7 \n\tmedia: autoselect status: active\n\tsupported media: autoselect\nfw0: flags=8863<up,broadcast,smart,running,simplex,multicast> mtu 2030\n\tlladdr 00:11:24:ff:fe:45:4b:1a \n\tmedia: autoselect <full-duplex> status: inactive\n\tsupported media: autoselect <full-duplex>\nwlt1: flags=41<up,running> mtu 1500\ntap0: flags=8842<broadcast,running,simplex,multicast> mtu 1500\n\tether 74:61:70:00:00:00 \n\tclosed\ntun0: flags=8850<pointopoint,running,simplex,multicast> mtu 1500\n\tclosed'</span><br /><span style="font-family: courier new;">>>> ieeemac.find_macs(o)</span><br /><span style="font-family: courier new;">[<ieeemac.mac>, <ieeemac.mac>, <ieeemac.mac>, <ieeemac.mac>]</span><br /><span style="font-family: courier new;">>>> ml = ieeemac.find_macs(o)</span><br /><span style="font-family: courier new;">>>> ml</span><br /><span style="font-family: courier new;">[<ieeemac.mac>, <ieeemac.mac>, <ieeemac.mac>, <ieeemac.mac>]</span><br /><span style="font-family: courier new;">>>> ml[0] </span><br /><span style="font-family: courier new;"><ieeemac.mac></span><br /><span style="font-family: courier new;">>>> dir(ml[0])</span><br /><span style="font-family: courier new;">['__doc__', '__eq__', '__getattr__', '__init__', '__module__', '__str__', '_formats', 'format', 'formats', 'groups', 'groups_need_fixing', 'to_format']</span><br /><span style="font-family: courier new;">>>> ml[0].to_format("cisco")</span><br /><span style="font-family: courier new;">'0011.2445.4b1a'</span>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com2tag:blogger.com,1999:blog-455416252368984615.post-28781243542401953372008-02-24T12:57:00.000-08:002008-02-24T12:59:54.851-08:00Easy Win32 Python and RegistrySo I have some experience with APIs for accessing the registry (when I wrote some SCADA Nessus Plugins) but it can't get any easier than this <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/546543">recipe</a>.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-43571606628904136472008-01-13T19:57:00.000-08:002008-01-13T20:03:04.599-08:00NetworkX: This I might actually find time to play with<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg006Fjs_CxHuZ7WfAqwNb0UYJz8JphDz-ARxsKGEM_uAX_G_K8fdqBFVOcHGi87UPW19dq5K8xWXH-5KR7fIeEXWNGtSe7KoR4vh5hkXSJ974mQp41KlcXo1FIwof5KsE-Vb1OZJhtSAw/s1600-h/networx.png"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg006Fjs_CxHuZ7WfAqwNb0UYJz8JphDz-ARxsKGEM_uAX_G_K8fdqBFVOcHGi87UPW19dq5K8xWXH-5KR7fIeEXWNGtSe7KoR4vh5hkXSJ974mQp41KlcXo1FIwof5KsE-Vb1OZJhtSAw/s200/networx.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5155177488122978850" /></a><br /><br />Just ran across <a href="https://networkx.lanl.gov/wiki">NetworkX</a> tonight:<br /><br /><blockquote><br />NetworkX (NX) is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. Features: Includes standard graph-theoretic and statistical physics functions, Easy exchange of network algorithms between applications, disciplines, and platforms, Includes many classic graphs and synthetic networks, Nodes and edges can be "anything" (e.g. time-series, text, images, XML records)<br /></blockquote>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-83966716163537960732008-01-04T19:05:00.000-08:002008-01-04T19:11:00.097-08:00A Better Python Cmd LibraryThe Python <a href="http://docs.python.org/lib/module-cmd.html">cmd module</a> has always been been better than the <a href="https://rubyforge.org/projects/cmd/">Ruby imitation</a> (after all like most things about Ruby, it is cheap copy of the original, distinctive feel?) but <a href="https://sourceforge.net/projects/python-cmd2">cmd2</a> turns this into a real ass-kicking with the following features:<br /><br /><pre><br /> * Searchable command history (commands: "hi", "li", "run")<br /> * Load commands from file, save to file, edit commands in file<br /> * Multi-line commands<br /> * Case-insensitive commands<br /> * Special-character shortcut commands (beyond cmd's "@" and "!")<br /> * Settable environment parameters<br /> * Parsing commands with flags<br /></pre>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com1tag:blogger.com,1999:blog-455416252368984615.post-27282173707592082972008-01-04T18:59:00.000-08:002008-01-04T19:02:44.382-08:00Django on Jython?I previously <a href="http://blogfranz.blogspot.com/2007/08/non-jython-news-and-irrelevance-of.html">whined about the non-progress of Jython</a> (especially relative to JRuby) but <a href="http://zyasoft.com/pythoneering/2008/01/django-on-jython-minding-gap.html">this is great news</a>.<br /><blockquote><br />The most important thing to know about Django on Jython is that we are almost there, and with clean code. End-to-end functionality is demonstrated by the admin tool running in full CRUD, along with a substantial number of unit tests and syncdb.<br /></blockquote>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-17910915818626535932008-01-02T08:51:00.000-08:002008-01-02T08:53:22.663-08:00Maybe someday I'll have time to read on Python BytecodeMaybe someday I'll get a chance to fully digest<a href="http://thermalnoise.wordpress.com/2007/12/30/exploring-python-bytecode/">Exploring Python Bytecode</a>.<br /><br /><blockquote><br />For the past month or so, I’ve been trying to understand what appears to be a black art mostly because of lacking documentation - Python bytecode generation and peephole optimization. Some notes from the study for the benefit of IRC-mate ‘jstatm’ and anyone else living on similar planes of insanity.<br /><br />Although bytecode applies to objects other than functions such as tracebacks, dictionaries and strings, I am only interested in optimization and flow analysis of class methods, functions and lambdas. Lets get to the action straight away with an example. Here is a small python program to disassemble and display the bytecode of a function in human readable form.<br /></blockquote>Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-90212944125939863612008-01-01T07:57:00.000-08:002008-01-01T07:58:09.158-08:00Decorators, Python Black Magic and the Residue of Past ProgrammingWhile trying to figure out <a href="http://www.threatmind.net/secwiki/PythonDecorators">decorators</a> I ran across a really cool presentation called <a href="http://www.python.ie/blackmagic/">Python Black Magic (or how I learned to stop writing Java in Python)</a>. I understand this, since much of the Python I've written over the years, was even worse -- <i>I was writing Perl in Python</i>. For the longest time Python OO conventions seemed strange compared to Java/C# and I refused to use them sticking to horrific <a href="http://blogfranz.blogspot.com/2007/12/using-hashes-like-it-is-1999.html">Perl-like hash of a hash of a hash data structures.</a> On the one hand if you are sort of programming-ADD-like-me, I definitely see the advantage of developing a set of crisp clean, language agnostic design patters. Who cares if your code isn't completely Pythonic or if you aren't exploiting all the Ruby functional programming fu, your code will be accessible to the largest possible audience.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-58314327322709683922007-12-28T21:16:00.001-08:002007-12-28T21:24:45.258-08:00Web Scripting with Twill (I wish I had this when I used to do WebApp Assessments)A few weeks ago I thought I had the need to script (for the life of my I can't remember why I wanted to do this, I should have blogged on it) Firefox. Well I didn't any Python or Ruby tools for taking control of the browser (I remember seeing how to do this with Python and IE a loooong time ago) but tonight I ran across <a href="http://twill.idyll.org/">Twill</a> which looks pretty cool and I assume uses the <a href="http://www.blogger.com/%20http://docs.python.org/lib/module-cmd.html">cmd module</a><br /><br />mfranz@gutsy61:~$ twill-sh<br /><br />-= Welcome to twill! =-<br /><br />current page: *empty page*<br /><br />>> go http://www.threatmind.net/secwiki<br />==> at http://www.threatmind.net/secwiki<br />current page: http://www.threatmind.net/secwiki<br />>> showforms<br /><br />Form #1<br />## ## __Name__________________ __Type___ __ID________ __Value__________________<br />1 action hidden (None) fullsearch<br />2 context hidden (None) 180<br /><br /><br /><br />3 value text searchinput<br />4 1 titlesearch submit titlesearch Titles<br />5 2 fullsearch submit fullsearch Text<br /><br /><br />Form #2<br />## ## __Name__________________ __Type___ __ID________ __Value__________________<br />1 action select (None) ['raw'] of ['raw', 'print', 'refresh ...<br />2 1 None submit (None) Do<br /><br /><br />Form #3<br />## ## __Name__________________ __Type___ __ID________ __Value__________________<br />1 action select (None) ['raw'] of ['raw', 'print', 'refresh ...<br />2 1 None submit (None) Do<br /><br /><br /><br />current page: http://www.threatmind.net/secwiki<br />>> help<br /><br />Undocumented commands:<br />======================<br />add_auth fa info save_html title<br />add_extra_header find load_cookies setglobal url<br />agent follow notfind setlocal <br />back formaction redirect_error show <br />clear_cookies formclear redirect_output show_cookies <br />clear_extra_headers formfile reload show_extra_headers<br />code formvalue reset_browser showforms <br />config fv reset_error showhistory <br />debug get_browser reset_output showlinks <br />echo getinput run sleep <br />exit getpassword runfile submit <br />extend_with go save_cookies tidy_okMatt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-50534379770047613742007-12-27T14:35:00.000-08:002007-12-27T17:56:42.386-08:00Obviously I'm not Even an Intermediate Level Python ProgrammerWhile a thread on <a href="http://groups.google.com/group/comp.lang.python/browse_thread/thread/527cafad9c341490/">regex performance</a> revealed how much I've forgotten (or never knew) even though I started coding in Python (1.5.x) back in 1999. My confusion didn't have really anything to do with regexes but the two different approaches, one which was more peculiar to my only-coding-in-Ruby-recently brain:<br /><br /><span style="font-weight: bold;">Class Approach</span><br /><pre>import re<br />class Searcher(object):<br /> def __init__(self, rex):<br /> self.crex = re.compile(rex)<br /> def __call__(self, txt):<br /> return self.crex.search(txt)<br /><br />s = Searcher("dog")<br />print s("dog").string<br /></pre><br />After I remembered what the <span style="font-family: courier new;">__call__</span> was used for (which I actually like) and got used to the __'s (which I don't like) and I've never liked the self's in Python method arguments -- this made sense.<br /><br /><span style="font-weight: bold;">Function Returning a Function</span><br /><pre>import re<br />def searcher(rex):<br /> crex = re.compile(rex)<br /> def _(txt):<br /> return crex.search(txt)<br /> return _<br />s = searcher("dog")<br />print s("dog").string<br /></pre><br /><br />At first this didn't make much sense and I got tricked by the underscore (thinking it was some sort of Perl-like special function name or something, it isn't though!). Wny would I call a function returning another function that I would use over and over again. Why would you do that? What is interesting though is if that s("dog")("dog") also produces identical results although I have no idea why (except that the first nested function within a function always executes the second parameter).Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-38205042416960612902007-12-24T19:48:00.000-08:002007-12-24T20:05:35.477-08:00Names, Objects, Bindings, and Thinking Like a PythonistaOn the Python Mailing list there was a discussion about "references" and someone posted a link to <a href="http://starship.python.net/crew/mwh/hacks/objectthink.html">How to think like a Pythonista</a> with some nice ASCII art.<br /><br /><br /><span style="font-size:78%;"><span style="font-family:courier new;">Names look like this:</span><br /><br /><span style="font-family:courier new;"> ,-----.</span><br /><span style="font-family:courier new;"> | foo |</span><br /><span style="font-family:courier new;"> `-----'</span><br /><br /><span style="font-family:courier new;">Names live in namespaces, but that's not really important for the</span><br /><span style="font-family:courier new;">matter at hand as the only namespace in play is the one associated</span><br /><span style="font-family:courier new;">with the read-eval-print loop of the interpreter. In fact names are</span><br /><span style="font-family:courier new;">only minor players in the current drama; bindings and objects are the</span><br /><span style="font-family:courier new;">real stars.</span><br /><span style="font-family:courier new;">...</span></span><br /><br />I haven't done much Ruby coding this month (cause of <a href="http://blogfranz.blogspot.com/2007/12/welcome-samuel-austin.html">the baby</a> so I'm trying to use the break to brush up on my Python. So a nice article for that.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0tag:blogger.com,1999:blog-455416252368984615.post-25005326837981307532007-12-23T16:20:00.000-08:002007-12-23T16:22:03.364-08:00Angry Ruby Meet Happy Python!Because I don't seem <a href="http://angryruby.blogspot.com">too angry</a> anymore.Matt Franzhttp://www.blogger.com/profile/00973881935128108475noreply@blogger.com0