If you’re anything like the dozens of ambitious programmers I coach at DYR Hackcamp and Hackchella, there’s a good chance you want to achieve these career goals…

  • Start freelance-consulting and get paid for your skills and knowledge
  • Get a full-time Ruby and Rails developer position, locally or remotely
  • Build a micro SaaS app or niche website that could generate enough income to replace your current salary and give you both time and location freedom

Yet, it’s taking you longer than you expect – more than one year – to achieve any one of these goals so that you can finally call yourself a professional Ruby developer.

You don’t have the confidence you desperately need to sell yourself to potential clients and employers so that you can get paid to use your skills.

You don’t believe in your own capabilities to build a Ruby application from scratch, without following another step-by-step tutorial that’s outdated.

You don’t have clarity about what your next steps are and whether you’re good enough to start looking for a full-time Ruby developer position, freelance-consulting clients or even build your own niche site or micro SaaS product.

So let’s remove every single doubt you have about your Ruby programming skills and knowledge with this advanced training. Once you learn how to Build Well-Tested Ruby Programs From Scratch, you should be able to…

  • Understand and use Ruby language constructs
  • Use proper Ruby programming idioms
  • Write Object-Oriented Ruby programs
  • Understand and apply Object-Oriented Design principles
  • Organize your Ruby code for reuse and distribution
  • Provide Input/Output support for your apps
  • Write and run automated unit tests with RSpec

Are you ready to gain more confidence as a programmer who can solve expensive business problems with Ruby without constant hand-holding?

Let’s get started, ambitious programmer…

Context – Building an Automated Teller Machine

The CEO at StartupYou wants to enter the microfinance market.

Her team has found that providing zero-interest loans to villagers to start a small business is not enough to reduce poverty.

The villagers also need a secure place to stash their cash, instead of hiding it under their beds or holes in the bush, where it could easily be stolen.

But here’s the problem…

It’ll cost too much to setup the same kind of global banking infrastructure found in developed countries, so StartupYou’s solution is to find trusted elders who’d become stewards of a community bank and administer the microfinance services in their village.

These stewards will be given the tools and training they need to provide basic financial services to every entrepreneur who receives a zero-interest microloan from StartupYou.

The most important tool the stewards will need to perform their duties is a ledger for keeping a permanent record of every financial transaction.

Instead of using a paper ledger, StartupYou has decided to build a Ruby program that works on Windows, Linux and MacOS computers.

The Ruby program should work even in remote locations where internet access is limited, once it’s downloaded and installed on a computer.

As the CTO at StartupYou, your assignment is to design and build a Ruby program that automates the steward’s workflow.

The first 4 videos here explain the financial system you’re going to model with your Ruby program so that StartupYou can deliver their services to clients efficiently.

Business Goals

Your primary business goal is to reduce time to market for StartupYou so that they can start providing their financial services in multiple villages without a huge upfront investment in a full-blown banking infrastructure.

Your secondary business goal is free up the steward’s time as they deliver the financial services to their community on behalf of StartupYou.

Usage Scenario

Here’s how a steward would use your Ruby program to keep records of every financial transaction, once they download all the Ruby files required and install the current version of Ruby programming language.

(A file for executing your Ruby program)
#bank_manager.rb
require_relative 'lib/bank'
require_relative 'lib/account'

bank_one = Bank.new('Bank of RubyVillage')
puts "Welcome to #{ bank_one.name }."

puts ""

#accounts
keynes = Account.new('Keynes','RV001A','42018')
bank_one.open_an_account(keynes)
smith = Account.new('Smith','RV001B', '42018')
bank_one.open_an_account(smith)

#transactions
bank_one.deposit(smith, 200.00)
bank_one.deposit(keynes, 100.00)

bank_one.withdraw(smith, 50.25)
bank_one.withdraw(keynes, 30.50)

#Quick Check
puts "There are #{ bank_one.accounts.count} accounts"
puts "Current liabilities are #{ bank_one.liability }"
puts "Current assets are #{ bank_one.assets }"

puts ""
(Executing your Ruby program in Terminal)
$ cd ./atm-ruby-master
$ ruby bank_manager.rb
Welcome to Bank of RubyVillage.

There are 2 accounts
Current liabilities are 219.25
Current assets are 1000.0

RSpec Test Cases

I’d like to give you a hand-up because you’re a valuable member of the Kingmakers community. Use the RSpec test cases below so that you can get started today, accelerate your product development and release your Ruby program in record time.

You’ll know you’ve built a strong foundation in Ruby programming and that you’ve achieved your goals for this project once all of the tests pass.

(RSpec test cases for Bank Class)
#bank_spec.rb

require_relative '../lib/bank'
require_relative '../lib/account'

describe Bank, '#initialize' do
  before do
    name = 'Bank of RubyVillage'
    assets = 1000.0

    @bank = Bank.new(name, assets)
  end

  it "has a name" do
    expect(@bank.name).to eql('Bank of RubyVillage')
  end

  it "has initial assets" do
    expect(@bank.assets).to eql(1000.00)
  end

  it "has no accounts" do
    expect(@bank.accounts.size).to eql(0)
  end

  it "does not have a liability" do
    expect(@bank.liability).to eql(0.0)
  end
end 

describe Bank, '#open_an_account' do
  it "creates an additional account" do
    bank = Bank.new('BoRV')
    account = Account.new('Peter','RV001A','42018')
    bank.open_an_account(account)
    expect(bank.accounts.count).to eql(1)
  end
end

describe Bank, '#deposit' do
  before do
    @bank = Bank.new('BoRV')
    @account = Account.new('Peter','RV001A','42018') 
    @bank.open_an_account(@account)
    @bank.deposit(@account, 100.00)
  end

  it "increases the bank's liability" do
    expect(@bank.liability).to eql(100.00)
  end

  it "credits the account holder" do
   expect(@account.balance).to eql(100.00)
  end
end
describe Bank, '#withdraw' do
  before do
    @bank = Bank.new('BoRV')
    @account = Account.new('Peter','RV001A','42018')
    @bank.open_an_account(@account)
    @bank.deposit(@account, 100.00)
  end

context "with sufficient funds" do
    it "debits the account holder" do
      @bank.withdraw(@account, 50.00)
      expect(@account.balance).to eql(50.00)
    end

    it "decreases the bank's liability" do
      @bank.withdraw(@account, 50.00)
      expect(@bank.liability).to eql(50.00)
    end
  end

context "without sufficient funds" do
    it "doesn't decrease the bank's liability" do
      @bank.withdraw(@account, 200.00)
      expect(@bank.liability).to eql(100.00)
    end

    it "doesn't debit the account holder" do
      @bank.withdraw(@account, 200.00)
      expect(@account.balance).to eql(100.00)
    end
  end
end
(RSpec test cases for Account Class)
#account_spec.rb

require_relative '../lib/account'

describe Account, '#initialize' do
  before do
    name = 'Mozzie'
    address = 'RV001A'
    pin = '4343'

    @account = Account.new(name, address, pin)
  end

    it "has the holder's name" do
      expect(@account.holder_name).to eql('Mozzie')
    end

    it "has the owner's address" do
      expect(@account.address).to eql('RV001A')
    end

    it "has pin number" do
      expect(@account.pin).to eql('4343')
    end

    it "has an account number" do
      expect(@account.account_number).to
         eql(@account.object_id.to_s)
    end
    
  it "has 0 balance" do
      expect(@account.balance).to eql(0.0)
    end

  context "creating another accounts" do
    it "has a unique account_number" do
      account_2 = Account.new('Smith', 'RV001B', '3454')
      expect(account_2.account_number).to_not
         eql(@account.account_number)
    end
  end
end

Libraries and Tools

To get started, you must setup a your development environment.

To setup your development environment for Mac OS, follow these instructions.

To setup your development environment for Linux, follow these instructions.

And to setup your development environment for Windows, I’d encourage you to do a parallel installation of Linux; then setup a Linux development environment.

If you need a quick refresher, check out this video tutorial on Ruby programming.

Your Ideal Next Step

You’ll know it’s time to move to the next step in your Ruby and Rails development career – create an open source Ruby package – once all of the RSpec test cases I’ve included in this project brief are passing.

You’ll finally confirm that you’re familiar with the core features of the Ruby programming language and that you can apply them when writing your next Ruby application.

If you really want to ReProfit from your hard work quickly, publish a blog post that walks readers through your implementation of this program…

…and share a link to your blog post in the comments section below.