kandi background
Explore Kits

calculator | Sample Calculator App for Android | Apps library

 by   sauce-archives Java Version: 0.1-iOS License: No License

 by   sauce-archives Java Version: 0.1-iOS License: No License

Download this library from

kandi X-RAY | calculator Summary

calculator is a Java library typically used in Apps applications. calculator has no bugs, it has no vulnerabilities, it has build file available and it has high support. You can download it from GitHub.
Sample Calculator App for Android.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • calculator has a highly active ecosystem.
  • It has 26 star(s) with 122 fork(s). There are 28 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 3 open issues and 0 have been closed. On average issues are closed in 2233 days. There are 2 open pull requests and 0 closed requests.
  • It has a positive sentiment in the developer community.
  • The latest version of calculator is 0.1-iOS
calculator Support
Best in #Apps
Average in #Apps
calculator Support
Best in #Apps
Average in #Apps

quality kandi Quality

  • calculator has 0 bugs and 0 code smells.
calculator Quality
Best in #Apps
Average in #Apps
calculator Quality
Best in #Apps
Average in #Apps

securitySecurity

  • calculator has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • calculator code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
calculator Security
Best in #Apps
Average in #Apps
calculator Security
Best in #Apps
Average in #Apps

license License

  • calculator does not have a standard license declared.
  • Check the repository for any license declaration and review the terms closely.
  • Without a license, all rights are reserved, and you cannot use the library in your applications.
calculator License
Best in #Apps
Average in #Apps
calculator License
Best in #Apps
Average in #Apps

buildReuse

  • calculator releases are available to install and integrate.
  • Build file is available. You can build the component from source.
  • It has 1314 lines of code, 31 functions and 9 files.
  • It has high code complexity. Code complexity directly impacts maintainability of the code.
calculator Reuse
Best in #Apps
Average in #Apps
calculator Reuse
Best in #Apps
Average in #Apps
Top functions reviewed by kandi - BETA

kandi has reviewed calculator and discovered the below as its top functions. This is intended to give you an instant insight into calculator implemented functionality, and help decide if they suit your requirements.

  • Called when a divider is clicked
    • Called when a click listener is pressed
      • On click listener .
        • Called when the edit text is clicked .
          • Setup the content view .
            • Called when edit text is decoded .
              • set octal string
                • get hex string
                  • Called when the text is clicked
                    • from EditText

                      Get all kandi verified functions for this library.

                      Get all kandi verified functions for this library.

                      calculator Key Features

                      Sample Calculator App for Android

                      Javascript - Stuck in an if statement - Beginner Question

                      copy iconCopydownload iconDownload
                      let first_num;
                      let second_num;
                      let operation;
                      
                      for (var i = 9; i < 12; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          operation = this.innerText;
                        });
                      }
                      
                      for (let i = 0; i < 9; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          if (!operation) {
                            document.getElementById('firstNumber').innerText += this.innerText;
                          } else {
                            document.getElementById('secondNumber').innerText += this.innerText;
                          }
                        });
                      }
                      
                      document.getElementById('result-btn').addEventListener('click', function () {
                        first_num = document.getElementById('firstNumber').innerText;
                        second_num = document.getElementById('secondNumber').innerText;
                        document.getElementById('result').innerText = calculate(
                          parseInt(first_num),
                          parseInt(second_num),
                          operation
                        );
                      });
                      
                      function calculate(a, b, operation) {
                        if (operation === '+') {
                          return sum(a, b);
                        } else if (operation === '-') {
                          return minus(a, b);
                        } else if (operation === '*') {
                          return multiply(a, b);
                        }
                      }
                      
                      function sum(a, b) {
                        return a + b;
                      }
                      function minus(a, b) {
                        return a - b;
                      }
                      function multiply(a, b) {
                        return a * b;
                      }
                      <div class="container">
                          <button type="button" name="button">1</button>
                          <button type="button" name="button">2</button>
                          <button type="button" name="button">3</button>
                          <br />
                          <button type="button" name="button">4</button>
                          <button type="button" name="button">5</button>
                          <button type="button" name="button">6</button>
                          <br />
                          <button type="button" name="button">7</button>
                          <button type="button" name="button">8</button>
                          <button type="button" name="button">9</button>
                          <br />
                          <br />
                          <button type="button" name="button">+</button>
                          <button type="button" name="button">*</button>
                          <button type="button" name="button">-</button>
                          <br />
                          <button id="result-btn" type="button" name="button">Result</button>
                          <h1>First Number: <span id="firstNumber"></span></h1>
                          <h1>Second Number: <span id="secondNumber"></span></h1>
                          <h1>Result: <span id="result"></span></h1>
                        </div>
                      let first_num;
                      let second_num;
                      let operation;
                      
                      for (var i = 9; i < 12; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          operation = this.innerText;
                        });
                      }
                      
                      for (let i = 0; i < 9; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          if (!operation) {
                            document.getElementById('firstNumber').innerText += this.innerText;
                          } else {
                            document.getElementById('secondNumber').innerText += this.innerText;
                          }
                        });
                      }
                      
                      document.getElementById('result-btn').addEventListener('click', function () {
                        first_num = document.getElementById('firstNumber').innerText;
                        second_num = document.getElementById('secondNumber').innerText;
                        document.getElementById('result').innerText = calculate(
                          parseInt(first_num),
                          parseInt(second_num),
                          operation
                        );
                      });
                      
                      function calculate(a, b, operation) {
                        if (operation === '+') {
                          return sum(a, b);
                        } else if (operation === '-') {
                          return minus(a, b);
                        } else if (operation === '*') {
                          return multiply(a, b);
                        }
                      }
                      
                      function sum(a, b) {
                        return a + b;
                      }
                      function minus(a, b) {
                        return a - b;
                      }
                      function multiply(a, b) {
                        return a * b;
                      }
                      <div class="container">
                          <button type="button" name="button">1</button>
                          <button type="button" name="button">2</button>
                          <button type="button" name="button">3</button>
                          <br />
                          <button type="button" name="button">4</button>
                          <button type="button" name="button">5</button>
                          <button type="button" name="button">6</button>
                          <br />
                          <button type="button" name="button">7</button>
                          <button type="button" name="button">8</button>
                          <button type="button" name="button">9</button>
                          <br />
                          <br />
                          <button type="button" name="button">+</button>
                          <button type="button" name="button">*</button>
                          <button type="button" name="button">-</button>
                          <br />
                          <button id="result-btn" type="button" name="button">Result</button>
                          <h1>First Number: <span id="firstNumber"></span></h1>
                          <h1>Second Number: <span id="secondNumber"></span></h1>
                          <h1>Result: <span id="result"></span></h1>
                        </div>

                      Ball-Triangle Collision

                      copy iconCopydownload iconDownload
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                            // Find which of
                            //
                            // P1 to P2 = green
                            // P1 to P3 = purple
                            // P2 to P3 = blue
                            //
                            // PO to PO + V0 intersects with
                            
                            // Find the intersection point between lines A and B
                            function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                              // Calculate the slope of line A
                              let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                              // Calculate the y-intercept of line A
                              let Ab = Ay1 - Ax1 * Am;
                              
                              // slope of line B
                              let Bm = (By2 - By1) / (Bx2 - Bx1);
                              // y-intercept of line B
                              let Bb = By1 - Bx1 * Bm;
                              
                              if (Am === Bm) {
                                // Parallel lines
                                return;
                              }
                              
                              if (!Number.isFinite(Am)) {
                                // Line A is vertical
                                if (!Number.isFinite(Bm)) {
                                  // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                                  return;
                                } else {
                                  // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                                  const xInt = Ax1;
                                  // Simply use the equation for line segment B to find the corresponding Y value
                                  const yInt = Bm * xInt + Bb;
                                  return createVector(xInt, yInt);
                                }
                              } else if (!Number.isFinite(Bm)) {
                                // Line B is vertical
                                const xInt = Bx1;
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              } else {
                                // Derived from Am * x + Ab = Bm * x + Bb
                                const xInt = (Bb - Ab) / (Am - Bm);
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              }
                            }
                            
                            let P1toP2int =
                              intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P1toP3int =
                              intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P2toP3int =
                              intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            // These intersection points assume that all lines point infinitely in both
                            // directions, so we still have some more work to do.
                              
                            // Check if each of these points is within the target segment
                            function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                              if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                                // If the line segment is more vertical, check the Y position
                                return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                              } else {
                                return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                              }
                            }
                            
                            if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                            
                            // Check if each intersection point is in the direction our ray is pointing
                            function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                              // If the ray is more vertical, check the y coordinates
                              if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                                // If the ray is pointing in the positive Y direction
                                // (rayY1 > rayY0) then the yInt must be on the positive
                                // side of rayY0; and vice versa
                                return (rayY1 > rayY0) === (yInt > rayY0);
                              } else {
                                return (rayX1 > rayX0) === (xInt > rayX0);
                              }
                            }
                            
                            if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                      
                      let angle = 0;
                      let sides = [];
                      let vertices = [];
                      
                      const len = 100;
                      
                      let angleOne;
                      let angleTwo;
                      let angleThree;
                      
                      function setup() {
                        createCanvas(windowWidth, windowHeight);
                        angleMode(DEGREES);
                      
                        angleOne = createSlider(0, 89, 60);
                        angleOne.position(10, 10);
                        angleOne.style("width", "80px");
                      
                        angleTwo = createSlider(0, 89, 60);
                        angleTwo.position(10, 30);
                        angleTwo.style("width", "80px");
                      
                        angleThree = createSlider(0, 360, 0);
                        angleThree.position(10, 50);
                        angleThree.style("width", "80px");
                      
                        // Initial vertice & side setup (these don't change)
                        let v1 = createVector(width / 2 - len / 2, height * 0.7);
                        let v2 = createVector(width / 2 + len / 2, height * 0.7);
                      
                        sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
                      
                        vertices[0] = new Vertex(v1.x, v1.y);
                        vertices[1] = new Vertex(v2.x, v2.y);
                      }
                      
                      function draw() {
                        background(255);
                      
                        let angOne = angleOne.value();
                        let angTwo = angleTwo.value();
                        let rayAngle = angleThree.value();
                        fill(0);
                        strokeWeight(0);
                        textSize(15);
                        text(angOne, 100, 25);
                        text(angTwo, 100, 45);
                        text(rayAngle, 100, 65);
                      
                        let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
                        let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
                      
                        vertices[2] = new Vertex(
                          vertices[0].a.x + v2Offset.x,
                          vertices[0].a.y + v2Offset.y
                        );
                        vertices[3] = new Vertex(
                          vertices[1].a.x + v3Offset.x,
                          vertices[1].a.y + v3Offset.y
                        );
                      
                        // Update the sides
                        sides[1] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[2].a.x,
                          vertices[2].a.y
                        );
                      
                        sides[3] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[3].a.x,
                          vertices[3].a.y
                        );
                      
                        const m1 =
                          (vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
                      
                        const m2 =
                          (vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
                      
                        // Calculate the y-offset relative to vertices[0]
                        const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
                      
                        const xInt = b2 / (m1 - m2);
                        const yInt = xInt * m1;
                        // Note xInt and yInt are relative to vertices[0]
                      
                        // draw all the things
                        // sides.forEach((s) => s.show());
                      
                        // stroke(0, 255, 0);
                        // strokeWeight(20);
                        point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        sides[4] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "blue"
                        );
                      
                        sides[5] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "purple"
                        );
                      
                        scale(2); // so I can make the triangle actually *visible*
                        translate(-width / 3, -height / 4);
                      
                        sides[0].show();
                        sides[4].show();
                        sides[5].show();
                      
                        vertices[0].show();
                        vertices[1].show();
                        vertices[4].show();
                      
                        strokeWeight(1);
                        stroke(255, 0, 0);
                        noFill();
                        arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
                        arc(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          40,
                          40, -180, -(180 - angleTwo.value()),
                          PIE
                        );
                      
                        let P1 = vertices[0].a;
                        let P2 = vertices[1].a;
                        let P3 = vertices[4].a;
                      
                        stroke(255, 255, 0);
                        stroke("purple"); // Change the color
                        strokeWeight(5); // Make the points 10 pixels in size
                      
                        let P0 = createVector(P1.x + 60, P1.y - 40);
                        
                        
                        let V0 = createVector(15 * cos(rayAngle), 15 * sin(rayAngle));
                      
                        point(P0.x, P0.y);
                        stroke(255, 0, 0);
                        point(P0.x + V0.x, P0.y + V0.y);
                        strokeWeight(2);
                        stroke("purple");
                        line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                      
                        // console.log(P1x,P1y,P2x,P2y,P3x,P3y);
                      
                        // Find which of
                        //
                        // P1 to P2 = green
                        // P1 to P3 = purple
                        // P2 to P3 = blue
                        //
                        // PO to PO + V0 intersects with
                        
                        // Find the intersection point between lines A and B
                        function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                          // Calculate the slope of line A
                          let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                          // Calculate the y-intercept of line A
                          let Ab = Ay1 - Ax1 * Am;
                          
                          // slope of line B
                          let Bm = (By2 - By1) / (Bx2 - Bx1);
                          // y-intercept of line B
                          let Bb = By1 - Bx1 * Bm;
                          
                          if (Am === Bm) {
                            // Parallel lines
                            return;
                          }
                          
                          if (!Number.isFinite(Am)) {
                            // Line A is vertical
                            if (!Number.isFinite(Bm)) {
                              // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                              return;
                            } else {
                              // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                              const xInt = Ax1;
                              // Simply use the equation for line segment B to find the corresponding Y value
                              const yInt = Bm * xInt + Bb;
                              return createVector(xInt, yInt);
                            }
                          } else if (!Number.isFinite(Bm)) {
                            // Line B is vertical
                            const xInt = Bx1;
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          } else {
                            // Derived from Am * x + Ab = Bm * x + Bb
                            const xInt = (Bb - Ab) / (Am - Bm);
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          }
                        }
                        
                        let P1toP2int =
                          intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P1toP3int =
                          intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P2toP3int =
                          intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        // These intersection points assume that all lines point infinitely in both
                        // directions, so we still have some more work to do.
                          
                        // Check if each of these points is within the target segment
                        function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                          if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                            // If the line segment is more vertical, check the Y position
                            return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                          } else {
                            return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                          }
                        }
                        
                        if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Check if each intersection point is in the direction our ray is pointing
                        function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                          // If the ray is more vertical, check the y coordinates
                          if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                            // If the ray is pointing in the positive Y direction
                            // (rayY1 > rayY0) then the yInt must be on the positive
                            // side of rayY0; and vice versa
                            return (rayY1 > rayY0) === (yInt > rayY0);
                          } else {
                            return (rayX1 > rayX0) === (xInt > rayX0);
                          }
                        }
                        
                        if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Only one of these should be true, except perhaps if the ray passes precisely through a corner
                        if (P1toP2int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP2int.x, P1toP2int.y);
                          fill("Green");
                          noStroke();
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P1toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP3int.x, P1toP3int.y);
                          fill("Purple");
                          noStroke();
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P2toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P2toP3int.x, P2toP3int.y);
                          fill("Blue");
                          noStroke();
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        /* I don't understand this math at all
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                        let times = [t1, t2, t3];
                        let posTimes = [];
                      
                        for (let i = 0; i < times.length; i++) {
                          times[i] = round(times[i], 2);
                        }
                      
                        // console.log("After rounding:", times);
                      
                        for (let i = 0; i < times.length; i++) {
                          if (times[i] > 0) {
                            posTimes.push(times[i]);
                          }
                        }
                      
                        // console.log("posTimes:", posTimes);
                        trueTime = min(posTimes);
                        if (trueTime == round(t1, 2)) {
                          fill("Blue");
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else if (trueTime == round(t2, 2)) {
                          fill("Green");
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else {
                          fill("Purple");
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        */
                      }
                      
                      class Side {
                        constructor(x1, y1, x2, y2, col = "black") {
                          this.a = createVector(x1, y1);
                          this.b = createVector(x2, y2);
                          this.color = col;
                        }
                      
                        show() {
                          stroke(this.color);
                          strokeWeight(4);
                          line(this.a.x, this.a.y, this.b.x, this.b.y);
                        }
                      }
                      
                      class Vertex {
                        constructor(x1, y1) {
                          this.a = createVector(x1, y1);
                        }
                      
                        show() {
                          stroke(255, 0, 0);
                          strokeWeight(10);
                          point(this.a.x, this.a.y);
                        }
                      }
                      html, body { margin: 0; padding: 0; overflow: hidden }
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                            // Find which of
                            //
                            // P1 to P2 = green
                            // P1 to P3 = purple
                            // P2 to P3 = blue
                            //
                            // PO to PO + V0 intersects with
                            
                            // Find the intersection point between lines A and B
                            function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                              // Calculate the slope of line A
                              let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                              // Calculate the y-intercept of line A
                              let Ab = Ay1 - Ax1 * Am;
                              
                              // slope of line B
                              let Bm = (By2 - By1) / (Bx2 - Bx1);
                              // y-intercept of line B
                              let Bb = By1 - Bx1 * Bm;
                              
                              if (Am === Bm) {
                                // Parallel lines
                                return;
                              }
                              
                              if (!Number.isFinite(Am)) {
                                // Line A is vertical
                                if (!Number.isFinite(Bm)) {
                                  // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                                  return;
                                } else {
                                  // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                                  const xInt = Ax1;
                                  // Simply use the equation for line segment B to find the corresponding Y value
                                  const yInt = Bm * xInt + Bb;
                                  return createVector(xInt, yInt);
                                }
                              } else if (!Number.isFinite(Bm)) {
                                // Line B is vertical
                                const xInt = Bx1;
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              } else {
                                // Derived from Am * x + Ab = Bm * x + Bb
                                const xInt = (Bb - Ab) / (Am - Bm);
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              }
                            }
                            
                            let P1toP2int =
                              intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P1toP3int =
                              intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P2toP3int =
                              intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            // These intersection points assume that all lines point infinitely in both
                            // directions, so we still have some more work to do.
                              
                            // Check if each of these points is within the target segment
                            function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                              if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                                // If the line segment is more vertical, check the Y position
                                return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                              } else {
                                return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                              }
                            }
                            
                            if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                            
                            // Check if each intersection point is in the direction our ray is pointing
                            function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                              // If the ray is more vertical, check the y coordinates
                              if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                                // If the ray is pointing in the positive Y direction
                                // (rayY1 > rayY0) then the yInt must be on the positive
                                // side of rayY0; and vice versa
                                return (rayY1 > rayY0) === (yInt > rayY0);
                              } else {
                                return (rayX1 > rayX0) === (xInt > rayX0);
                              }
                            }
                            
                            if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                      
                      let angle = 0;
                      let sides = [];
                      let vertices = [];
                      
                      const len = 100;
                      
                      let angleOne;
                      let angleTwo;
                      let angleThree;
                      
                      function setup() {
                        createCanvas(windowWidth, windowHeight);
                        angleMode(DEGREES);
                      
                        angleOne = createSlider(0, 89, 60);
                        angleOne.position(10, 10);
                        angleOne.style("width", "80px");
                      
                        angleTwo = createSlider(0, 89, 60);
                        angleTwo.position(10, 30);
                        angleTwo.style("width", "80px");
                      
                        angleThree = createSlider(0, 360, 0);
                        angleThree.position(10, 50);
                        angleThree.style("width", "80px");
                      
                        // Initial vertice & side setup (these don't change)
                        let v1 = createVector(width / 2 - len / 2, height * 0.7);
                        let v2 = createVector(width / 2 + len / 2, height * 0.7);
                      
                        sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
                      
                        vertices[0] = new Vertex(v1.x, v1.y);
                        vertices[1] = new Vertex(v2.x, v2.y);
                      }
                      
                      function draw() {
                        background(255);
                      
                        let angOne = angleOne.value();
                        let angTwo = angleTwo.value();
                        let rayAngle = angleThree.value();
                        fill(0);
                        strokeWeight(0);
                        textSize(15);
                        text(angOne, 100, 25);
                        text(angTwo, 100, 45);
                        text(rayAngle, 100, 65);
                      
                        let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
                        let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
                      
                        vertices[2] = new Vertex(
                          vertices[0].a.x + v2Offset.x,
                          vertices[0].a.y + v2Offset.y
                        );
                        vertices[3] = new Vertex(
                          vertices[1].a.x + v3Offset.x,
                          vertices[1].a.y + v3Offset.y
                        );
                      
                        // Update the sides
                        sides[1] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[2].a.x,
                          vertices[2].a.y
                        );
                      
                        sides[3] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[3].a.x,
                          vertices[3].a.y
                        );
                      
                        const m1 =
                          (vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
                      
                        const m2 =
                          (vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
                      
                        // Calculate the y-offset relative to vertices[0]
                        const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
                      
                        const xInt = b2 / (m1 - m2);
                        const yInt = xInt * m1;
                        // Note xInt and yInt are relative to vertices[0]
                      
                        // draw all the things
                        // sides.forEach((s) => s.show());
                      
                        // stroke(0, 255, 0);
                        // strokeWeight(20);
                        point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        sides[4] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "blue"
                        );
                      
                        sides[5] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "purple"
                        );
                      
                        scale(2); // so I can make the triangle actually *visible*
                        translate(-width / 3, -height / 4);
                      
                        sides[0].show();
                        sides[4].show();
                        sides[5].show();
                      
                        vertices[0].show();
                        vertices[1].show();
                        vertices[4].show();
                      
                        strokeWeight(1);
                        stroke(255, 0, 0);
                        noFill();
                        arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
                        arc(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          40,
                          40, -180, -(180 - angleTwo.value()),
                          PIE
                        );
                      
                        let P1 = vertices[0].a;
                        let P2 = vertices[1].a;
                        let P3 = vertices[4].a;
                      
                        stroke(255, 255, 0);
                        stroke("purple"); // Change the color
                        strokeWeight(5); // Make the points 10 pixels in size
                      
                        let P0 = createVector(P1.x + 60, P1.y - 40);
                        
                        
                        let V0 = createVector(15 * cos(rayAngle), 15 * sin(rayAngle));
                      
                        point(P0.x, P0.y);
                        stroke(255, 0, 0);
                        point(P0.x + V0.x, P0.y + V0.y);
                        strokeWeight(2);
                        stroke("purple");
                        line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                      
                        // console.log(P1x,P1y,P2x,P2y,P3x,P3y);
                      
                        // Find which of
                        //
                        // P1 to P2 = green
                        // P1 to P3 = purple
                        // P2 to P3 = blue
                        //
                        // PO to PO + V0 intersects with
                        
                        // Find the intersection point between lines A and B
                        function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                          // Calculate the slope of line A
                          let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                          // Calculate the y-intercept of line A
                          let Ab = Ay1 - Ax1 * Am;
                          
                          // slope of line B
                          let Bm = (By2 - By1) / (Bx2 - Bx1);
                          // y-intercept of line B
                          let Bb = By1 - Bx1 * Bm;
                          
                          if (Am === Bm) {
                            // Parallel lines
                            return;
                          }
                          
                          if (!Number.isFinite(Am)) {
                            // Line A is vertical
                            if (!Number.isFinite(Bm)) {
                              // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                              return;
                            } else {
                              // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                              const xInt = Ax1;
                              // Simply use the equation for line segment B to find the corresponding Y value
                              const yInt = Bm * xInt + Bb;
                              return createVector(xInt, yInt);
                            }
                          } else if (!Number.isFinite(Bm)) {
                            // Line B is vertical
                            const xInt = Bx1;
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          } else {
                            // Derived from Am * x + Ab = Bm * x + Bb
                            const xInt = (Bb - Ab) / (Am - Bm);
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          }
                        }
                        
                        let P1toP2int =
                          intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P1toP3int =
                          intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P2toP3int =
                          intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        // These intersection points assume that all lines point infinitely in both
                        // directions, so we still have some more work to do.
                          
                        // Check if each of these points is within the target segment
                        function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                          if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                            // If the line segment is more vertical, check the Y position
                            return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                          } else {
                            return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                          }
                        }
                        
                        if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Check if each intersection point is in the direction our ray is pointing
                        function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                          // If the ray is more vertical, check the y coordinates
                          if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                            // If the ray is pointing in the positive Y direction
                            // (rayY1 > rayY0) then the yInt must be on the positive
                            // side of rayY0; and vice versa
                            return (rayY1 > rayY0) === (yInt > rayY0);
                          } else {
                            return (rayX1 > rayX0) === (xInt > rayX0);
                          }
                        }
                        
                        if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Only one of these should be true, except perhaps if the ray passes precisely through a corner
                        if (P1toP2int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP2int.x, P1toP2int.y);
                          fill("Green");
                          noStroke();
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P1toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP3int.x, P1toP3int.y);
                          fill("Purple");
                          noStroke();
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P2toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P2toP3int.x, P2toP3int.y);
                          fill("Blue");
                          noStroke();
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        /* I don't understand this math at all
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                        let times = [t1, t2, t3];
                        let posTimes = [];
                      
                        for (let i = 0; i < times.length; i++) {
                          times[i] = round(times[i], 2);
                        }
                      
                        // console.log("After rounding:", times);
                      
                        for (let i = 0; i < times.length; i++) {
                          if (times[i] > 0) {
                            posTimes.push(times[i]);
                          }
                        }
                      
                        // console.log("posTimes:", posTimes);
                        trueTime = min(posTimes);
                        if (trueTime == round(t1, 2)) {
                          fill("Blue");
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else if (trueTime == round(t2, 2)) {
                          fill("Green");
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else {
                          fill("Purple");
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        */
                      }
                      
                      class Side {
                        constructor(x1, y1, x2, y2, col = "black") {
                          this.a = createVector(x1, y1);
                          this.b = createVector(x2, y2);
                          this.color = col;
                        }
                      
                        show() {
                          stroke(this.color);
                          strokeWeight(4);
                          line(this.a.x, this.a.y, this.b.x, this.b.y);
                        }
                      }
                      
                      class Vertex {
                        constructor(x1, y1) {
                          this.a = createVector(x1, y1);
                        }
                      
                        show() {
                          stroke(255, 0, 0);
                          strokeWeight(10);
                          point(this.a.x, this.a.y);
                        }
                      }
                      html, body { margin: 0; padding: 0; overflow: hidden }
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                            // Find which of
                            //
                            // P1 to P2 = green
                            // P1 to P3 = purple
                            // P2 to P3 = blue
                            //
                            // PO to PO + V0 intersects with
                            
                            // Find the intersection point between lines A and B
                            function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                              // Calculate the slope of line A
                              let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                              // Calculate the y-intercept of line A
                              let Ab = Ay1 - Ax1 * Am;
                              
                              // slope of line B
                              let Bm = (By2 - By1) / (Bx2 - Bx1);
                              // y-intercept of line B
                              let Bb = By1 - Bx1 * Bm;
                              
                              if (Am === Bm) {
                                // Parallel lines
                                return;
                              }
                              
                              if (!Number.isFinite(Am)) {
                                // Line A is vertical
                                if (!Number.isFinite(Bm)) {
                                  // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                                  return;
                                } else {
                                  // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                                  const xInt = Ax1;
                                  // Simply use the equation for line segment B to find the corresponding Y value
                                  const yInt = Bm * xInt + Bb;
                                  return createVector(xInt, yInt);
                                }
                              } else if (!Number.isFinite(Bm)) {
                                // Line B is vertical
                                const xInt = Bx1;
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              } else {
                                // Derived from Am * x + Ab = Bm * x + Bb
                                const xInt = (Bb - Ab) / (Am - Bm);
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              }
                            }
                            
                            let P1toP2int =
                              intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P1toP3int =
                              intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P2toP3int =
                              intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            // These intersection points assume that all lines point infinitely in both
                            // directions, so we still have some more work to do.
                              
                            // Check if each of these points is within the target segment
                            function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                              if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                                // If the line segment is more vertical, check the Y position
                                return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                              } else {
                                return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                              }
                            }
                            
                            if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                            
                            // Check if each intersection point is in the direction our ray is pointing
                            function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                              // If the ray is more vertical, check the y coordinates
                              if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                                // If the ray is pointing in the positive Y direction
                                // (rayY1 > rayY0) then the yInt must be on the positive
                                // side of rayY0; and vice versa
                                return (rayY1 > rayY0) === (yInt > rayY0);
                              } else {
                                return (rayX1 > rayX0) === (xInt > rayX0);
                              }
                            }
                            
                            if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                      
                      let angle = 0;
                      let sides = [];
                      let vertices = [];
                      
                      const len = 100;
                      
                      let angleOne;
                      let angleTwo;
                      let angleThree;
                      
                      function setup() {
                        createCanvas(windowWidth, windowHeight);
                        angleMode(DEGREES);
                      
                        angleOne = createSlider(0, 89, 60);
                        angleOne.position(10, 10);
                        angleOne.style("width", "80px");
                      
                        angleTwo = createSlider(0, 89, 60);
                        angleTwo.position(10, 30);
                        angleTwo.style("width", "80px");
                      
                        angleThree = createSlider(0, 360, 0);
                        angleThree.position(10, 50);
                        angleThree.style("width", "80px");
                      
                        // Initial vertice & side setup (these don't change)
                        let v1 = createVector(width / 2 - len / 2, height * 0.7);
                        let v2 = createVector(width / 2 + len / 2, height * 0.7);
                      
                        sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
                      
                        vertices[0] = new Vertex(v1.x, v1.y);
                        vertices[1] = new Vertex(v2.x, v2.y);
                      }
                      
                      function draw() {
                        background(255);
                      
                        let angOne = angleOne.value();
                        let angTwo = angleTwo.value();
                        let rayAngle = angleThree.value();
                        fill(0);
                        strokeWeight(0);
                        textSize(15);
                        text(angOne, 100, 25);
                        text(angTwo, 100, 45);
                        text(rayAngle, 100, 65);
                      
                        let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
                        let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
                      
                        vertices[2] = new Vertex(
                          vertices[0].a.x + v2Offset.x,
                          vertices[0].a.y + v2Offset.y
                        );
                        vertices[3] = new Vertex(
                          vertices[1].a.x + v3Offset.x,
                          vertices[1].a.y + v3Offset.y
                        );
                      
                        // Update the sides
                        sides[1] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[2].a.x,
                          vertices[2].a.y
                        );
                      
                        sides[3] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[3].a.x,
                          vertices[3].a.y
                        );
                      
                        const m1 =
                          (vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
                      
                        const m2 =
                          (vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
                      
                        // Calculate the y-offset relative to vertices[0]
                        const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
                      
                        const xInt = b2 / (m1 - m2);
                        const yInt = xInt * m1;
                        // Note xInt and yInt are relative to vertices[0]
                      
                        // draw all the things
                        // sides.forEach((s) => s.show());
                      
                        // stroke(0, 255, 0);
                        // strokeWeight(20);
                        point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        sides[4] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "blue"
                        );
                      
                        sides[5] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "purple"
                        );
                      
                        scale(2); // so I can make the triangle actually *visible*
                        translate(-width / 3, -height / 4);
                      
                        sides[0].show();
                        sides[4].show();
                        sides[5].show();
                      
                        vertices[0].show();
                        vertices[1].show();
                        vertices[4].show();
                      
                        strokeWeight(1);
                        stroke(255, 0, 0);
                        noFill();
                        arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
                        arc(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          40,
                          40, -180, -(180 - angleTwo.value()),
                          PIE
                        );
                      
                        let P1 = vertices[0].a;
                        let P2 = vertices[1].a;
                        let P3 = vertices[4].a;
                      
                        stroke(255, 255, 0);
                        stroke("purple"); // Change the color
                        strokeWeight(5); // Make the points 10 pixels in size
                      
                        let P0 = createVector(P1.x + 60, P1.y - 40);
                        
                        
                        let V0 = createVector(15 * cos(rayAngle), 15 * sin(rayAngle));
                      
                        point(P0.x, P0.y);
                        stroke(255, 0, 0);
                        point(P0.x + V0.x, P0.y + V0.y);
                        strokeWeight(2);
                        stroke("purple");
                        line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                      
                        // console.log(P1x,P1y,P2x,P2y,P3x,P3y);
                      
                        // Find which of
                        //
                        // P1 to P2 = green
                        // P1 to P3 = purple
                        // P2 to P3 = blue
                        //
                        // PO to PO + V0 intersects with
                        
                        // Find the intersection point between lines A and B
                        function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                          // Calculate the slope of line A
                          let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                          // Calculate the y-intercept of line A
                          let Ab = Ay1 - Ax1 * Am;
                          
                          // slope of line B
                          let Bm = (By2 - By1) / (Bx2 - Bx1);
                          // y-intercept of line B
                          let Bb = By1 - Bx1 * Bm;
                          
                          if (Am === Bm) {
                            // Parallel lines
                            return;
                          }
                          
                          if (!Number.isFinite(Am)) {
                            // Line A is vertical
                            if (!Number.isFinite(Bm)) {
                              // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                              return;
                            } else {
                              // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                              const xInt = Ax1;
                              // Simply use the equation for line segment B to find the corresponding Y value
                              const yInt = Bm * xInt + Bb;
                              return createVector(xInt, yInt);
                            }
                          } else if (!Number.isFinite(Bm)) {
                            // Line B is vertical
                            const xInt = Bx1;
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          } else {
                            // Derived from Am * x + Ab = Bm * x + Bb
                            const xInt = (Bb - Ab) / (Am - Bm);
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          }
                        }
                        
                        let P1toP2int =
                          intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P1toP3int =
                          intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P2toP3int =
                          intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        // These intersection points assume that all lines point infinitely in both
                        // directions, so we still have some more work to do.
                          
                        // Check if each of these points is within the target segment
                        function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                          if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                            // If the line segment is more vertical, check the Y position
                            return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                          } else {
                            return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                          }
                        }
                        
                        if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Check if each intersection point is in the direction our ray is pointing
                        function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                          // If the ray is more vertical, check the y coordinates
                          if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                            // If the ray is pointing in the positive Y direction
                            // (rayY1 > rayY0) then the yInt must be on the positive
                            // side of rayY0; and vice versa
                            return (rayY1 > rayY0) === (yInt > rayY0);
                          } else {
                            return (rayX1 > rayX0) === (xInt > rayX0);
                          }
                        }
                        
                        if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Only one of these should be true, except perhaps if the ray passes precisely through a corner
                        if (P1toP2int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP2int.x, P1toP2int.y);
                          fill("Green");
                          noStroke();
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P1toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP3int.x, P1toP3int.y);
                          fill("Purple");
                          noStroke();
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P2toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P2toP3int.x, P2toP3int.y);
                          fill("Blue");
                          noStroke();
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        /* I don't understand this math at all
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                        let times = [t1, t2, t3];
                        let posTimes = [];
                      
                        for (let i = 0; i < times.length; i++) {
                          times[i] = round(times[i], 2);
                        }
                      
                        // console.log("After rounding:", times);
                      
                        for (let i = 0; i < times.length; i++) {
                          if (times[i] > 0) {
                            posTimes.push(times[i]);
                          }
                        }
                      
                        // console.log("posTimes:", posTimes);
                        trueTime = min(posTimes);
                        if (trueTime == round(t1, 2)) {
                          fill("Blue");
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else if (trueTime == round(t2, 2)) {
                          fill("Green");
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else {
                          fill("Purple");
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        */
                      }
                      
                      class Side {
                        constructor(x1, y1, x2, y2, col = "black") {
                          this.a = createVector(x1, y1);
                          this.b = createVector(x2, y2);
                          this.color = col;
                        }
                      
                        show() {
                          stroke(this.color);
                          strokeWeight(4);
                          line(this.a.x, this.a.y, this.b.x, this.b.y);
                        }
                      }
                      
                      class Vertex {
                        constructor(x1, y1) {
                          this.a = createVector(x1, y1);
                        }
                      
                        show() {
                          stroke(255, 0, 0);
                          strokeWeight(10);
                          point(this.a.x, this.a.y);
                        }
                      }
                      html, body { margin: 0; padding: 0; overflow: hidden }
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                            // Find which of
                            //
                            // P1 to P2 = green
                            // P1 to P3 = purple
                            // P2 to P3 = blue
                            //
                            // PO to PO + V0 intersects with
                            
                            // Find the intersection point between lines A and B
                            function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                              // Calculate the slope of line A
                              let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                              // Calculate the y-intercept of line A
                              let Ab = Ay1 - Ax1 * Am;
                              
                              // slope of line B
                              let Bm = (By2 - By1) / (Bx2 - Bx1);
                              // y-intercept of line B
                              let Bb = By1 - Bx1 * Bm;
                              
                              if (Am === Bm) {
                                // Parallel lines
                                return;
                              }
                              
                              if (!Number.isFinite(Am)) {
                                // Line A is vertical
                                if (!Number.isFinite(Bm)) {
                                  // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                                  return;
                                } else {
                                  // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                                  const xInt = Ax1;
                                  // Simply use the equation for line segment B to find the corresponding Y value
                                  const yInt = Bm * xInt + Bb;
                                  return createVector(xInt, yInt);
                                }
                              } else if (!Number.isFinite(Bm)) {
                                // Line B is vertical
                                const xInt = Bx1;
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              } else {
                                // Derived from Am * x + Ab = Bm * x + Bb
                                const xInt = (Bb - Ab) / (Am - Bm);
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              }
                            }
                            
                            let P1toP2int =
                              intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P1toP3int =
                              intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P2toP3int =
                              intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            // These intersection points assume that all lines point infinitely in both
                            // directions, so we still have some more work to do.
                              
                            // Check if each of these points is within the target segment
                            function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                              if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                                // If the line segment is more vertical, check the Y position
                                return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                              } else {
                                return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                              }
                            }
                            
                            if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                            
                            // Check if each intersection point is in the direction our ray is pointing
                            function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                              // If the ray is more vertical, check the y coordinates
                              if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                                // If the ray is pointing in the positive Y direction
                                // (rayY1 > rayY0) then the yInt must be on the positive
                                // side of rayY0; and vice versa
                                return (rayY1 > rayY0) === (yInt > rayY0);
                              } else {
                                return (rayX1 > rayX0) === (xInt > rayX0);
                              }
                            }
                            
                            if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                      
                      let angle = 0;
                      let sides = [];
                      let vertices = [];
                      
                      const len = 100;
                      
                      let angleOne;
                      let angleTwo;
                      let angleThree;
                      
                      function setup() {
                        createCanvas(windowWidth, windowHeight);
                        angleMode(DEGREES);
                      
                        angleOne = createSlider(0, 89, 60);
                        angleOne.position(10, 10);
                        angleOne.style("width", "80px");
                      
                        angleTwo = createSlider(0, 89, 60);
                        angleTwo.position(10, 30);
                        angleTwo.style("width", "80px");
                      
                        angleThree = createSlider(0, 360, 0);
                        angleThree.position(10, 50);
                        angleThree.style("width", "80px");
                      
                        // Initial vertice & side setup (these don't change)
                        let v1 = createVector(width / 2 - len / 2, height * 0.7);
                        let v2 = createVector(width / 2 + len / 2, height * 0.7);
                      
                        sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
                      
                        vertices[0] = new Vertex(v1.x, v1.y);
                        vertices[1] = new Vertex(v2.x, v2.y);
                      }
                      
                      function draw() {
                        background(255);
                      
                        let angOne = angleOne.value();
                        let angTwo = angleTwo.value();
                        let rayAngle = angleThree.value();
                        fill(0);
                        strokeWeight(0);
                        textSize(15);
                        text(angOne, 100, 25);
                        text(angTwo, 100, 45);
                        text(rayAngle, 100, 65);
                      
                        let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
                        let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
                      
                        vertices[2] = new Vertex(
                          vertices[0].a.x + v2Offset.x,
                          vertices[0].a.y + v2Offset.y
                        );
                        vertices[3] = new Vertex(
                          vertices[1].a.x + v3Offset.x,
                          vertices[1].a.y + v3Offset.y
                        );
                      
                        // Update the sides
                        sides[1] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[2].a.x,
                          vertices[2].a.y
                        );
                      
                        sides[3] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[3].a.x,
                          vertices[3].a.y
                        );
                      
                        const m1 =
                          (vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
                      
                        const m2 =
                          (vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
                      
                        // Calculate the y-offset relative to vertices[0]
                        const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
                      
                        const xInt = b2 / (m1 - m2);
                        const yInt = xInt * m1;
                        // Note xInt and yInt are relative to vertices[0]
                      
                        // draw all the things
                        // sides.forEach((s) => s.show());
                      
                        // stroke(0, 255, 0);
                        // strokeWeight(20);
                        point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        sides[4] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "blue"
                        );
                      
                        sides[5] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "purple"
                        );
                      
                        scale(2); // so I can make the triangle actually *visible*
                        translate(-width / 3, -height / 4);
                      
                        sides[0].show();
                        sides[4].show();
                        sides[5].show();
                      
                        vertices[0].show();
                        vertices[1].show();
                        vertices[4].show();
                      
                        strokeWeight(1);
                        stroke(255, 0, 0);
                        noFill();
                        arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
                        arc(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          40,
                          40, -180, -(180 - angleTwo.value()),
                          PIE
                        );
                      
                        let P1 = vertices[0].a;
                        let P2 = vertices[1].a;
                        let P3 = vertices[4].a;
                      
                        stroke(255, 255, 0);
                        stroke("purple"); // Change the color
                        strokeWeight(5); // Make the points 10 pixels in size
                      
                        let P0 = createVector(P1.x + 60, P1.y - 40);
                        
                        
                        let V0 = createVector(15 * cos(rayAngle), 15 * sin(rayAngle));
                      
                        point(P0.x, P0.y);
                        stroke(255, 0, 0);
                        point(P0.x + V0.x, P0.y + V0.y);
                        strokeWeight(2);
                        stroke("purple");
                        line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                      
                        // console.log(P1x,P1y,P2x,P2y,P3x,P3y);
                      
                        // Find which of
                        //
                        // P1 to P2 = green
                        // P1 to P3 = purple
                        // P2 to P3 = blue
                        //
                        // PO to PO + V0 intersects with
                        
                        // Find the intersection point between lines A and B
                        function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                          // Calculate the slope of line A
                          let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                          // Calculate the y-intercept of line A
                          let Ab = Ay1 - Ax1 * Am;
                          
                          // slope of line B
                          let Bm = (By2 - By1) / (Bx2 - Bx1);
                          // y-intercept of line B
                          let Bb = By1 - Bx1 * Bm;
                          
                          if (Am === Bm) {
                            // Parallel lines
                            return;
                          }
                          
                          if (!Number.isFinite(Am)) {
                            // Line A is vertical
                            if (!Number.isFinite(Bm)) {
                              // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                              return;
                            } else {
                              // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                              const xInt = Ax1;
                              // Simply use the equation for line segment B to find the corresponding Y value
                              const yInt = Bm * xInt + Bb;
                              return createVector(xInt, yInt);
                            }
                          } else if (!Number.isFinite(Bm)) {
                            // Line B is vertical
                            const xInt = Bx1;
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          } else {
                            // Derived from Am * x + Ab = Bm * x + Bb
                            const xInt = (Bb - Ab) / (Am - Bm);
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          }
                        }
                        
                        let P1toP2int =
                          intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P1toP3int =
                          intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P2toP3int =
                          intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        // These intersection points assume that all lines point infinitely in both
                        // directions, so we still have some more work to do.
                          
                        // Check if each of these points is within the target segment
                        function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                          if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                            // If the line segment is more vertical, check the Y position
                            return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                          } else {
                            return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                          }
                        }
                        
                        if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Check if each intersection point is in the direction our ray is pointing
                        function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                          // If the ray is more vertical, check the y coordinates
                          if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                            // If the ray is pointing in the positive Y direction
                            // (rayY1 > rayY0) then the yInt must be on the positive
                            // side of rayY0; and vice versa
                            return (rayY1 > rayY0) === (yInt > rayY0);
                          } else {
                            return (rayX1 > rayX0) === (xInt > rayX0);
                          }
                        }
                        
                        if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Only one of these should be true, except perhaps if the ray passes precisely through a corner
                        if (P1toP2int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP2int.x, P1toP2int.y);
                          fill("Green");
                          noStroke();
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P1toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP3int.x, P1toP3int.y);
                          fill("Purple");
                          noStroke();
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P2toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P2toP3int.x, P2toP3int.y);
                          fill("Blue");
                          noStroke();
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        /* I don't understand this math at all
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                        let times = [t1, t2, t3];
                        let posTimes = [];
                      
                        for (let i = 0; i < times.length; i++) {
                          times[i] = round(times[i], 2);
                        }
                      
                        // console.log("After rounding:", times);
                      
                        for (let i = 0; i < times.length; i++) {
                          if (times[i] > 0) {
                            posTimes.push(times[i]);
                          }
                        }
                      
                        // console.log("posTimes:", posTimes);
                        trueTime = min(posTimes);
                        if (trueTime == round(t1, 2)) {
                          fill("Blue");
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else if (trueTime == round(t2, 2)) {
                          fill("Green");
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else {
                          fill("Purple");
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        */
                      }
                      
                      class Side {
                        constructor(x1, y1, x2, y2, col = "black") {
                          this.a = createVector(x1, y1);
                          this.b = createVector(x2, y2);
                          this.color = col;
                        }
                      
                        show() {
                          stroke(this.color);
                          strokeWeight(4);
                          line(this.a.x, this.a.y, this.b.x, this.b.y);
                        }
                      }
                      
                      class Vertex {
                        constructor(x1, y1) {
                          this.a = createVector(x1, y1);
                        }
                      
                        show() {
                          stroke(255, 0, 0);
                          strokeWeight(10);
                          point(this.a.x, this.a.y);
                        }
                      }
                      html, body { margin: 0; padding: 0; overflow: hidden }
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                            // Find which of
                            //
                            // P1 to P2 = green
                            // P1 to P3 = purple
                            // P2 to P3 = blue
                            //
                            // PO to PO + V0 intersects with
                            
                            // Find the intersection point between lines A and B
                            function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                              // Calculate the slope of line A
                              let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                              // Calculate the y-intercept of line A
                              let Ab = Ay1 - Ax1 * Am;
                              
                              // slope of line B
                              let Bm = (By2 - By1) / (Bx2 - Bx1);
                              // y-intercept of line B
                              let Bb = By1 - Bx1 * Bm;
                              
                              if (Am === Bm) {
                                // Parallel lines
                                return;
                              }
                              
                              if (!Number.isFinite(Am)) {
                                // Line A is vertical
                                if (!Number.isFinite(Bm)) {
                                  // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                                  return;
                                } else {
                                  // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                                  const xInt = Ax1;
                                  // Simply use the equation for line segment B to find the corresponding Y value
                                  const yInt = Bm * xInt + Bb;
                                  return createVector(xInt, yInt);
                                }
                              } else if (!Number.isFinite(Bm)) {
                                // Line B is vertical
                                const xInt = Bx1;
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              } else {
                                // Derived from Am * x + Ab = Bm * x + Bb
                                const xInt = (Bb - Ab) / (Am - Bm);
                                const yInt = Am * xInt + Ab;
                                return createVector(xInt, yInt);
                              }
                            }
                            
                            let P1toP2int =
                              intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P1toP3int =
                              intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            let P2toP3int =
                              intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                              
                            // These intersection points assume that all lines point infinitely in both
                            // directions, so we still have some more work to do.
                              
                            // Check if each of these points is within the target segment
                            function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                              if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                                // If the line segment is more vertical, check the Y position
                                return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                              } else {
                                return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                              }
                            }
                            
                            if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                            
                            // Check if each intersection point is in the direction our ray is pointing
                            function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                              // If the ray is more vertical, check the y coordinates
                              if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                                // If the ray is pointing in the positive Y direction
                                // (rayY1 > rayY0) then the yInt must be on the positive
                                // side of rayY0; and vice versa
                                return (rayY1 > rayY0) === (yInt > rayY0);
                              } else {
                                return (rayX1 > rayX0) === (xInt > rayX0);
                              }
                            }
                            
                            if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                              P1toP2int = undefined;
                            }
                            if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                              P1toP3int = undefined;
                            }
                            if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                              P2toP3int = undefined;
                            }
                      
                      let angle = 0;
                      let sides = [];
                      let vertices = [];
                      
                      const len = 100;
                      
                      let angleOne;
                      let angleTwo;
                      let angleThree;
                      
                      function setup() {
                        createCanvas(windowWidth, windowHeight);
                        angleMode(DEGREES);
                      
                        angleOne = createSlider(0, 89, 60);
                        angleOne.position(10, 10);
                        angleOne.style("width", "80px");
                      
                        angleTwo = createSlider(0, 89, 60);
                        angleTwo.position(10, 30);
                        angleTwo.style("width", "80px");
                      
                        angleThree = createSlider(0, 360, 0);
                        angleThree.position(10, 50);
                        angleThree.style("width", "80px");
                      
                        // Initial vertice & side setup (these don't change)
                        let v1 = createVector(width / 2 - len / 2, height * 0.7);
                        let v2 = createVector(width / 2 + len / 2, height * 0.7);
                      
                        sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
                      
                        vertices[0] = new Vertex(v1.x, v1.y);
                        vertices[1] = new Vertex(v2.x, v2.y);
                      }
                      
                      function draw() {
                        background(255);
                      
                        let angOne = angleOne.value();
                        let angTwo = angleTwo.value();
                        let rayAngle = angleThree.value();
                        fill(0);
                        strokeWeight(0);
                        textSize(15);
                        text(angOne, 100, 25);
                        text(angTwo, 100, 45);
                        text(rayAngle, 100, 65);
                      
                        let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
                        let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
                      
                        vertices[2] = new Vertex(
                          vertices[0].a.x + v2Offset.x,
                          vertices[0].a.y + v2Offset.y
                        );
                        vertices[3] = new Vertex(
                          vertices[1].a.x + v3Offset.x,
                          vertices[1].a.y + v3Offset.y
                        );
                      
                        // Update the sides
                        sides[1] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[2].a.x,
                          vertices[2].a.y
                        );
                      
                        sides[3] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[3].a.x,
                          vertices[3].a.y
                        );
                      
                        const m1 =
                          (vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
                      
                        const m2 =
                          (vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
                      
                        // Calculate the y-offset relative to vertices[0]
                        const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
                      
                        const xInt = b2 / (m1 - m2);
                        const yInt = xInt * m1;
                        // Note xInt and yInt are relative to vertices[0]
                      
                        // draw all the things
                        // sides.forEach((s) => s.show());
                      
                        // stroke(0, 255, 0);
                        // strokeWeight(20);
                        point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
                      
                        sides[4] = new Side(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "blue"
                        );
                      
                        sides[5] = new Side(
                          vertices[0].a.x,
                          vertices[0].a.y,
                          vertices[4].a.x,
                          vertices[4].a.y,
                          "purple"
                        );
                      
                        scale(2); // so I can make the triangle actually *visible*
                        translate(-width / 3, -height / 4);
                      
                        sides[0].show();
                        sides[4].show();
                        sides[5].show();
                      
                        vertices[0].show();
                        vertices[1].show();
                        vertices[4].show();
                      
                        strokeWeight(1);
                        stroke(255, 0, 0);
                        noFill();
                        arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
                        arc(
                          vertices[1].a.x,
                          vertices[1].a.y,
                          40,
                          40, -180, -(180 - angleTwo.value()),
                          PIE
                        );
                      
                        let P1 = vertices[0].a;
                        let P2 = vertices[1].a;
                        let P3 = vertices[4].a;
                      
                        stroke(255, 255, 0);
                        stroke("purple"); // Change the color
                        strokeWeight(5); // Make the points 10 pixels in size
                      
                        let P0 = createVector(P1.x + 60, P1.y - 40);
                        
                        
                        let V0 = createVector(15 * cos(rayAngle), 15 * sin(rayAngle));
                      
                        point(P0.x, P0.y);
                        stroke(255, 0, 0);
                        point(P0.x + V0.x, P0.y + V0.y);
                        strokeWeight(2);
                        stroke("purple");
                        line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                      
                        // console.log(P1x,P1y,P2x,P2y,P3x,P3y);
                      
                        // Find which of
                        //
                        // P1 to P2 = green
                        // P1 to P3 = purple
                        // P2 to P3 = blue
                        //
                        // PO to PO + V0 intersects with
                        
                        // Find the intersection point between lines A and B
                        function intersection(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2) {
                          // Calculate the slope of line A
                          let Am = (Ay2 - Ay1) / (Ax2 - Ax1);
                          // Calculate the y-intercept of line A
                          let Ab = Ay1 - Ax1 * Am;
                          
                          // slope of line B
                          let Bm = (By2 - By1) / (Bx2 - Bx1);
                          // y-intercept of line B
                          let Bb = By1 - Bx1 * Bm;
                          
                          if (Am === Bm) {
                            // Parallel lines
                            return;
                          }
                          
                          if (!Number.isFinite(Am)) {
                            // Line A is vertical
                            if (!Number.isFinite(Bm)) {
                              // Line B is also vertical (Am may not equal Bm though because Infinity != NegativeInfinity)
                              return;
                            } else {
                              // Since line A is vertical, intersection point will lie along the same x position as Ax1 and Ax2
                              const xInt = Ax1;
                              // Simply use the equation for line segment B to find the corresponding Y value
                              const yInt = Bm * xInt + Bb;
                              return createVector(xInt, yInt);
                            }
                          } else if (!Number.isFinite(Bm)) {
                            // Line B is vertical
                            const xInt = Bx1;
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          } else {
                            // Derived from Am * x + Ab = Bm * x + Bb
                            const xInt = (Bb - Ab) / (Am - Bm);
                            const yInt = Am * xInt + Ab;
                            return createVector(xInt, yInt);
                          }
                        }
                        
                        let P1toP2int =
                          intersection(P1.x, P1.y, P2.x, P2.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P1toP3int =
                          intersection(P1.x, P1.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        let P2toP3int =
                          intersection(P2.x, P2.y, P3.x, P3.y, P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
                          
                        // These intersection points assume that all lines point infinitely in both
                        // directions, so we still have some more work to do.
                          
                        // Check if each of these points is within the target segment
                        function isWithin(lineX1, lineY1, lineX2, lineY2, xInt, yInt) {
                          if (abs((lineY2 - lineY1) / (lineX2 - lineX1)) > 1) {
                            // If the line segment is more vertical, check the Y position
                            return yInt >= min(lineY1, lineY2) && yInt <= max(lineY1, lineY2);
                          } else {
                            return xInt >= min(lineX1, lineX2) && xInt <= max(lineX1, lineX2);
                          }
                        }
                        
                        if (P1toP2int && !isWithin(P1.x, P1.y, P2.x, P2.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isWithin(P1.x, P1.y, P3.x, P3.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isWithin(P2.x, P2.y, P3.x, P3.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Check if each intersection point is in the direction our ray is pointing
                        function isOnRay(rayX0, rayY0, rayX1, rayY1, xInt, yInt) {
                          // If the ray is more vertical, check the y coordinates
                          if (abs((rayY1 - rayY0) / (rayX1 - rayX0)) > 1) {
                            // If the ray is pointing in the positive Y direction
                            // (rayY1 > rayY0) then the yInt must be on the positive
                            // side of rayY0; and vice versa
                            return (rayY1 > rayY0) === (yInt > rayY0);
                          } else {
                            return (rayX1 > rayX0) === (xInt > rayX0);
                          }
                        }
                        
                        if (P1toP2int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP2int.x, P1toP2int.y)) {
                          P1toP2int = undefined;
                        }
                        if (P1toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P1toP3int.x, P1toP3int.y)) {
                          P1toP3int = undefined;
                        }
                        if (P2toP3int && !isOnRay(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y, P2toP3int.x, P2toP3int.y)) {
                          P2toP3int = undefined;
                        }
                        
                        // Only one of these should be true, except perhaps if the ray passes precisely through a corner
                        if (P1toP2int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP2int.x, P1toP2int.y);
                          fill("Green");
                          noStroke();
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P1toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P1toP3int.x, P1toP3int.y);
                          fill("Purple");
                          noStroke();
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        if (P2toP3int) {
                          stroke("Red");
                          strokeWeight(8);
                          point(P2toP3int.x, P2toP3int.y);
                          fill("Blue");
                          noStroke();
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        /* I don't understand this math at all
                        let A1 = P3y - P1y;
                        let B1 = -(P3x - P1x);
                        let C1 = A1 * P1x + B1 * P1y;
                      
                        let A2 = -(P3y - P2y);
                        let B2 = P3x - P2x;
                        let C2 = A2 * P2x + B2 * P2y;
                      
                        let A3 = -(P2y - P1y);
                        let B3 = P2x - P1x;
                        let C3 = A3 * P2x + B3 * P2y;
                      
                        let t1 = (C1 - A1 * P0.x - B1 * P0.y) / (A1 * V0.x + B1 * P0.y);
                        let t2 = (C2 - A2 * P0.x - B2 * P0.y) / (A2 * V0.x + B2 * P0.y);
                        let t3 = (C3 - A3 * P0.x - B3 * P0.y) / (A3 * V0.x + B3 * P0.y);
                      
                        let times = [t1, t2, t3];
                        let posTimes = [];
                      
                        for (let i = 0; i < times.length; i++) {
                          times[i] = round(times[i], 2);
                        }
                      
                        // console.log("After rounding:", times);
                      
                        for (let i = 0; i < times.length; i++) {
                          if (times[i] > 0) {
                            posTimes.push(times[i]);
                          }
                        }
                      
                        // console.log("posTimes:", posTimes);
                        trueTime = min(posTimes);
                        if (trueTime == round(t1, 2)) {
                          fill("Blue");
                          text("Hit Blue", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else if (trueTime == round(t2, 2)) {
                          fill("Green");
                          text("Hit Green", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        } else {
                          fill("Purple");
                          text("Hit Purple", vertices[1].a.x + 50, max(50, vertices[1].a.y - 50));
                        }
                        
                        */
                      }
                      
                      class Side {
                        constructor(x1, y1, x2, y2, col = "black") {
                          this.a = createVector(x1, y1);
                          this.b = createVector(x2, y2);
                          this.color = col;
                        }
                      
                        show() {
                          stroke(this.color);
                          strokeWeight(4);
                          line(this.a.x, this.a.y, this.b.x, this.b.y);
                        }
                      }
                      
                      class Vertex {
                        constructor(x1, y1) {
                          this.a = createVector(x1, y1);
                        }
                      
                        show() {
                          stroke(255, 0, 0);
                          strokeWeight(10);
                          point(this.a.x, this.a.y);
                        }
                      }
                      html, body { margin: 0; padding: 0; overflow: hidden }
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                      N = (L1.y - L2.y, L2.x - L1.x)
                      t = dot(R1-L1, N) / dot(L2-L1, N)
                      X = R1 + (R2-R1) * t    (if 0 <= t <= 1 and dot(R2-R1, X-R1) > 0)
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      var sketch = function( p ) {
                      
                      p.setup = function() {
                          let sketchCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      p.windowResized = function() {
                          p.resizeCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      function closest_hit_point(r1, r2, points, lines) {
                          let hit_p = undefined;
                          let dist = undefined;
                          let N = undefined;
                          for (let i = 0; i < lines.length; ++i) {
                              let l1 = points[lines[i][0]];
                              let l2 = points[lines[i][1]];
                              let new_hit_p = intersect_ray_line_segment(r1, r2, points[lines[i][0]], points[lines[i][1]]);
                              if (new_hit_p) {
                                  let new_d = p5.Vector.dist(r1, new_hit_p);
                                  if (new_d > 0.1 && (!dist || new_d < dist)) {
                                      dist = new_d;
                                      hit_p = new_hit_p;
                                      N = p.createVector(l1.y - l2.y, l2.x - l1.x);
                                  }
                              }
                          }
                          return hit_p ? [hit_p, N] : undefined;
                      }
                      
                      p.draw = function() {
                              
                          let sx = p.width / 2;
                          let sy = p.height / 2;
                          let points = [
                              p.createVector(-sx*0.7, -sy*0.2), p.createVector(-sx*0.7, +sy*0.2), 
                              p.createVector(-sx*0.3, -sy*0.5), p.createVector(sx*0.4, -sy*0.5), 
                              p.createVector(sx*0.6, -sy*0.3), p.createVector(sx*0.6, sy*0.5),  p.createVector(-sx*0.3, sy*0.5)];
                          let lines = [[0, 1], [2, 3], [3, 4], [4, 5], [5, 6]]
                          let center = new p5.Vector(0, 0);
                      
                          let mouse_p = p.createVector(p.mouseX - sx, p.mouseY - sy);
                          let direction = p.createVector(mouse_p.x - center.x, mouse_p.y - center.y);
                          let hit_points = [center]
                          if (center.x != mouse_p.x || center.y != mouse_p.y) {
                              let start = center;
                              result = closest_hit_point(center, mouse_p, points, lines);
                              let count = 0
                              while (result && count < 100) {
                                  hit_points.push(result[0]);
                                  direction = direction.reflect(result[1]);
                                  result = closest_hit_point(result[0], p5.Vector.add(result[0], direction), points, lines);
                                  count ++;
                              }
                          }
                          direction.normalize();
                          hit_points.push(direction.mult( new p5.Vector(p.width, p.height).mag()).add(hit_points[hit_points.length-1]));
                      
                          p.translate(p.width/2, p.height/2);
                          p.background(192);
                          p.strokeWeight(3);
                          p.stroke(64, 64, 255);
                          p.fill(128, 128, 255);
                          for (let i = 0; i < lines.length; ++i) {
                              let p0 = points[lines[i][0]];
                              let p1 = points[lines[i][1]];
                              p.line(p0.x, p0.y, p1.x, p1.y);
                          }
                          for (let i = 0; i < points.length; ++i) {
                              p.ellipse(points[i].x, points[i].y, 10, 10);
                          }
                          p.stroke(0, 0, 0);
                          p.fill(128, 128, 128);
                          p.ellipse(center.x, center.y, 10, 10);
                          for (let i = 1; i < hit_points.length; ++i) {
                              p.line(hit_points[i-1].x, hit_points[i-1].y, hit_points[i].x, hit_points[i].y);
                          }
                          for (let i = 0; i < hit_points.length; ++i) {
                              p.ellipse(hit_points[i].x, hit_points[i].y, 10, 10);
                          }
                      }
                      
                      };
                      
                      var circle_3_pts = new p5(sketch);
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                      N = (L1.y - L2.y, L2.x - L1.x)
                      t = dot(R1-L1, N) / dot(L2-L1, N)
                      X = R1 + (R2-R1) * t    (if 0 <= t <= 1 and dot(R2-R1, X-R1) > 0)
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      var sketch = function( p ) {
                      
                      p.setup = function() {
                          let sketchCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      p.windowResized = function() {
                          p.resizeCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      function closest_hit_point(r1, r2, points, lines) {
                          let hit_p = undefined;
                          let dist = undefined;
                          let N = undefined;
                          for (let i = 0; i < lines.length; ++i) {
                              let l1 = points[lines[i][0]];
                              let l2 = points[lines[i][1]];
                              let new_hit_p = intersect_ray_line_segment(r1, r2, points[lines[i][0]], points[lines[i][1]]);
                              if (new_hit_p) {
                                  let new_d = p5.Vector.dist(r1, new_hit_p);
                                  if (new_d > 0.1 && (!dist || new_d < dist)) {
                                      dist = new_d;
                                      hit_p = new_hit_p;
                                      N = p.createVector(l1.y - l2.y, l2.x - l1.x);
                                  }
                              }
                          }
                          return hit_p ? [hit_p, N] : undefined;
                      }
                      
                      p.draw = function() {
                              
                          let sx = p.width / 2;
                          let sy = p.height / 2;
                          let points = [
                              p.createVector(-sx*0.7, -sy*0.2), p.createVector(-sx*0.7, +sy*0.2), 
                              p.createVector(-sx*0.3, -sy*0.5), p.createVector(sx*0.4, -sy*0.5), 
                              p.createVector(sx*0.6, -sy*0.3), p.createVector(sx*0.6, sy*0.5),  p.createVector(-sx*0.3, sy*0.5)];
                          let lines = [[0, 1], [2, 3], [3, 4], [4, 5], [5, 6]]
                          let center = new p5.Vector(0, 0);
                      
                          let mouse_p = p.createVector(p.mouseX - sx, p.mouseY - sy);
                          let direction = p.createVector(mouse_p.x - center.x, mouse_p.y - center.y);
                          let hit_points = [center]
                          if (center.x != mouse_p.x || center.y != mouse_p.y) {
                              let start = center;
                              result = closest_hit_point(center, mouse_p, points, lines);
                              let count = 0
                              while (result && count < 100) {
                                  hit_points.push(result[0]);
                                  direction = direction.reflect(result[1]);
                                  result = closest_hit_point(result[0], p5.Vector.add(result[0], direction), points, lines);
                                  count ++;
                              }
                          }
                          direction.normalize();
                          hit_points.push(direction.mult( new p5.Vector(p.width, p.height).mag()).add(hit_points[hit_points.length-1]));
                      
                          p.translate(p.width/2, p.height/2);
                          p.background(192);
                          p.strokeWeight(3);
                          p.stroke(64, 64, 255);
                          p.fill(128, 128, 255);
                          for (let i = 0; i < lines.length; ++i) {
                              let p0 = points[lines[i][0]];
                              let p1 = points[lines[i][1]];
                              p.line(p0.x, p0.y, p1.x, p1.y);
                          }
                          for (let i = 0; i < points.length; ++i) {
                              p.ellipse(points[i].x, points[i].y, 10, 10);
                          }
                          p.stroke(0, 0, 0);
                          p.fill(128, 128, 128);
                          p.ellipse(center.x, center.y, 10, 10);
                          for (let i = 1; i < hit_points.length; ++i) {
                              p.line(hit_points[i-1].x, hit_points[i-1].y, hit_points[i].x, hit_points[i].y);
                          }
                          for (let i = 0; i < hit_points.length; ++i) {
                              p.ellipse(hit_points[i].x, hit_points[i].y, 10, 10);
                          }
                      }
                      
                      };
                      
                      var circle_3_pts = new p5(sketch);
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                      N = (L1.y - L2.y, L2.x - L1.x)
                      t = dot(R1-L1, N) / dot(L2-L1, N)
                      X = R1 + (R2-R1) * t    (if 0 <= t <= 1 and dot(R2-R1, X-R1) > 0)
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      var sketch = function( p ) {
                      
                      p.setup = function() {
                          let sketchCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      p.windowResized = function() {
                          p.resizeCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      function closest_hit_point(r1, r2, points, lines) {
                          let hit_p = undefined;
                          let dist = undefined;
                          let N = undefined;
                          for (let i = 0; i < lines.length; ++i) {
                              let l1 = points[lines[i][0]];
                              let l2 = points[lines[i][1]];
                              let new_hit_p = intersect_ray_line_segment(r1, r2, points[lines[i][0]], points[lines[i][1]]);
                              if (new_hit_p) {
                                  let new_d = p5.Vector.dist(r1, new_hit_p);
                                  if (new_d > 0.1 && (!dist || new_d < dist)) {
                                      dist = new_d;
                                      hit_p = new_hit_p;
                                      N = p.createVector(l1.y - l2.y, l2.x - l1.x);
                                  }
                              }
                          }
                          return hit_p ? [hit_p, N] : undefined;
                      }
                      
                      p.draw = function() {
                              
                          let sx = p.width / 2;
                          let sy = p.height / 2;
                          let points = [
                              p.createVector(-sx*0.7, -sy*0.2), p.createVector(-sx*0.7, +sy*0.2), 
                              p.createVector(-sx*0.3, -sy*0.5), p.createVector(sx*0.4, -sy*0.5), 
                              p.createVector(sx*0.6, -sy*0.3), p.createVector(sx*0.6, sy*0.5),  p.createVector(-sx*0.3, sy*0.5)];
                          let lines = [[0, 1], [2, 3], [3, 4], [4, 5], [5, 6]]
                          let center = new p5.Vector(0, 0);
                      
                          let mouse_p = p.createVector(p.mouseX - sx, p.mouseY - sy);
                          let direction = p.createVector(mouse_p.x - center.x, mouse_p.y - center.y);
                          let hit_points = [center]
                          if (center.x != mouse_p.x || center.y != mouse_p.y) {
                              let start = center;
                              result = closest_hit_point(center, mouse_p, points, lines);
                              let count = 0
                              while (result && count < 100) {
                                  hit_points.push(result[0]);
                                  direction = direction.reflect(result[1]);
                                  result = closest_hit_point(result[0], p5.Vector.add(result[0], direction), points, lines);
                                  count ++;
                              }
                          }
                          direction.normalize();
                          hit_points.push(direction.mult( new p5.Vector(p.width, p.height).mag()).add(hit_points[hit_points.length-1]));
                      
                          p.translate(p.width/2, p.height/2);
                          p.background(192);
                          p.strokeWeight(3);
                          p.stroke(64, 64, 255);
                          p.fill(128, 128, 255);
                          for (let i = 0; i < lines.length; ++i) {
                              let p0 = points[lines[i][0]];
                              let p1 = points[lines[i][1]];
                              p.line(p0.x, p0.y, p1.x, p1.y);
                          }
                          for (let i = 0; i < points.length; ++i) {
                              p.ellipse(points[i].x, points[i].y, 10, 10);
                          }
                          p.stroke(0, 0, 0);
                          p.fill(128, 128, 128);
                          p.ellipse(center.x, center.y, 10, 10);
                          for (let i = 1; i < hit_points.length; ++i) {
                              p.line(hit_points[i-1].x, hit_points[i-1].y, hit_points[i].x, hit_points[i].y);
                          }
                          for (let i = 0; i < hit_points.length; ++i) {
                              p.ellipse(hit_points[i].x, hit_points[i].y, 10, 10);
                          }
                      }
                      
                      };
                      
                      var circle_3_pts = new p5(sketch);
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
                      N = (L1.y - L2.y, L2.x - L1.x)
                      t = dot(R1-L1, N) / dot(L2-L1, N)
                      X = R1 + (R2-R1) * t    (if 0 <= t <= 1 and dot(R2-R1, X-R1) > 0)
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      var sketch = function( p ) {
                      
                      p.setup = function() {
                          let sketchCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      p.windowResized = function() {
                          p.resizeCanvas(p.windowWidth, p.windowHeight);
                      }
                      
                      function intersect_ray_line_segment(r1, r2, l1, l2) {
                          let R = p5.Vector.sub(r2, r1);
                          let L = p5.Vector.sub(l2, l1);
                          let N = p.createVector(-R.y, R.x);
                          if (L.dot(N) == 0) {
                              return undefined; // parallel
                          }
                          let t = p5.Vector.sub(r1, l1).dot(N) / L.dot(N);
                          if (t < 0 || t > 1) {
                              return undefined; // intersection is not on line segment
                          }
                          let X = L.mult(t).add(l1);
                          if (R.dot(p5.Vector.sub(X, r1)) < 0) {
                              return undefined; // wrong direction
                          }
                          return X;
                      }
                      
                      function closest_hit_point(r1, r2, points, lines) {
                          let hit_p = undefined;
                          let dist = undefined;
                          let N = undefined;
                          for (let i = 0; i < lines.length; ++i) {
                              let l1 = points[lines[i][0]];
                              let l2 = points[lines[i][1]];
                              let new_hit_p = intersect_ray_line_segment(r1, r2, points[lines[i][0]], points[lines[i][1]]);
                              if (new_hit_p) {
                                  let new_d = p5.Vector.dist(r1, new_hit_p);
                                  if (new_d > 0.1 && (!dist || new_d < dist)) {
                                      dist = new_d;
                                      hit_p = new_hit_p;
                                      N = p.createVector(l1.y - l2.y, l2.x - l1.x);
                                  }
                              }
                          }
                          return hit_p ? [hit_p, N] : undefined;
                      }
                      
                      p.draw = function() {
                              
                          let sx = p.width / 2;
                          let sy = p.height / 2;
                          let points = [
                              p.createVector(-sx*0.7, -sy*0.2), p.createVector(-sx*0.7, +sy*0.2), 
                              p.createVector(-sx*0.3, -sy*0.5), p.createVector(sx*0.4, -sy*0.5), 
                              p.createVector(sx*0.6, -sy*0.3), p.createVector(sx*0.6, sy*0.5),  p.createVector(-sx*0.3, sy*0.5)];
                          let lines = [[0, 1], [2, 3], [3, 4], [4, 5], [5, 6]]
                          let center = new p5.Vector(0, 0);
                      
                          let mouse_p = p.createVector(p.mouseX - sx, p.mouseY - sy);
                          let direction = p.createVector(mouse_p.x - center.x, mouse_p.y - center.y);
                          let hit_points = [center]
                          if (center.x != mouse_p.x || center.y != mouse_p.y) {
                              let start = center;
                              result = closest_hit_point(center, mouse_p, points, lines);
                              let count = 0
                              while (result && count < 100) {
                                  hit_points.push(result[0]);
                                  direction = direction.reflect(result[1]);
                                  result = closest_hit_point(result[0], p5.Vector.add(result[0], direction), points, lines);
                                  count ++;
                              }
                          }
                          direction.normalize();
                          hit_points.push(direction.mult( new p5.Vector(p.width, p.height).mag()).add(hit_points[hit_points.length-1]));
                      
                          p.translate(p.width/2, p.height/2);
                          p.background(192);
                          p.strokeWeight(3);
                          p.stroke(64, 64, 255);
                          p.fill(128, 128, 255);
                          for (let i = 0; i < lines.length; ++i) {
                              let p0 = points[lines[i][0]];
                              let p1 = points[lines[i][1]];
                              p.line(p0.x, p0.y, p1.x, p1.y);
                          }
                          for (let i = 0; i < points.length; ++i) {
                              p.ellipse(points[i].x, points[i].y, 10, 10);
                          }
                          p.stroke(0, 0, 0);
                          p.fill(128, 128, 128);
                          p.ellipse(center.x, center.y, 10, 10);
                          for (let i = 1; i < hit_points.length; ++i) {
                              p.line(hit_points[i-1].x, hit_points[i-1].y, hit_points[i].x, hit_points[i].y);
                          }
                          for (let i = 0; i < hit_points.length; ++i) {
                              p.ellipse(hit_points[i].x, hit_points[i].y, 10, 10);
                          }
                      }
                      
                      };
                      
                      var circle_3_pts = new p5(sketch);
                      <script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>

                      Use \n in Python as a normal string

                      copy iconCopydownload iconDownload
                      >>> print("\\n")
                      \n
                      >>> print("\n")
                      
                      
                      >>> print("/n")
                      /n
                      
                      r"\n"
                      
                      "\\n"
                      
                      r"\n"
                      
                      "\\n"
                      
                      def ask_num():
                          num_list = []
                          # ask for a number (we will make it a string so we can add comma and /n)
                          num = input("Enter numbers: ")
                          # put the num in the list
                          num_list.append(num)
                          # seperate the numbers
                          num_list = num.split(r"\n")
                          # print the list
                          print(num_list)
                      

                      How do I take a custom function and use it with dplyr group_by in r?

                      copy iconCopydownload iconDownload
                      library(dplyr)
                      out <- full_df %>% 
                        group_by(team) %>% 
                        group_modify(~with(.x, 
                          calculate_goals_norm(shot_xg_list = unlist(cluster), 
                                 n_matches = tot_matches, norm_matches = 20))) %>%
                        ungroup
                      
                      > as.data.frame(out)
                         team goals prob
                      1     A     0  0.6
                      2     A     1  4.0
                      3     A     2 12.4
                      4     A     3 20.6
                      5     A     4 23.8
                      6     A     5 19.0
                      7     A     6 11.6
                      8     A     7  5.6
                      9     A     8  1.8
                      10    A     9  0.4
                      11    A    10  0.1
                      12    A    12  0.0
                      13    B     0  0.0
                      14    B     1  0.8
                      15    B     2  3.7
                      16    B     3 11.1
                      17    B     4 18.6
                      18    B     5 22.4
                      19    B     6 19.6
                      20    B     7 12.4
                      21    B     8  6.9
                      22    B     9  2.9
                      23    B    10  1.1
                      24    B    11  0.3
                      25    B    12  0.1
                      26    B    14  0.0
                      
                      sim_goal_list <- as_tibble(sim_goal_list)
                      
                      sim_goal_dat <-  data.frame(value = unlist(sim_goal_list));
                      
                      
                      calculate_goals_norm <- function(shot_xg_list, n_matches, norm_matches){
                        
                        #set seed only for stackoverflow question!!!!
                        set.seed(123)
                        
                        #Start goal total at 0
                        goals_total <- 0
                        
                        #Function to take an xG number and simulate whether it was a goal or not
                        xg_to_goals_sim <- function(shot_xg){
                      
                          #Start goal count at 0
                          Goals <- 0
                      
                          #For each shot, if it goes in, add a goal
                          for (shot in shot_xg){
                            if (runif(1)<=shot){
                              Goals <- Goals + 1
                            }
                          }
                      
                          #Finally, return the number of goals
                          return(Goals)
                      
                        }
                        
                        #Run xG calculator 10000 times to test winner %
                        sim_goal_list <- c()
                        # Create a for statement to populate the list
                        for (i in 1:10000) {
                          #Run the above formula for xG list
                          #But first we need to normalize the number of xG by randomly picking from xG
                          
                          if(n_matches == norm_matches){
                            new_shot_xg_list <- shot_xg_list
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches < norm_matches){
                            new_shot_xg_list <- c(shot_xg_list, 
                                                  sample(shot_xg_list, 
                                                         round(length(shot_xg_list)/n_matches*norm_matches,0)-length(shot_xg_list),
                                                         replace=FALSE))
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches > norm_matches){
                            
                            new_shot_xg_list <- sample(shot_xg_list, 
                                                       round(length(shot_xg_list)/n_matches*norm_matches,0),
                                                       replace=FALSE)
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                        }
                        
                        sim_goal_dat <-  data.frame(value = unlist(sim_goal_list))
                        
                          goal_prob <- sim_goal_dat %>% 
                            count(value) %>% 
                            summarise(goals = value,
                                      prob = round(n/1000*10,1)) %>% 
                            arrange(goals)
                        
                          return(goal_prob)
                        
                        
                        
                        
                        
                        
                      }
                      
                      library(dplyr)
                      out <- full_df %>% 
                        group_by(team) %>% 
                        group_modify(~with(.x, 
                          calculate_goals_norm(shot_xg_list = unlist(cluster), 
                                 n_matches = tot_matches, norm_matches = 20))) %>%
                        ungroup
                      
                      > as.data.frame(out)
                         team goals prob
                      1     A     0  0.6
                      2     A     1  4.0
                      3     A     2 12.4
                      4     A     3 20.6
                      5     A     4 23.8
                      6     A     5 19.0
                      7     A     6 11.6
                      8     A     7  5.6
                      9     A     8  1.8
                      10    A     9  0.4
                      11    A    10  0.1
                      12    A    12  0.0
                      13    B     0  0.0
                      14    B     1  0.8
                      15    B     2  3.7
                      16    B     3 11.1
                      17    B     4 18.6
                      18    B     5 22.4
                      19    B     6 19.6
                      20    B     7 12.4
                      21    B     8  6.9
                      22    B     9  2.9
                      23    B    10  1.1
                      24    B    11  0.3
                      25    B    12  0.1
                      26    B    14  0.0
                      
                      sim_goal_list <- as_tibble(sim_goal_list)
                      
                      sim_goal_dat <-  data.frame(value = unlist(sim_goal_list));
                      
                      
                      calculate_goals_norm <- function(shot_xg_list, n_matches, norm_matches){
                        
                        #set seed only for stackoverflow question!!!!
                        set.seed(123)
                        
                        #Start goal total at 0
                        goals_total <- 0
                        
                        #Function to take an xG number and simulate whether it was a goal or not
                        xg_to_goals_sim <- function(shot_xg){
                      
                          #Start goal count at 0
                          Goals <- 0
                      
                          #For each shot, if it goes in, add a goal
                          for (shot in shot_xg){
                            if (runif(1)<=shot){
                              Goals <- Goals + 1
                            }
                          }
                      
                          #Finally, return the number of goals
                          return(Goals)
                      
                        }
                        
                        #Run xG calculator 10000 times to test winner %
                        sim_goal_list <- c()
                        # Create a for statement to populate the list
                        for (i in 1:10000) {
                          #Run the above formula for xG list
                          #But first we need to normalize the number of xG by randomly picking from xG
                          
                          if(n_matches == norm_matches){
                            new_shot_xg_list <- shot_xg_list
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches < norm_matches){
                            new_shot_xg_list <- c(shot_xg_list, 
                                                  sample(shot_xg_list, 
                                                         round(length(shot_xg_list)/n_matches*norm_matches,0)-length(shot_xg_list),
                                                         replace=FALSE))
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches > norm_matches){
                            
                            new_shot_xg_list <- sample(shot_xg_list, 
                                                       round(length(shot_xg_list)/n_matches*norm_matches,0),
                                                       replace=FALSE)
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                        }
                        
                        sim_goal_dat <-  data.frame(value = unlist(sim_goal_list))
                        
                          goal_prob <- sim_goal_dat %>% 
                            count(value) %>% 
                            summarise(goals = value,
                                      prob = round(n/1000*10,1)) %>% 
                            arrange(goals)
                        
                          return(goal_prob)
                        
                        
                        
                        
                        
                        
                      }
                      
                      library(dplyr)
                      out <- full_df %>% 
                        group_by(team) %>% 
                        group_modify(~with(.x, 
                          calculate_goals_norm(shot_xg_list = unlist(cluster), 
                                 n_matches = tot_matches, norm_matches = 20))) %>%
                        ungroup
                      
                      > as.data.frame(out)
                         team goals prob
                      1     A     0  0.6
                      2     A     1  4.0
                      3     A     2 12.4
                      4     A     3 20.6
                      5     A     4 23.8
                      6     A     5 19.0
                      7     A     6 11.6
                      8     A     7  5.6
                      9     A     8  1.8
                      10    A     9  0.4
                      11    A    10  0.1
                      12    A    12  0.0
                      13    B     0  0.0
                      14    B     1  0.8
                      15    B     2  3.7
                      16    B     3 11.1
                      17    B     4 18.6
                      18    B     5 22.4
                      19    B     6 19.6
                      20    B     7 12.4
                      21    B     8  6.9
                      22    B     9  2.9
                      23    B    10  1.1
                      24    B    11  0.3
                      25    B    12  0.1
                      26    B    14  0.0
                      
                      sim_goal_list <- as_tibble(sim_goal_list)
                      
                      sim_goal_dat <-  data.frame(value = unlist(sim_goal_list));
                      
                      
                      calculate_goals_norm <- function(shot_xg_list, n_matches, norm_matches){
                        
                        #set seed only for stackoverflow question!!!!
                        set.seed(123)
                        
                        #Start goal total at 0
                        goals_total <- 0
                        
                        #Function to take an xG number and simulate whether it was a goal or not
                        xg_to_goals_sim <- function(shot_xg){
                      
                          #Start goal count at 0
                          Goals <- 0
                      
                          #For each shot, if it goes in, add a goal
                          for (shot in shot_xg){
                            if (runif(1)<=shot){
                              Goals <- Goals + 1
                            }
                          }
                      
                          #Finally, return the number of goals
                          return(Goals)
                      
                        }
                        
                        #Run xG calculator 10000 times to test winner %
                        sim_goal_list <- c()
                        # Create a for statement to populate the list
                        for (i in 1:10000) {
                          #Run the above formula for xG list
                          #But first we need to normalize the number of xG by randomly picking from xG
                          
                          if(n_matches == norm_matches){
                            new_shot_xg_list <- shot_xg_list
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches < norm_matches){
                            new_shot_xg_list <- c(shot_xg_list, 
                                                  sample(shot_xg_list, 
                                                         round(length(shot_xg_list)/n_matches*norm_matches,0)-length(shot_xg_list),
                                                         replace=FALSE))
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches > norm_matches){
                            
                            new_shot_xg_list <- sample(shot_xg_list, 
                                                       round(length(shot_xg_list)/n_matches*norm_matches,0),
                                                       replace=FALSE)
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                        }
                        
                        sim_goal_dat <-  data.frame(value = unlist(sim_goal_list))
                        
                          goal_prob <- sim_goal_dat %>% 
                            count(value) %>% 
                            summarise(goals = value,
                                      prob = round(n/1000*10,1)) %>% 
                            arrange(goals)
                        
                          return(goal_prob)
                        
                        
                        
                        
                        
                        
                      }
                      
                      library(dplyr)
                      out <- full_df %>% 
                        group_by(team) %>% 
                        group_modify(~with(.x, 
                          calculate_goals_norm(shot_xg_list = unlist(cluster), 
                                 n_matches = tot_matches, norm_matches = 20))) %>%
                        ungroup
                      
                      > as.data.frame(out)
                         team goals prob
                      1     A     0  0.6
                      2     A     1  4.0
                      3     A     2 12.4
                      4     A     3 20.6
                      5     A     4 23.8
                      6     A     5 19.0
                      7     A     6 11.6
                      8     A     7  5.6
                      9     A     8  1.8
                      10    A     9  0.4
                      11    A    10  0.1
                      12    A    12  0.0
                      13    B     0  0.0
                      14    B     1  0.8
                      15    B     2  3.7
                      16    B     3 11.1
                      17    B     4 18.6
                      18    B     5 22.4
                      19    B     6 19.6
                      20    B     7 12.4
                      21    B     8  6.9
                      22    B     9  2.9
                      23    B    10  1.1
                      24    B    11  0.3
                      25    B    12  0.1
                      26    B    14  0.0
                      
                      sim_goal_list <- as_tibble(sim_goal_list)
                      
                      sim_goal_dat <-  data.frame(value = unlist(sim_goal_list));
                      
                      
                      calculate_goals_norm <- function(shot_xg_list, n_matches, norm_matches){
                        
                        #set seed only for stackoverflow question!!!!
                        set.seed(123)
                        
                        #Start goal total at 0
                        goals_total <- 0
                        
                        #Function to take an xG number and simulate whether it was a goal or not
                        xg_to_goals_sim <- function(shot_xg){
                      
                          #Start goal count at 0
                          Goals <- 0
                      
                          #For each shot, if it goes in, add a goal
                          for (shot in shot_xg){
                            if (runif(1)<=shot){
                              Goals <- Goals + 1
                            }
                          }
                      
                          #Finally, return the number of goals
                          return(Goals)
                      
                        }
                        
                        #Run xG calculator 10000 times to test winner %
                        sim_goal_list <- c()
                        # Create a for statement to populate the list
                        for (i in 1:10000) {
                          #Run the above formula for xG list
                          #But first we need to normalize the number of xG by randomly picking from xG
                          
                          if(n_matches == norm_matches){
                            new_shot_xg_list <- shot_xg_list
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches < norm_matches){
                            new_shot_xg_list <- c(shot_xg_list, 
                                                  sample(shot_xg_list, 
                                                         round(length(shot_xg_list)/n_matches*norm_matches,0)-length(shot_xg_list),
                                                         replace=FALSE))
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches > norm_matches){
                            
                            new_shot_xg_list <- sample(shot_xg_list, 
                                                       round(length(shot_xg_list)/n_matches*norm_matches,0),
                                                       replace=FALSE)
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                        }
                        
                        sim_goal_dat <-  data.frame(value = unlist(sim_goal_list))
                        
                          goal_prob <- sim_goal_dat %>% 
                            count(value) %>% 
                            summarise(goals = value,
                                      prob = round(n/1000*10,1)) %>% 
                            arrange(goals)
                        
                          return(goal_prob)
                        
                        
                        
                        
                        
                        
                      }
                      
                      library(dplyr)
                      out <- full_df %>% 
                        group_by(team) %>% 
                        group_modify(~with(.x, 
                          calculate_goals_norm(shot_xg_list = unlist(cluster), 
                                 n_matches = tot_matches, norm_matches = 20))) %>%
                        ungroup
                      
                      > as.data.frame(out)
                         team goals prob
                      1     A     0  0.6
                      2     A     1  4.0
                      3     A     2 12.4
                      4     A     3 20.6
                      5     A     4 23.8
                      6     A     5 19.0
                      7     A     6 11.6
                      8     A     7  5.6
                      9     A     8  1.8
                      10    A     9  0.4
                      11    A    10  0.1
                      12    A    12  0.0
                      13    B     0  0.0
                      14    B     1  0.8
                      15    B     2  3.7
                      16    B     3 11.1
                      17    B     4 18.6
                      18    B     5 22.4
                      19    B     6 19.6
                      20    B     7 12.4
                      21    B     8  6.9
                      22    B     9  2.9
                      23    B    10  1.1
                      24    B    11  0.3
                      25    B    12  0.1
                      26    B    14  0.0
                      
                      sim_goal_list <- as_tibble(sim_goal_list)
                      
                      sim_goal_dat <-  data.frame(value = unlist(sim_goal_list));
                      
                      
                      calculate_goals_norm <- function(shot_xg_list, n_matches, norm_matches){
                        
                        #set seed only for stackoverflow question!!!!
                        set.seed(123)
                        
                        #Start goal total at 0
                        goals_total <- 0
                        
                        #Function to take an xG number and simulate whether it was a goal or not
                        xg_to_goals_sim <- function(shot_xg){
                      
                          #Start goal count at 0
                          Goals <- 0
                      
                          #For each shot, if it goes in, add a goal
                          for (shot in shot_xg){
                            if (runif(1)<=shot){
                              Goals <- Goals + 1
                            }
                          }
                      
                          #Finally, return the number of goals
                          return(Goals)
                      
                        }
                        
                        #Run xG calculator 10000 times to test winner %
                        sim_goal_list <- c()
                        # Create a for statement to populate the list
                        for (i in 1:10000) {
                          #Run the above formula for xG list
                          #But first we need to normalize the number of xG by randomly picking from xG
                          
                          if(n_matches == norm_matches){
                            new_shot_xg_list <- shot_xg_list
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches < norm_matches){
                            new_shot_xg_list <- c(shot_xg_list, 
                                                  sample(shot_xg_list, 
                                                         round(length(shot_xg_list)/n_matches*norm_matches,0)-length(shot_xg_list),
                                                         replace=FALSE))
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                          if(n_matches > norm_matches){
                            
                            new_shot_xg_list <- sample(shot_xg_list, 
                                                       round(length(shot_xg_list)/n_matches*norm_matches,0),
                                                       replace=FALSE)
                            goals_total <- xg_to_goals_sim(new_shot_xg_list)
                            sim_goal_list[[i]] <- goals_total
                          }
                          
                        }
                        
                        sim_goal_dat <-  data.frame(value = unlist(sim_goal_list))
                        
                          goal_prob <- sim_goal_dat %>% 
                            count(value) %>% 
                            summarise(goals = value,
                                      prob = round(n/1000*10,1)) %>% 
                            arrange(goals)
                        
                          return(goal_prob)
                        
                        
                        
                        
                        
                        
                      }
                      

                      Powershell Basic

                      copy iconCopydownload iconDownload
                      Write-Host "Microsoft Powershell Calculator V3"
                      
                      function ParseInput {
                          $ref = ''
                          do {
                              $parsed = [int]::TryParse((Read-Host "Entrez une premiere valeur numerique"), [ref]$ref)
                              if (-not $parsed) {
                                  Write-Host "ERREUR ! Vous devez entrez une valeur numerique"
                              }
                          } while (-not $parsed)
                          $ref
                      }
                      
                      $R = $true
                      
                      while ($R) {
                          $Valeur1 = ParseInput
                          $Valeur2 = ParseInput
                          $operation = Read-Host "Quelle opération voulez-vous réaliser? Choisissez entre [+, -, *, or /] "
                          Switch($operation) {
                              - {
                                  Write-Host "Le resultat de votre soustraction est :"
                                  $Valeur1 - $Valeur2
                              }
                              + {
                                  Write-Host "Le resultat de votre addition est :"
                                  $Valeur1 + $Valeur2
                              }
                              * {
                                  Write-Host "Le resultat de votre multiplication est :"
                                  $Valeur1 * $Valeur2
                              }
                              / {
                                  Write-Host "Le resultat de votre division est :"
                                  $Valeur1 / $Valeur2
                              }
                              default {
                                  Write-Host "Option Invalide"
                              }
                          }
                          $choix = Read-Host "Desirez-vous continuer? Y/N"
                          if($choix -notmatch "^(Yes|Y)$") {
                              $R = $false
                          }
                      }
                      

                      Add Data To a New Sheet

                      copy iconCopydownload iconDownload
                      Option Explicit
                      
                      Sub AddToList()
                      
                          Const sName As String = "DILUTION CALCULATOR"
                          Const srgAddress As String = "M4,O4,Q4" ' at least two cells
                          
                          Const dName As String = "SETUP"
                          ' Both arrays have to have the same number of elements.
                          Dim dCols As Variant: dCols = VBA.Array(1, 5, 9, 13)
                          Dim Criteria As Variant
                          Criteria = VBA.Array("Customer", "Order Number", "Quantity", "Status")
                          
                          Dim wb As Workbook: Set wb = ThisWorkbook
                          
                          Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
                          Dim srg As Range: Set srg = sws.Range(srgAddress)
                          Dim cCount As Long: cCount = srg.Cells.Count
                          
                          Dim sCell As Range
                          
                          For Each sCell In srg.Cells
                              If Len(CStr(sCell.Value)) = 0 Then
                                  MsgBox "Please enter data in all fields.", vbCritical
                                  Exit Sub
                              End If
                          Next sCell
                          
                          Dim cIndex As Variant
                          cIndex = Application.Match(CStr(srg.Cells(1).Value), Criteria, 0)
                          
                          If IsError(cIndex) Then
                              MsgBox "Criteria not found.", vbCritical
                              Exit Sub
                          End If
                              
                          Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
                          Dim drg As Range: Set drg = dws.Cells(dws.Rows.Count, dCols(cIndex - 1)) _
                              .End(xlUp).Offset(1).Resize(, cCount - 1)
                          
                          Dim dc As Long
                          
                          For Each sCell In srg.Cells
                              If dc > 0 Then
                                  drg.Cells(dc).Value = sCell.Value
                              End If
                              dc = dc + 1
                          Next sCell
                          
                          srg.ClearContents
                          
                      End Sub
                      

                      Transferring an Excel Moving Average Calculator to R

                      copy iconCopydownload iconDownload
                      library(dplyr)
                      library(zoo)
                      
                      ndays <- 2
                      
                      data %>%
                        filter(Loan) %>%
                        arrange(day) %>%
                        mutate(q45days = rollapplyr(`usd price`, ndays, quantile, prob = 0.75, fill = NA)) %>%
                        filter(`usd price` < q45days) %>%
                        select(-q45days) %>%
                        mutate(fourtyfive_avg= rollmeanr(`usd price`, 45, fill = 0)) %>%
                        relocate(fourtyfive_avg)
                      
                      library(tidyverse)
                      library(lubridate)
                      #> 
                      #> Attaching package: 'lubridate'
                      #> The following objects are masked from 'package:base':
                      #> 
                      #>     date, intersect, setdiff, union
                      
                      data <- 
                        structure(list(`usd price` = c(50000, 60000, 40000, 35000, 1e+05, 
                        95000), `cad price` = c(62500, 75000, 50000, 43750, 125000, 118750
                        ), day = structure(c(1642118400, 1641772800, 1639958400, 1639785600, 
                        1638316800, 1640995200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                            Loan = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)), class = c("tbl_df", 
                        "tbl", "data.frame"), row.names = c(NA, -6L))
                      
                      data <- data %>% mutate(day=lubridate::parse_date_time(day, "ymd"))
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      data %>% arrange(day)
                      #> # A tibble: 6 x 5
                      #>   `usd price` `cad price` day                 Loan  fourtyfive_avg
                      #>         <dbl>       <dbl> <dttm>              <lgl>          <dbl>
                      #> 1      100000      125000 2021-12-01 00:00:00 TRUE             NaN
                      #> 2       35000       43750 2021-12-18 00:00:00 TRUE           35000
                      #> 3       40000       50000 2021-12-20 00:00:00 TRUE           37500
                      #> 4       95000      118750 2022-01-01 00:00:00 FALSE             NA
                      #> 5       60000       75000 2022-01-10 00:00:00 TRUE           45000
                      #> 6       50000       62500 2022-01-14 00:00:00 TRUE           46250
                      
                      library(tidyverse)
                      library(lubridate)
                      #> 
                      #> Attaching package: 'lubridate'
                      #> The following objects are masked from 'package:base':
                      #> 
                      #>     date, intersect, setdiff, union
                      
                      data <- 
                        structure(list(`usd price` = c(50000, 60000, 40000, 35000, 1e+05, 
                        95000), `cad price` = c(62500, 75000, 50000, 43750, 125000, 118750
                        ), day = structure(c(1642118400, 1641772800, 1639958400, 1639785600, 
                        1638316800, 1640995200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                            Loan = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)), class = c("tbl_df", 
                        "tbl", "data.frame"), row.names = c(NA, -6L))
                      
                      data <- data %>% mutate(day=lubridate::parse_date_time(day, "ymd"))
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      data %>% arrange(day)
                      #> # A tibble: 6 x 5
                      #>   `usd price` `cad price` day                 Loan  fourtyfive_avg
                      #>         <dbl>       <dbl> <dttm>              <lgl>          <dbl>
                      #> 1      100000      125000 2021-12-01 00:00:00 TRUE             NaN
                      #> 2       35000       43750 2021-12-18 00:00:00 TRUE           35000
                      #> 3       40000       50000 2021-12-20 00:00:00 TRUE           37500
                      #> 4       95000      118750 2022-01-01 00:00:00 FALSE             NA
                      #> 5       60000       75000 2022-01-10 00:00:00 TRUE           45000
                      #> 6       50000       62500 2022-01-14 00:00:00 TRUE           46250
                      
                      library(tidyverse)
                      library(lubridate)
                      #> 
                      #> Attaching package: 'lubridate'
                      #> The following objects are masked from 'package:base':
                      #> 
                      #>     date, intersect, setdiff, union
                      
                      data <- 
                        structure(list(`usd price` = c(50000, 60000, 40000, 35000, 1e+05, 
                        95000), `cad price` = c(62500, 75000, 50000, 43750, 125000, 118750
                        ), day = structure(c(1642118400, 1641772800, 1639958400, 1639785600, 
                        1638316800, 1640995200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                            Loan = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)), class = c("tbl_df", 
                        "tbl", "data.frame"), row.names = c(NA, -6L))
                      
                      data <- data %>% mutate(day=lubridate::parse_date_time(day, "ymd"))
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      data %>% arrange(day)
                      #> # A tibble: 6 x 5
                      #>   `usd price` `cad price` day                 Loan  fourtyfive_avg
                      #>         <dbl>       <dbl> <dttm>              <lgl>          <dbl>
                      #> 1      100000      125000 2021-12-01 00:00:00 TRUE             NaN
                      #> 2       35000       43750 2021-12-18 00:00:00 TRUE           35000
                      #> 3       40000       50000 2021-12-20 00:00:00 TRUE           37500
                      #> 4       95000      118750 2022-01-01 00:00:00 FALSE             NA
                      #> 5       60000       75000 2022-01-10 00:00:00 TRUE           45000
                      #> 6       50000       62500 2022-01-14 00:00:00 TRUE           46250
                      
                      library(tidyverse)
                      library(lubridate)
                      #> 
                      #> Attaching package: 'lubridate'
                      #> The following objects are masked from 'package:base':
                      #> 
                      #>     date, intersect, setdiff, union
                      
                      data <- 
                        structure(list(`usd price` = c(50000, 60000, 40000, 35000, 1e+05, 
                        95000), `cad price` = c(62500, 75000, 50000, 43750, 125000, 118750
                        ), day = structure(c(1642118400, 1641772800, 1639958400, 1639785600, 
                        1638316800, 1640995200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
                            Loan = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)), class = c("tbl_df", 
                        "tbl", "data.frame"), row.names = c(NA, -6L))
                      
                      data <- data %>% mutate(day=lubridate::parse_date_time(day, "ymd"))
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      myfunc <- function(x){
                        fourtyfive_days <- as.Date(x - ddays(45))
                        
                        if(!data$Loan[data$day %in% x]) return(NA)
                        
                        data <-
                          data %>%
                          filter(Loan) %>%
                          filter(`usd price` <= quantile(`usd price`, probs = 0.75)) %>% 
                          filter(day <= x) %>%
                          filter(day >= fourtyfive_days) %>%
                          summarize(fourtyfive_avg = mean(`usd price`))
                        
                          return(data$fourtyfive_avg)
                      }
                      data$fourtyfive_avg <- sapply(data$day, simplify = TRUE,  FUN = myfunc)
                      
                      data %>% arrange(day)
                      #> # A tibble: 6 x 5
                      #>   `usd price` `cad price` day                 Loan  fourtyfive_avg
                      #>         <dbl>       <dbl> <dttm>              <lgl>          <dbl>
                      #> 1      100000      125000 2021-12-01 00:00:00 TRUE             NaN
                      #> 2       35000       43750 2021-12-18 00:00:00 TRUE           35000
                      #> 3       40000       50000 2021-12-20 00:00:00 TRUE           37500
                      #> 4       95000      118750 2022-01-01 00:00:00 FALSE             NA
                      #> 5       60000       75000 2022-01-10 00:00:00 TRUE           45000
                      #> 6       50000       62500 2022-01-14 00:00:00 TRUE           46250
                      

                      how to apply background outside of text

                      copy iconCopydownload iconDownload
                      <div class="wrapper">
                          <!-- A lot of content here -->
                      </div>
                      
                      <html>
                          <head>
                              <title>Terps Calculators Inc</title>
                              <style>
                                  body{
                                      background: url(https://s4.uupload.ir/files/722_30hg.jpg) 
                                  no-repeat; background-size: cover; margin: 100px;
                                  }
                                 .body{padding: 70px; border-style: ridge; border-width: 20px; border-color: grey;
                                  background-color: white;
                                  }
                      
                                 header, nav, main, footer{background-color: rgb(254, 189, 173); border: 4px solid grey;}
                                  header{font-family: Kunstler Script; font-size: 70px; padding: 30px 237px;}
                                  nav{font-family: sans-serif; font-size: 19px; text-align: center;}
                                  a:link{color: red;}
                                  main{padding: 30px 200px; color: black; font-weight: bold;}
                                  .intro{ font-weight: bold; text-decoration: underline; font-size: 30px;}
                                  p{font-size: 18px;}
                                  .head{font-weight: bold; font-size: 22px; font-family: arial;}
                                  .text{font-style: italic;}
                                  .color{text-decoration: underline; color: red; font-size: 25px; font-style: italic;}
                                  footer{border: none; text-align: center; font-size: 20px; font-weight: bold;}
                              </style>
                          </head>
                          <body>
                              <div class="body">
                              <header>
                                  <img src="Burj Khalifa.jpg" width="100px" height="130px"> Terps Calculators Inc. 
                                  <img src="University of Maryland.png" width="100px" height="100px">
                              </header>
                              <br>
                              <nav>
                                  <a href="http://www.umd.edu">http://www.umd.edu,</a> <a href="http://www.cs.umd.edu">http://www.cs.umd.edu,</a> 
                                  <a href="http://www.testudo.umd.edu">http://www.testudo.umd.edu</a>
                              </nav>
                              <br>
                              <main>
                                  <div class="intro">Introduction</div>
                                  <p><span class="head">Terps Calculators Inc.</span><span class="text">
                                   implements and provides these calculators for your use. We keep expanding 
                                   our collection every day, so make sure you stop by often.</span></p>
                                  <div class="intro">Calculators</div>
                                  <br><br>
                                  <img src="Calculator.png" height="60px" width="50px"> <span class="color">&nbsp;Grades Calculator</span>
                                  <br>
                                  <img src="Calculator.png" height="60px" width="50px"><span class="color">&nbsp;Interest Calculator</span>
                              </main>
                              <br>
                              <footer>Terps Calculators Inc.&reg;</footer>
                              </div>
                          </body>
                      </html>```
                      

                      Javascript function to calculate window areas in a table

                      copy iconCopydownload iconDownload
                      function addNewWindow(){
                        let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.foreach(h=>{
                        h.addEventListener('change', ()=>{
                          let width = h.parentElement.querySelector('.width');
                          let window = h.parentElement.querySelector('.window');
                          if(width.value !== ""){
                            calculate(width.value, h.value, window )
                          }
                        })
                      })
                      winputs.foreach(w=>{
                        w.addEventListener('change', ()=>{
                          let height = w.parentElement.querySelector('.height ');
                          let window = w.parentElement.querySelector('.window');
                          if(height.value !== ""){
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result){
                        result.value = w*h;
                      }
                      
                      function addNewWindow() {
                        let table = document.querySelector('#table');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.forEach(h => {
                        h.addEventListener('input', () => {
                          let width = h.parentElement.parentElement.querySelector('.width');
                          let window = h.parentElement.parentElement.querySelector('.window');
                          if (width.value !== "") {
                            calculate(width.value, h.value, window)
                          }
                        })
                      })
                      winputs.forEach(w => {
                        w.addEventListener('input', () => {
                          let height = w.parentElement.parentElement.querySelector('.height');
                          let window = w.parentElement.parentElement.querySelector('.window');
                          if (height.value !== "") {
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result) {
                        result.value = w * h;
                      }
                      <table id="table">
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                      </table>
                      
                      
                      <button onclick="addNewWindow()">add</button>
                      let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      
                      function addNewWindow(){
                        let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.foreach(h=>{
                        h.addEventListener('change', ()=>{
                          let width = h.parentElement.querySelector('.width');
                          let window = h.parentElement.querySelector('.window');
                          if(width.value !== ""){
                            calculate(width.value, h.value, window )
                          }
                        })
                      })
                      winputs.foreach(w=>{
                        w.addEventListener('change', ()=>{
                          let height = w.parentElement.querySelector('.height ');
                          let window = w.parentElement.querySelector('.window');
                          if(height.value !== ""){
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result){
                        result.value = w*h;
                      }
                      
                      function addNewWindow() {
                        let table = document.querySelector('#table');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.forEach(h => {
                        h.addEventListener('input', () => {
                          let width = h.parentElement.parentElement.querySelector('.width');
                          let window = h.parentElement.parentElement.querySelector('.window');
                          if (width.value !== "") {
                            calculate(width.value, h.value, window)
                          }
                        })
                      })
                      winputs.forEach(w => {
                        w.addEventListener('input', () => {
                          let height = w.parentElement.parentElement.querySelector('.height');
                          let window = w.parentElement.parentElement.querySelector('.window');
                          if (height.value !== "") {
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result) {
                        result.value = w * h;
                      }
                      <table id="table">
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                      </table>
                      
                      
                      <button onclick="addNewWindow()">add</button>
                      let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      
                      function addNewWindow(){
                        let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.foreach(h=>{
                        h.addEventListener('change', ()=>{
                          let width = h.parentElement.querySelector('.width');
                          let window = h.parentElement.querySelector('.window');
                          if(width.value !== ""){
                            calculate(width.value, h.value, window )
                          }
                        })
                      })
                      winputs.foreach(w=>{
                        w.addEventListener('change', ()=>{
                          let height = w.parentElement.querySelector('.height ');
                          let window = w.parentElement.querySelector('.window');
                          if(height.value !== ""){
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result){
                        result.value = w*h;
                      }
                      
                      function addNewWindow() {
                        let table = document.querySelector('#table');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.forEach(h => {
                        h.addEventListener('input', () => {
                          let width = h.parentElement.parentElement.querySelector('.width');
                          let window = h.parentElement.parentElement.querySelector('.window');
                          if (width.value !== "") {
                            calculate(width.value, h.value, window)
                          }
                        })
                      })
                      winputs.forEach(w => {
                        w.addEventListener('input', () => {
                          let height = w.parentElement.parentElement.querySelector('.height');
                          let window = w.parentElement.parentElement.querySelector('.window');
                          if (height.value !== "") {
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result) {
                        result.value = w * h;
                      }
                      <table id="table">
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                      </table>
                      
                      
                      <button onclick="addNewWindow()">add</button>
                      let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      
                      function addNewWindow(){
                        let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.foreach(h=>{
                        h.addEventListener('change', ()=>{
                          let width = h.parentElement.querySelector('.width');
                          let window = h.parentElement.querySelector('.window');
                          if(width.value !== ""){
                            calculate(width.value, h.value, window )
                          }
                        })
                      })
                      winputs.foreach(w=>{
                        w.addEventListener('change', ()=>{
                          let height = w.parentElement.querySelector('.height ');
                          let window = w.parentElement.querySelector('.window');
                          if(height.value !== ""){
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result){
                        result.value = w*h;
                      }
                      
                      function addNewWindow() {
                        let table = document.querySelector('#table');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.forEach(h => {
                        h.addEventListener('input', () => {
                          let width = h.parentElement.parentElement.querySelector('.width');
                          let window = h.parentElement.parentElement.querySelector('.window');
                          if (width.value !== "") {
                            calculate(width.value, h.value, window)
                          }
                        })
                      })
                      winputs.forEach(w => {
                        w.addEventListener('input', () => {
                          let height = w.parentElement.parentElement.querySelector('.height');
                          let window = w.parentElement.parentElement.querySelector('.window');
                          if (height.value !== "") {
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result) {
                        result.value = w * h;
                      }
                      <table id="table">
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                      </table>
                      
                      
                      <button onclick="addNewWindow()">add</button>
                      let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      
                      function addNewWindow(){
                        let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.foreach(h=>{
                        h.addEventListener('change', ()=>{
                          let width = h.parentElement.querySelector('.width');
                          let window = h.parentElement.querySelector('.window');
                          if(width.value !== ""){
                            calculate(width.value, h.value, window )
                          }
                        })
                      })
                      winputs.foreach(w=>{
                        w.addEventListener('change', ()=>{
                          let height = w.parentElement.querySelector('.height ');
                          let window = w.parentElement.querySelector('.window');
                          if(height.value !== ""){
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result){
                        result.value = w*h;
                      }
                      
                      function addNewWindow() {
                        let table = document.querySelector('#table');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      }
                      
                      
                      var hinputs = document.querySelectorAll('.height');
                      var winputs = document.querySelectorAll('.width');
                      hinputs.forEach(h => {
                        h.addEventListener('input', () => {
                          let width = h.parentElement.parentElement.querySelector('.width');
                          let window = h.parentElement.parentElement.querySelector('.window');
                          if (width.value !== "") {
                            calculate(width.value, h.value, window)
                          }
                        })
                      })
                      winputs.forEach(w => {
                        w.addEventListener('input', () => {
                          let height = w.parentElement.parentElement.querySelector('.height');
                          let window = w.parentElement.parentElement.querySelector('.window');
                          if (height.value !== "") {
                            calculate(w.value, height.value, window)
                          }
                        })
                      })
                      
                      function calculate(w, h, result) {
                        result.value = w * h;
                      }
                      <table id="table">
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                        <tr>
                          <td><input type="number" class="height"></td>
                          <td><input type="number" class="width"></td>
                          <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                        </tr>
                      </table>
                      
                      
                      <button onclick="addNewWindow()">add</button>
                      let table = document.querySelectot('#table1');
                        let window = `
                          <tr>
                            <td><input type="number" class="height"></td>
                            <td><input type="number" class="width"></td>
                            <td><input type="number" class="window" disabled style="user-select: select-all"></td>
                          </tr>
                        `;
                        table.insertAdjacentHTML('beforeend', window)
                      
                      // select the first item with class `height` in the DOM => not what you want
                      var height = document.querySelector('.height').value;
                      
                      // this should work
                      var height = row.querySelector('.height').value;
                      
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      
                      const add = document.getElementById('add')
                      const calc = document.getElementById('calc')
                      const table1 = document.getElementById('table1')
                      
                      add.addEventListener('click', addWindow1)
                      calc.addEventListener('click', calculateArea1)
                      
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      <button id="add">add</button>
                      <button id="calc">calc</button>
                      <table id="table1">
                        <tr>
                          <th>Height</th>
                          <th>Width</th>
                          <th>Area</th>
                        </tr>
                        <tr class="data">
                          <td><input class="height" type="text" /></td>
                          <td><input class="width" type="text" /></td>
                          <td>
                            <div class="area"></div>
                          </td>
                        </tr>
                      </table>
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      
                      const add = document.getElementById('add')
                      const calc = document.getElementById('calc')
                      const table1 = document.getElementById('table1')
                      
                      add.addEventListener('click', addWindow1)
                      calc.addEventListener('click', calculateArea1)
                      
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      <button id="add">add</button>
                      <button id="calc">calc</button>
                      <table id="table1">
                        <tr>
                          <th>Height</th>
                          <th>Width</th>
                          <th>Area</th>
                        </tr>
                        <tr class="data">
                          <td><input class="height" type="text" /></td>
                          <td><input class="width" type="text" /></td>
                          <td>
                            <div class="area"></div>
                          </td>
                        </tr>
                      </table>
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      
                      const add = document.getElementById('add')
                      const calc = document.getElementById('calc')
                      const table1 = document.getElementById('table1')
                      
                      add.addEventListener('click', addWindow1)
                      calc.addEventListener('click', calculateArea1)
                      
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      <button id="add">add</button>
                      <button id="calc">calc</button>
                      <table id="table1">
                        <tr>
                          <th>Height</th>
                          <th>Width</th>
                          <th>Area</th>
                        </tr>
                        <tr class="data">
                          <td><input class="height" type="text" /></td>
                          <td><input class="width" type="text" /></td>
                          <td>
                            <div class="area"></div>
                          </td>
                        </tr>
                      </table>
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      
                      const add = document.getElementById('add')
                      const calc = document.getElementById('calc')
                      const table1 = document.getElementById('table1')
                      
                      add.addEventListener('click', addWindow1)
                      calc.addEventListener('click', calculateArea1)
                      
                      function addWindow1() {
                        const row1 = table1.insertRow(1)
                        row1.className = 'data'
                        row1.innerHTML = `
                            <td><input class="height" type="text" /></td>
                            <td><input class="width" type="text" /></td>
                            <td><div class="area"></div></td>
                            `
                      }
                      
                      function calculateArea1() {
                        const data = document.querySelectorAll('.data')
                      
                        for (let i = 0; i < data.length; i++) {
                          const height = data[i].querySelector('.height').value
                          const width = data[i].querySelector('.width').value
                          data[i].querySelector('.area').textContent = height * width
                        }
                      }
                      <button id="add">add</button>
                      <button id="calc">calc</button>
                      <table id="table1">
                        <tr>
                          <th>Height</th>
                          <th>Width</th>
                          <th>Area</th>
                        </tr>
                        <tr class="data">
                          <td><input class="height" type="text" /></td>
                          <td><input class="width" type="text" /></td>
                          <td>
                            <div class="area"></div>
                          </td>
                        </tr>
                      </table>

                      Using JS to show HTML output of calculation

                      copy iconCopydownload iconDownload
                      document.getElementById("submitBtn").addEventListener("click",function(){
                      let gen = document.querySelector('#gender').value
                         let weight = document.querySelector('#weight').value
                          let height = document.querySelector('#height').value
                           let ages = document.querySelector('#age').value
                      calcBMR(gen,weight,height,ages)
                      })
                          function calcBMR(gender, weightKG, heightCM, age) {
                             let BMR
                              // Calculate BMR
                              if (gender = 'male') {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                              } else {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                              }
                          
                              document.querySelector('#output').textContent = BMR;
                          }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      document.getElementById("submitBtn").addEventListener("click",function(){
                      let gen = document.querySelector('#gender').value
                         let weight = document.querySelector('#weight').value
                          let height = document.querySelector('#height').value
                           let ages = document.querySelector('#age').value
                      calcBMR(gen,weight,height,ages)
                      })
                          function calcBMR(gender, weightKG, heightCM, age) {
                             let BMR
                              // Calculate BMR
                              if (gender = 'male') {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                              } else {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                              }
                          
                              document.querySelector('#output').textContent = BMR;
                          }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      let out = document.getElementById("output");
                      let gender = document.getElementById("gender");
                      let height = document.getElementById("height");
                      let weight = document.getElementById("weight");
                      let age = document.getElementById("age");
                      
                      // If you want to pass arguments to the event handler, you need to wrap the handler call in another function
                      document.getElementById("submitBtn").addEventListener("click", function(){calcBMR(gender.value.toLowerCase(), +weight.value, +height.value, +age.value)});
                          
                          function calcBMR(gender, weightKG, heightCM, age) {
                              let BMR = null;  // Declare the variable in the function scope
                              console.log(gender, weightKG, heightCM, age);
                          
                              // Calculate BMR
                              if (gender === 'male') {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                              } else {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                              }
                          
                              console.log(BMR);
                              output.textContent = BMR;
                              
                          }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm" onsubmit="calcBMR()">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button type="button" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      let out = document.getElementById("output");
                      let gender = document.getElementById("gender");
                      let height = document.getElementById("height");
                      let weight = document.getElementById("weight");
                      let age = document.getElementById("age");
                      
                      // If you want to pass arguments to the event handler, you need to wrap the handler call in another function
                      document.getElementById("submitBtn").addEventListener("click", function(){calcBMR(gender.value.toLowerCase(), +weight.value, +height.value, +age.value)});
                          
                          function calcBMR(gender, weightKG, heightCM, age) {
                              let BMR = null;  // Declare the variable in the function scope
                              console.log(gender, weightKG, heightCM, age);
                          
                              // Calculate BMR
                              if (gender === 'male') {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                              } else {
                                  BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                              }
                          
                              console.log(BMR);
                              output.textContent = BMR;
                              
                          }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm" onsubmit="calcBMR()">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button type="button" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      function calcBMR(e) {
                      e.preventDefault();
                      var elements = document.getElementById("bmrForm").elements; // logic to get all form elements
                      var obj ={};
                      for(var i = 0 ; i < elements.length ; i++){
                          var item = elements.item(i);
                          obj[item.id] = item.value;
                      }
                      const {gender, weight, height, age } = obj; //Get values from obj
                      // Calculate BMR
                      let BMR = '';
                      if (gender === 'male') {
                          BMR = 10 * weight + 6.25 * height - 5 * age + 5;
                      } else {
                          BMR = 10 * weight + 6.25 * height - 5 * age - 161;
                      }
                      console.log(BMR);
                      }
                      
                      function calcBMR() {
                          let gender = document.getElementById("gender").value;
                          let weightKG = document.getElementById("weight").value;
                          let heightCM = document.getElementById("height").value;
                          let age = document.getElementById("age").value;
                          let BMR;
                          // Calculate BMR
                          if (gender === 'male') {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                          } else {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                          }
                      
                          console.log(BMR);
                          document.getElementById("output").textContent = BMR;
                          return false;
                      }
                      <body>
                      <script src="./script.js"></script>
                      <section>
                          <form id="bmrForm" onsubmit="return calcBMR()">
                              <input type="text" id="gender" placeholder="Male or female?">
                              <input type="number" id="weight" placeholder="Weight in KG">
                              <input type="number" id="height" placeholder="Height in CM">
                              <input type="number" id="age" placeholder="How old are you?">
                              <button type="submit" id="submitBtn">Do Magic!</button>
                          </form>
                          <p id="output">0</p>
                      </section>
                      function calcBMR() {
                          let gender = document.getElementById("gender").value;
                          let weightKG = document.getElementById("weight").value;
                          let heightCM = document.getElementById("height").value;
                          let age = document.getElementById("age").value;
                          let BMR;
                          // Calculate BMR
                          if (gender === 'male') {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                          } else {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                          }
                      
                          console.log(BMR);
                          document.getElementById("output").textContent = BMR;
                          return false;
                      }
                      <body>
                      <script src="./script.js"></script>
                      <section>
                          <form id="bmrForm" onsubmit="return calcBMR()">
                              <input type="text" id="gender" placeholder="Male or female?">
                              <input type="number" id="weight" placeholder="Weight in KG">
                              <input type="number" id="height" placeholder="Height in CM">
                              <input type="number" id="age" placeholder="How old are you?">
                              <button type="submit" id="submitBtn">Do Magic!</button>
                          </form>
                          <p id="output">0</p>
                      </section>
                      document.getElementById("bmrForm").addEventListener("submit", calcBMR);
                      
                      const output = document.getElementById('output');
                      
                      function calcBMR(event) {
                          // Get the [gender, weightKG, heightCM, age] value
                          let gender = document.getElementById('gender').value;
                          let weightKG = document.getElementById('weight').value;
                          let heightCM = document.getElementById('height').value;
                          let age = document.getElementById('age').value;
                      
                          // Set default BMR to 0
                          let BMR = 0;
                          // Calculate BMR
                          if (gender = 'male') {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                          } else {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                          }
                      
                          console.log(BMR);
                          output.innerText = BMR;
                      
                          // Cancel form submit
                          event.preventDefault();
                          return;
                      }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button type="submit" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      document.getElementById("bmrForm").addEventListener("submit", calcBMR);
                      
                      const output = document.getElementById('output');
                      
                      function calcBMR(event) {
                          // Get the [gender, weightKG, heightCM, age] value
                          let gender = document.getElementById('gender').value;
                          let weightKG = document.getElementById('weight').value;
                          let heightCM = document.getElementById('height').value;
                          let age = document.getElementById('age').value;
                      
                          // Set default BMR to 0
                          let BMR = 0;
                          // Calculate BMR
                          if (gender = 'male') {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age + 5;
                          } else {
                              BMR = 10 * weightKG + 6.25 * heightCM - 5 * age - 161;
                          }
                      
                          console.log(BMR);
                          output.innerText = BMR;
                      
                          // Cancel form submit
                          event.preventDefault();
                          return;
                      }
                      <body>
                          <script src="./script.js"></script>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?">
                                  <input type="number" id="weight" placeholder="Weight in KG">
                                  <input type="number" id="height" placeholder="Height in CM">
                                  <input type="number" id="age" placeholder="How old are you?">
                                  <button type="submit" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      // your form
                      var form = document.getElementById("formId");
                      
                      var DoMagic = function(event) 
                      {
                        event.preventDefault();
                        var elements = form.elements;
                        if (elements["gender"].value == "male") 
                        {
                          var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value + 5;
                        }
                        else 
                        {
                          var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value - 161;
                        }
                        document.getElementById("result").textContent = "Result: " + result;
                      }
                      
                      // attach event listener
                      form.addEventListener("submit", DoMagic, true);
                      <form id = "formId">
                        <label>Gender</label>
                        <select name="gender">
                          <option value="male">Male</option>
                          <option value="female">Female</option>
                        </select>
                        <br>
                        <label>Weight (kg)</label>
                        <input name="weight" type="number">
                        <br>
                        <label>Height (cm)</label>
                        <input name="height" type="number">
                        <br>
                        <label>Age (years)</label>
                        <input name="age" type="number">
                        <br>
                        <input type="submit" value="Do Magic!">
                      </form>
                      <span id='result'> </span>
                      // your form
                      var form = document.getElementById("formId");
                      
                      var DoMagic = function(event) 
                      {
                        event.preventDefault();
                        var elements = form.elements;
                        if (elements["gender"].value == "male") 
                        {
                          var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value + 5;
                        }
                        else 
                        {
                          var result = 10 * elements["weight"].value + 6.25 * elements["height"].value - 5 * elements["age"].value - 161;
                        }
                        document.getElementById("result").textContent = "Result: " + result;
                      }
                      
                      // attach event listener
                      form.addEventListener("submit", DoMagic, true);
                      <form id = "formId">
                        <label>Gender</label>
                        <select name="gender">
                          <option value="male">Male</option>
                          <option value="female">Female</option>
                        </select>
                        <br>
                        <label>Weight (kg)</label>
                        <input name="weight" type="number">
                        <br>
                        <label>Height (cm)</label>
                        <input name="height" type="number">
                        <br>
                        <label>Age (years)</label>
                        <input name="age" type="number">
                        <br>
                        <input type="submit" value="Do Magic!">
                      </form>
                      <span id='result'> </span>
                       <body>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?" name="gender">
                                  <input type="number" id="weight" placeholder="Weight in KG" name="weight">
                                  <input type="number" id="height" placeholder="Height in CM" name="height">
                                  <input type="number" id="age" placeholder="How old are you?" name="age">
                                  <button type="submit" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      
                      
                      document.getElementById("bmrForm").addEventListener("submit", calcBMR);
                      const output = document.querySelector('#output')
                          
                      function calcBMR(e) {
                            e.preventDefault();
                        
                        output.innerText = ''
                        const formData = new FormData(e.target)
                        const { age, gender, height, weight} = Object.fromEntries(formData);
                      
                            let BMR  = 0
                              // Calculate BMR
                              if (gender === 'male') {
                                  BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) + 5;
                              } else {
                                   BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) - 161;
                              }
                          
                              output.innerText = BMR
                          }
                      
                      
                       <body>
                          <section>
                              <form id="bmrForm">
                                  <input type="text" id="gender" placeholder="Male or female?" name="gender">
                                  <input type="number" id="weight" placeholder="Weight in KG" name="weight">
                                  <input type="number" id="height" placeholder="Height in CM" name="height">
                                  <input type="number" id="age" placeholder="How old are you?" name="age">
                                  <button type="submit" id="submitBtn">Do Magic!</button>
                              </form>
                              <p id="output">0</p>
                          </section>
                      </body>
                      
                      
                      document.getElementById("bmrForm").addEventListener("submit", calcBMR);
                      const output = document.querySelector('#output')
                          
                      function calcBMR(e) {
                            e.preventDefault();
                        
                        output.innerText = ''
                        const formData = new FormData(e.target)
                        const { age, gender, height, weight} = Object.fromEntries(formData);
                      
                            let BMR  = 0
                              // Calculate BMR
                              if (gender === 'male') {
                                  BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) + 5;
                              } else {
                                   BMR = 10 * parseInt(weight) + 6.25 * parseInt(height) - 5 * parseInt(age) - 161;
                              }
                          
                              output.innerText = BMR
                          }
                      
                      

                      Community Discussions

                      Trending Discussions on calculator
                      • Javascript - Stuck in an if statement - Beginner Question
                      • Ball-Triangle Collision
                      • Use \n in Python as a normal string
                      • How do I take a custom function and use it with dplyr group_by in r?
                      • Powershell Basic
                      • What instance of `Num` is used with literals e.g. in `print 1`?
                      • Add Data To a New Sheet
                      • Transferring an Excel Moving Average Calculator to R
                      • how to apply background outside of text
                      • Javascript function to calculate window areas in a table
                      Trending Discussions on calculator

                      QUESTION

                      Javascript - Stuck in an if statement - Beginner Question

                      Asked 2022-Apr-01 at 23:24

                      I am trying to make a calculator, simply my problem is this:

                      1. Page refreshes.
                      2. User clicks on any number and the number gets added to the First Number: nums_clicked h1.
                      3. If user clicks on an operator sign(+ - *), the clicked boolean becomes true.
                      4. If clicked is true, add the numbers clicked to the Second Number: nums_clicked

                      My problem is even if I click on an operator sign, it keeps adding the numbers I am clicking to the First Number: nums_clicked h1, why is that happening? It even happens while clicked is TRUE!

                      My

                      let numbers = [];
                      let first_num = "";
                      let second_num = "";
                      let clicked = false;
                      let result = false;
                      for (var i = 0; i < 9; i++) {
                        numbers[i] = parseInt(document.querySelectorAll("button")[i].innerText);
                      
                      }
                      
                      for (var i = 9; i < 12; i++) {
                        document.querySelectorAll("button")[i].addEventListener("click", function() {
                          clicked = true;
                        });
                      }
                      
                      if (!clicked && !result) {
                        for (let i = 0; i < 9; i++) {
                          if (clicked) {
                            break;
                          }
                          document.querySelectorAll("button")[i].addEventListener("click",
                            function() {
                              console.log("clicked = " + clicked);
                      
                              first_num += this.innerText;
                              document.getElementById("firstNumber").innerText = "Number1: " + first_num;
                            });
                        }
                      }
                      if (clicked && !result) {
                        for (let i = 0; i < 9; i++) {
                      
                          document.querySelectorAll("button")[i].addEventListener("click",
                            function() {
                      
                              second_num += this.innerText;
                              document.getElementById("secondNumber").innerText = "Number2: " + second_num;
                            });
                        }
                      }
                      document.getElementById("result-btn").addEventListener("click",
                        function() {
                      
                          result = true;
                        });
                      <!DOCTYPE html>
                      <html lang="en" dir="ltr">
                      
                      <head>
                        <meta charset="utf-8">
                        <link rel="stylesheet" href="css/styles.css">
                        <title></title>
                      </head>
                      
                      <body>
                      
                        <div class="container">
                      
                          <button type="button" name="button">1</button>
                          <button type="button" name="button">2</button>
                          <button type="button" name="button">3</button>
                          <br>
                          <button type="button" name="button">4</button>
                          <button type="button" name="button">5</button>
                          <button type="button" name="button">6</button>
                          <br>
                          <button type="button" name="button">7</button>
                          <button type="button" name="button">8</button>
                          <button type="button" name="button">9</button>
                          <br>
                          <br>
                          <button type="button" name="button">+</button>
                          <button type="button" name="button">*</button>
                          <button type="button" name="button">-</button>
                          <br>
                          <button id="result-btn" type="button" name="button">Result</button>
                          <h1 id="firstNumber">First Number: </h1>
                          <h1 id="secondNumber">Second Number: </h1>
                          <h1 id="result">Result: </h1>
                        </div>
                        <script src="index.js" charset="utf-8"></script>
                      </body>
                      
                      </html>

                      Code:

                      Screenshot of index.html (Red part while clicked=false and blue part is while clicked=true: enter image description here

                      ANSWER

                      Answered 2022-Apr-01 at 23:24

                      Your main issue was that you were never creating the click events for the second number, because those were behind the if(!result.... Like Barmar mentioned, even if you created the click events for the second number, the events from the first number would be triggered also and it would still not work. Also you did not had anything for setting the actual results.

                      I made some changes on your code to make it simpler to understand, but still trying to follow your logic. Here you go:

                      let first_num;
                      let second_num;
                      let operation;
                      
                      for (var i = 9; i < 12; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          operation = this.innerText;
                        });
                      }
                      
                      for (let i = 0; i < 9; i++) {
                        document.querySelectorAll('button')[i].addEventListener('click', function () {
                          if (!operation) {
                            document.getElementById('firstNumber').innerText += this.innerText;
                          } else {
                            document.getElementById('secondNumber').innerText += this.innerText;
                          }
                        });
                      }
                      
                      document.getElementById('result-btn').addEventListener('click', function () {
                        first_num = document.getElementById('firstNumber').innerText;
                        second_num = document.getElementById('secondNumber').innerText;
                        document.getElementById('result').innerText = calculate(
                          parseInt(first_num),
                          parseInt(second_num),
                          operation
                        );
                      });
                      
                      function calculate(a, b, operation) {
                        if (operation === '+') {
                          return sum(a, b);
                        } else if (operation === '-') {
                          return minus(a, b);
                        } else if (operation === '*') {
                          return multiply(a, b);
                        }
                      }
                      
                      function sum(a, b) {
                        return a + b;
                      }
                      function minus(a, b) {
                        return a - b;
                      }
                      function multiply(a, b) {
                        return a * b;
                      }
                      <div class="container">
                          <button type="button" name="button">1</button>
                          <button type="button" name="button">2</button>
                          <button type="button" name="button">3</button>
                          <br />
                          <button type="button" name="button">4</button>
                          <button type="button" name="button">5</button>
                          <button type="button" name="button">6</button>
                          <br />
                          <button type="button" name="button">7</button>
                          <button type="button" name="button">8</button>
                          <button type="button" name="button">9</button>
                          <br />
                          <br />
                          <button type="button" name="button">+</button>
                          <button type="button" name="button">*</button>
                          <button type="button" name="button">-</button>
                          <br />
                          <button id="result-btn" type="button" name="button">Result</button>
                          <h1>First Number: <span id="firstNumber"></span></h1>
                          <h1>Second Number: <span id="secondNumber"></span></h1>
                          <h1>Result: <span id="result"></span></h1>
                        </div>

                      Source https://stackoverflow.com/questions/71713398

                      Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                      Vulnerabilities

                      No vulnerabilities reported

                      Install calculator

                      You can download it from GitHub.
                      You can use calculator like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the calculator component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .

                      Support

                      For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

                      DOWNLOAD this Library from

                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      Explore Related Topics

                      Share this Page

                      share link
                      Consider Popular Apps Libraries
                      Try Top Libraries by sauce-archives
                      Compare Apps Libraries with Highest Support
                      Compare Apps Libraries with Highest Quality
                      Compare Apps Libraries with Highest Security
                      Compare Apps Libraries with Permissive License
                      Compare Apps Libraries with Highest Reuse
                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      • © 2022 Open Weaver Inc.