• It's far from finished and there may be other bugs and errors, but here is the program I'm making. It's an Ohm's Law Calculator. This problem has been holding me back all day so I would really like to solve it, especially since it seems trivial.

    let Layout = require("Layout");
    
    const UNITS = {
      "Voltage (V)": "Volts",
      "Current (I)": "Amps",
      "Resistance (R)": "Ohms",
      "Power (P)": "Watts",
    };
    
    const FORMULAS = {
      'Voltage (V)': {
        'Current (I), Resistance (R)': "{0} * {1}",
        'Power (P), Current (I)': "{0} / {1}",
        'Power (P), Resistance (R)': "Math.sqrt({0} * {1})"
      },
      'Current (I)': {
        'Voltage (V), Resistance (R)': "{0} / {1}",
        'Power (P), Voltage (V)': "{0} / {1}",
        'Power (P), Resistance (R)': "Math.sqrt({0} / {1})"
      },
      'Resistance (R)': {
        'Voltage (V), Current (I)': "{0} / {1}",
        'Power (P), Current (I)': "{0} / (Math.pow({1}, 2))",
        'Power (P), Voltage (V)': "(Math.pow({0}, 2)) / {1}"
      },
      'Power (P)': {
        'Voltage (V), Current (I)': "{0} * {1}",
        'Current (I), Resistance (R)': "(Math.pow({0}, 2)) * {1}",
        'Voltage (V), Resistance (R)': "(Math.pow({0}, 2)) / {1}"
      },
    };
    
    let lastStringWidth = 0;
    let calculatedVariable;
    let selectedVariable;
    let variableValues = {};
    let inputStr = "";
    
    let layout = new Layout({
      type: "v",
      c: [
        { type: "txt", font: "6x8:3", label: "", id: "label" },
        { type: "h", c: "123".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
        { type: "h", c: "456".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
        { type: "h", c: "789".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
        { type: "h", c: ".0C".split("").map(i => ({ type: "btn", font: "6x8:3", label: i, cb: () => { handleButtonPress(i); }, fillx: 1, filly: 1 })) },
        { type: "h", c: [{ type: "btn", font: "6x8:2", label: "Enter", cb: () => { handleEnter(); }, fillx: 1, filly: 1 }] }
      ]
    }, { lazy: true });
    
    function clearInputArea() {
      let label = layout.label;
      // Calculate rectangle coordinates for clearing
      let xCenter = g.getWidth() / 2;
      let halfStringWidth = lastStringWidth / 2;
      let x1 = xCenter - halfStringWidth;
      let y1 = label.y;
      let x2 = xCenter + halfStringWidth;
      let y2 = label.y + g.getFontHeight();
      // Clear the old label area
      g.clearRect(x1, y1, x2, y2);
    }
    
    function clearTextArea() {
      let x1 = 0;
      let y1 = 0;
      let x2 = g.getWidth();
      let y2 = 22;
      // Clear the old label area
      g.clearRect(x1, y1, x2, y2);
    }
    
    function clearScreen() { // Except Back Button
      let x2 = g.getWidth();
      let y2 = g.getHeight();
      g.clearRect(24, 0, x2, 24);
      g.clearRect(0, 24, x2, y2);
    }
    
    function showCalculatorInputScreen(variable) {
      selectedVariable = variable;
      layout.render();
    }
    
    function setValue(newStr) {
      clearTextArea();
      inputStr = newStr;
      layout.label.label = inputStr;
      layout.render();
      lastStringWidth = g.stringWidth(inputStr);
    }
    
    function handleButtonPress(value) {
      if (value === 'C') {
        setValue("");
      } else {
        inputStr += value;
        setValue(inputStr);
      }
    }
    
    function calculateValue(calculatedVariable, variableValues) {
      let formulas = FORMULAS[calculatedVariable];
      let formulaKeys = Object.keys(formulas);
      for (let i = 0; i < formulaKeys.length; i++) {
        let formulaKey = formulaKeys[i];
        let variables = formulaKey.split(', ');
        if (variables.every(variable => variableValues.hasOwnProperty(variable))­) {
          let formula = formulas[formulaKey];
          let formulaValues = variables.map(variable => variableValues[variable]);
          let calculatedValue = eval(formula.replace(/\{(\d+)\}/g, (_, index) => formulaValues[index]));
          let result = Object.entries(variableValues).map(funct­ion (entry) {
            let variable = entry[0];
            let value = entry[1];
            return [variable, `${value} ${UNITS[variable]}`];
          });
          result.push([calculatedVariable, `${calculatedValue.toFixed(2)} ${UNITS[calculatedVariable]}`]);
          return {
            formula: formula.replace(/\{(\d+)\}/g, (_, index) => formulaValues[index]),
            value: calculatedValue.toFixed(2),
            unit: UNITS[calculatedVariable],
            result: result,
          };
        }
      }
    }
    
    (function () {
      let mainMenu = {
        '': { 'title': 'Ohm\'s Law Calc' },
        '< Back': () => Bangle.showClock()
      };
    
      Object.keys(UNITS).forEach(unit => {
        mainMenu[unit] = () => handleUnitSelection(unit);
      });
    
      function showVariableSelectionMenu() {
        let variableSelectionMenu = {
          '': { 'title': 'Select Variable' },
          '< Back': () => E.showMenu(mainMenu)
        };
    
        let variables = Object.keys(UNITS);
        let remainingVariables = variables.filter(v => v !== calculatedVariable);
        remainingVariables.forEach(variable => {
          variableSelectionMenu[variable] = function () {
            showInputMenu(variable);
          };
        });
        E.showMenu(variableSelectionMenu);
      }
    
      function showInputMenu(variable) {
        let inputMenu = {
          '': { 'title': variable },
        };
        E.showMenu(inputMenu);
        layout.render();
      }
    
      function handleEnter() {
        if (calculatedVariable === null) {
          return;
        }
    
        variableValues[selectedVariable] = parseFloat(inputStr);
    
        if (Object.keys(variableValues).length === 1 && variableValues.hasOwnProperty(selectedVa­riable)) {
          let temp = variableValues[selectedVariable];
          delete variableValues[selectedVariable];
          variableValues[Object.keys(variableValue­s)[0]] = temp;
        }
    
        if (Object.keys(variableValues).length === 2) {
          let result = calculateValue(calculatedVariable, variableValues);
          showResultsScreen(result);
          calculatedVariable = null;
          variableValues = {};
          inputStr = "";
        } else {
          clearScreen();
          showVariableSelectionMenu();
        }
    
        inputStr = "";
        setValue("");
      }
    
      function handleUnitSelection(unit) {
        calculatedVariable = unit;
        showVariableSelectionMenu();
      }
    
      function showResultsScreen(result) {
        let resultsMenu = {
          '': { 'title': 'Results' },
          '< Back': function () {
            clearScreen();
            E.showMenu(mainMenu);
          },
          'Formula': result.formula,
          ['Calculated ' + result.unit]: result.value + ' ' + result.unit
        };
    
        result.result.forEach(([variable, value]) => {
          resultsMenu[variable] = value;
        });
    
        E.showMenu(resultsMenu);
      }
    
      E.showMenu(mainMenu);
    })();
    
About

Avatar for stweedo @stweedo started