First Attempt Final

This commit is contained in:
Steven Carpenter 2024-08-12 15:54:12 -04:00
commit 8814117c81
6 changed files with 862 additions and 0 deletions

22
LICENSE.txt Normal file
View file

@ -0,0 +1,22 @@
Copyright (c) 2023 Kyle Simpson <getify@gmail.com>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

36
css/style.css Normal file
View file

@ -0,0 +1,36 @@
#word-spelling {
display: flex;
}
.element {
position:relative;
display: block;
width: 8em;
height: 8em;
border: 1px solid #000;
margin-right: 0.2em;
flex-shrink: 0;
}
.element > .number {
position: absolute;
right: 0.5em;
top: 0.5em;
font-size: 1.1em;
}
.element > .symbol {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
font-size: 3em;
}
.element > .name {
position: absolute;
bottom: 0.3em;
left: 50%;
transform: translateX(-50%);
font-size: 1.3em;
}

21
index.html Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<title>Periodic Table Speller</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<p>
Word: <input type="text" id="enter-word">
<button type="button" id="spell-btn">spell</button>
</p>
<hr>
<div id="word-spelling"></div>
<script type="module" src="js/app.js"></script>
</body>
</html>

101
js/app.js Normal file
View file

@ -0,0 +1,101 @@
import Speller from "./speller.js";
if (/complete|interactive|loaded/.test(document.readyState)) {
ready();
}
else {
document.addEventListener("DOMContentLoaded",ready);
}
// ****************************
function ready(){
var enterWordEl = document.getElementById("enter-word");
var spellBtn = document.getElementById("spell-btn");
var wordSpellingEl = document.getElementById("word-spelling");
enterWordEl.addEventListener("keydown",onKeydown,false);
spellBtn.addEventListener("click",checkWord,false);
// ********************************
function onKeydown(evt) {
if (evt.key == "Enter") {
checkWord();
}
}
function checkWord() {
var inputWord = enterWordEl.value.toLowerCase().trim();
enterWordEl.value = inputWord;
// validate the input
if (!/^[a-z]{3,}$/.test(inputWord)) {
alert("Enter a word at least 3 letters long!");
return;
}
// attempt to spell word
var symbols = Speller.check(inputWord);
// was a valid spelling found?
if (symbols.length > 0) {
enterWordEl.value = "";
spellWord(symbols);
}
else {
wordSpellingEl.innerHTML = "<strong>-- couldn't spell it! --</strong>";
}
}
function spellWord(symbols) {
wordSpellingEl.innerHTML = "";
for (let symbol of symbols) {
let elementEntry = Speller.lookup(symbol);
let elementDiv = document.createElement("div");
elementDiv.className = "element";
elementDiv.innerHTML = `
<div class="number">${elementEntry.number}</div>
<div class="symbol">${elementEntry.symbol}</div>
<div class="name">${elementEntry.name}</div>
`;
wordSpellingEl.appendChild(elementDiv);
}
}
}
// TEST WORDS
//
// [
// "accept","access","accessibilities","accrete","accrual","accuracy","accuse","aces","ache",
// "acids","acne","acorn","action","agitation","agnostic","ago","alimony","alpacas","america",
// "american","amish","amputate","amputation","aspirin","attention","auction","autistic","bacon",
// "ballistic","banana","band","bane","bank","baptism","barf","base","bay","bears","because",
// "beers","berserk","body","bone","bonfire","boo","boy","brain","brains","bro","brunch","bunch",
// "burn","busy","butane","cacti","cafe","camp","can","candy","candycane","canine","cannibal",
// "cap","car","cheers","china","chocolate","clock","coffees","cone","cook","counts","cover","cow",
// "coy","coyote","cufflinks","cuisine","cup","cute","cuteness","cyborg","cyclic","cyclone",
// "cynics","dyes","dynamic","dynamite","dynamo","dynasties","dysfunctional","erosion","erotic",
// "erupt","essence","faces","false","fat","fear","feline","fence","fetish","fibs","final","fire",
// "flash","flog","flow","fog","forever","fraction","frog","frolic","fry","fun","function",
// "functional","functions","fusion","gala","gasp","gear","gene","generation","genesis","genius",
// "hack","hacker","hackers","halos","harp","has","hats","heat","heinous","helicopter","heretic",
// "honk","hook","hose","hundreds","hymn","hymnal","hyperbolic","icky","icon","inclines","inspire",
// "insulin","iron","irresponsibilities","kick","kind","knife","knits","know","krypton","lab",
// "lady","lifespan","lips","lubrication","lucky","mock","mockery","more","motion","mouse","neon",
// "nits","notification","nun","osmosis","ostentatious","pancreas","papyrus","patcher","patchier",
// "phone","physics","pirate","play","player","poacher","poison","police","polish","posh","pounds",
// "preparer","pretender","psychic","puffer","raccoon","rage","recluse","rescues","researh",
// "resin","responsibilities","retina","reunite","reverse","rhubarb","rub","ruby","ruin","run",
// "rune","rush","sack","sag","salvation","sarcasm","sassy","satin","scallion","scandal","scares",
// "scotch","septic","sickness","siphon","skunk","sniper","snowy","soccer","sociopath","spam",
// "span","spin","sure","tavern","taxes","teach","team","tetanus","tether","that","thin","think",
// "tick","ticklish","under","unicorns","union","unreal","use","utah","vaccine","vampire","verse",
// "violin","virus","viscosities","voice","vote","war","wash","wasp","watch","water","what","when",
// "who","wife","wise","witch","with","won","wonder","wonky","yams","yards","yarn","yikes","you",
// "youth","yucky"
// ]

90
js/speller.js Normal file
View file

@ -0,0 +1,90 @@
export default {
check,
lookup,
};
var elements;
var symbols = {};
await loadPeriodicTable();
// ****************************
async function loadPeriodicTable() {
elements = await (await fetch("periodic-table.json")).json();
for (let element of elements){
symbols[element.symbol.toLowerCase()] = element;
}
}
//TODO: write function that for each letter of the word checks the first letter
// of the symbols and makes a new data set of the matches then parses out any
// two letter symbols that arn't pairwise then return the pruned dataset to check
// instead of using lookup on the initial dataset for each pass on the word
function findCanidates(inputWord){
let pairwiseCanidates = [];
let singleCanidates = [];
for (let i = 0; i < inputWord.length; i++){
if(inputWord[i] in symbols && !singleCanidates.includes(inputWord[i])){
singleCanidates.push(inputWord[i]);
}
if (i <= (inputWord.length - 2)){
let two = inputWord.slice(i,i+2);
if (two in symbols && !pairwiseCanidates.includes(two)){
pairwiseCanidates.push(two);
}
}
}
return [...pairwiseCanidates,...singleCanidates];
}
function spellWord(canidates,charsLeft){
if(charsLeft.length == 0){
return [];
}
else {
if (charsLeft.length >= 2) {
let two = charsLeft.slice(0,2);
let rest = charsLeft.slice(2);
//found a match?
if (canidates.includes(two)){
// more chars to match?
if (rest.length > 0){
let res = spellWord(canidates,rest);
if(res.join("") == rest) {
return [two, ...res];
}
}
else {
return [two];
}
}
}
//now check for one letter symbols
if(charsLeft.length >= 1){
let one = charsLeft[0];
let rest = charsLeft.slice(1);
if(canidates.includes(one)){
if(rest.length > 0){
let res = spellWord(canidates,rest);
if (res.join("") == rest){
return [ one, ...res]
}
}
else {
return [one];
}
}
}
}
}
function check(inputWord) {
var canidates = findCanidates(inputWord);
return spellWord(canidates,inputWord);
}
function lookup(elementSymbol) {
return symbols[elementSymbol];
}

592
periodic-table.json Normal file
View file

@ -0,0 +1,592 @@
[
{
"name": "Hydrogen",
"number": 1,
"symbol": "H"
},
{
"name": "Helium",
"number": 2,
"symbol": "He"
},
{
"name": "Lithium",
"number": 3,
"symbol": "Li"
},
{
"name": "Beryllium",
"number": 4,
"symbol": "Be"
},
{
"name": "Boron",
"number": 5,
"symbol": "B"
},
{
"name": "Carbon",
"number": 6,
"symbol": "C"
},
{
"name": "Nitrogen",
"number": 7,
"symbol": "N"
},
{
"name": "Oxygen",
"number": 8,
"symbol": "O"
},
{
"name": "Fluorine",
"number": 9,
"symbol": "F"
},
{
"name": "Neon",
"number": 10,
"symbol": "Ne"
},
{
"name": "Sodium",
"number": 11,
"symbol": "Na"
},
{
"name": "Magnesium",
"number": 12,
"symbol": "Mg"
},
{
"name": "Aluminium",
"number": 13,
"symbol": "Al"
},
{
"name": "Silicon",
"number": 14,
"symbol": "Si"
},
{
"name": "Phosphorus",
"number": 15,
"symbol": "P"
},
{
"name": "Sulfur",
"number": 16,
"symbol": "S"
},
{
"name": "Chlorine",
"number": 17,
"symbol": "Cl"
},
{
"name": "Argon",
"number": 18,
"symbol": "Ar"
},
{
"name": "Potassium",
"number": 19,
"symbol": "K"
},
{
"name": "Calcium",
"number": 20,
"symbol": "Ca"
},
{
"name": "Scandium",
"number": 21,
"symbol": "Sc"
},
{
"name": "Titanium",
"number": 22,
"symbol": "Ti"
},
{
"name": "Vanadium",
"number": 23,
"symbol": "V"
},
{
"name": "Chromium",
"number": 24,
"symbol": "Cr"
},
{
"name": "Manganese",
"number": 25,
"symbol": "Mn"
},
{
"name": "Iron",
"number": 26,
"symbol": "Fe"
},
{
"name": "Cobalt",
"number": 27,
"symbol": "Co"
},
{
"name": "Nickel",
"number": 28,
"symbol": "Ni"
},
{
"name": "Copper",
"number": 29,
"symbol": "Cu"
},
{
"name": "Zinc",
"number": 30,
"symbol": "Zn"
},
{
"name": "Gallium",
"number": 31,
"symbol": "Ga"
},
{
"name": "Germanium",
"number": 32,
"symbol": "Ge"
},
{
"name": "Arsenic",
"number": 33,
"symbol": "As"
},
{
"name": "Selenium",
"number": 34,
"symbol": "Se"
},
{
"name": "Bromine",
"number": 35,
"symbol": "Br"
},
{
"name": "Krypton",
"number": 36,
"symbol": "Kr"
},
{
"name": "Rubidium",
"number": 37,
"symbol": "Rb"
},
{
"name": "Strontium",
"number": 38,
"symbol": "Sr"
},
{
"name": "Yttrium",
"number": 39,
"symbol": "Y"
},
{
"name": "Zirconium",
"number": 40,
"symbol": "Zr"
},
{
"name": "Niobium",
"number": 41,
"symbol": "Nb"
},
{
"name": "Molybdenum",
"number": 42,
"symbol": "Mo"
},
{
"name": "Technetium",
"number": 43,
"symbol": "Tc"
},
{
"name": "Ruthenium",
"number": 44,
"symbol": "Ru"
},
{
"name": "Rhodium",
"number": 45,
"symbol": "Rh"
},
{
"name": "Palladium",
"number": 46,
"symbol": "Pd"
},
{
"name": "Silver",
"number": 47,
"symbol": "Ag"
},
{
"name": "Cadmium",
"number": 48,
"symbol": "Cd"
},
{
"name": "Indium",
"number": 49,
"symbol": "In"
},
{
"name": "Tin",
"number": 50,
"symbol": "Sn"
},
{
"name": "Antimony",
"number": 51,
"symbol": "Sb"
},
{
"name": "Tellurium",
"number": 52,
"symbol": "Te"
},
{
"name": "Iodine",
"number": 53,
"symbol": "I"
},
{
"name": "Xenon",
"number": 54,
"symbol": "Xe"
},
{
"name": "Cesium",
"number": 55,
"symbol": "Cs"
},
{
"name": "Barium",
"number": 56,
"symbol": "Ba"
},
{
"name": "Lanthanum",
"number": 57,
"symbol": "La"
},
{
"name": "Cerium",
"number": 58,
"symbol": "Ce"
},
{
"name": "Praseodymium",
"number": 59,
"symbol": "Pr"
},
{
"name": "Neodymium",
"number": 60,
"symbol": "Nd"
},
{
"name": "Promethium",
"number": 61,
"symbol": "Pm"
},
{
"name": "Samarium",
"number": 62,
"symbol": "Sm"
},
{
"name": "Europium",
"number": 63,
"symbol": "Eu"
},
{
"name": "Gadolinium",
"number": 64,
"symbol": "Gd"
},
{
"name": "Terbium",
"number": 65,
"symbol": "Tb"
},
{
"name": "Dysprosium",
"number": 66,
"symbol": "Dy"
},
{
"name": "Holmium",
"number": 67,
"symbol": "Ho"
},
{
"name": "Erbium",
"number": 68,
"symbol": "Er"
},
{
"name": "Thulium",
"number": 69,
"symbol": "Tm"
},
{
"name": "Ytterbium",
"number": 70,
"symbol": "Yb"
},
{
"name": "Lutetium",
"number": 71,
"symbol": "Lu"
},
{
"name": "Hafnium",
"number": 72,
"symbol": "Hf"
},
{
"name": "Tantalum",
"number": 73,
"symbol": "Ta"
},
{
"name": "Tungsten",
"number": 74,
"symbol": "W"
},
{
"name": "Rhenium",
"number": 75,
"symbol": "Re"
},
{
"name": "Osmium",
"number": 76,
"symbol": "Os"
},
{
"name": "Iridium",
"number": 77,
"symbol": "Ir"
},
{
"name": "Platinum",
"number": 78,
"symbol": "Pt"
},
{
"name": "Gold",
"number": 79,
"symbol": "Au"
},
{
"name": "Mercury",
"number": 80,
"symbol": "Hg"
},
{
"name": "Thallium",
"number": 81,
"symbol": "Tl"
},
{
"name": "Lead",
"number": 82,
"symbol": "Pb"
},
{
"name": "Bismuth",
"number": 83,
"symbol": "Bi"
},
{
"name": "Polonium",
"number": 84,
"symbol": "Po"
},
{
"name": "Astatine",
"number": 85,
"symbol": "At"
},
{
"name": "Radon",
"number": 86,
"symbol": "Rn"
},
{
"name": "Francium",
"number": 87,
"symbol": "Fr"
},
{
"name": "Radium",
"number": 88,
"symbol": "Ra"
},
{
"name": "Actinium",
"number": 89,
"symbol": "Ac"
},
{
"name": "Thorium",
"number": 90,
"symbol": "Th"
},
{
"name": "Protactinium",
"number": 91,
"symbol": "Pa"
},
{
"name": "Uranium",
"number": 92,
"symbol": "U"
},
{
"name": "Neptunium",
"number": 93,
"symbol": "Np"
},
{
"name": "Plutonium",
"number": 94,
"symbol": "Pu"
},
{
"name": "Americium",
"number": 95,
"symbol": "Am"
},
{
"name": "Curium",
"number": 96,
"symbol": "Cm"
},
{
"name": "Berkelium",
"number": 97,
"symbol": "Bk"
},
{
"name": "Californium",
"number": 98,
"symbol": "Cf"
},
{
"name": "Einsteinium",
"number": 99,
"symbol": "Es"
},
{
"name": "Fermium",
"number": 100,
"symbol": "Fm"
},
{
"name": "Mendelevium",
"number": 101,
"symbol": "Md"
},
{
"name": "Nobelium",
"number": 102,
"symbol": "No"
},
{
"name": "Lawrencium",
"number": 103,
"symbol": "Lr"
},
{
"name": "Rutherfordium",
"number": 104,
"symbol": "Rf"
},
{
"name": "Dubnium",
"number": 105,
"symbol": "Db"
},
{
"name": "Seaborgium",
"number": 106,
"symbol": "Sg"
},
{
"name": "Bohrium",
"number": 107,
"symbol": "Bh"
},
{
"name": "Hassium",
"number": 108,
"symbol": "Hs"
},
{
"name": "Meitnerium",
"number": 109,
"symbol": "Mt"
},
{
"name": "Darmstadtium",
"number": 110,
"symbol": "Ds"
},
{
"name": "Roentgenium",
"number": 111,
"symbol": "Rg"
},
{
"name": "Copernicium",
"number": 112,
"symbol": "Cn"
},
{
"name": "Nihonium",
"number": 113,
"symbol": "Nh"
},
{
"name": "Flerovium",
"number": 114,
"symbol": "Fl"
},
{
"name": "Moscovium",
"number": 115,
"symbol": "Mc"
},
{
"name": "Livermorium",
"number": 116,
"symbol": "Lv"
},
{
"name": "Tennessine",
"number": 117,
"symbol": "Ts"
},
{
"name": "Oganesson",
"number": 118,
"symbol": "Og"
}
]