← All coding practice

Coding Practice · Beginner · October 15, 2026 · 9 min read

Python Coding Exercise #42: Gift Tax Calculator

Part of the series Python Practice Exercise — part 42

Before you start: Know input() and int() · Know if, elif and else · Know comparison operators

The question

Some say paying taxes makes Finns happy, so let’s see if the secret of happiness lies in one of the taxes set out in Finnish tax code.

According to the Finnish Tax Administration, a gift is a transfer of property to another person against no compensation or payment. If the total value of the gifts you receive from the same donor in the course of 3 years is €5,000 or more, you must pay gift tax.

When the gift is received from a close relative or a family member, the amount of tax to be paid is determined by the following table:

Value of giftTax at the lower limitTax rate for the exceeding part (%)
5 000 — 25 0001008
25 000 — 55 0001 70010
55 000 — 200 0004 70012
200 000 — 1 000 00022 10015
1 000 000 —142 10017

So, for a gift of 6 000 euros the recipient pays a tax of 180 euros (100 + (6 000 - 5 000) * 0.08). Similarly, for a gift of 75 000 euros the recipient pays a tax of 7 100 euros (4 700 + (75 000 - 55 000) * 0.12).

Please write a program which calculates the correct amount of tax for a gift from a close relative. Have a look at the examples below to see what is expected. Notice the lack of thousands separators in the input values: you may assume there will be no spaces or other thousands separators in the numbers in the input, as we haven’t yet covered dealing with these.

Value of gift: 3500
No tax!
Value of gift: 5000
Amount of tax: 100.0 euros
Value of gift: 27500
Amount of tax: 1950.0 euros

Before coding: make a reference table

This question is tricky because it has multiple ranges to take care of. When I have to consider both a lower and an upper limit, it helps me to create a simpler table for reference before writing any code. This is the table I made:

Gift valueBase taxRate
Below €5,000No tax—
€5,000 to below €25,000€1008%
€25,000 to below €55,000€1,70010%
€55,000 to below €200,000€4,70012%
€200,000 to below €1,000,000€22,10015%
€1,000,000 and above€142,10017%

Writing “to below” in each row makes it clear which end of each range is included: the lower limit belongs to the range, and the upper limit belongs to the next one. The table also shows that every row follows the same pattern, so each bracket uses the same formula:

tax = base tax + (gift value - lower limit) * rate

The base tax is the amount owed at the lower limit, and the rate applies only to the part of the gift that is above that limit. For a gift of 6,000 euros, the bracket starts at 5,000, so the tax is 100 + (6000 - 5000) * 0.08 = 180.

My Solution

gift_value = int(input("Value of gift: "))
if gift_value < 5000:
    print("No tax!")
else:
    if gift_value < 25000:
        tax = 100+(gift_value-5000)*0.08
    elif gift_value < 55000:
        tax = 1700+(gift_value-25000)*0.10
    elif gift_value < 200000:
        tax = 4700+(gift_value-55000)*0.12
    elif gift_value < 1000000:
        tax = 22100+(gift_value-200000)*0.15
    elif gift_value >= 1000000:
        tax = 142100+(gift_value-1000000)*0.17

    print(f"Amount of tax: {tax} euros")

How My Solution Works

1. Converting the input to a number (type casting)

The first line, gift_value = int(input("Value of gift: ")), uses type casting, which means converting a value from one type to another. The function input() always gives back a string, even when the user types digits, so "27500" is text.

The function int() converts it to the integer 27500, which the program needs to compare the gift with the limits and to calculate the tax. Without int(), the first comparison would stop the program with TypeError: '<' not supported between instances of 'str' and 'int'.

See Exercise #08 and Exercise #31 for more about converting values, and Data Types in Python for the data types involved.

2. The “no tax” case comes first

Gifts under 5,000 euros aren’t taxed at all, so the first if handles them and prints No tax!. Everything else goes into the else block, where the tax is calculated.

3. One branch for each bracket, using only the upper limit

Inside the else, there is one branch per row of the table. Each condition only checks the upper limit of its range, such as gift_value < 25000. The lower limit doesn’t need to be written, because the earlier branches have already ruled out the smaller values. By the time Python reaches elif gift_value < 55000, it already knows the gift is at least 25,000, since otherwise the branch above would have caught it. (This is the same idea that the University Solution used in Exercise #38, where each grade range was defined only by its upper limit. It also relies on the order of the branches, as in Exercise #36.)

This is what makes the reference table so useful: each row turns into one elif, with the upper limit as the condition and the base tax and rate in the formula.

Row of the tableConditionFormula
€5,000 to below €25,000gift_value < 25000100 + (gift_value - 5000) * 0.08
€25,000 to below €55,000gift_value < 550001700 + (gift_value - 25000) * 0.10
€55,000 to below €200,000gift_value < 2000004700 + (gift_value - 55000) * 0.12
€200,000 to below €1,000,000gift_value < 100000022100 + (gift_value - 200000) * 0.15
€1,000,000 and abovegift_value >= 1000000142100 + (gift_value - 1000000) * 0.17

4. Print the result once

Each branch only stores the tax in the variable tax. A single print() at the end shows it, so the sentence Amount of tax: ... euros is written only once. The tax has a decimal point, such as 100.0, because the rates (0.08, 0.10 and so on) are decimal numbers, which makes the whole calculation a float.

The message itself is written as an f-string: the f in front of the quotes lets Python replace {tax} with the value stored in the variable tax, so the text and the number are put together in one go, without converting the number with str(). F-strings are explained in Exercise #04.

Here are some gifts worked through:

GiftBranchCalculationPrinted
3,500gift_value < 5000noneNo tax!
5,000gift_value < 25000100 + (5000 − 5000) × 0.08100.0
6,000gift_value < 25000100 + (6000 − 5000) × 0.08180.0
27,500gift_value < 550001700 + (27500 − 25000) × 0.101950.0
75,000gift_value < 2000004700 + (75000 − 55000) × 0.127100.0
1,500,000gift_value >= 1000000142100 + (1500000 − 1000000) × 0.17227100.0

5. The last branch

The final branch is elif gift_value >= 1000000. That condition is always true when Python reaches it, because every smaller gift was caught by the branches above. So a plain else: would do exactly the same job.

University Solution

value = int(input("Value of gift: "))

if value < 5000:
    tax = 0
elif value <= 25000:
    tax = 100 + (value - 5000) * 0.08
elif value <= 55000:
    tax = 1700 + (value - 25000) * 0.10
elif value <= 200000:
    tax = 4700 + (value - 55000) * 0.12
elif value <= 1000000:
    tax = 22100 + (value - 200000) * 0.15
else:
    tax = 142100 + (value - 1000000) * 0.17

if tax == 0:
    print("No tax!")
else:
    print(f"Amount of tax: {tax} euros")

The University Solution follows the same plan, with a few differences:

  • One chain, with the “no tax” case inside it. For gifts under 5,000, it sets tax = 0, instead of printing right away. All the cases are in a single if / elif chain.
  • The printing is decided at the end. The second if tax == 0: prints No tax! when the tax is zero, and the amount otherwise. This works because the tax is never 0 for a gift of 5,000 euros or more, since the smallest tax is the 100 euros at the lower limit.
  • <= for the upper limits. Its conditions say value <= 25000, where My Solution says gift_value < 25000.
  • A plain else for the last bracket, as mentioned above.

Does < or <= matter?

My Solution puts a gift of exactly 25,000 euros in the second bracket, and the University Solution puts it in the first. That looks like a real difference, but both give the same answer, 1700.0:

  • In the second bracket: 1700 + (25000 - 25000) * 0.10 = 1700.
  • In the first bracket: 100 + (25000 - 5000) * 0.08 = 1700.

The tax table is continuous: the “tax at the lower limit” of each bracket is exactly the tax that the previous bracket produces at its upper limit. The same is true at every boundary:

BoundaryTax from the lower bracket”Tax at the lower limit” of the next bracket
25,000100 + 20,000 × 0.08 = 1,7001,700
55,0001,700 + 30,000 × 0.10 = 4,7004,700
200,0004,700 + 145,000 × 0.12 = 22,10022,100
1,000,00022,100 + 800,000 × 0.15 = 142,100142,100

That’s why the choice between < and <= makes no difference here. Both solutions give identical output for all the gift values tested, including values on each boundary and on either side of it. In an exercise where the two choices would give different answers, like the grade boundaries in Exercise #38, the choice matters a lot.

Things to notice

Some amounts print with long decimals. Because the rates are decimal numbers, floating-point rounding can show up in the result. For a gift of 5,112 euros, both programs print Amount of tax: 108.96000000000001 euros, and for 999,999 euros they print 142099.84999999998. The exact tax is 108.96 and 142099.85. The samples in the exercise (100.0, 1950.0) don’t show this, so the exercise expects the amount as Python calculates it. (This is the same floating-point effect as in Exercise #31.)

The input has no separators. The exercise promises that the number is typed without spaces or thousands separators, like 27500 and not 27 500, because int() can’t convert text with a space in it.

Key takeaways

  • When a problem has many ranges, make a simpler reference table first. Write down each range, its base amount and its rate.
  • Each bracket follows the same formula: base tax + (value - lower limit) * rate.
  • Because earlier branches rule out smaller values, each elif only needs the upper limit of its range.
  • A final elif whose condition is always true can be a plain else.
  • Storing the result in a variable in each branch, and printing once at the end, avoids repeating the same print().
  • If a table is continuous at its boundaries, < and <= give the same result. Check this before deciding whether the choice matters.
  • Rates written as decimals make the result a float, which can print with rounding noise.
  • input() returns a string, so convert it with int() (type casting) before using it in comparisons and calculations.
  • An f-string, such as f"Amount of tax: {tax} euros", puts the value of a variable straight into the text.

✦ This is part of my Python Practice Exercise series, where I work through exercises while learning Python and explain each answer in plain language. ✦


Practice Source: This exercise is taken from the Python Programming MOOC 2026 by the University of Helsinki. I’m working through the exercises as part of my Python learning journey and documenting my answers and explanations here.

Tagged: python · conditionals · elif · arithmetic · float