Skip to content

Instantly share code, notes, and snippets.

@kieranajp
Created September 6, 2012 23:09
Show Gist options
  • Save kieranajp/3661124 to your computer and use it in GitHub Desktop.
Save kieranajp/3661124 to your computer and use it in GitHub Desktop.
Employment Income Tax Calculator in Ruby
class Tax
attr_accessor :threshold
def initialize(threshold)
# There's probably a better way of doing default values
@threshold = threshold.to_i || 7592
end
def parseTaxCode(taxCode)
# Try this bit in ruby 1.9
=begin
unless taxCode.ascii_only?
return false
end
=end
firstChar = taxCode[0,1]
secondChar = taxCode[1,1]
lastChar = taxCode[-1,1]
length = taxCode.length - 1
# All these type casts are going to be expensive, there must be a better way of doing this
# but I'm not sure I fully understand the logic.
case firstChar
when 'K'
code = taxCode[1..8].to_i + 1
code = code.to_s + '0'
code = code.to_i * -1
when 'B'
code = 0
when 'D'
code = secondChar === '0' ? 'D0' : 'D1'
else
code = taxCode[0,length]
code = code.to_s + '0'
code = code.to_i
end
end
def taxCalc (annualIncome, code)
nicable = annualIncome - @threshold
if nicable <= 0
nic = 0
elsif nicable <= 34892
nic = nicable * 0.12
elsif nicable > 34892
nic = (nicable - 34892) * 0.02 + 4187.04;
end
# Better would be if code is *parseable to* an integer. (`if !!code.to_i` ?)
if code.is_a? Integer
taxable = annualIncome - code.to_i
if taxable <= 0
tax = 0
elsif taxable <= 34370
tax = taxable * 0.2
elsif taxable <= 150000
tax = (taxable - 34370)*0.4 + 6874
elsif taxable > 150000
tax = (taxable - 150000)*0.5 + 53126;
end
elsif code == 'D0'
tax = annualIncome * 0.4
elsif code == 'D1'
tax = annualIncome * 0.5
end
deductions = tax + nic
net = annualIncome - deductions
=begin
# This is for ruby < 1.9
puts (net/12).round() / 100.0
puts (tax/12).round() / 100.0
puts (nic/12).round() / 100.0
=end
netmonthly = (net/12).round(2).to_s
taxmonthly = (tax/12).round(2).to_s
nicmonthly = (nic/12).round(2).to_s
# String interpolation is always going to be more performant than concatenation.
# Even if Ruby's strings are mutable (which I don't know, but would assume so)
'Your monthly income will be #{netmonthly} and you will have paid #{taxmonthly} in tax and #{nicmonthly} in NI.'
end
def run()
puts 'Hi there, welcome to my Income Tax Calculator, built in Ruby\n'
puts "What is your annual income?"
# Is Ruby strongly-typed or what? This language makes no sense :p
income = gets.chomp.to_i
puts "What is your tax code?"
taxCode = gets.chomp
taxCalc(income, parseTaxCode(taxCode.upcase))
end
end
# If the constructor value were editable, theoretically the program could be
# kept up-to-date every year automatically. Unless tax works even more weirdly
# than I suspect.
tax = Tax.new(7592)
puts tax.run()
@kieranajp
Copy link
Author

  1. I don't know anything about tax codes but I'm pretty sure if I did I could optimise the parser
  2. ascii_only? should work but I haven't bothered to upgrade to ruby 1.9
  3. Needs validation.

@kieranajp
Copy link
Author

See also: methods & return values (http://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html) - Ruby does implicit returns but the principle is the same, it's just less obvious what you're returning. (Hence: ruby is a bad language to learn :P)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment