Monday, November 05, 2012

On Private Software

This was originally posted on my new website, where you can read the full post. Please subscribe to the new feed there to follow new things I write.

Private software is software one writes only for themselves and never shares or intends to share. It isn't commercial, because it isn't sold or even distributed at all. It isn't open source, but it shares something in spirit. I write about this in favor, though like all things, on a case by caes basis.

I'm coming to really enjoy the idea of private software. Private software made by a person to solve a personal need and none other. It is, at its surface, very contrary to what you might expect Open Source to be about, but in a way I believe it to be a great shining example of the ideals open source comes from.


Sunday, November 04, 2012

Jules 0.2 Released

This originally posted to my new site and has been reposted for anyone following my old feeds. Please subscribe to my new website.

I've released version 0.2 of Jules today, which is actually the first packaged version released. There are no users other than me, so no care was taken in backwards compatibility and this is less announcing a new verison and more an announcement of the project as a whole.

Jules is a static blog generator named after a victorian-ish era literary or intellectual character, because that's a trendy thing to do. (Jekyl, Hyde, Nikola, etc.)

The design is flexible and plugin-oriented. Much of the built-in functionality is available through a set of plugins, which creates an architecture very prone to adaptation and customization. One of the major goals (though not yet reached) is template impartiality.

Today, Jules is a very capable little static website generator you may find useful for your personal, project, or organization site.

You can install Jules easily with
pip install jules

Which will install the latest version from PyPI.

Why I Won'T Be Doing Nanowrimo Anymore

This was originally posted at my new website. Please read it there, and follow my new feed to follow what I write about in the future!

I looked forward to it, I planned on it, and I was prepared for it. My outlines were ready, my story was waiting. So, why am I not doing NaNoWriMo this year?

Please subscribe to my new feed when you visit the new site!

Sunday, October 28, 2012

PyCarolinas 2012 Recap

This was originally posted at my new website. Please read it there, and follow my new feed to follow what I write about in the future!

I ran a conference.

I said it had to be done, apparently I said I'd even be the one to do it. Before I knew it, I was doing it and now its over.

All the way up to the date of our inaugural year I was feeling unprepared, afraid I was forgetting terribly important things, or simply that the event would be uneventful. I could not have been more unprepared for the sheer success of PyCarolinas, from the presentations everyone was able to enjoy to the success of the food and drinks we provided to keep them all going to the amazing sense of community and connectedness everyone at the conference obviously felt.

Read the rest...

Thursday, September 27, 2012

PyCarolinas 2012 Registration is Open!

Cross-posted from the PyCarolinas blog

Have you been looking forward to grabbing your spot for PyCarolinas 2012?
That time is today, as we’re ready to accept registrations for the inaugural event on October 20th and 21st. Spots our limited, due to our generously donated space, to 150 attendees including staff, speakers, and sponsor slots.
Don’t hesitate to registration, you might loose your spot. We expect nothing short of a great turn out, our schedule is fantastic, our keynotes are prime, and our sponsors are nothing short of enormously generous.
Come out and enjoy the wonderful fall weather in Chapel Hill, NC and what is sure to be the first year of a great tradition!

Sunday, September 23, 2012

I Am Worried About The Future Of Python

This piece was posted to my new website.

Python is Great

I've been in love with the language for a decade.

I feel a connection to the community that has only grown over time, both in numbers and in awesomeness. However, I see difficult times ahead. Not where Python is or where it is going, but places it will always have trouble entering growing in importance. I think we have, as a community, really downplayed the significance of some of our beloved languages shortcomings.
I'm concerned about growing areas in software, which are hostile to Python. This is a coincidental, but important direction a lot of focus in software is moving in.

Read the full post at my new site and please subscribe to the new feed there.

Friday, August 31, 2012

Read Counter, an Idea

Originally posted to my new website, where all of this content will eventually go.

Just a thought. We have so many tools for, essentially, ranking content.

We vote on Reddit, like on facebook, plus one on Google. We pretend this stuff is (relatively) new, but aren't they all just non-passive hit counters? Maybe a return to the beginnings would be nice. But, simply loading a page isn't enough.

My proposal: the Read Counter.

At the end of a page, the Read Counter would trigger simply by scrolling into view. It would be a rough measurement of traffic, and as a simple bonus would avoid counting people who opened the page but don't seem to have actually read the content.

Simple, but useful. Passive, but meaningful.

Friday, August 24, 2012

PyCon 2013 Posts I want to see

PyCon 2013 will be my third PyCon, and I'm walking into it with a better idea what I'm hoping for than my first two. Here is my shortlist for talk hopes.

  • Python inside Government
    Are any federal, state, or local governments using Python internally? In any important or large ways? Maybe at the national archives or the library of congress? I want to know about these things! Does the IRS crunch my taxes with Python?

  • Python and Big Data
    Working with large datasets fascinates me, probably because I don't get the opportunity to do so. I'd love to see where Python is being used to crunch big datasets. I wonder if gets used in any pipelines in processing results from CERN? Or maybe diagnosing medical tests?
  • Python close to the wire, embedded or working with wire protocols
    Using Python in mobile devices, embedded devices, or implementing binary protocols on the wire that need to work fast and with low latency? These are things people often don't think Python does well, so prove them wrong.
  • Python in movies
    Pixar, Disney, I know you guys are out there! Is python used in stages of the pipeline to make all those 3D movies I take my kids to see?
  • Community-centric talks, please!
    These are personally interesting to me, because I want to build community. I want to learn from more people who are great at it.
If you can give any of these talks, or any talk at all, submit your proposal for PyCon 2013!

Saturday, June 30, 2012

Julython is on!

I'm participating in Julython, are you?

Julython is a great initiative to promote Python developers focusing on their own projects through the month of July and contributing to the community providing great software, great libraries, and great tools. Sign up, track your commits on GitHub and BitBucket, and tell your dev friends to take part.

Julython is going to be a lot of fun!

Saturday, June 09, 2012

How To use Sphinx Autodoc on ReadTheDocs with a Django application

Sphinx is awesome for writing documentation. ReadTheDocs is awesome for hosting it. Autodocs are great for covering your entire API easily. Django is a great framework that makes my job easier.

Between these four things is an interaction that only brought me pain, however. I'm here to help the next dev avoid this.

Autodocs works by importing your modules and walking over the classes and functions to build documentation out of the existing docstrings. It can be used to generate complete API docs quickly and keep them in sync with the libraries existing docstrings, so you won't get conflicts between your docs and your code. Fantastic.

This creates a problem when used with Django applications, where many things cannot be imported unless a valid settings module can be found. This can prevent a hurdle in some situations, and requires a little boilerplate to get working properly with Sphinx. It require a little extra to get working on ReadTheDocs. What makes this particularly hard to figure out, is the environment running on their servers is not the same as your own, and you have only terse error reports to guess about.

Here is the snippet you need to add into the of your docs/ to tell Sphinx how to load a

import sys, os

import django 

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
if django.VERSION < (1, 4):
    from import setup_environ

    settings = __import__(os.environ["DJANGO_SETTINGS_MODULE"])

and a simple is all you need sitting beside that.

# Django settings for docs project.
# import source code dir
import os
import sys
sys.path.insert(0, os.getcwd())
sys.path.insert(0, os.path.join(os.getcwd(), os.pardir))

SITE_ID = 303
DEBUG = True

DATABASES = {"default": {

    "NAME": ":memory:",
    "ENGINE": "django.db.backends.sqlite3",
    "USER": '',
    "PASSWORD": '',
    "PORT": '',


    'YOUR_APP_HERE', # This is where you put your app

And you should be good to go!

Wednesday, June 06, 2012

Announcement: Tracerlib 0.1 Released

Tracerlib is a set of utilities to make tracing Python code easier.

It provides TracerManager, which can allow multiple trace functions to coexist. It can easily be enabled and disabled, either manually or as a context manager in a with statement.

Tracer classes make handling the different trace events much easier.
class TraceExceptions(Tracer):
    def trace_exception(self, func_name, exctype, value, tb):
        print "Saw an exception: %r" % (value,) 
Tracer is also easily capable of filtering which events it listens to. It accepts both an  
events parameter, a list of trace events it will respond to, and a watch parameter, a list of paths it will respond to in the form of package.module.class.function.
This can easily wrap a trace function, or you can subclass Tracer and implement one of its helpful trace_*() methods.

And, a helper class FrameInspector which wraps a frame and makes it trivial to inspect the function name and arguments the function had been called with.
inspector = FrameInspector(sys._getframe())

print "Called", inspector.func_name
print "args:", inspector.args
print "kwargs:", inspector.kwargs 
You can read the full documentation at the read the docs site and see the code at github.

Saturday, May 19, 2012

I Read Things On The Internet

It is true, from time to time I read things on the internet. What has been bothering me lately is the feeling that all of these ideas I'm consuming and all of my responses to them are just lost into a sea churning together everything into the unidentifiable paste that comes out of my head.

So, I've decided to start logging this. After all, the word "blog" is a shortening of "weblog", a web log, a log of the things you've read on the web. I want this for my own daily readings, both to keep a record for myself (and anyone with an interest) and to note my thoughts, comments, responses, and questions about the things I come across.

Ironfroggy Reads Things On The Internet is this new thing. It is a blog on Tumblr, which I find a useful tool for smaller posts and their bookmarklet is perfect for my needs here. I'll be directing the posts to twitter to, as an experiment. Let me know if that turns out annoying.

Follow it, if you care to. Mostly its for me, but I believe in transparency by default.

Thursday, May 17, 2012

ANN: straight.command 0.1a1 - A command framework with a plugin architecture

New Project Announcement:

I'd like to announce a new project, based on straight.plugin, a command framework that provides a declarative way to define command-line options, sub-commands, and allows plugins from third-parties to expand commands.

This is all very early, I'm calling this version 0.1a1 and lots of things are missing, but here is an example (which works) of a small todo application built with this.

#!/usr/bin/env python

from __future__ import print_function
import sys
from straight.command import Command, Option, SubCommand

class List(Command):
    def run_default(self, **extra):
        for line in open(self.parent.args['filename']):

class Add(Command):
    new_todo = Option(dest='new_todo', action='append')

    def run_default(self, new_todo, **extra):
        with open(self.parent.args['filename'], 'a') as f:
            for one_todo in new_todo:
                print(one_todo.strip('\n'), file=f)

class Todo(Command):
    filename = Option(dest='filename', action='store')

    list = SubCommand('list', List)
    add = SubCommand('add', Add)

if __name__ == '__main__':

And a sample of the result of this little script:

$ ./ todo.txt add "Write an example tool"
$ ./ todo.txt add "Get the documentation cleaned up and on readthedocs"
$ ./ todo.txt add "Blog about the project"
$ ./ todo.txt list
Write an example tool
Get the documentation cleaned up and on readthedocs
Blog about the project

The documentation and source are both available now.

Tuesday, February 14, 2012

ANN: Django Better Cache 0.5.3

I've added a small, but useful, addition to Django Better Cache, today. The new bettercache.decorators.CachedFormMethod utility is a decorator for Django form methods, which is essentially a memoizer, but with a nice twist.

This is great for forms that include DB or search index reading methods which can be expensive and you'd like to cache, but normal memoization fails when the important parameters to key on are in the form data, not the arguments to the actual method.

Read about the new decorator at the docs to learn more.

class FriendsLookup(forms.Form):

    username = forms.CharField(required=True)

    @CachedFormMethod(expires=60*15) # expire in 15 minutes
    def get_friends_list(self, include_pending=False):
        username = self.cleaned_data['username']
        friends = Friendship.objects.filter(
        if include_pending:
            friends = friends.filter(status__in=(PENDING, APPROVED))
            friends = friends.filter(status=APPROVED)

        return friends 

Tuesday, January 31, 2012

ANN: Django Better Cache 0.5.1 with expanded docs

I've made a small incremental release on Django Better Cache, adding a from_miss() method to handle cache misses in CacheModel objects. Now, you can define your cache model and how it initializes data when the cache is empty, and perform all your lookups through the CacheModel, expecting misses to auto-populate for you.

You can see a quick example of the new functionality below, but I have also made large improvements to the documentation hosted over at ReadTheDocs, so go read the full docs right now, if you are interested.

from bettercache.objects import CacheModel
from django.contrib import auth

class User(CacheModel):
    username = Key()
    email = Field()
    full_name = Field()

    def from_miss(self, username):
        user = auth.models.User.objects.get(username=username) =
        self.full_name = user.get_full_name()

If this get() does not find the object in the cache, it will create a new
User instance and call from_miss() with the key parameter username to
initialize it, and then save and return that object for you. The next call,
it will find it in the cache.

user = User.get(username="bob")

Sunday, January 29, 2012

ANN: straight.plugin 1.3 released - with docs!

I think it is worth a new release to announce that I have documented straight.plugin and published the docs to ReadTheDocs. I hope this will help anyone who has had trouble parsing my terse README file, and will improve adoption of the project in the future.

Check out the new code and the new docs.

Thursday, January 26, 2012

A little trick for wide pages

We have wide monitors and our reading doesn't tend to like wide text very well. This is why newspapers have lots of narrow columns, rather than stretch each story across the entire width of the paper.

Not all websites follow this tip, so drag this to your bookmark toolbar and squeeze the margin in 100px at a time, until you can read more naturally.

Yes, I could resize my window, but the same width isn't right for all pages, and most are padded or have sidebars. This is good when you only need some of the pages you have open to be narrower than the rest.

Sunday, January 22, 2012

ANN: Django Better Cache 0.5 Released

I am announcing the release of Django Better Cache 0.5 today. This release includes a move to sphinx as a documentation tool and a new component, the bettercache.objects module, which provides a lite ORM-like interface for caching data.

Please read the full, but short documentation over at Read The Docs for details on the bettercache {% cache %} tag and the bettercache.objects ORM, and have a much easier time with your caching needs.

Here is just a quick example of the new cache models, from the docs:

class User(CacheModel):
    username = Key()
    email = Field()
    full_name = Field()

user = User(
    username = 'bob',
    email = '',
    full_name = 'Bob T Fredrick',


user = User.get(username='bob') == ''
user.full_name == 'Bob T Fredrick'

Tuesday, January 17, 2012

Leaving Google AppEngine

Calvin Spealman
I can use AWS and work on technological engineering issues, or appengine and work on price-ological engineering issues. :-/

Maybe I should take myself seriously when I said this. In the past few months, I've barely done any feature or bug work on JournaApp, because it takes my limited time and energy just keeping myself under quota when I'm the only user of the app. I can't keep that up and keep my sanity, and it is honestly an emotionally draining exercise. This is creating a toxin that affects everything I do, so I'm going to take it out of my life.

I don't know if I'll port JournalApp or not. I like it, it has been fun and useful, but I'll probably take project notes in Evernote from here on forward, and on paper again. I miss paper.
I write here about programming, how to program better, things I think are neat and are related to programming. I might write other things at my personal website.

I am happily employed by the excellent Caktus Group, located in beautiful and friendly Carrboro, NC, where I work with Python, Django, and Javascript.

Blog Archive