Created
September 6, 2012 23:09
-
-
Save kieranajp/3661124 to your computer and use it in GitHub Desktop.
Employment Income Tax Calculator in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Author
kieranajp
commented
Sep 6, 2012
- I don't know anything about tax codes but I'm pretty sure if I did I could optimise the parser
- ascii_only? should work but I haven't bothered to upgrade to ruby 1.9
- Needs validation.
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