Write a function to calculate compound tax using the following table:

For $10 and under, the tax rate should be 10%.
For $20 and under, the tax rate on the first $10 is %10, and the tax on the rest is 7%.
For $30 and under, the tax rate on the first $10 is still %10, the rate for the next $10 is still 7%, and everything else is 5%.
Tack on an additional 3% for the portion of the total above $30.
Return 0 for invalid input(anything that's not a positive real number).


Examples:

An input of 10, should return 1 (1 is 10% of 10)
An input of 21, should return 1.75 (10% of 10 + 7% of 10 + 5% of 1)

* Note that the returned value should be rounded to the nearest penny.

Difficulty: EASY
Tags: Fundamentals

Starter code:
def tax_calculator(total):
	

Solutions:
def tax_calculator(total):
	if not isinstance(total, (int, float)) or total < 0:
		return 0
	tax = 0
	if total > 30:
		tax = 2.2 + (total - 30) * 0.03
	elif total > 20:
		tax = 1.7 + (total - 20) * 0.05
	elif total > 10:
		tax = 1 + (total - 10) * 0.07
	elif total > 0:
		tax = total / 10.0
	return round(tax, 2)


def tax_calculator(total):
	tax = 0
	if type(total) in (float, int) and total > 0:
		for (limit, rate) in ((30, 3), (20, 5), (10, 7), (0, 10)):
			if total > limit:
				tax += rate * (total - limit)
				total = limit
	return round(tax) / 100


rates = ((30, 0.03), (20, 0.05), (10, 0.07), (0, 0.1))

def tax_calculator(total):
	if type(total) in (int, float) and total > 0:
		amount = 0
		for (limit, rate) in rates:
			if total > limit:
				amount += (total - limit) * rate
				total = limit
		return round(amount, 2)
	return 0


def tax_calculator(total):
	if not isinstance(total, (int, float)) or total <= 0:
		return 0
	bands = [(10, 0.1), (10, 0.07), (10, 0.05), (None, 0.03)]
	residue = total
	tax = 0
	for (band_width, rate) in bands:
		if residue == 0:
			break
		if band_width is not None:
			chunk = residue if residue <= band_width else band_width
		else:
			chunk = residue
		tax += chunk * rate
		residue -= chunk
	return round(tax, 2)


def tax_calculator(total):
	try:
		total = max(float(total), 0)
	except (AttributeError, TypeError, ValueError):
		total = 0
	tax = 0
	for (rate, limit) in [(0.1, 10), (0.07, 10), (0.05, 10), (0.03, 99999999999999)]:
		tax += min(total, limit) * rate
		total -= limit
		if total <= 0:
			break
	return round(tax, 2)


from numbers import Real

class TaxCalculator(object):

	def __init__(self, bands, highest_rate):
		self.__table = list(self._get_table(bands, highest_rate))

	@staticmethod
	def _get_table(bands, highest_rate):
		(lower_bound, cumulative_tax) = (0.0, 0.0)
		for (upper_bound, rate) in bands:
			yield (lower_bound, rate, cumulative_tax)
			cumulative_tax += (upper_bound - lower_bound) * rate
			lower_bound = upper_bound
		yield (lower_bound, highest_rate, cumulative_tax)

	def __call__(self, amount):
		if isinstance(amount, Real):
			for (lower_bound, rate, cumulative_tax) in reversed(self.__table):
				if amount >= lower_bound:
					return round((amount - lower_bound) * rate + cumulative_tax, 2)
		return 0.0
tax_calculator = TaxCalculator([(10.0, 0.1), (20.0, 0.07), (30.0, 0.05)], 0.03)


def tax_calculator(total):
	if type(total) not in [int, float] or total < 0:
		return 0
	if total <= 10:
		tax = 0.1 * total
	elif total <= 20:
		tax = 1 + 0.07 * (total - 10)
	else:
		tax = 1.7 + 0.05 * min(total - 20, 10)
		if total > 30:
			tax += 0.03 * (total - 30)
	return round(tax, 2)


def tax_calculator(t):
	return isinstance(t, (float, int)) and round(max(0, t) * 0.1 - max(0, t - 10) * 0.03 - max(0, t - 20) * 0.02 - max(0, t - 30) * 0.02, 2)


tax_calculator = lambda total: round((total - 30) * 0.03 + 2.2 if total - 30 > 0 else (total - 20) * 0.05 + 1.7 if total - 20 > 0 else (total - 10) * 0.07 + 1 if total - 10 > 0 else total * 0.1, 2) if (type(total) == int or type(total) == float) and total > 0 else 0