Monzo Transaction Reader
Project on GitHub: https://github.com/LucyLeach/monzo-transaction-reader
I wrote a simple program to read transactions from the Monzo API, parse my tagging system and write them into a spreadsheet for analysis. I’ve been wanting to do this project for a long time – while Monzo’s spending analysis tools are awesome, I wanted my own custom tags and the ability to split a single transaction across two tags. (I’ll be honest, if the spending summary had been available when I first started using Monzo, I would just have used the inbuilt categories, but once I had the idea in my head for this I couldn’t not do it!)
My aims for this project:
- Code to read an external API from scratch – surprisingly I’ve never done this in any of my personal projects!
- Get back into writing code after almost two years off
- Produce a useful tool to help me analyse my spending habits month-on-month
- Try out Java 10 – I barely had the chance to use Java 8 before leaving work
I enjoy coding. Having spent almost ten years of my life doing it professionally, it’s great to step back and check whether this is actually the case. And it is. The challenge of how to make something work, the chance to learn some new things, the sense of accomplishment when you get the API call right, run a set of tests and get all green, or produce a spreadsheet. I was definitely rusty to start with (and still not quite up to my usual level) but it came back quickly, including all the IntelliJ shortcuts!
Java 8 is still new to me, let alone 10. The most relevant difference in 8 was the introduction of native functional style features – the stream interface and lambdas primarily. I had experimented with functional style programming at Markit (using Google Collections and a little Scala), but then didn’t have much opportunity at Morgan Stanley as Java 8 wasn’t introduced to our team til quite late in my time there (and my final project there was all about the CompletableFutures, which are another cool Java 8 feature). I had tried it out on my personal Hanjie Solver project, but it’s still not the same as using it in anger. And so given I hadn’t really internalised it yet, it was harder to get back into it. In particular, Collectors are still a bit of a blindspot – I’d get myself all tied up in a knot how to do something, then realise there was an inbuilt Collector that did exactly the right thing already! Java 9 and 10 didn’t have a great deal of impact to me, although 10’s var syntax certainly makes the code look a lot different! I decided to try out the “declare everything a var where you can” approach and it seemed to work nicely, although I would like to experience how well this works in a team environment where you’re reading other people’s code with some past colleagues in mind who wouldn’t always use the most obvious variable names! I would have loved to have seen val syntax as well even if it didn’t win the vote for inclusion, more immutability please! I also found it amusing that Java 9 introduced a lot of Collections utility methods like List.of() that were pretty much copies of Google Collections again. I shouldn’t bash, it’s good to see them in core Java and have some great copyOf methods to produce immutable collections by default. (All the under the hood stuff sounds great but not very relevant for this project.)
I now know a lot more about OAuth and using someone’s API. This is quite an easy statement to make because I knew nothing to start with! The Monzo docs made it nice and straightforward to understand, and pointed me to the HTTPie tool for which I will forever be grateful for – so much better than trying to get all the flags right in curl. Things like refreshing the token caught me out a little to start with, but the Google OAuth for Java library made things straightforward once I understood what was happening behind the scenes. There’s a few different little tools I’ve been meaning to build for myself using other APIs (particularly Fitbit and Evernote) that will probably be in less familiar web languages, so this was a nice first step.
I struggle striking balance between clean code and quick code in personal projects. The code to parse my tags and process the transactions took forever to write but is relatively clean and at least has decent test coverage, the code to create the report from these transactions was quick but untested, and currently untestable. It’s almost certainly got bugs at all the edge cases. The latter would be unacceptable in production code but I found it necessary in this project because I was just spending too much time not getting anywhere! I’m going to call it rapid prototyping to try and get away with it, and of course I’ll definitely come back and clean it up. Definitely. Absolutely. Or just wait til it breaks and patch it up, like everyone else who says that. It’s frustrating because I recognise the need for the proper approach and the fact that it saves time in the long run, but it just wasn’t right in this case where I can afford for it to fall to pieces and correct errors when I see them and where no one else is going to have to maintain it. I think another part of the problem here is that I’m used to working on existing legacy codebases with terrible code coverage. My usual approach is to work out what I’m going to change, add test coverage around it and then change it. I’m simply not so used to TDD when you’re writing all the code from scratch and where I’m writing the spec through the tests. This lead to the transaction parsing tests being integration tests rather than unit tests (they’d look so much better in a Fitnesse style table format), and so many changes in the return types that I can’t even count, readjusting the tests each time. I’ve learnt a bit from this – in particular isolate your tests from return type changes til the end – and with more practice I’ll get the hang of it.
I want more graphs! My first thought with this project was that I’d build some pretty real-time tool with graphs showing proportions of spending in different categories/tags. That may still be on the table some day, but I wanted something a little simpler for the first pass. In the end, I couldn’t even find useful graph types in Excel to use (and Apache Poi is great but doesn’t really do graphs), so I ended up with just adding tables of data til I could easily spot what I wanted to spot. There’s still an itch to scratch there though, and I’d love to learn some more front-end skills (I’ve had a hankering for d3js since a colleague showed it to me), so there’s an extension piece to come.