Build a Roman Numeral Converter Project - Build a Roman Numeral Converter

Tell us what’s happening:

I still have to finish but it seems to work, but if I try to send the test it gives me several errors, for example it tells me that if I enter a number greater than 3999 the text doesn’t come out but that’s not true!

Your code so far

<!DOCTYPE HTML>
<html lang="en">
  <head>
    <title>Roman Numeral Converter</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initialScale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400..900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <div id="title">
      <h1>Roman Numeral Converter</h1>
      <h2>Numeri imperii Romani</h2>
    </div>
    <div id="input-container">
      <label for="number" id="input-label">AVE!<br>Enter a number to convert to ancient Roman numbers</label>
      <input id="number" placeholder="SPQR" />
      <button id="convert-btn" type="button" >Try</button>
      </div>
      <div id="output" class="hidden"></div>
      <table id="conversion-table" border="1">
  <thead>
    <tr>
      <th>Arabs</th>
      <th>Romans</th>
      <th>Cardinal number</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>I</td>
      <td>unus, una, unum</td>
    </tr>
    <tr>
      <td>2</td>
      <td>II</td>
      <td>duo, duae, duo</td>
    </tr>
    <tr>
      <td>3</td>
      <td>III</td>
      <td>tres, tria</td>
    </tr>
    <tr>
      <td>4</td>
      <td>IV</td>
      <td>quattuor</td>
    </tr>
    <tr>
      <td>5</td>
      <td>V</td>
      <td>quinque</td>
    </tr>
    <tr>
      <td>6</td>
      <td>VI</td>
      <td>sex</td>
    </tr>
    <tr>
      <td>7</td>
      <td>VII</td>
      <td>septem</td>
    </tr>
    <tr>
      <td>8</td>
      <td>VIII</td>
      <td>octo</td>
    </tr>
    <tr>
      <td>9</td>
      <td>IX</td>
      <td>novem</td>
    </tr>
    <tr>
      <td>10</td>
      <td>X</td>
      <td>decem</td>
    </tr>
    <tr>
      <td>11</td>
      <td>XI</td>
      <td>undecim</td>
    </tr>
    <tr>
      <td>12</td>
      <td>XII</td>
      <td>duodecim</td>
    </tr>
    <tr>
      <td>13</td>
      <td>XIII</td>
      <td>tredecim</td>
    </tr>
    <tr>
      <td>14</td>
      <td>XIV</td>
      <td>quattuordecim</td>
    </tr>
    <tr>
      <td>15</td>
      <td>XV</td>
      <td>quindecim</td>
    </tr>
    <tr>
      <td>16</td>
      <td>XVI</td>
      <td>sedecim</td>
    </tr>
    <tr>
      <td>17</td>
      <td>XVII</td>
      <td>septemdecim</td>
    </tr>
    <tr>
      <td>18</td>
      <td>XVIII</td>
      <td>duodeviginti</td>
    </tr>
    <tr>
      <td>19</td>
      <td>XIX</td>
      <td>undeviginti</td>
    </tr>
    <tr>
      <td>20</td>
      <td>XX</td>
      <td>viginti</td>
    </tr>
    <tr>
      <td>21</td>
      <td>XXI</td>
      <td>unus et viginti / viginti unus</td>
    </tr>
    <tr>
      <td>22</td>
      <td>XXII</td>
      <td>duo et viginti / viginti duo</td>
    </tr>
    <tr>
      <td>30</td>
      <td>XXX</td>
      <td>triginta</td>
    </tr>
    <tr>
      <td>40</td>
      <td>XL</td>
      <td>quadraginta</td>
    </tr>
    <tr>
      <td>50</td>
      <td>L</td>
      <td>quinquaginta</td>
    </tr>
    <tr>
      <td>60</td>
      <td>LX</td>
      <td>sexaginta</td>
    </tr>
    <tr>
      <td>70</td>
      <td>LXX</td>
      <td>septuaginta</td>
    </tr>
    <tr>
      <td>80</td>
      <td>LXXX</td>
      <td>octoginta</td>
    </tr>
    <tr>
      <td>90</td>
      <td>XC</td>
      <td>nonaginta</td>
    </tr>
    <tr>
      <td>100</td>
      <td>C</td>
      <td>centum</td>
    </tr>
    <tr>
      <td>150</td>
      <td>CL</td>
      <td>centum quinquaginta</td>
    </tr>
    <tr>
      <td>160</td>
      <td>CLX</td>
      <td>centum sexaginta</td>
    </tr>
    <tr>
      <td>200</td>
      <td>CC</td>
      <td>ducenti</td>
    </tr>
    <tr>
      <td>250</td>
      <td>CCL</td>
      <td>ducenti quinquaginta</td>
    </tr>
    <tr>
      <td>300</td>
      <td>CCC</td>
      <td>trecenti</td>
    </tr>
    <tr>
      <td>400</td>
      <td>CD</td>
      <td>quadringenti</td>
    </tr>
    <tr>
      <td>500</td>
      <td>D</td>
      <td>quingenti</td>
    </tr>
    <tr>
      <td>600</td>
      <td>DC</td>
      <td>sescenti</td>
    </tr>
    <tr>
      <td>700</td>
      <td>DCC</td>
      <td>septingenti</td>
    </tr>
    <tr>
      <td>800</td>
      <td>DCCC</td>
      <td>octingenti</td>
    </tr>
    <tr>
      <td>900</td>
      <td>CM</td>
      <td>nongenti</td>
    </tr>
    <tr>
      <td>1 000</td>
      <td>M</td>
      <td>mille</td>
    </tr>
    <tr>
      <td>2 000</td>
      <td>MM</td>
      <td>duo milia</td>
    </tr>
    <tr>
      <td>3 000</td>
      <td>MMM</td>
      <td>tria milia</td>
    </tr>
      </tbody>
      </table>
      <div id="footer">Created by Michael Gennai - freeCodeCamp Javascript Algorithms and Data Structures - Certification Project 2/5</div>
    <script src="script.js"></script>
  </body>
</html>

const inputContainer = document.getElementById("input-container");
const inputLabel = document.getElementById("input-label");
const inputNumber = document.getElementById("number");
const convertBtn = document.getElementById("convert-btn");
const result = document.getElementById("output");
const table = document.getElementById("conversion-table");

let resultShowed = false;

function convertNumber(input) {
  if (isNaN(input)) {
  result.style.fontSize = `2rem`;
  result.innerText = "Please enter a valid number";
  } else if (input <= 0) {
    result.style.fontSize = `2rem`;
    result.innerText = "Please enter a number greater than or equal to 1";
  } else if (input >= 4000) {
    result.style.fontSize = `2rem`;
    result.innerText = "Please enter a number less than or equal to 3999";
  } else {
  const roman = [
    ['M', 1000],
    ['CM', 900],
    ['D', 500],
    ['CD', 400],
    ['C', 100],
    ['XC', 90],
    ['L', 50],
    ['XL', 40],
    ['X', 10],
    ['IX', 9],
    ['V', 5],
    ['IV', 4],
    ['I', 1]
  ];
  const converted = [];

  roman.forEach((arr) => {
    while (input >= arr[1]) {
      converted.push(arr[0]);
      input -= arr[1];
    }
  })
  const romanNumber = converted.join("");

  result.innerText = romanNumber;
  }

  result.classList.remove("hidden");
  inputNumber.classList.add("hidden");
  inputNumber.value = "";
  inputContainer.classList.add("hidden");
  inputLabel.classList.add("hidden");
  convertBtn.innerText = "Clear";
  table.style.marginTop = `-150px`;   
  resultShowed = true;
}

function reset() {
result.innerText = "";
inputNumber.classList.remove("hidden");
  inputContainer.classList.remove("hidden");
  inputLabel.classList.remove("hidden");
  convertBtn.innerText = "Try";
  table.style.marginTop = `auto`;
  result.style.fontSize = `8rem`;
resultShowed = false;
}

convertBtn.addEventListener("click", () => {
if (!resultShowed) {  
  const parsedInputNumber = parseInt(inputNumber.value, 10);
  convertNumber(parsedInputNumber);
} else {
  reset();
}})



:root {
  --color-yellow: #ffb300;
  --color-blue: #45567d;
  --color-red: #8e001c;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family: "cinzel", "tahoma";
}

html{
  scroll-behavior: smooth;
  overflow-X: hidden;
}

body {
  background: linear-gradient(to right, #f8f9fa, #e9ecef);
}

#title {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 30px auto;
}

#title h1{
  color: var(--color-red);
  font-size: 4rem;
  border: 10px solid;
  padding: 10px;
  text-shadow: 1px 1px 2px black;
}

#title h2{
  color: var(--color-yellow);
  font-size: 2.2rem;
  font-style: italic;
  text-shadow: 1px 1px 2px black;
  margin: 0 auto;
}

#input-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 650px;
  height: 330px;
  gap: 30px;
  margin: 80px auto;
}

#input-label {
  font-size: 1.8rem;
  font-weight: bold;
  text-align: center;
  border: 10px solid var(--color-red);
}

#number {
  width: 500px;
  height: 60px;
  margin: 30px auto; 
  border: none;
  border-bottom: 5px solid var(--color-red);
  border-top: 5px solid var(--color-red);
  background-color: transparent;
  text-align: center;
  font-size: 2.7rem;
  transition: transform 0.3;
}

#number:active {
  border: none;
  border-bottom: 5px solid var(--color-red);
  border-top: 5px solid var(--color-red);
  background-color: var(--color-yellow);
}

#number:hover {
  transform: scale(1.2);
}

#convert-btn {
  width: 200px;
  height: 100px;
  font-size: 3rem;
  border: 5px solid var(--color-red);
  transition: transform 0.3s;
}

#convert-btn:hover {
  transform: scale(1.2);
}

#conversion-table {
  border: 3px solid var(--color-red);
  margin: 30px auto;
  font-size: 2rem;
}

#output {
  position: absolute;
  top: 42vh;
  left: 49vw;
  width: 100%;
  text-align: center;
  transform: translate(-50%, -50%);
  font-size: 8rem;
  font-weight: bold;
  text-decoration: underline;
  text-shadow: 1px 1px 2px;
}

#footer {
  margin-top: 70px;
  margin-bottom: 0;
  height: 60px;
  font-size: 1.5rem; 
  background-color: var(--color-red);
}

.hidden {
  display: none;
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36

Challenge Information:

Build a Roman Numeral Converter Project - Build a Roman Numeral Converter

You should not be using global variables like this

i tried to use a object
const state = {
resultShowed : false,
};
e everything works but i fail the test, if instead i use const resultShowed = false; i pass the test but the page get stuck in a bug

I would not replace one global state variable with another. I would stop hiding data in the global space and instead only use information passed into functions.

but can you explain me why? or pass me something to read

Your code contains global variables that are changed each time the function is run. This means that after each function call completes, subsequent function calls start with the previous value. To fix this, make sure your function doesn’t change any global variables, and declare/assign variables within the function if they need to be changed.

Example:

var myGlobal = [1];
function returnGlobal(arg) {
  myGlobal.push(arg);
  return myGlobal;
} // unreliable - array gets longer each time the function is run

function returnLocal(arg) {
  var myLocal = [1];
  myLocal.push(arg);
  return myLocal;
} // reliable - always returns an array of length 2
1 Like

i get it, i change my code and eliminate the global variable but the test keep fail

const inputContainer = document.getElementById("input-container");
const inputLabel = document.getElementById("input-label");
const inputNumber = document.getElementById("number");
const convertBtn = document.getElementById("convert-btn");
const result = document.getElementById("output");
const table = document.getElementById("conversion-table");

function convertNumber(input) {
  if (isNaN(input)) {
  result.style.fontSize = `2rem`;
  result.innerText = "Please enter a valid number";
  } else if (input <= 0) {
    result.style.fontSize = `2rem`;
    result.innerText = "Please enter a number greater than or equal to 1";
  } else if (input >= 4000) {
    result.style.fontSize = `2rem`;
    result.innerText = "Please enter a number less than or equal to 3999";
  } else {
  const roman = [
    ['M', 1000],
    ['CM', 900],
    ['D', 500],
    ['CD', 400],
    ['C', 100],
    ['XC', 90],
    ['L', 50],
    ['XL', 40],
    ['X', 10],
    ['IX', 9],
    ['V', 5],
    ['IV', 4],
    ['I', 1]
  ];
  const converted = [];

  roman.forEach((arr) => {
    while (input >= arr[1]) {
      converted.push(arr[0]);
      input -= arr[1];
    }
  })
  const romanNumber = converted.join("");

  result.innerText = romanNumber;
  }

  result.classList.remove("hidden");
  inputNumber.classList.add("hidden");
  inputNumber.value = "";
  inputContainer.classList.add("hidden");
  inputLabel.classList.add("hidden");
  convertBtn.innerText = "Clear";
  table.style.marginTop = `-150px`;   
}

function reset() {
result.innerText = "";
inputNumber.classList.remove("hidden");
  inputContainer.classList.remove("hidden");
  inputLabel.classList.remove("hidden");
  convertBtn.innerText = "Try";
  table.style.marginTop = `auto`;
  result.style.fontSize = `8rem`;
}

convertBtn.addEventListener("click", () => {
if (!result.innerText) {  
  const parsedInputNumber = parseInt(inputNumber.value, 10);
  convertNumber(parsedInputNumber);
} else {
  reset();
}})


the tests can’t use the Clear button, instead they will still try to fill the #number element again and press the #convert-btn and check the content of #output, which would not be there so the tests fail

1 Like