Java 2

Week 6

Topics Covered this week

  • Microsoft Azure
  • Model, View, Controller

Cloud Services

Cloud Certifications

Renewing Azure Credits

  • If you signed up for an Azure license last year, you may receive an email like this one saying you need to renew your license.

Renewing Azure Credits

  • Find the "Billing Alerts" tile and click the "View alerts" button.
  • Click the "Review and accept" button if shown to accept any new Terms and Conditions.
  • Click the "Renew now" button and follow the login prompts.
  • The Education service may show that you have 0 credits but that the credit expires in 365 days.
  • If you open your existing App Service, it should run.
  • Delete existing services and start from scratch.

Create a new Web App

  • Click on the Azure Portal home page to create an "App Service".
  • Click the "+ Create" button. Select "Create" next to Web App.
  • Do not create a database yet.
  • Choose the "Azure for Students" subscription.
  • Click to create a new Resource Group. Name it something like "java-kirkwood".
  • Select your desired region (US Central).
    • Note that some US regions don't support free student accounts.
  • Uncheck "Unique default hostname (preview) on"
  • Give your web app a unique short name, like "yourname" or "yourname-java".
  • Select "Java 21" as the runtime stack.
  • Change the "Java web server stack" to Apache Tomcat 10.1.
  • Select "Free F1" for the hosting plan - See pricing

Create a new Web App

  • Click "Create".
  • The deployment process will take several minutes.
  • Create a new private GitHub repository called "java2ee-demo".
  • Commit and push your project to GitHub.
  • When the Azure deployment is complete, click "Go to Resource".
  • Copy the web app URL and paste it in the About section of your GitHub repository.
  • When you open the app, you will be greeted with "Hey, Java Developers!"
  • Click the Settings tab. Add "mlhaus" as a collaborator.

Fraction Class - Part 1

  • Create a new class called Fraction
  • Create two int instance variables, called numerator and denominator.
  • Create a default constructor that assigns 1 to both the numerator and denominator.
  • Create a toString method that returns a string representation of the fraction in the format "numerator/denominator"
public class Fraction {
    private int numerator;
    private int denominator;

    public Fraction() {
        numerator = 1;
        denominator = 1;
    }

    public String toString() {
        return numerator + "/" + denominator;
    }
}

Fraction Class - Part 2

  • Create another constructor that has two int parameters, called numerator and denominator. Assign both parameters to the instance variables.

  • Create a getNumerator and getDenominator method.
  • Create a setNumerator and setDenominator method.
public class Fraction {
    // code omitted

    public Fraction(int numerator, int denominator) {
        setNumerator(numerator);
        setDenominator(denominator);
    }

    public int getNumerator() {
        return numerator;
    }

    public void setNumerator(int numerator) {
        this.numerator = numerator;
    }

    public int getDenominator() {
        return denominator;
    }

    public void setDenominator(int denominator) {
        this.denominator = denominator;
    }


}

Fraction Class - Part 3

  • Modify the setDenominator method to throw an ArithmeticException with the message "Denominator cannot be zero", if the denominator is 0. 
public void setDenominator(int denominator) {
    if(denominator == 0){
        throw new ArithmeticException("cannot be zero");
    }
    this.denominator = denominator;
}

Fraction Class - Part 4

  • Create a static method called "gcd" that has two int parameters, called num1 and num2, and returns an int. 
  • The greatest common divisor of two numbers is the largest positive integer number that divides both the numbers without leaving any remainder. For example, the greatest common divisor of 30 and 45 is 15
  • This solution from Stack Overflow uses Recursion.
  • This method is static because it is a helper method related to all Fraction objects, not a single Fraction object.
  • This method could go in the Helpers class if you think you will use it for other applications.
public static int gcd(int a, int b) {
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

Fraction Class - Part 5a

  • Create a method called "simplify" that has no parameters, and returns a Fraction object.
  • Write code to find the greatest common divisor of the current numerator and denominator.
  • Instantiate a new Fraction object called "simplified" where the numerator is the current numerator divided by the greatest common divisor, and the denominator is the current denominator divided by the greatest common divisor.
    1. For example, 75/45 is 5/3 (75 divided by 15 is 5, 45 divided by 15 is 3).
public Fraction simplify() {
    int gcd = gcd(this.numerator, this.denominator);
    Fraction simplified = new Fraction(this.numerator/gcd, this.denominator/gcd);
        
    return simplified;
}

Fraction Class - Part 5b

  • If the simplified fraction's numerator is greater than or equal to zero and the fraction's denominator is less than zero, reverse their negativity.
    1. For example, 1/-2 would become -1/2
  • If the simplified fraction's numerator and denominator are both less than zero, remove their negativity.
    1. For example, -1/-2 would become 1/2
public Fraction simplify() {
    int gcd = gcd(this.numerator, this.denominator);
	Fraction simplified = new Fraction(this.numerator/gcd, this.denominator/gcd);
    if(simplified.numerator >= 0 && simplified.denominator <= 0 
        || simplified.numerator <= 0 && simplified.denominator <= 0) {
        simplified.numerator *= -1;
        simplified.denominator *= -1;
    }
    return simplified;
}

Fraction Class - Part 6a

  • Create a method called "mixedNumber" that has no parameters, and returns a String.
  • Inside this method, obtain the simplified version of the current Fraction object by calling the simplify method.
  • If the simplified fraction's denominator is 1, return the simplified fraction's numerator, converted to a String.
    • For example, if the Fraction is 2/1, return "2".
  • Otherwise, return the simplified fraction as a String.
    1. Hint: call the toString() method using the simplified fraction.
public String mixedNumber() {
    Fraction simplified = this.simplify();
    if(simplified.denominator == 1) {
        return Integer.toString(simplified.numerator);
    }
    return simplified.toString();
}

Fraction Class - Part 6b

  • If the simplified fraction's numerator is 0, return "0".
    • For example, if the Fraction is 0/1, return "0" 
  • If the simplified fraction's numerator is greater than the denominator, return the fraction as a mixed number.
    1. For example, 13/5 is 2 3/5.
      1. 13 / 5 is 2 (the whole number)
      2. 13 % 5 is 3 (the remainder)
public String mixedNumber() {
    Fraction simplified = this.simplify();
    if(simplified.denominator == 1) {
        return Integer.toString(simplified.numerator);
    } else if(simplified.numerator == 0) {
        return "0";
    } else if(simplified.numerator > simplified.denominator) {
        int wholeNumber = simplified.numerator / simplified.denominator;
        int remainder = simplified.numerator % simplified.denominator;
        return wholeNumber + " " + remainder + "/" + simplified.denominator;
    }
    return simplified.toString();
}

Fraction Class - Part 6c

  • If the simplified fraction's numerator is less than 0 and the absolute value of the simplified fraction's numerator is greater than the simplified fraction's denominator, return the fraction as a negative mixed number. 
    1. For example, -13/5 is -2 3/5
      1. -13 / 5 is -2 (the whole number)
      2. -13 % 5 is -3
      3. 13 % 5 is 3 (the remainder)
    2. For example, -4/5 would be ignored
public String mixedNumber() {
    Fraction simplified = this.simplify();
    if(simplified.denominator == 1) {
        return Integer.toString(simplified.numerator);
    } else if(simplified.numerator == 0) {
        return "0";
    } else if(simplified.numerator > simplified.denominator) {
        int wholeNumber = simplified.numerator / simplified.denominator;
        int remainder = simplified.numerator % simplified.denominator;
        return wholeNumber + " " + remainder + "/" + simplified.denominator;
    } else if(simplified.numerator < 0 && Math.abs(simplified.numerator) > simplified.denominator) {
        int wholeNumber = simplified.numerator / simplified.denominator;
        int remainder = Math.abs(simplified.numerator) % simplified.denominator;
        return wholeNumber + " " + remainder + "/" + simplified.denominator;
    }
    return simplified.toString();
}

Fraction Class - Part 7

  • Create a method called "add" that has one Fraction parameter, called "other", and returns a String. 
  • Create a new Fraction object where the numerator is (a*d + c*b) and the denominator is (b*d).
    • a is this Fraction's numerator, b is this Fraction's denominator, c is the other Fraction's numerator, d is the other Fraction's denominator.
  • Return the result in the following format by calling the mixedNumber method for each Fraction object.
    1. 2 3/5 + 1/2 = 3 1/10
public String add(Fraction other) {
    Fraction result = new Fraction();
    result.setNumerator(this.numerator * other.denominator + other.numerator * this.denominator);
    result.setDenominator(this.denominator * other.denominator);
    return String.format("%s + %s = %s", this.mixedNumber(), other.mixedNumber(), result.mixedNumber());
}

fraction.jsp

  • Create a new JSP called "fraction.jsp". Add this starter HTML.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fraction Calculator</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>

<div class="container my-4">
    <h1>Fraction Calculator</h1>
    <p class="lead">Enter two fractions and press submit to calculate the sum.</p>
    <form>
        <div class="row">
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control">
                </div>
            </div>
            <div class="col-1 d-flex justify-content-center display-3">
                <span>+</span>
            </div>
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control">
                </div>
            </div>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

Fraction Servlet

  • Create a new Servlet called FractionServlet. Add this starter code.
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet(value="/fraction")
public class FractionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("fraction.jsp").forward(req, resp);
    }
}

fraction.jsp

  • Set up the form to make a post request to the servlet.
    <form method="post" action="fraction">
  • Add name attributes to the 4 inputs:
    name="num1"
    name="den1"
    name="num2"
    name="den2"
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fraction Calculator</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>

<div class="container my-4">
    <h1>Fraction Calculator</h1>
    <p class="lead">Enter two fractions and press submit to calculate the sum.</p>
    <form method="post" action="fraction">
        <div class="row">
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num1">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den1">
                </div>
            </div>
            <div class="col-1 d-flex justify-content-center display-3">
                <span>+</span>
            </div>
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num2">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den2">
                </div>
            </div>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

Fraction Servlet

  • Create a doPost method that gets that data and sets the values as attributes.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String num1 = req.getParameter("num1");
    String den1 = req.getParameter("den1");
    String num2 = req.getParameter("num2");
    String den2 = req.getParameter("den2");
    req.setAttribute("num1", num1);
    req.setAttribute("den1", den1);
    req.setAttribute("num2", num2);
    req.setAttribute("den2", den2);
    req.getRequestDispatcher("fraction.jsp").forward(req, resp);
}

fraction.jsp

  • Create a scriplet that gets the attributes set on the servlet.
  • Add value attributes to the form fields to keep the data when the form is submitted.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String num1 = (String)request.getAttribute("num1");
    num1 = num1 == null ? "" : num1;
    String den1 = (String)request.getAttribute("den1");
    den1 = den1 == null ? "" : den1;
    String num2 = (String)request.getAttribute("num2");
    num2 = num2 == null ? "" : num2;
    String den2 = (String)request.getAttribute("den2");
    den2 = den2 == null ? "" : den2;
%>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fraction Calculator</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>

<div class="container my-4">
    <h1>Fraction Calculator</h1>
    <p class="lead">Enter two fractions and press submit to calculate the sum.</p>
    <form method="post" action="fraction">
        <div class="row">
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num1" value="<%= num1 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den1" value="<%= den1 %>">
                </div>
            </div>
            <div class="col-1 d-flex justify-content-center display-3">
                <span>+</span>
            </div>
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num2" value="<%= num2 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den2" value="<%= den2 %>">
                </div>
            </div>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

Fraction Servlet

  • Add code to validate the numerators.
  • Set an error attribute if their input is not valid.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String num1 = req.getParameter("num1");
    String den1 = req.getParameter("den1");
    String num2 = req.getParameter("num2");
    String den2 = req.getParameter("den2");
    req.setAttribute("num1", num1);
    req.setAttribute("den1", den1);
    req.setAttribute("num2", num2);
    req.setAttribute("den2", den2);
    String error = "";
    Fraction f1 = new Fraction();
    try {
        f1.setNumerator(Integer.parseInt(num1));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 1 is not valid</li>";
    }

    Fraction f2 = new Fraction();
    try {
        f2.setNumerator(Integer.parseInt(num2));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 2 is not valid</li>";
    }

    if(!error.equals("")) {
        req.setAttribute("error", "<ul>" + error + "</ul>");
        req.getRequestDispatcher("fraction.jsp").forward(req, resp);
        return;
    }

    req.getRequestDispatcher("fraction.jsp").forward(req, resp);
}

fraction.jsp

  • Get the error attribute and display it.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String num1 = (String)request.getAttribute("num1");
    num1 = num1 == null ? "" : num1;
    String den1 = (String)request.getAttribute("den1");
    den1 = den1 == null ? "" : den1;
    String num2 = (String)request.getAttribute("num2");
    num2 = num2 == null ? "" : num2;
    String den2 = (String)request.getAttribute("den2");
    den2 = den2 == null ? "" : den2;

    String error = (String)request.getAttribute("error");
    error = error == null ? "" : error;
%>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fraction Calculator</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>

<div class="container my-4">
    <h1>Fraction Calculator</h1>
    <p class="lead">Enter two fractions and press submit to calculate the sum.</p>
    <form method="post" action="fraction">
        <div class="row">
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num1" value="<%= num1 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den1" value="<%= den1 %>">
                </div>
            </div>
            <div class="col-1 d-flex justify-content-center display-3">
                <span>+</span>
            </div>
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num2" value="<%= num2 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den2" value="<%= den2 %>">
                </div>
            </div>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <div style="color: red;"><%= error %></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

Fraction Servlet

  • Add code to validate the denominators.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String num1 = req.getParameter("num1");
    String den1 = req.getParameter("den1");
    String num2 = req.getParameter("num2");
    String den2 = req.getParameter("den2");
    req.setAttribute("num1", num1);
    req.setAttribute("den1", den1);
    req.setAttribute("num2", num2);
    req.setAttribute("den2", den2);
    String error = "";
    Fraction f1 = new Fraction();
    try {
        f1.setNumerator(Integer.parseInt(num1));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 1 is not valid</li>";
    }
    try {
        f1.setDenominator(Integer.parseInt(den1));
    } catch (NumberFormatException e) {
        error += "<li>Denominator 1 is not valid</li>";
    } catch (ArithmeticException e) {
        error += "<li>Denominator 1 cannot be zero</li>";
    }

    Fraction f2 = new Fraction();
    try {
        f2.setNumerator(Integer.parseInt(num2));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 2 is not valid</li>";
    }
    try {
        f2.setDenominator(Integer.parseInt(den2));
    } catch (NumberFormatException e) {
        error += "<li>Denominator 2 is not valid</li>";
    } catch (ArithmeticException e) {
        error += "<li>Denominator 2 cannot be zero</li>";
    }

    if(!error.equals("")) {
        req.setAttribute("error", "<ul>" + error + "</ul>");
        req.getRequestDispatcher("fraction.jsp").forward(req, resp);
        return;
    }

    req.getRequestDispatcher("fraction.jsp").forward(req, resp);
}

Fraction Servlet

  • If no errors exist, call the Fraction object's add method. Set the result as an attribute.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String num1 = req.getParameter("num1");
    String den1 = req.getParameter("den1");
    String num2 = req.getParameter("num2");
    String den2 = req.getParameter("den2");
    req.setAttribute("num1", num1);
    req.setAttribute("den1", den1);
    req.setAttribute("num2", num2);
    req.setAttribute("den2", den2);
    String error = "";
    Fraction f1 = new Fraction();
    try {
        f1.setNumerator(Integer.parseInt(num1));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 1 is not valid</li>";
    }
    try {
        f1.setDenominator(Integer.parseInt(den1));
    } catch (NumberFormatException e) {
        error += "<li>Denominator 1 is not valid</li>";
    } catch (ArithmeticException e) {
        error += "<li>Denominator 1 cannot be zero</li>";
    }

    Fraction f2 = new Fraction();
    try {
        f2.setNumerator(Integer.parseInt(num2));
    } catch (NumberFormatException e) {
        error += "<li>Numerator 2 is not valid</li>";
    }
    try {
        f2.setDenominator(Integer.parseInt(den2));
    } catch (NumberFormatException e) {
        error += "<li>Denominator 2 is not valid</li>";
    } catch (ArithmeticException e) {
        error += "<li>Denominator 2 cannot be zero</li>";
    }

    if(!error.equals("")) {
        req.setAttribute("error", "<ul>" + error + "</ul>");
        req.getRequestDispatcher("fraction.jsp").forward(req, resp);
        return;
    }

    String result = f1.add(f2);
    req.setAttribute("result", result);
    req.getRequestDispatcher("fraction.jsp").forward(req, resp);
}

fraction.jsp

  • Get the result attribute and display it.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String num1 = (String)request.getAttribute("num1");
    num1 = num1 == null ? "" : num1;
    String den1 = (String)request.getAttribute("den1");
    den1 = den1 == null ? "" : den1;
    String num2 = (String)request.getAttribute("num2");
    num2 = num2 == null ? "" : num2;
    String den2 = (String)request.getAttribute("den2");
    den2 = den2 == null ? "" : den2;

    String error = (String)request.getAttribute("error");
    error = error == null ? "" : error;
   
   	String result = (String)request.getAttribute("result");
    result = result == null ? "" : result;
%>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fraction Calculator</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>

<div class="container my-4">
    <h1>Fraction Calculator</h1>
    <p class="lead">Enter two fractions and press submit to calculate the sum.</p>
    <form method="post" action="fraction">
        <div class="row">
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num1" value="<%= num1 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den1" value="<%= den1 %>">
                </div>
            </div>
            <div class="col-1 d-flex justify-content-center display-3">
                <span>+</span>
            </div>
            <div class="col-1">
                <div class="form-group mb-2 pb-2 border-bottom border-5">
                    <input type="text" class="form-control" name="num2" value="<%= num2 %>">
                </div>
                <div class="form-group mb-2">
                    <input type="text" class="form-control" name="den2" value="<%= den2 %>">
                </div>
            </div>
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <div style="color: red;"><%= error %></div>
    <div style="color: green;"><%= result %></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

Sample Run

  • Numerator 1: -29
  • Denominator 1: 12
  • Numerator 2: 22
  • Denominator 2: 16
    -2 5/12 + 1 3/8 = -1 1/24