ARCHIVE NOTICE

My website can still be found at industrialcuriosity.com, but I have not been posting on this blog as I've been primarily focused on therightstuff.medium.com - please head over there and take a look!
Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Saturday, 13 February 2021

Approaching Software Engineering as an evolutionary process

A year or two ago I had an opportunity to sit down with AWS's Marcin Kowalski in a cafeteria and discuss the problems of software development at almost-unimaginable scale. I walked away with a new (for me) conception of software engineering that is part engineering, part organic biology, and I've found this perspective has shifted my approach to software development in a powerful and immensely helpful way.

As Computer Scientists and Software Engineers, we've been trained to employ precision in algorithm design, architecture and implementation: Everything must be Perfect. Everything must be Done Right.

For smaller, isolated projects, this engineering approach is critical, sound and practical, but once we begin to creep into the world of integrated solutions and micro-services it rapidly begins to break down.

Sunday, 16 August 2020

Enabling Programmable Bank Cards To Do All The Things

A little while back, Offerzen and Investec opened up their Programmable Bank Card Beta for South Africans, taking over from Root, and I was excited to be able to sign up!

My long-term goal with programmable banking is to integrate crypto transactions directly with my regular banking - which might be possible quite soon as Investec is starting to roll out its open API offering in addition to the card programme - and as far as I can tell that could be a real game-changer in terms of making crypto trading practical for non-investment purposes.
When I joined, though, what I found was a disparate group of really interesting projects and only a two-second time window to influence whether your card transaction will be approved or not.

I decided to bide my time by building a bridge for everyone else's solutions, one which would provide a central location to determine transaction approval and enable card holders (including myself, of course) to forward their transactions securely to as many services as they like without costing them running time on their card logic.

It was obvious to me that this needed to be a cloud solution, and as someone with zero serverless experience1 I spent some time evaluating AWS, Google and Microsoft's offerings. My priorities were simple:
  • right tool for the job
  • low cost
  • high performance
  • good user experience
In the end AWS was the clear winner with the first two priorities, so much so that I didn't even bother worrying about any potential performance tradeoffs (there probably aren't any) and I was prepared to put up with their generally mixed bag of user experience. I also had the added incentive that my current employer uses AWS in their stack so I would be benefiting my employer at the same time.

Overall, I'm very glad that I chose AWS in spite of the trials and tribulations, which you can follow in my earlier post about building a template for CDK for beginners (like myself). In addition to learning how to use CDK, this project has given me solid experience in adapting to cloud architecture and patterns that are substantially different from anything I've worked with before, and I've already been able to effectively apply my learnings to my contract work.

One of the obligations of the Programmable Bank Card beta programme is sharing your work and presenting it; I was happy to do so, but for months I've been locked down and working in the same space as my wife and four year-old (we don't have room for an office or much privacy in our apartment); with all the distractions of home schooling and having to work while my wife and kid play my favourite video games I've barely been able to keep up my hours with my paid gig, so making time for extra stuff? That hasn't been so easy.

A couple of weeks ago my presentation was due, and I spent a lot of the preceding two weekends in a mad scramble to get my project as production-ready as I could - secure, reliable, usable. Half an hour before "go time" I finally deployed my offering, and I was a little bit nervous doing a live demo... I mean, sure, I'd tested all the end points after each deployment - but as we all know: Things Happen. Usually During Live Demos.

Fortunately, the presentation went very well! I spent the following weekend adding any missing "critical" functionality (such as scheduling lambda warmups and implementing external card usage updates), and I'm hoping that some of my fellow community members get some good use out of it (whether on their own stacks or mine).

The code can be found here on GitLab, and a few days ago OfferZen published the recording of my presentation on their blog along with its transcript2 and my slide deck.

Thank you for joining me on my journey!



1 Although I was employed by one of the major cloud providers for a while, I've only worked "on" their cloud rather than "in", and while I do have extensive experience with Azure none of it included serverless functions.

2 The transcript has a few minor transcription errors, but they're more amusing than confusing.

Monday, 29 July 2013

Comment Driven Coding

This is undoubtedly my favourite trick, and oddly enough it's the one that drives experienced hackers round the bend!

Background

I've always thought that I had this commenting thing down. When my teachers in high school and in university told me I needed to comment my code, I listened! They were satisfied, too. I took up tutoring whenever I couldn't find work, and I adamantly preached what I practised. Nobody was going to be able to call me an inconsiderate coder.

That is, until I entered the army. My initial exposure to the comment style in an environment with high developer turnover and long-term maintenance responsibilities was like being picked up by a ship after days stranded at sea. For the first time I really understood the value of a well-placed, meaningful comment. I learned to expect comments whenever the code became even a little tricky, and I learned to be safe rather than sorry.

After a couple of years in the army, I transferred to the real deal: real-time avionics development. If the army comments were like a ship, this was like finding myself on dry land! I was shocked by the extreme attitude, and it took me a while to get to grips with it. For the first time in my life, I was writing comments for every single statement.

Every... single... statement. Let that sink in a moment. Even though each comment had to be meaningful - so instead of "add 1 to i" it would be "increment the loop counter" - this meant that there was far more comment text than code in any given source file. At first it was a bit of a headache, but soon the comments and the code began to blend and I found myself feeling far more comfortable with these complex systems than I'd ever been with any others. Nothing was left to the imagination, no guessing required. The things that didn't make any sense? They'd let you know precisely why.

After years of this I returned to the real world, the perpetually rushed, highly-stressed and highly caffeinated world of 25-hour work days led by marketing teams who promise the impossible to be delivered yesterday using codebases and frameworks that were built exclusively for the most antisocial misogynistic masochist enthusiasts and are generally worked on by whoever has the highest grades in the only-partially-related academic field of computer science.

These people do not have time for comments. They usually have a very specific idea of what comments look like, those unhelpful things that tell you what the code does. There's a popular opinion that good code is so readable that it doesn't need to be commented! But unfortunately, that's only partially true.

You see, and here I'm going to wind down on the personal history and get to the point of this post, good, clean code might tell you what it does but it doesn't tell you what it's supposed to do. It doesn't expose the logic of a group of statements, and it certainly doesn't provide an unambiguous guide to the code you're writing under the gun.

Method

Comment Driven Coding is summarized in four easy steps:
1. Comment before you code
2. Comment the desired behaviour in English
3. Split your comments into logical steps.
4. Repeat until your comments describe the smallest reasonable description of logical behaviour.
One level above pseudo-code, use comments as a way to structure your code prior to implementation. This will handle all of the logic before you let syntax and details get in the way. Begin with the higher level functionality and drill-down until you've fleshed out the details.

[EXAMPLE FUNCTION INSPIRED BY THIS POST]

/* Reduced Sum Of Digits (RSOD) is calculated by repeatedly summing the digits of a number until a single digit is produced. */
function ReduceToRSOD(number) {
  // return the RSOD
} // ReduceToRSOD

The first things to notice here are that we have explained RSOD clearly, we have explained the inner logic in the broadest sense possible and we have used a comment to explicitly mark the function of the closing brace. This last step may seem extreme, but as the number of braces and the size and complexity of the code increase it will become more difficult to keep track of the code blocks no matter how well the code is indented.

/* Reduced Sum Of Digits (RSOD) is calculated by repeatedly summing the digits of a number until a single digit is produced. */
function ReduceToRSOD(number) {
  // if the number is comprised of a single digit, return it
  // if the number is comprised of multiple digits
    // separate the digits and add them together
    // recursively apply the ReduceToRSOD function
} // ReduceToRSOD

By doing this using comments instead of code, logical errors or missed cases will be far easier to spot.

/* Reduced Sum Of Digits (RSOD) is calculated by repeatedly summing the digits of a number until a single digit is produced. */
function ReduceToRSOD(number) {
  // return an error code if the number is a not positive integer
  // if the number is comprised of a single digit, return it
  // if the number is comprised of multiple digits
    // separate the digits and add them together
    // while the number has more digits
      // add the last digit to a result variable
      // remove the last digit from the number
    // recursively apply the ReduceToRSOD function
} // ReduceToRSOD

The comments not only make the code readable, but they also function as the perfect tool for performing a code review. Does the comment logic make sense? Does the code do what the comments describe?
var INVALID_NUMBER = -1;

/* Reduced Sum Of Digits (RSOD) is calculated by repeatedly summing the digits of a number until a single digit is produced. */
function ReduceToRSOD(number) {
  // return an error code if the number is a not positive integer
  if ((parseInt(number)== Number.Nan) || (number < 0)) return INVALID_NUMBER;
  // if the number is comprised of a single digit, return it
  if (number < 10) return number;
  // if the number is comprised of multiple digits
    // separate the digits and add them together
    var result = 0;
    // while the number has more digits
    while (number > 0) {
      // add the last digit to a result variable
      result += number % 10;
      // remove the last digit from the number
      number = (number - (number % 10)) / 10;
    } // while the number has more digits
    // recursively apply the ReduceToRSOD function
    return ReduceToRSOD(result);
} // ReduceToRSOD
 
The reason this works so well is that even the brightest and most experienced programmers don't truly think in code. Our brains are wired for language and the easiest way to look at a problem is when it's expressed in words or images.

A well-written comment never gets old. The code might change, but what it's supposed to be doing will not.
 
At first glance it may look and sound like it'll take longer to write your code this way, but it really won't. It's quicker to write in natural language, and once the ideas have been broken down into their simplest logical components the code practically writes itself!