OOP in R, Simulating a simple banking system.

OOP in R, Simulating a simple banking system.

Introduction

Object-Oriented Programming has been the best way to write programs in any language. But why the OOP technique? As a matter of fact, our physical world is made up of objects with different qualities.OOP is based on the concept of “object” which can contain data or code.

A good example can be an animal object with several properties like movement, sound, diet, life span, etc. We can also talk about a “bank object”, which I will be considering in this post, with properties like customers, accounts, and methods like accounts creation, loan repayments, etc.

Why OOP in R.

Well, personally I began my R journey with simple procedural-oriented programming then I graduates with functional programming. It's only after being exposed to the goodies that come with structuring my scripts in an Object-Oriented Way using python. R offers more than one method of writing Object-Oriented programs such as S3, S4, R6, etc. In this post, I will focus on using R6 Classes offered by the R6 package. This is because it gives an almost similar method Python uses. If you are not good with python, you have nothing to worry about, all you need to know is how to write an R function and simple operations.

Much about OOP can be found here.

Some key concepts we are going to learn here are:

  1. Classes Definition
  2. Class instances
  3. Methods:
  • Public methods
  • Private methods

4. Introspection

Hypothetical example.

In this post,I will go through a simple banking system that enables us to:

1. Create accounts

2. Make deposits

3. Make withdrawals

4. Request and pay loans.

5. Simulate a simple USSD request in the console.

Excited? Let's proceed.

Required packages.

We will only need two packages for this project, namely,tidyverse and R6.

Install these packages if you don have them already in your current R installation.\

No alt text provided for this image


Defining Classes

The focal point of OOP is a class that is used to create objects. A class is the blueprint of an object. It literally describes what an object will be but separate from the object itself. The same class can be used for creating multiple objects.

R6 Classes are created using the keyword R6Class.It contains functions called methods. The methods specify the behavior and actions that an object created with the same class can perform using its specif data.

It's important to take note of the two most important arguments of the class:

  1. classname : Defines the class name. Not required for the class to work through, but as described in the package documentation, it's useful for S3 method dispatch.
  2. public: A list of public members, which can be functions (methods) and non-functions (fields).

Below is a simple way to create a class in R6. First, let's call our class CBS-short for the core banking system.

No alt text provided for this image

In the above class, I have defined a class CBS with a method initialize(). For someone coming from python, you can think of this as the __init__ method. It is called when an instance of the object class is created using the class name as the function. In this method, the self$attribute can be used to set the initial value of an instance’s attributes.

Class instantiation.

Instances are objects built from classes that contain real data and objects. To instantiate an object of the class above we use, $new() the method as shown below. Let's call our bank ABCBank

No alt text provided for this image


Methods and class attributes.

Classes have other methods defined to add functionality to them. These methods are basically functions.

Class attributes on the other hand are created by assigning variables within the body of the class, eg ‘bank_name’ and ‘accs’ in the above example. They are accessible within the class. To access these attributes you will use the self$attribute parameter as explained above.

To build our core banking system, we will need some methods to offer functionality. At this point, you will need the knowledge of R functions.

Tl;dr

Account Creation method.

A client will need his/her First Name, Second Name, and National ID Number for this.

No alt text provided for this image

The above function simply creates a table data frame of the newly created account and adds it to the existing accounts. Other properties like private$ included will be explained below.

Deposit Method

In order for our clients to make deposits, we will require their loan accounts and amount to be deposited as shown in the function below.

No alt text provided for this image


You can notice that a message is sent to the client after making the deposit.

Withdrawal method

No alt text provided for this image


Quick overview of what's going on here: In order for a withdrawal to be successful, the correct account is supplied plus an amount that wont leave the account with less than Ksh 100.

Account Balance

To check the account balance we need just the account number the following is just a simple filter method from all the accounts.

No alt text provided for this image


Loan Request Method

All this method does is simply to check if the supplied account number is accurate, check if the client has an existing loan to avoid multiple loan disbursements.

Notice that to access the client database you need the self$accs which has the list of all clients.

No alt text provided for this image

Loan Repayment

Same as the above, we only need the account number and amount to be repaid. If the amount is more than the balance, the extra amount is added to the transnational account balance.

If the client tries to repay a loan which inst existing,the program shuts and the transaction is canceled.

Nice, right?

No alt text provided for this image

Checking Loan Balance

Works same as Account balance check.

No alt text provided for this image

Simulating USSD in the console method

You would like the access all these methods with a single call of this class. We will access all the methods in the class using the self$method parameter.

For efficiency purposes, a new client who has just registered is taken to the menu straight away.

No alt text provided for this image


Controlling access to methods.

R6 classes have two main ways of controlling access. These are part of the class arguments but are not

  1. private : An optional list of private members, which can be functions and non-functions.To access these methods, we use the private$method or private$attribute parameters.

In our models, we can see that we called private$check_acc and private$account_setup methods.Let's explain what they do down here.

Private Methods: account_setup

This function generates new account numbers and checks if it is similar to any account previously generated. If this is true it generates again until a unique one is made. This ensures that the generated account number is unique. The function also checks if a client tries to register twice with the same National ID Number. If so, the client is prompted to enter a new one.

No alt text provided for this image


Private Methods: check_acc

For any transaction, we will need an account number. It is therefore important to check the validity of the account entered using one single function defined in the private method as shown.

No alt text provided for this image


Final Program

All the way up to this point below is the all the methods and attribute combined in the class.

No alt text provided for this image


Let's instantiate again.

ABCBank <- CBS$new(bank_name = "ABC Bank")

##  --------- 
##  This is  ABC Bank . 
##  ---------

Introspection

We can always inspect our classes using the class function and use names function to get a list of all methods contained in a class as shown below from an instantiation.

class(ABCBank)

## [1] "CBS" "R6"

We can see it shows that our instance is from the CBS class and it inherits from the R6 class.

names(ABCBank)

##  [1] ".__enclos_env__"    "bank_name"          "accs"              
##  [4] "clone"              "get_services"       "check_loan_balance"
##  [7] "repay_loan"         "request_loan"       "check_balance"     
## [10] "make_withdrawal"    "make_deposit"       "create_account"    
## [13] "initialize"

All the methods discussed above are listed here.

Let's see a simple example of our system.

To use this system interactively, run the class above, instantiate then call get_services method.

ABCBank$get_services()

## Welcome to ABC Banking Services!
## Select
## 1:Create new account
## 2:Deposit
## 3:Withdraw
## 4:Request Loan
## 5:Repay Loan
## 6:My Account Balance
## 7:My Loan Balance
Enter here:

Finally.

It's important to note that when defining a method in a class you do not use <- sign for an assignment but the standard = sign.

I will write about class inheritance and other OOP concepts in R in my next blog. You are free to copy this script and play with it on your R studio console.

Since I got the gist of OOP in R, my programming quality in R has really improved. You can give it a shot too .:)

Let me know if you found this interesting or if you found a bug.

You can find a clean script here.

Best

To view or add a comment, sign in

More articles by George Oduor

Others also viewed

Explore content categories