DEV Community

Chukwuma Anyadike
Chukwuma Anyadike

Posted on

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
        }
    }
)();
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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'
    },
]
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)