Zacząłem tworzyć aplikację, którą zamierzam docelowo wykorzystywać w mojej obecnej pracy (automatyka). Po prostu potrzebuję konwertera z jednego systemu liczbowego na inny. Dodatkowo musi on działać w konkretny (wygodny dla mnie) sposób. Więc zacząłem coś dłubać. Na razie jest to prosta konwersja hex => dec. Docelowo będą też inne systemy jak i funkcjonalności. Projekt ma charakter nie tylko praktyczny, ale i edukacyjny. Dlatego konwersji dokonuję "ręcznie", a w sposób wykorzystujący natywne możliwości JS (hexString = yourNumber.toString(16);
).
Chciałem się dowiedzieć, co sądzicie o kodzie w obecnej postaci. Mianowicie:
- czytelność kodu (nazwy funkcji i zmiennych)
- czy logika oraz UI nie są pomieszane
- sposób walidacji danych wejściowych
- czy popełniłem jakieś karygodne błędy
W następnej kolejności chcę wykorzystać poniższy kod to nauki pisania testów. Z tego co mi wiadomo, testy powinno się pisać na bieżąco. Nie po ukończeniu aplikacji. Więc na tym etapie robię checkpoint i proszę o konstruktywną krytykę.
Oto kod:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="converter.css">
<script src="converter.js" defer></script>
</head>
<body>
<div id="background">
<input type="text" id="HexValueField" placeholder="put hex value here">
<p id="ErrorMessageField">ok</p>
<button type="button" id="ConvertButton">Convert!</button>
<p id="DecValueField">result</p>
</div>
</body>
</html>
#background
{
height: 100vh;
width: 100vw;
}
#HexValueField
{
display: block;
text-align: center;
margin: auto;
margin-bottom: 10px;
}
#ConvertButton
{
display: block;
margin: auto;
margin-bottom: 20px;
}
#DecValueField, #ErrorMessageField
{
color: blue;
margin: 0;
margin-bottom: 20px;
padding: 0;
text-align: center;
}
#ErrorMessageField
{
color: red;
visibility: hidden;
}
const HexValueFiled = document.getElementById("HexValueField");
const ErrorMessageField = document.getElementById("ErrorMessageField");
const ConvertButton = document.getElementById("ConvertButton");
const DecValueFiled = document.getElementById("DecValueField");
// ========================================================== //
HexValueFiled.addEventListener("input", e => validateInput(e));
function validateInput(e)
{
let EnteredValue = e.target.value;
let AllowedCharacters = /^[A-Fa-f0-9]*$/;
if (AllowedCharacters.test(EnteredValue))
{
hideError()
}
else
(
displayError("Invalid character detected!")
);
}
function hideError()
{
ErrorMessageField.style.visibility = "hidden";
ErrorMessageField.textContent = "ok";
ConvertButton.disabled = false;
}
function displayError(message)
{
ErrorMessageField.style.visibility = "visible";
ErrorMessageField.textContent = message;
ConvertButton.disabled = true;
}
// ========================================================== //
ConvertButton.addEventListener("click", convertToDecimal)
function convertToDecimal()
{
let HexValue = HexValueFiled.value;
let HexValueReversed = [...HexValue].reverse();
let DecValue = 0;
HexValueReversed.map((element, index) =>
{
DecValue += decodeLettersToNumbers(element) * Math.pow(16, index)
})
displayResult(DecValue);
}
function decodeLettersToNumbers(character)
{
switch (character)
{
case '1':
return parseInt(character);
case '2':
return parseInt(character);
case '3':
return parseInt(character);
case '4':
return parseInt(character);
case '5':
return parseInt(character);
case '6':
return parseInt(character);
case '7':
return parseInt(character);
case '8':
return parseInt(character);
case '9':
return parseInt(character);
case 'A':
case 'a':
return parseInt(10);
case 'B':
case 'b':
return parseInt(11);
case 'C':
case 'c':
return parseInt(12);
case 'D':
case 'd':
return parseInt(13);
case 'E':
case 'e':
return parseInt(14);
case 'F':
case 'f':
return parseInt(15);
default:
displayError("Something went wrong!");
}
}
function displayResult(result)
{
DecValueFiled.textContent = result;
}