Skip to content

Repository files navigation

Atomic Search & Decay Calculator

Formerly Radioactive Decay Calculator

Description

Don't have the time to reference your periodic table while you do your mountain of questions assigned by your Physics teacher? This Google Chrome extension allows you to quickly search for elements and calculates alpha, beta+/- & electron capture decays.

This project was originally a site created for GryphHacks 2022 (University of Guelph's Hackathon). In 2024, I completely rewrote the code, clearing out most of the bugs, making it compatible with the Content Security Policy (CSP), and making it more cleaner and readable. Moreover, I added features like atom search and copy button.

Contacting me

To let me know if there are any issues, feel free to use the issues tab on this GitHub repo or emailing me at dereksong28@gmail.com.

Licensing

Licensed under the MIT License, available through the license.md file.

Extension created by Derek Song, 2024.

What it uses

  • Javascript for logic and calculations
  • HTML for front end
  • CSS for styles
  • Bootstrap, for more consistent and faster styling
  • JSON for Chrome extension identification

Moreover, additional tools used were:

  • Figma - to sketch up user interface prototypes
  • Adobe Illustrator - for vector graphics
  • Adobe After Effects - for marketing videos

Google Chrome permissions

This extension requires the use of one of the special permissions, specifically clipboardWrite. This permission is only used for the functions DecayCopy and AtomicSearchCopy, where decays / elements are copied to your keyboard from the click of your button.

What each file does

  • index.html is the front end; where the user interacts with the project
  • styles.css contains style instructions for the index file
  • background.js contains most of the functions used for the project. It is used to find the variables inputted, do calculations, and prints output
  • atomicData.js contains an array, const AtomicSymbol, which houses every element
  • manifest.json contains the manifest which is used by Google Chrome to identify the extension as well as permissions needed to use

How it works

Identification and calling functions

In index.html, each element contains an id, which the function callers use to know which function to call. For example,
input type="text" id="BetaPosShortFormOUT" class="form-control1" aria-label="Isotope number" aria-describedby="basic-addon2"

...is an input with the id "BetaPosShortFormOUT". This is read in background.js with

document.getElementById("BetaPosShortFormOUT").addEventListener("input", function() {
    BetaPosAtomicSymbolRev(this.value);
});

Basically, if BetaPosShortFormOUT has an input, trigger the function BetaPosAtomicSymbolRev. As that function has one parameter, value, assign the value in id BetaPosShortFormOUT as that value.

For functions with multiple parameters, then it'll work a bit differently. For example, recall function AtomicSearchGroupName, which searches for an element in AtomicSymbol given the unknown atomic group and period.

This is the code given to call the function if AtomicSearchGroupNameIN is given and assign its variables:

document.getElementById("AtomicSearchGroupNameIN").addEventListener("input", function() {
    var value = this.value;
    var value2 = document.getElementById("AtomicSearchGroupPeriodIN").value;
    AtomicSearchGroupName(value, value2);
});

If AtomicSearchGroupNameIN is called, then it will assign that value as value. It will also assign another value, value2, with the value of AtomicSearchGroupPeriodIN, the input of the period. It then calls the function with the 2 values using AtomicSearchGroupName(value, value2)

Functions that assign input and prints the output

These functions occur after an ID is given (i.e. the code on top). For example AtomicSearchAtomName triggers if an input, a string with the id AtomSearchAtomicNameIN is inputted.
function AtomicSearchAtomName (value){
    // Function to print the name of an Atom. Input = AtomSearchAtomicNameIN (str)  
    var position = atomicSearch(AtomicSymbol, value, "name"); // Pass both arguments to aanFinder
    if (position !== -1) {
        var originalValuePosition = AtomicSymbol[position]; // Find position of the item
        var groupName = groupSearch(originalValuePosition.group) // Find names for the groups
        var blockName = blockSearch(originalValuePosition.group, originalValuePosition.period) // Find names for the block
    
        // Output; a more concise version compared to the previous version
        document.getElementById("AtomSearchAtomicSymbolOUT").innerHTML = originalValuePosition.shortform;
        document.getElementById("AtomSearchAtomicNumberOUT").innerHTML = originalValuePosition.aanConst;
        document.getElementById("AtomSearchAtomicNameOUT").innerHTML = originalValuePosition.name;
        document.getElementById("AtomicSearchGroupNameOUT").innerHTML = groupName[0];
        document.getElementById("AtomicSearchGroupNameOUTalt").innerHTML = groupName[1];
        document.getElementById("AtomicSearchGroupPeriodOUT").innerHTML = originalValuePosition.period;
        document.getElementById("AtomSearchAtomicMassOUT").innerHTML = originalValuePosition.avgMass;
        document.getElementById("AtomicBlockOUT").innerHTML = blockName[0];
        document.getElementById("AtomicBlockOUTalt").innerHTML = blockName[1];
    }
}

The function identifies the unknown atomic element by passing calling atomicSearch (explained below), with the value, and notes that the value is the name of the atomic value.

If the position is valid (which if it passes if (position !== -1) {, where -1 is an invalid or missing element), then it will assign that position as the variable originalValuePosition. It will find the group by calling groupSearch with the group parameter of originalValuePosition.group, as well as find the block by calling the blockName function.

Other functions may also have a resultant variable, which calculates the outcome element given a decay. For example, in the function BetaPosAtomicNumber, resultant is: var resultant = AtomicSymbol[position-1]. It finds the n-th element in AtomicSymbol, where n is the position of the original element subtracted by one (i.e. the effects of a beta-positive decay).

The values are then outputted by calling the ID of all of the appropriate elements and assigning it as

  • the appropriate value in either originalValuePosition or resultant
  • the n-th element in an array (e.g. blockName[0])) if the output of the function is an array. Refer to specific function documentation for which array to use

.innerHTML vs .value

Recall that some of the IDs call for the .innerHTML and others call for the .value. In general,
  • .innerHTML is used for any HTML element whose output is in a span element
  • .values is used for any HTML element whose output is in a input element. Generally used in elements like atomic number, short form, or mass.

Function atomicSearch

atomicSearch is an important function as it searches through array atomicSymbol and finds the requested element. Parameters are:

  • AtomicSymbol, which is the array that houses all of the elements (const)
  • value, which is the value to search for (str or int)
  • searchVal, which defines what to search for. Only use aanConst, atomSearch, name, mass (str)
  • value2, another value to search for. Only used if searchVal = atomSearch (str or int)

For any string inputs, there is usually a snippet of code after the if structure which looks like value = value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();. This turns the first letter of the string into uppercase, and all of the others to lowercase, which is the style used in the array AtomicSymbol. (e.g. hEliuM turns to Helium).

Then, a for loop is used.

   for (var i = 0; i < AtomicSymbol.length; i++) { // Search for item matching value at "i". If "i" == value, get its index, else add 1 to i.
            if (AtomicSymbol[i].shortform === value) {
                return i; // Return the index of the found element
            }
        }
        return -1; // Return -1 if no matching element is found

The for loop defines a value i and sets it as zero. This tells it to start at position zero, and go up to the length of AtomicSymbol. If the shortform of AtomicSymbol at position i holds true, then return the value of i. Else, add 1 to i and continue.

If i < AtomicSymbol.length is reached, then return -1. The other functions will interpret a value of -1 as a missing or invalid element.

For searchVal === atomSearch, where 2 values are given, a slightly different if structure is used.

if (AtomicSymbol[i].group === parseInt(value)  && AtomicSymbol[i].period === parseInt(value2)) { // Variable "value" represents group assignment, variable "value2" represents period.
        return i; // Return the index of the found element
    } else if (AtomicSymbol[i].group === value && AtomicSymbol[i].period === parseInt(value2)) { // Special coniditon if "N/A" is inputted. Does not convert value into int. 
        return i; // Return the index of the found element
    } 

If AtomicSymbol's group at position i equals value, and the AtomicSymbol's period at position i equals to value2 is also true, return i. Additionally, if value is a string (only happens if "N/A is inputted), it omits the parseInt(value) only for value, which converts the str to int.

Const AtomicSymbol

AtomicSymbol is an array and is the only thing inside atomicData.js. It looks roughly like this:
const AtomicSymbol = [ // An array of Atomic elements. Use = AtomicSymbol[]. name: Name of element (str); shortform: Element intials (str); aanConst: Atomic number (int) ; group: Group on periodic table (int) ; period: Period on periodic table (int) ; avgMass: the average mass of an element (float)
    {
        name: "N/A",
        shortform: "N/A",
        aanConst: 0, 
        group: -1,
        period: -1,
        avgMass: -1,
    },
    {
        name: "Hydrogen",
        shortform: "H",
        aanConst: 1, 
        group: 1,
        period: 1,
        avgMass: 1.0078,
    }, 
    ...(etc)
  • name is the full name of the element. Capitalize the first letter and make sure the other letters are lowercase (N/A is the only special exception to this rule.) The functions are programmed to automatically convert string inputs to this format. (e.g. "Hydrogen") (str)
  • shortform is the abbreviation of the element. Capitalize the first letter and make sure the other letters are lowercase (N/A is the only special exception to this rule.) The functions are programmed to automatically convert string inputs to this format. (e.g. "He") (str)
  • aanConst is the atomic number of the element (int).
  • group is the group of the element (int).
  • period is the period of the element (int).
  • avgMass is the average mass of the element (float).

To reference, use AtomicSymbol[i].element, where i is the position of the element in the list (technically the atomic number), and .element is the element you want to search for.

Functions blockName and groupName

Both functions are similar as they compare one/multiple values, and return a set of variables in an array.

  • blockName takes in group and period and assigns the appropriate block and azimuthal quantum number. Reference result[0] for block, and result[1] for azNum, assuming that var result = blockSearch(group, period)
  • groupName takes in group and assigns appropriate group and IUPAC name. To reference, call result[0] for groupName, and result[1] for IUPACname, assuming that var result = groupSearch(group)

Functions DecayCopy and AtomSearchCopy

This tool has a feature to easily copy decays and elements. This is done through these two functions, where
  • DecayCopy copies alpha, beta +/-, and electron capture decays. It takes in one value which indicates the type of decay. (str)
  • AtomSearchCopy copies atomic search. It takes no value.

The functions first call the HTML elements in the selected decay type. It creates a const named textCopy, which is a text area in the document. It then assembles the sentence, usually with a statement like

textCopy.value = atomicName + "\nShort form: " + atomicSymbol + "\nAtomic number: " + atomicNumber + "\nGroup: " + atomicGroup + "\nIUPAC group name: " + atomicGroupAlt +"\nPeriod: " + atomicPeriod + "\nBlock: " + atomicBlock + "\nAzimuthal quantum number: " + atomicBlockAlt + "\nAverage mass: " + atomicMass

For DecayCopy an if statement is used, comparing the type of element. It then assembles the sentence according to the decay.

Next, textCopy is appended to the node of the document (document.body.appendChild(textCopy);). It is then selected (textCopy.select();), and the clipboard is instructed to copy the value (navigator.clipboard.writeText(textCopy.value)). After that is done, the node is cleared (document.body.removeChild(textCopy);).

Showing/hiding elements

Similar to the "identifying" functions, these functions tell the webpage what to hide or load. For example, the function below listens if AtomSearchbtn is clicked or not, and if so, defines each element as its own variable, then shows AtomSearch and hides the others.

document.getElementById('AtomSearchbtn').addEventListener('click', function() {
    // Funciton to show AtomSearch and hide other elements upon clicking AtomSearchbtn. Inputs = none
    // Variables for elements
    var BetaPositive = document.getElementById('BetaPositive');
    var Alpha = document.getElementById('Alpha');
    var BetaNegative = document.getElementById('BetaNegative');
    var ElectronCapture = document.getElementById('ElectronCapture');
    var AtomSearch = document.getElementById('AtomSearch');
    
    // Hides/show approprate elements
    BetaPositive.style.display = 'none';
    Alpha.style.display = 'none';
    BetaNegative.style.display = 'none';
    ElectronCapture.style.display = 'none';
    AtomSearch.style.display = 'block'
});

In general, these HTML ids correspond to:

  • Alpha - alpha decay element (button to show: Alphabtn)
  • AtomSearch - atom search element (button to show: AtomSearchbtn)
  • BetaPositive - beta positive decay element (button to show: BetaPositivebtn)
  • BetaNegative - beta negative decay element (button to show: BetaNegativebtn)
  • ElectronCapture - electron capture (button to show: ElectronCapturebtn)

To show an element, set the element's .style.display to equal to block. To hide, set as none.

On load

When the extension is first opened, it defaults to opening atom search and hiding the other elements.

Button links

This tool uses Bootstrap, which has default button functionality. While normally you will put an href into an a tag to link it to another page, this isn't supported in a Google Chrome extension. Hencewhy this piece of code exists
document.getElementById('GitHub').addEventListener('click', function() {
    // Link to github repo
    chrome.tabs.update({ url: 'https://github.com/twotoque/physicscalculator/' });
});

This code listens to if an HTML id named GitHub is clicked. If it is, then Chrome is instructed to update the tab to go to the corresponding link, in this case https://github.com/twotoque/physicscalculator/.

About

Searches periodic table for elements and calculates alpha, beta positive, beta negative, and electron capture decays

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages