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: introductory

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.10), (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)*.1-max(0,t-10)*.03-max(0,t-20)*.02-max(0,t-30)*.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