General

Python Enum Class for Django

Tuesday, July 26th, 2011 | General | 2 Comments

For the last several months, I’ve been developing in Python for a Django project. Python is new to me but there’s something about it which just feels right. It’s clean, dynamic, powerful, comes with a full complement of tools and has already proven itself useful in the field with large proponents such as Google as well as my Linux distribution of choice – Gentoo – basing their system package manager off of it.

While I don’t post here often, I decided to share the Enum class I’ve been using with Django which is specifically used for the Django ModelFields when you specify the choices for an attribute of your Model.

For those who don’t know what the above means, Django uses a model approach in which you specify the data model you will be using – for example a User which could contain a username, password, etc – to represent the database schema. So, you design a single Python class, say User, and you add the attributes of a username and password. Django then loads this class and creates the database schema for you. Also, because the schema is ultimately a Python class and based off of Django Model classes, you can use the class and manipulate it and the Django subsystem will know how to save, load and update the data stored in the database without you ever having to worry about SQL. Kinda like:

current = User.objects.get( id = 1 )
print "Hello {}".format( current.username )
current.username = 'NewName'
current.save()

Viola. Extremely convenient.

Some of the fields in your schema – or attributes of your Model – will have a limited amount of valid options. For example, an User account may be INACTIVE, ACTIVE or DISABLED. These states are the only possible states. So the User.state attribute should only be limited to those possible choices. You can specify this in django with the following:

USER_STATES = ( ( 0, 'Inactive' ), ( 1, 'Active' ), ( 2, 'Disabled' ) )

class User( models.Model ):
    ...
    state = models.IntegerField( choices = USER_STATES, default = 0 )
    ...

So now that Integer field will be validated against the allowed states. The problem is, you now have to refer to the states numerically from now on in your code:

if myuser.state == 0:
    do this

Or alternatively:

if myuser.state == USER_STATES[0][0]:
    do this

Both of which is really messy and bad. You want to be able to define the user states in a similar manner you do with other languages – using an Enum. Turns out it’s quite easy if you write your own Enum class. Here is the class I wrote:

ChoicesEnum Class for Django

class ChoicesEnum( object ):
    def __init__( self, *args, **kwargs ):
        super( ChoicesEnum, self ).__init__()
        vals = {}
        for key,val in kwargs.iteritems():
            vals[ key ] = val
        object.__setattr__( self, "_vals", vals )

    def choices( self ):
        cho = []
        vals = object.__getattribute__( self, "_vals" )
        for key, val in vals.iteritems():
            cho.append( val )
        cho.sort()
        return cho

    def __getattr__( self, name ):
        return object.__getattribute__( self, "_vals" )[ name ][ 0 ]

    def __setattr__( self, name, value ):
        object.__setattr__( self, "_vals" )[ name ][ 0 ] = value

    def __delattr__( self, name ):
        del object.__setattr__( self, "_vals" )[ name ]

And so usage would be as follows:

UserState = ChoicesEnum(
      INACTIVE = ( 0, 'Inactive' ),
      ACTIVE = ( 1, 'Active' ),
      DISABLED = ( 2, 'Disabled' ),
)

class User( models.Model ):
    ...
    state = models.IntegerField(
                     choices = UserState.choices(),
                     default = UserState.INACTIVE
                    )
    ...

And then you can use the UserState object as you would a normal Enum on most languages:

if myuser.state == UserState.INACTIVE:
    do this

It’s really quite nice and cleans up your code substantially.

Eclipse IDE for Java Development

Friday, January 14th, 2011 | General | No Comments

Most of my development is done in console with vim (because I’m hardcore that way) but I’m finishing up the SMPP Simulator – which is Java based – and I’ve decided to do it with Eclipse. This goes against my unofficial anti-IDE philosophy which I’ve had for several years, since the disappearance of the original Borland IDEs. Those original IDEs were still young and in their infancy and they didn’t get in the way of development because they hadn’t learnt how yet. The new ones decided to try and help out – like Clippy from MS Word.

Over the years I’ve tried them again on occasion, from the newer offerings from Borland, Embarcadero, Microsoft, NetBeans, etc. However they all suffered from a seemingly increasing amount of bloat with each iteration. Recently that trend has been reversing, I think.

Eclipse is probably one of the best IDEs I’ve used in a while. It’s simple. It’s supports development. On initial installation there are a few “issues” with it such as automatic brace and bracket insertion, which really just interrupts the typing ‘cos you have to then side-step around it. However, these can all be turned off once you figure out how.

Also, to use an IDE you need a significant amount of screen real estate. A laptop won’t cut it unless it’s 17″ and more. It makes the experience tolerable. My screens over the last few years have all been around 15″ because of my laptop world but my new desktop has bigger ones. These help. They help out so much.

Right now I’m quite pleased with the direction and progress Eclipse is taking. I’ll still stick to vim and console for C++ development – I haven’t tried Eclipse’s C++ IDE yet – but I think Eclipse is probably the only way to go for Java development.

PS: I’ve you’re going to do visual editing, you should go with Google’s WindowBuilder Pro. Install it as a plugin to Eclipse. The other visual editors aren’t worth it. Trust me on this.

Noise in the job market

Tuesday, October 12th, 2010 | General | 2 Comments

There’s so much noise in the job market. I’ve posted an job advert to fill the position of a junior developer online. It says quite clearly: linux/unix environment and C++. Yet I get quite so many responses without these skills.

Some of the CV’s are quite interesting. You can see the people who are trying to make something of themselves and pull themselves out of where they are; their CV’s stick out. You can also spot good people and bad people immediately from the CV’s. Or rather, should I say that you can spot well-formulated CV’s immediately? Fortunately for me, I don’t have to read them during the first round. I have some interview tests which they can do at home. I send these out to all the people who apply. So there’s no human bias; it’s just a pure skills test. No responses yet.

Perhaps the skill set I need is too much in demand and the people I need are all already employed? It’s a problem. One week of employee-seeking has been quite discouraging so far.

DocBook and Good Output

Friday, January 29th, 2010 | General | No Comments

It’s really taken quite some time for me to get a grip on the entire concept of DocBook and, specifically, how it goes from DocBook to a pretty PDF file. Every time I’ve started fiddling around with it, it’s cost me several hours just trying to remember how it all works and fits together.

Today I am happy to say that it all finally clicked into place for me. And, in hindsight, I went about understanding and learning DocBook using an incorrect approach – basically back-to-front. I tried to understand DocBook, then the transformation layer and then get to XSL FO. No.. bad idea. If you’re trying to learn DocBook and get a good understanding of how everything works, you need to learn in order:

  • XML Namespaces – Just kinda know what they are about and how to import them and use them.
  • XSL FO – Learn about blocks, general attributes and properties, documents and flows.
  • XSLT – Figure out how XSLT works, the templates, callbacks, “variables”, etc. Understand that it’s not a procedural language and not a see-this-replace-with-that kind of engine. Understand that you’ll actually building a DOM.
  • DocBook – Get acquainted with the allows tags, the hierarchy and what they’re used for in the document.
  • DocBook XSL – The stylesheets you can get which perform XSLT transformations from DocBook schema into FO schema, for example.

Still, it’ll take some time if you’re coming in as a newbie. Speaking as a programmer, I found it really different.

gSOAP and types

Tuesday, October 20th, 2009 | General | 2 Comments

Well I had this problem and I thought I’d write a quick post about it because I couldn’t find anything useful on the Internet. It took me in depth debugging to resolve the issue. The issue was, I was getting this error in TEST.log: “Validation constraint violation: data type mismatch in element ‘id’” where my id tag was defined as an xsd:long. This had an internal type in gsoap of LONG64.

So, what the heck was the problem? I fiddled with a custom typemap.dat and made sure the xsd__long was defined as an int64_t (‘cos it is on my platform) and I even found some suggestions on the Internet to use “-e” when compiling using soapcpp2. Nada.

That’s when I started debugging gSOAP – as I have been doing continuously the last two weeks – and I traced the problem all the way back to a function inside stdsoap2.cpp called “soap_s2LONG64″. This function is responsible for string to long conversion. Now the first thing I noticed is that it’s possible for the entire function to be completely empty because almost all of it is conditional with a lot of #ifdefs. I double checked this by having a look at my compiled assembly and sure enough it was completely empty. There was no way for this function to ever succeed.

What had I done wrong? Well I had included the gsoap code directly into my build – my makefile – and I wasn’t building it as a separate library. What I had failed to notice though is that the stdsoap2.h needs config.h to determine which functions are available on the system. Some of these functions are the very ones used within soap_s2LONG64. Since there was no detection and definition of the defines, there was no real body to the function. That’s why it was happening.

Of course, I just added the checks into autoconf and made sure that stdsoap2.h’s include directive for the config.h file was pointing to the right place. Viola. It was working like a charm.

In summary: If you’ve included stdsoap2.cpp into your build, then you need to define which string to long conversion functions are in your system. You can do with this with your compilation command (g++ -DHAVE_STRTOLL) or define it just before you include stdsoap2.h in your code. Of course, autoconf makes it a lot easier. It’s up to the build system you’re using. If you’re doing it manually, try defining HAVE_STRTOLL or HAVE_SSCANF.

Support through FogBugz

Friday, October 2nd, 2009 | General | No Comments

Today I signed up for the trial of FogBugz. It’s an issue tracking/customer support/project management/other stuff kind of system. So far it seems to live up to what it promises.

I needed a nice support architecture where, if someone sent an email to support, it would get pulled into a system, processed, etc and everything would happen to give the person a fantastic support experience – if there is such a thing. This seems to do it.

It’s also incredibly easy to setup and fast to get going. There’s basically no learning curve. The entire setup, including creating an email address on my side, took about 10-30 minutes. Support system done. So far so good.

Boost, their build system and Solaris

Thursday, October 1st, 2009 | General | 2 Comments

Today I had the experience of trying to modify the boost build system (boost 1.35.0) to adapt to a specific environment of mine – a temporary Solaris environment. Boost’s build system is really quite err… different. I’m not sure if “sucks” is the right word. I would need to get a complete understanding of how it all works before I would be confident using bad words about it. For such a useful and good library, I never expected just getting it to build to be such a problem.

Most people won’t have the problem I’m having since I think it might work out-of-the-box for a “common” system like Linux or their package management system has installed it for them. For me, however, I wanted to do two thing:

  • Add some extra compiler flags to specify the correct CPU architecture
  • Make sure the Sun linker was correctly detected instead of boost using the g++ frontend to do the linking. The command line options are incorrect.

Seems simple enough? Well the problem when you roll-your-own build systems like this is that it differs from the standard conventions. So you can’t use any knowledge or experience to fix this. You have to suddenly learn something new. This shouldn’t be the case for a standard library.

For example, just overriding CPPFLAGS, CFLAGS or CXXFLAGS on the command line had absolutely no effect despite the fact that the configure script said it would. And where do you set the linker easily … ? Well, you cant.

However, I managed to combine knowledge I acquired from several different sites to get this working.

http://www.pion.org/files/pion-platform/common/doc/README.solaris
http://blogs.sun.com/sga/entry/how_to_build_boost_1
http://shoaibmir.wordpress.com/2009/08/12/building-boost-under-solaris/

Each of which has some useful piece of information. And so I did the following… I made sure the prefixes and everything were set up.


./configure --prefix=<path> LDFLAGS="-L<path>" CPPFLAGS="-I<path>"

(Not sure of the CPPFLAGS or LDFLAGS were honoured, I didn’t check.) And then this generates a “user-config.jam” file in the top directory. I modified mine as follows:


# Boost.Build Configuration
# Automatically generated by Boost configure

# Compiler configuration
using gcc : : : <compileflags>-mcpu=v9 <linker-type>sun ;

# Python configuration
using python : 2.3 : /usr/sfw ;

If you don’t specify the CPU architecture, you get warnings from the assembler (as) about the opcode “cas” being incorrect for the architecture – applicable to v9′s instead of v8′s ‘cos “cas” is atomic on v9′s. “(Requires v9|v9a|v9b; requested architecture is v8.)”. And then ….


make

viola. Easy, huh? No …. not at all. The above represents several hours of work. I’m not even sure that it’s the “correct” way to do it.

XML in C++

Wednesday, September 30th, 2009 | General | No Comments

I needed some new XML libraries because most of my experience with these things were based on some internal, proprietary convenience libraries developed in-house at my last place of employment. I thought it would be easy and I’d find some useful and convenient libraries. However, it turns out that while XML is conceptually easy, the general programming conventions for these things are not! In fact, I’d say working with XML and the open source libraries available is a real pain.

In the end I’ve discovered two libraries which I find useful:

  • Xerces-C++ which is a part of the Apache project. It’s a fully implemented, validating XML parser which supports DOM, SAX and SAX2 APIs. It’s very good. It’s very big. It does it all.
  • If you don’t care about completeness and you just want to get the job done with your XML, then I’d recommend this small, simple, cross-platform, free and fast C++ XML Parser which is basically a header file and an implementation file. It’s quick and easy to use. Initially I was attracted to it because the API was almost exactly the same as the convenience library I’d used in my previous work. However, I didn’t end up using it because it really just cares about getting the job done and extracting or building XML. So other nice things like error codes, etc have been neglected. For example, the inability of the parser to parse a file will result in the parser exit()’ing the entire application. So I couldn’t use this in an end-user product. Otherwise, great for RAD. The author will also re-license the code to you if you need a BSD license.

Taxes and IP export laws

Monday, September 21st, 2009 | General | No Comments

It turns out that the export of Intellectual Property or licensing of it to people outside of South Africa is supposed to be regulated by government institutions. It’s essentially the same as exporting and importing of physical goods. So I’m meeting with a specialist in the field tomorrow to discuss my entire setup and make sure I’m not breaking any international laws. He’s also going to get me hooked up with the appropriate licenses and I’ll be able to distribute SuiteSMPP under my proposed Open Source Compatible license.

Also, from what I can see, my entire current business costs are tax deductible to approximately 150% of the value. It turns out that South Africa offers a huge tax incentive for R&D in the whole Intellectual Property space. The definition of R&D is broad enough to include the salaries of software developers. Awesome. This incentive is further sweetened for some countries outside of the Republic – including the UK, China, Belgium and others – because they can then claim deducations from both South Africa and their own governments. It’s interesting and complicated stuff.

Delayed SuiteSMPP release

Friday, September 11th, 2009 | General | No Comments

Originally I had planned to release SuiteSMPP on the 11th of September. Apart from the obvious coincidence of 9/11 which was probably not a good idea, I’ve decided to delay this by a week or so for a couple reasons:

  • I actually have quite a lot of work at the moment doing an integration project. This is taking up all of my time.
  • I haven’t yet received access to the Sun EZQual virtual lab to compile the code on a SUN machine.

I’m eventually going to need a SUN machine of my own but then that brings in the problem of cost and of hosting. Ah well….