Musings on programming


My finance project is done…

Well, sort of. It does what I want it to do. I still need to add a few features. Search and sorting for a start. Maybe some more reports. I could do with better error handling. I’ll need a way to start a new financial year automatically and maybe carry over budgets. There are a few performance issues that need addressing…

OK. So it’s not done.

Projects like this never are. I’d say it’s a small to medium sized project, but I did what I always do with any new skill. I bit off more than I could immediately chew. The trouble is that I only embark on a personal project when I have an end goal in mind and that end goal is always ambitious for a beginner. I rarely take the time to work through the toy projects used in tutorials – I’ll immediately start trying to adapt what I’m reading to the project that I have in mind.

As an aside, it’s not just programming. I’d love to be able to create 3D rendered art, but in my mind I have photorealistic landscapes and buildings when I know in reality that I’d have to spend weeks just learning how to render a sphere… I digress…

At least with programming projects I have enough background to get up to speed reasonably quickly.

I’ve been following my usual path when learning a new language or framework – find examples and copy them. It’s only when things don’t work or I can’t quite tweak the examples to my needs that I really start to learn. Take Django’s class based views. As soon as I started repeating code in several classes I realised I had to get to grips with inheritance and mixins. I was familiar with the concept, but not with Python’s implementation of it. I still only have a surface level understanding.

I already knew the basics of Python, but I’ve also been picking up some idioms.

For example, take building an array of month names using the calendar module’s abbreviation method. My initial “I just need to get this working” approach was to define an empty list and then populate it:

import calendar

months = []
for i in range (1,13):
    months.append(calendar.month_abbr[i])

At least I knew enough to use the range function for my loop. As I got more comfortable with Python’s iterators and the Pythonic way of doing things I changed it to define and populate the list in a single step:

months = [ calendar.month_abbr[i] for i in range(1,13) ]

In some ways I prefer the first version. It’s crystal clear and the second is slightly more opaque. Not so much in this trivial example, but in some places I ended up with a nested mix of lists and dictionaries. Here’s an example that’s building the source data that will be sent to the template for the monthly expenses by category chart:

expenses_by_month = {
  category: { 
    'amount': ','.join(['{}'.format(amounts[month]) for month in range(1,13)]),
    'colour': '"{}"'.format(CATCOLOURS[category]) 
  } for category, amounts in expenses['categories'].items()
}

I do wonder if that one will still be clear when I come back to it in six months time. It probably depends on how much other Python code I write during that time, and there’s an argument for keeping it as simple as possible. Perhaps it doesn’t matter that the programming style appropriate to an occasional programmer is different, and simpler, than that of a full time developer. It’s the difference between being able to get by in a foreign language and being a native speaker. If English wasn’t my first language, my ambitions might extend to being able to read the news and perhaps some thrillers but I wouldn’t tackle Ulysses.

Bad example. Ulysses is to literature what Perl is to programming languages…

I say that with considerably more affection for Perl than for Ulysses. I am actually more fluent in Perl than in Python. When it came to importing my GnuCash export and spreadsheets into my new app I needed to manipulate the data and map old account structures to new ones. Perl’s regular expression handling was perfect for the job. I could’ve done the same job in Python, but it was a one off task and it was quicker to do it in Perl.

At the moment my code is a bit of a mixed bag. Some of it needs a tidy up because I’ve learnt new techniques. Some needs a tidy up because I took a brute force approach to extracting and manipulating data to make quick progress rather than spend the time looking for a more elegant solution. Some needs work because it doesn’t perform well – I’m learning that Django’s templates aren’t necessarily efficient. Some of it needs improvement to feel more modern, such as having forms overlaid on top of list screens instead of being completely separate pages. That last one would require greater use of Javascript to move functionality into the front end – which opens up a whole new learning curve.

I probably won’t do all of those changes in this project. Instead, I’ll take what I’ve learnt and apply it to my next project, whatever that happens to be. Next time around I think I’ll look at using Django as a backend, via the REST API, and do most of the UI work in Javascript instead of populating templates. Not because that’s necessarily better, but because it’s something new to learn.

Now I just need to come up with another project…

in Finance Project

Add a Comment

Your email address will not be published. All comments will be reviewed.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Posts