I'm a beginner coding in python. I really don't understand what this error refers to. Any help will be greatly appreciated. the code is supposed to calculate the taxes of people in a certain country as follows: Yearly Income: 0 - 1000
Tax Rate: 0%
Yearly Income: 1,001 - 10,000
Tax Rate: 10%
Yearly Income: 10,001 - 20,200
Tax Rate: 15%
Yearly Income: 20,201 - 30,750
Tax Rate: 20%
Yearly Income: 30,751 - 50,000
Tax Rate: 25%
Yearly Income: Over 50,000
Tax Rate: 30%
my code:
def calculate_tax(pDict):
if type(pDict) is dict:
try:
length = len(pDict)
count = 0
#decleration of new updated dictionary
dict_list = {}
while count<length:
#calculate yearly tax
#countdown of values in the dictionary until the last value
totals = list(pDict.values())[count]
totals = int(totals)
names = list(pDict.keys())[count]
#decleration of variable to store tax
tTax = 0
if totals < 1000:
tTax = totals * 0
elif totals > 1000 and totals<= 10000:
tTax = 1000 * 0
totals = totals - 1000
tTax = tTax + totals * 0.1
elif totals > 10000 and totals <=20200:
tTax = 1000 * 0
tTax = tTax + 9000 * 0.1
totals=totals-10000
tTax = tTax + totals * 0.15
elif totals >20200 and totals <= 30750:
tTax = 1000 * 0
tTax = tTax + 9000 * 0.1
tTax = tTax + 10200 * 0.15
totals=totals-20200
tTax = tTax + totals * 0.2
elif totals>30750 and totals<=50000:
tTax = 1000 * 0
tTax = tTax + 9000 * 0.1
tTax = tTax + 10200 * 0.15
tTax = tTax + 10550 * 0.2
totals=totals-30750
tTax = tTax + totals * 0.25
else:
tTax = 1000 * 0
tTax = tTax + 9000 * 0.1
tTax = tTax + 10200 * 0.15
tTax = tTax + 10550 * 0.2
tTax = tTax + 19250 * 0.25
totals=totals-50000
tTax = tTax + totals * 0.3
dict_list.setdefault(names,tTax)
count = count + 1
return dict_list
except(attributeError,TypeError):
raise ValueError('The provided input is not a dictionary')
else:
print("only dict type values allowed")
the code used to test if my code works:
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')
Please help:-)
For reference, the complete exception message from the failing test is as follows:
ERROR: test_it_does_not_accept_integers (__main__.CalculateTaxTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "calculate_tax_test.py", line 27, in test_it_does_not_accept_integers
context.exception.message, "Invalid input of type int not allowed"
AttributeError: '_AssertRaisesContext' object has no attribute 'exception'
The failing test is this:
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"
)
The problem is that the assertion after calculate_tax is in the wrong place. If an exception is raised in calculate_tax, the assertion will be skipped. If no exception is raised, the assertion will fail. The assertion will therefore never pass.
The fix is to un-indent the assertion to move it out of the with statement. For clarity I've also inserted a blank line:
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"
)
The with self.assertRaises(...) statement can catch an exception if one gets raised by the call to calculate_tax. If this happens, the exception detail is then left in context, and your assertion would then be able to test whether the exception was as you expected.
However, even after making this change, the test still fails, because calculate_tax(1) doesn't raise a ValueError. I'll leave it up to you to fix this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With