An Income Tax program in Python
<p>I have been trying to solve a coding lab exercise but I keep getting errors in my program. Kindly help look at this code and tell me what's wrong with it.</p>

<p><strong>Question:</strong></p>

<blockquote>
  <p>Country X calculates tax for its citizens using a graduated scale rate as shown below:</p>
  
  <p>Yearly Income: 0 - 1000</p>
  
  <p>Tax Rate: 0%</p>
  
  <p>Yearly Income: 1,001 - 10,000</p>
  
  <p>Tax Rate: 10%</p>
  
  <p>Yearly Income: 10,001 - 20,200</p>
  
  <p>Tax Rate: 15%</p>
  
  <p>Yearly Income: 20,201 - 30,750</p>
  
  <p>Tax Rate: 20%</p>
  
  <p>Yearly Income: 30,751 - 50,000</p>
  
  <p>Tax Rate: 25%</p>
  
  <p>Yearly Income: Over 50,000</p>
  
  <p>Tax Rate: 30%</p>
  
  <p>Write a Python function named calculate_tax that will take as an
  argument, a dictionary containing key-value pairs of people's names as
  the keys and their yearly incomes as the values.</p>
  
  <p>The function should return a dictionary containing key-value pairs of
  the same peopleâs names as keys and their yearly tax bill as the
  values. For example, given the sample input below:</p>

<pre><code>    {
        âAlexâ: 500,
        âJamesâ: 20500,
        âKinuthiaâ: 70000
    } The output would be as follows:

    {
        âAlexâ: 0,
        âJamesâ: 2490,
        âKinuthiaâ: 15352.5
    }
</code></pre>
  
  <p>The tax for James would be calculated as follows:</p>
  
  <p>The first 1000 (1000 - 0)</p>
  
  <p>Calculation: 1,000 * 0%</p>
  
  <p>Tax: 0</p>
  
  <p>The next 9000 (10,000 - 1,000)</p>
  
  <p>Calculation: 9,000 * 10%</p>
  
  <p>Tax: 900</p>
  
  <p>The next 10,200 (20,200 -10,000)</p>
  
  <p>Calculation: 10,200 * 15%</p>
  
  <p>Tax: 1530</p>
  
  <p>The remaining 300 (20,500 - 20,200)</p>
  
  <p>Calculation: 300 * 20%</p>
  
  <p>Tax: 60</p>
  
  <p>Total Income: 20,500</p>
  
  <p>Total Tax: 0 + 900 + 1530 + 60 = 2490</p>
</blockquote>

<p><strong>My Code</strong></p>

<pre class="lang-py prettyprint-override"><code>income_input = {}

for key in income_input.keys():
    income_input[key] = income

def calculate_tax(income_input):

    if (income &gt;= 0) and (income &lt;= 1000):
        tax = (0*income)

    elif (income &gt; 1000) and (income &lt;= 10000):
        tax = (0.1 * (income-1000))

    elif (income &gt; 10000) and (income &lt;= 20200):
        tax = ((0.1*(10000-1000)) + (0.15*(income-10000)))

     elif (income &gt; 20200) and (income &lt;= 30750):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(income-20200)))

    elif (income &gt; 30750) and (income &lt;= 50000):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(30750-20200)) + (0.25*(income-30750)))

    elif (income &gt; 50000):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(30750-20200)) + (0.25*(50000-30750)) + (0.3*(income-50000)))   
    else:
        pass

    for key in income_input.keys():
        income_input[key] = tax

    return tax
</code></pre>

<p><strong>Test</strong></p>

<pre class="lang-py prettyprint-override"><code>from unittest import TestCase

class CalculateTaxTests(TestCase):
  def test_it_calculates_tax_for_one_person(self):
    result = calculate_tax({"James": 20500})
    self.assertEqual(result, {"James": 2490.0}, msg="Should return {'James': 2490.0} for the input {'James': 20500}")

  def test_it_calculates_tax_for_several_people(self):
    income_input = {"James": 20500, "Mary": 500, "Evan": 70000}
    result = calculate_tax(income_input)
    self.assertEqual({"James": 2490.0, "Mary": 0, "Evan": 15352.5}, result,
      msg="Should return {} for the input {}".format(
            {"James": 2490.0, "Mary": 0, "Evan": 15352.5},
            {"James": 20500, "Mary": 500, "Evan": 70000}
      )
    )

  def test_it_does_not_accept_integers(self):
    with self.assertRaises(ValueError) as context:
      calculate_tax(1)
      self.assertEqual(
        "The provided input is not a dictionary.",
        context.exception.message, "Invalid input of type int not allowed"
      )

  def test_calculated_tax_is_a_float(self):
    result = calculate_tax({"Jane": 20500})
    self.assertIsInstance(
      calculate_tax({"Jane": 20500}), dict, msg="Should return a result of data type dict")
    self.assertIsInstance(result["Jane"], float, msg="Tax returned should be an float.")

  def test_it_returns_zero_tax_for_income_less_than_1000(self):
    result = calculate_tax({"Jake": 100})
    self.assertEqual(result, {"Jake": 0}, msg="Should return zero tax for incomes less than 1000")

  def test_it_throws_an_error_if_any_of_the_inputs_is_non_numeric(self):
    with self.assertRaises(ValueError, msg='Allow only numeric input'):
      calculate_tax({"James": 2490.0, "Kiura": '200', "Kinuthia": 15352.5})

  def test_it_return_an_empty_dict_for_an_empty_dict_input(self):
    result = calculate_tax({})
    self.assertEqual(result, {}, msg='Should return an empty dict if the input was an empty dict')
</code></pre>

<p><strong>Output after running code</strong></p>

<pre><code>THERE IS AN ERROR/BUG IN YOUR CODE
Results: 
Internal Error: runTests aborted: TestOutcomeEvent(handled=False, test=, result=, outcome='error', exc_info=(, NameError("global name 'income' is not defined",), ), reason=None, expected=False, shortLabel=None, longLabel=None) is not JSON serializable
</code></pre>

<p><strong>Updated Code</strong></p>

<pre><code>    income_input = {}

  def calculate_tax(income_input):
    for key in income_input.items():
         tax = 0

    if (income_input[key]&gt;= 0) and (income_input[key]&lt;= 1000):
        tax = (0*income_input[key])

    elif (income_input[key]&gt; 1000) and (income_input[key]&lt;= 10000):
        tax = (0.1 * (income_input[key]-1000))

    elif (income_input[key]&gt; 10000) and (income_input[key]&lt;= 20200):
        tax = ((0.1*(10000-1000)) + (0.15*(income_input[key]-10000)))

    elif (income_input[key]&gt; 20200) and (income_input[key]&lt;= 30750):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(income_input[key]-20200)))

    elif (income_input[key]&gt; 30750) and (income_input[key]&lt;= 50000):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(30750-20200)) + (0.25*(income_input[key]-30750)))

    elif (income_input[key]&gt; 50000):
        tax = ((0.1*(10000-1000)) + (0.15*(20200-10000)) + (0.2*(30750-20200)) + (0.25*(50000-30750)) + (0.3*(income_input[key]-50000)))

    else:
        pass
income_input[key] = tax

return income_input
</code></pre>

<p><strong>New Error Message</strong></p>

<pre><code>    THERE IS AN ERROR/BUG IN YOUR CODE
    Results: 
    Internal Error: runTests aborted: TestOutcomeEvent(handled=False, test=, result=, outcome='error', exc_info=(, KeyError(('Jane', 20500),), ), reason=None, expected=False, shortLabel=None, longLabel=None) is not JSON serializable
</code></pre>

<p>Don't know how to eliminate the <code>KeyError</code> error.</p>

<p>my own code which is very much correct and the fastest way to write this function is by recursively calculating total tax per person
here is what i get below
Internal Error: runTests aborted: TestOutcomeEvent(handled=False, test=, result=, outcome='error', exc_info=(, AttributeError("'_AssertRaisesContext' object has no attribute 'exception'",), ), reason=None, expected=False, shortLabel=None, longLabel=None) is not JSON serializable</p>

<p>then it clicked i went to the tests and raised value error for test values that fail and voila it clicked</p>

python