How I Taught Myself to Code - A Credit Card Repayment Calculator

Tim Platt
12 min readJan 18, 2019

Introduction

Lending in the UK is at its all time highest. The average consumer credit borrowing stood at £4,140 per adult (15% of average earnings) as of Dec 2018. Each day 12 homes are re-possessed, 273 people are declared bankrupt and 3001 county court judgements are issued. An increasing number of people are reaching out to debt charities such as The Money Charity or Step Change as UK adults struggle to make ends meet.

Unfortunately, it’s those that are most vulnerable that suffer most; people with the poorest credit histories are forced to borrow at higher interest rates. Additionally, many individuals are simply not equipped with the financial tools and education needed to succeed with credit. People will miss repayments, fail to consolidate debts, not understand the APR rate that they’re accepting etc and their financial situation can snowball very quickly.

The story of Jerome Rogers had a profound impact on me. It reinforced how important it is to provide support for those navigating financial difficulty.

The Shortcomings of Minimum Repayments

My work has focused on addressing one specific educational gap with regards to credit lending. In short, I want to equip credit card consumers with the knowledge that repaying only a little more each month can significantly shorten how long it takes to clear their balance and the amount of interest they will pay.

A large % of UK credit card holders only make the minimum payment on their credit cards each month and it’s not necessarily a bad thing. Firstly, making the minimum repayment will ensure you don’t incur late payment fees and will allow you to clear at least your interest. Secondly, it’s perhaps all a consumer can afford and it gives them flexibility to pay a small amount while low on cash.

However, many credit card consumer don’t realise that they should strive to pay at least their minimum each month, but ideally a little but more. Why? It essentially boils down to the fact the minimum payment is calculated as . percentage of your balance i.e. “the greater of 1% of your balance + interest or £5”. Thus, as your balance decreases so does your minimum payment, which means it will take longer to repay your debts and cost your more to pay back what you owe.

Above is an example that takes a credit balance of £2,292 and an interest rate of 17.91% APR. It would take 25 years and 3 months to repay a this credit card paying only the minimum vs. 5 years and 3 months if we paid the first months minimum payment amount each month.

A Solution to Encourage Bigger Repayments

I’ve developed an app that allows people to visually calculate how much difference paying a fixed amount each month could make to their credit card repayment time and the interest they will pay. The app can be seen below:

The app’s information architecture is pretty straight forward (on paper). The first screen is the ‘landing screen’ and its purpose is to introduce the app to the user. This app is particularly suited to people who are ‘paying off’ their debt i.e. repaying their credit cards minimum payment on time each month (or some fixed amount) but not spending on that credit card. The app naturally is unable to take into account customers spend, fees etc. It’s aim is to give people an indicative idea of the impact paying £X vs. £Y per month, will have on their repayment time and the interest payable.

Next we have a series of screens that ask the user to provide 3 pieces of information: their credit card balance, APR and information about how their minimum payment is calculated.

Finally, I use this information display an interactive visualisation that tells users how long it will take to pay off their balance and how much interest they will pay (represented by a 360° solid ring) if they only pay their minimum. The ring then automatically transforms into an arc, which represents the time it would take to clear the credit card balance if the user paid their first min payment amount each and every month. It makes a staggering difference huh? The user can then increment the fixed monthly payment amount to see what impact that will have on repayment time and interest incurred.

The tool is relatively simple but for me it’s power lays in it’s ability to visually illustrate that a small change (paying a little bit more) can have a significant impact (clear credit card balance more quickly and incur less interest). People also like to work towards an end date i.e. if I can afford £X each month, when well I be debt free by? If I want to pay my credit card off in the next 3 years, what do I need to pay each month? Etc.

How Did I Develop This Solution?

OK, so let’s step through the implementation screen by screen.

Landing Screen

For the landing screen I used a framework called WhatsNewKit as recommended by a friend. The framework provides an easy to modify boilerplate “What’s New” screen, which I’ve used instead to introduce the app each time the user launches it.

I actually found the framework quite painful to use; installation was difficult, configuring button actions was tedious, customising properties i.e. alignment of screen text, simply didn’t work! Etc. The framework definitely looks great but it’s not a framework I’d readily use again or recommend to someone with my level of experience.

Capturing User Input

The next step was to capture the user input, which was surprisingly difficult! I experienced two challenges; validating the user input and formatting valid input correctly.

Validating User Input
Firstly, let’s take the APR input screen as an example. In order to validate user input we can use the UITextField’s delegate method textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String). This method is basically called each time a user changes the content of a UITextField. As a developer we get to know what UITextField was changed, the range of characters to be replaced and the replacement string for that range of characters. In the body of the delegate method we can decide whether we we reject the textfield input (return false) or accept it (return true).

In the above we check the user input is numeric, that the number of dots is less than or equal to 1 and the number of both decimal and integer digits is less than or equal to 2. If the input meets this criteria we could return true i.e. accept the input, however we instead all the updateAPRTextField() method as we need to add a % symbol, update the cursor position and check if we should enable the ‘next’ button:

Formatting User Input
In the above I do some formatting i.e. adding the % symbol and moving the cursor, however it’s not very clean code and it’s a lot of ‘fudging’.

Let’s take the balance input screen as an example of how to format user input in iOS. I needed to style the text field and keyboard the correct way i.e. the £ symbol is always left aligned, numbers are inputted right to left, a decimal point and comma insert themselves in the correct place etc.

This should be handled by subclassing UITextField and customising it for your own needs as. The solution to creating a UITextField that formats input as currency is shown in the code below. In honesty, a lot of the below came from scouring StackOverflow and it took me quite some time to understand what was going on. Don’t be afraid though, the below is complex and a lot of people, even on StackOverflow, weren’t super clear on UITextFields.

Minimum Repayment Calculation

OK, so we’ve captured valid user input and we now have what we need to calculate how long it will take the repay to clear the balance and the total amount of interest that will be paid. The code is as follows:

The code essentially does the following:

  • Casts all of the user inputs into Decimal type. Decimal is used over Double because it provides greater base 10 precision. Great article on this.
  • Create necessary variables and constants for performing calculation and storing return values.
  • While the balance remaining is greater than 0, calculate the minimum payment and what amount of this is interest.
  • Check if the minimum payment amount is greater than either a fixed amount given by the user or a percentage of balance only amount given by the user (sometimes minimum payments are just X% of the balance and don’t include interest).
  • Calculate the principal payment amount i.e. the minimum payment excluding interest. Deduct this from the remaining balance if it’s less than the remaining balance, else deduct the remaining balance.
  • Repeat steps 3–5 if the remaining balance is greater than 0.
  • Return the time it takes to pay off the credit card, the interest the user would pay and for each month return the min payment amount and remaining balance.

I also coded a fixed payment calculation so that users could compare a fixed amount each month against paying their minimum payment each month. As you could imagine, it’s similar to the above but much simpler.

Creating an Interactive Visualisation

I show the repayment time and cumulative interest visually as a ring using an awesome framework called UICircularProgressRing. I spent a long time trying to find a good framework fit for the task at hand and even tried to build my own visualisation from scratch (I’m still determined!), but this framework worked a charm and was super easy to use.

The first thing I do is initialise the progress rings properties i.e. maximum value, ring width, ring style etc. At this point, nothing is drawn on the screen, I’m simply defining the blue print.

The next thing is to set the progress rings initial value to be the maximum value i.e. the time it would take to pay the credit card balance if the user only pays their minimum. This is the max value as the app doesn’t allow the user to pay less than their minimum.

Finally, I set the ring to have a new value equivalent to the amount of time it would take the user to clear their debt if their payed their rounded up first minimum payment amount each month. The animation and ‘dot style’ effect is handle by the framework. The result is what I consider a very powerful visualisation which really brings to light what an impact paying a little more can have on a consumers repayment times.

OK, so let’s look at the Swift code behind this. Firstly, as mentioned, we define the properties of the progress ring object.

We then set the progress ring to be a full circle i.e. to equal the maximum value.

Finally, we have a method that updates the progress ring and information text each time the user enters a fixed amount or uses the ‘+’ or ‘-’ buttons to increment or decrement the repayment amount.

What Were The Challenges?

As I’m finding is the case with iOS, there’s a lot of things that you’d expect to be simple that are surprisingly difficult. The main thing though is that I’m learning! Even now, writing this blog, I’m looking at my code and realising how poorly written it is (the user input variables should really be properties of a ‘credit card debt’ object or something) but I think being a great coder is just a case of persistence and practice. So the tricky bits…

Arithmetic Precision

Humans count things using base 10; computers find it easier to count using base 2 (1 and 0). Integers translate from base 10 to base 2 just fine. The problem arises with fractions. Not every base 10 fraction can be represented accurately when using base 2.

Ok, so how does this manifest itself as a problem in programming. Well look at the following code:

The developer keeps a running tally. They add 0.01 (using Floats) in a loop 100 times, resulting in a sum of 1. However, the developer doesn’t get 1 due to the fact that they’re using a Float (binary type), which can’t accurately represent the value 0.01. We thus have a loss of precision.

NSDecimalNumber is a Swift Type that allows us to circumvent these precision issues, but is not as well documented and widely used as Float and Double.

Keyboard Handling

There’s two things stressful about keyboards in iOS: adjusting content relative to the keyboard and adding an accessory view if desired.

So showing a keyboard is simple, you basically just need to add a UITextField and when that field is touched the operating system automatically shows the keyboard (i.e. designates it as first responder). However, you need to think about adjusting your content if the keyboard obscures the UITextField from the use for example. To do this we need to register our UIViewController to the Notification Centre to receive certain notifications:

We then need to write to functions that handle the Notification object passed to them when a keyboard shows or hides. We can get the keyboard size from this Notification object and adjust the screens position accordingly (or the offset of a scrollview if using one):

A lot of this was new to me, hence why I found it challenging, specifically the #selector syntax, which in all honesty I’m still not completely comfortable with.

UITextField Delegate Methods

I battled for hours with performing input validation using UITextFields delegate methods. It’s likely that any time you take user input, you’ll want to perform client side validation to ensure that the user only enters valid input, but it can be quite complex.

I also foolishly tried to change the replacementString parameter of the delegate method (i.e. the users input). However, you can’t do… all you can do is return a Boolean value i.e. do you want to accept the users input or not. For hours I couldn’t figure our how to change the users input (to append a % symbol).

It was only after much Googling that I realise you can just call another method from within the UITextField’s delegate method and update the textfield with the tweaked user input from there (and only ever return false from UITextField’s delegate method).

What Were The Highlights?

The entire process of having an idea and watching it come to life is a highlight. There’s so many frustrating challenges you encounter when developing an app and as an equal amount of mini triumphs when you overcome them. The only part of the journey that’s bittersweet is that I wish I’d jumped into writing code earlier in my life and perhaps have pursued a career in it.

The icing on the cake however has been watching people actually take the app for a spin and be blown away by the relationship between what your repay and how quickly you clear your debt/the interest you incur. To see people benefit from your creations in the ways you intended is awesome.

Summary

There is a single intrinsic motivation behind why I’ve learned to develop iOS apps; quite simply I want to create technology that improves peoples lives and helps make life easier for people. It’s cheesy and perhaps naive, but it gives me purpose and there’s no better motivator than sense of purpose. This is the reason why all of my apps are free; it’s not about the money ❤️.

If you’re struggling with debt, please seek help and don’t bear the burden alone:

Step Change: 0800 138 1111

National Debt Line: 0808 808 4000

The Money Charity: 020 7062 8933

--

--