October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

Build a Coupon Calculator with Flask and Python Decimal

A small Flask app can calculate a percentage discount from a submitted price. This example uses Python Decimal, validates inputs, renders results safely, and makes its rounding and business-rule assumptions explicit.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Yes—you can build a simple coupon calculator with Python and Flask. The example below accepts a price and a percentage, calculates a discount with Decimal, and displays the result in a template. It demonstrates one chosen rule—a percentage off the entered price—not a universal policy for coupons, tax, shipping, stacking, or eligibility.

What this Flask coupon calculator does

Flask is a lightweight WSGI web application framework. Its basic pattern is to create a Flask application instance, then connect a URL to a Python function with a route decorator. A route can read submitted form data, validate it, calculate a result, and render an HTML template.

This tutorial uses a deliberately narrow example: the entered coupon percentage is applied to the entered price. The resulting total is the price minus that discount. It does not attempt to represent any specific merchant’s coupon rules.

Create the project

Install Flask in a virtual environment for the Python version used by your project, then create this small file structure:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
coupon-calculator/
├── app.py
└── templates/
    └── index.html

The Flask Quickstart explains the minimal application and route pattern, request data, and template rendering: Flask Quickstart.

Write the calculation and route

Use Decimal with text input rather than converting submitted values to binary floating-point numbers. Decimal can represent decimal amounts exactly and offers explicit rounding modes; choosing a rounding policy is still an application requirement, not something the framework decides. The Python documentation describes these properties in its Decimal documentation.

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

from flask import Flask, render_template, request

app = Flask(__name__)
CENT = Decimal("0.01")


def parse_decimal(value: str, field_name: str) -> Decimal:
    try:
        number = Decimal(value.strip())
    except (InvalidOperation, AttributeError):
        raise ValueError(f"Enter a valid {field_name}.")

    if not number.is_finite():
        raise ValueError(f"Enter a finite {field_name}.")
    return number


@app.route("/", methods=["GET", "POST"])
def index():
    result = None
    error = None
    price_text = ""
    percent_text = ""

    if request.method == "POST":
        price_text = request.form.get("price", "")
        percent_text = request.form.get("percent", "")

        try:
            price = parse_decimal(price_text, "price")
            percent = parse_decimal(percent_text, "percentage")

            if price < 0:
                raise ValueError("Price cannot be negative.")
            if percent < 0 or percent > 100:
                raise ValueError("Percentage must be between 0 and 100.")

            discount = (price * percent / Decimal("100")).quantize(
                CENT, rounding=ROUND_HALF_UP
            )
            total = (price - discount).quantize(
                CENT, rounding=ROUND_HALF_UP
            )
            result = {
                "discount": f"{discount:.2f}",
                "total": f"{total:.2f}",
            }
        except ValueError as exc:
            error = str(exc)

    return render_template(
        "index.html",
        price=price_text,
        percent=percent_text,
        result=result,
        error=error,
    )

The input parser rejects malformed and non-finite values. The route also rejects a negative price and percentages outside the example’s 0–100 range. Those are validation choices for this demonstration; a real application should define its own allowed inputs and coupon rules.

Why the rounding is explicit

The example rounds the discount to two decimal places using ROUND_HALF_UP, then subtracts that rounded discount from the price and rounds the total to two places. That is a visible, consistent demonstration choice—not a claim that every business or jurisdiction follows this policy. If a product requirement specifies a different rounding mode, precision, or calculation order, implement that rule deliberately.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Render a form and result

Create templates/index.html as follows. Flask’s normal Jinja template rendering escapes user-provided values in HTML contexts, which is important when redisplaying form values. Do not mark submitted text as safe HTML.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Coupon calculator</title>
  </head>
  <body>
    <main>
      <h1>Coupon calculator</h1>
      <p>Example rule: apply a percentage discount to the entered price.</p>

      {% if error %}
        <p role="alert">{{ error }}</p>
      {% endif %}

      <form method="post">
        <label for="price">Price</label>
        <input id="price" name="price" inputmode="decimal"
               value="{{ price }}" required>

        <label for="percent">Discount percentage</label>
        <input id="percent" name="percent" inputmode="decimal"
               value="{{ percent }}" required>

        <button type="submit">Calculate</button>
      </form>

      {% if result %}
        <section aria-live="polite">
          <h2>Calculation</h2>
          <p>Discount: {{ result.discount }}</p>
          <p>Price after discount: {{ result.total }}</p>
        </section>
      {% endif %}
    </main>
  </body>
</html>

This version omits a currency symbol because neither the currency nor its formatting conventions are specified. Add an explicit currency choice and formatting policy before presenting values as money in a particular locale.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Run the app for local testing

  1. From the project directory, set Flask’s application target and start its development server. On macOS or Linux:

    export FLASK_APP=app
    flask run

    On Windows PowerShell:

    $env:FLASK_APP = "app"
    flask run
  2. Open the local address printed by Flask, enter a price and percentage, then select Calculate. For example, entering 19.99 and 15 under this example’s rounding rule produces a 3.00 discount and a 16.99 total.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Flask’s built-in server is intended for testing, not production deployment. The Quickstart directs developers to the separate deployment guidance for publicly deployed applications.

Business rules to decide before using real coupons

The example’s formula is intentionally simple: discount = price × percentage ÷ 100, then total = price − discount. A real calculator needs explicit decisions about what the entered price represents and how a coupon applies.

  • Discount base: Decide whether discounts apply before or after tax, to shipping, or only to selected items.
  • Coupon combinations: Define whether multiple coupons can be stacked and, if so, their order.
  • Eligibility: Specify valid codes, product or customer restrictions, expiration, minimum spend, and any maximum discount.
  • Currency and precision: Establish accepted currency, input format, decimal precision, and the rounding method and stage required by the business.
  • Invalid entries: Choose whether malformed values, unsupported codes, or out-of-range inputs should be rejected, and what explanation the interface should show.

These rules vary by merchant and jurisdiction. A percentage-only demonstration cannot establish them; encode only the policy you have actually specified.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.