Building a Command Line Physics Calculations Application with an IIFE Module Pattern

In the previous article, I discussed immediately invoked function expressions or IIFE for short (Link). Now we will use some IIFE programming to construct an interactive command line application which solves basic physics problem. Previously, I created an IIFE based module called iifePhysicsCalculations.js. //iifePhysicsCalculations.js export const physicsCalculations = ( function () { //the below constants are private variables const g = 9.80665; //gravity constant in meters/second squared const c = 299792458; //speed of light in m/s //functions to be returned as methods in this module const velocity = (distance, time) => distance / time; const acceleration = (speed, time) => speed / time; const potentialEnergy = (mass, height) => mass * g * height; const momentum = (mass, speed) => mass * speed; const energy = (mass) => mass * (c ** 2); const force = (mass, acc) => mass * acc; const kineticEnergy = (mass, speed) => 0.5 * mass * (speed ** 2); //object containing named methods including two getter methods return { velocity, acceleration, potentialEnergy, momentum, energy, force, kineticEnergy, getSpeedOfLight: () => c, getGravityConstant: () => g } } )(); The above module will be exported but in order to do this let us create a basic package.jsonfile. This will allow us to import our modules in other files. //package.json { "type": "module" } We also need a way to generate the text associated with the prompts that will appear on the command line. I am creating a file called PhysicsEquations.js. This is another export module. //PhysicsEquations.js export const physicsEquations = [ { id: '1', calculation: "Velocity (V = distance/time)", entries: ["distance in meters", "time in seconds to travel distance"], units: 'meters per second' }, { id: '2', calculation: "Acceleration (A = change in velocity/time)", entries: ["change in velocity in meters per second", "time in seconds to reach velocity"], units: 'meters per second squared' }, { id: '3', calculation: "Potential Energy (PE = mgh)", entries: ["mass in kilograms", "height in meters"], units: 'Joules' }, { id: '4', calculation: "Momentum (M = mv)", entries: ["mass in kilograms", "speed in meters per second"], units: 'kilogram meters per second' }, { id: '5', calculation: "Molecular Energy (E = mc^2)", entries: ["mass in kilograms"], units: 'Joules' }, { id: '6', calculation: "Force (F = ma)", entries: ["mass in kilograms", "acceleration in meters per second squared"], units: 'Newtons' }, { id: '7', calculation: "Kinetic Energy (KE = (1/2)mv^2)", entries: ["mass in kilograms", "speed in meters per second"], units: 'Joules' }, ] Finally we will create the main application file itself, PhysicsCalculationsApp.js. This contains the logic for the command line inputs as well as imports for the other two modules. //PhysicsCalculationsApp.js import { physicsCalculations } from "./iifePhysicsCalculations.js"; import { physicsEquations } from "./PhysicsEquations.js"; import readline from 'node:readline'; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); const choices = physicsEquations.map(question => `\t${(physicsEquations.indexOf(question) + 1)}) ${question.calculation}`); const ids = physicsEquations.map(question => question.id); function calculate(equation, numbers) { switch (equation) { case '1': return physicsCalculations.velocity(...numbers); case '2': return physicsCalculations.acceleration(...numbers); case '3': return physicsCalculations.potentialEnergy(...numbers); case '4': return physicsCalculations.momentum(...numbers); case '5': return physicsCalculations.energy(...numbers); case '6': return physicsCalculations.force(...numbers); case '7': return physicsCalculations.kineticEnergy(...numbers); default: return NaN; } } const askQuestion = (question) => { return new Promise((resolve) => { rl.question(question, (answer) => { resolve(answer) }) }) }; function printChoices() { console.log('Physics Equations'); choices.forEach(choice => console.log(choice)); console.log('\t0) To exit\n'); } let calculating = true; while (calculating) { let numbers = []; printChoices(); const choice = await askQuestion(`Type a number to select an equation: `); if (!ids.includes(choice)) break; const physicsQuestion = physicsEquations.find(question =>

Jan 27, 2025 - 01:55
 0
Building a Command Line Physics Calculations Application with an IIFE Module Pattern

In the previous article, I discussed immediately invoked function expressions or IIFE for short (Link). Now we will use some IIFE programming to construct an interactive command line application which solves basic physics problem. Previously, I created an IIFE based module called iifePhysicsCalculations.js.

//iifePhysicsCalculations.js
export const physicsCalculations = (
    function () {

        //the below constants are private variables
        const g = 9.80665; //gravity constant in meters/second squared
        const c = 299792458; //speed of light in m/s

        //functions to be returned as methods in this module
        const velocity = (distance, time) => distance / time;
        const acceleration = (speed, time) => speed / time;
        const potentialEnergy = (mass, height) => mass * g * height;
        const momentum = (mass, speed) => mass * speed;
        const energy = (mass) => mass * (c ** 2);
        const force = (mass, acc) => mass * acc;
        const kineticEnergy = (mass, speed) => 0.5 * mass * (speed ** 2);

        //object containing named methods including two getter methods
        return {
            velocity,
            acceleration,
            potentialEnergy,
            momentum,
            energy,
            force,
            kineticEnergy,
            getSpeedOfLight: () => c,
            getGravityConstant: () => g
        }
    }
)();

The above module will be exported but in order to do this let us create a basic package.jsonfile. This will allow us to import our modules in other files.

//package.json
{
    "type": "module"
}

We also need a way to generate the text associated with the prompts that will appear on the command line. I am creating a file called PhysicsEquations.js. This is another export module.

//PhysicsEquations.js
export const physicsEquations = [
    {
        id: '1',
        calculation: "Velocity (V = distance/time)",
        entries: ["distance in meters", "time in seconds to travel distance"],
        units: 'meters per second'
    },
    {
        id: '2',
        calculation: "Acceleration (A = change in velocity/time)",
        entries: ["change in velocity in meters per second", "time in seconds to reach velocity"],
        units: 'meters per second squared'
    },
    {
        id: '3',
        calculation: "Potential Energy (PE = mgh)",
        entries: ["mass in kilograms", "height in meters"],
        units: 'Joules'
    },
    {
        id: '4',
        calculation: "Momentum (M = mv)",
        entries: ["mass in kilograms", "speed in meters per second"],
        units: 'kilogram meters per second'
    },
    {
        id: '5',
        calculation: "Molecular Energy (E = mc^2)",
        entries: ["mass in kilograms"],
        units: 'Joules'
    },
    {
        id: '6',
        calculation: "Force (F = ma)",
        entries: ["mass in kilograms", "acceleration in meters per second squared"],
        units: 'Newtons'
    },
    {
        id: '7',
        calculation: "Kinetic Energy (KE = (1/2)mv^2)",
        entries: ["mass in kilograms", "speed in meters per second"],
        units: 'Joules'
    },
]

Finally we will create the main application file itself, PhysicsCalculationsApp.js. This contains the logic for the command line inputs as well as imports for the other two modules.

//PhysicsCalculationsApp.js
import { physicsCalculations } from "./iifePhysicsCalculations.js";
import { physicsEquations } from "./PhysicsEquations.js";
import readline from 'node:readline';

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const choices = physicsEquations.map(question => `\t${(physicsEquations.indexOf(question) + 1)}) ${question.calculation}`);
const ids = physicsEquations.map(question => question.id);

function calculate(equation, numbers) {
    switch (equation) {
        case '1': return physicsCalculations.velocity(...numbers);
        case '2': return physicsCalculations.acceleration(...numbers);
        case '3': return physicsCalculations.potentialEnergy(...numbers);
        case '4': return physicsCalculations.momentum(...numbers);
        case '5': return physicsCalculations.energy(...numbers);
        case '6': return physicsCalculations.force(...numbers);
        case '7': return physicsCalculations.kineticEnergy(...numbers);
        default: return NaN;
    }
}

const askQuestion = (question) => {
    return new Promise((resolve) => {
        rl.question(question, (answer) => {
            resolve(answer)
        })
    })
};

function printChoices() {
    console.log('Physics Equations');
    choices.forEach(choice => console.log(choice));
    console.log('\t0) To exit\n');
}

let calculating = true;
while (calculating) {
    let numbers = [];

    printChoices();
    const choice = await askQuestion(`Type a number to select an equation: `);
    if (!ids.includes(choice)) break;
    const physicsQuestion = physicsEquations.find(question => question.id === choice);
    console.log(physicsQuestion.calculation);

    for (const entry of physicsQuestion.entries) {
        const number = await askQuestion(`Enter ${entry}: `);
        numbers.push(number)
    }

    console.log(`${physicsQuestion.calculation.split(' (')[0]} = ${calculate(choice, numbers)} ${physicsQuestion.units}\n`);
}

rl.close();

If you follow these steps, you will quickly have a command line application at your disposal to solve basic physics problems. We took the concept of IIFE and used it to create a small modular application.