javaluator icon indicating copy to clipboard operation
javaluator copied to clipboard

Is it possible to implement a method that returns the custom variables from the input given by the user?

Open KenobySky opened this issue 1 year ago • 1 comments

Hi! This library is great. Im having just one requirement, however:

Is it possible to implement a method that returns the custom variables from the input given by the user?

For example, the user inputs:

String input = "(workHours^2 * workers)/100";

And for that given input, the method would return : "workHours", "workers".


I did a method that attempts to do that, it works fine except when the variable name contains a number. For example: String input = "workHours1^2 * workers2) / 100";

....
allBrackets = new HashSet<>();
        allBrackets.add("(");
        allBrackets.add(")");
        allBrackets.add("[");
        allBrackets.add("]");
        allBrackets.add("}");
        allBrackets.add("{");

        allOperators = new HashSet<>();
        allOperators.add(LocalizedEvaluator.MULTIPLY.getSymbol());
        allOperators.add(LocalizedEvaluator.MODULO.getSymbol());
        allOperators.add(LocalizedEvaluator.DIVIDE.getSymbol());
        allOperators.add(LocalizedEvaluator.EXPONENT.getSymbol());
        allOperators.add(LocalizedEvaluator.MINUS.getSymbol());
        allOperators.add(LocalizedEvaluator.NEGATE.getSymbol());
        allOperators.add(LocalizedEvaluator.NEGATE_HIGH.getSymbol());
        allOperators.add(LocalizedEvaluator.PLUS.getSymbol());

        allFunctions = new HashMap<>();
        allFunctions.put(LocalizedEvaluator.RAIZ, LocalizedEvaluator.RAIZ.getName());
        allFunctions.put(LocalizedEvaluator.ABS, LocalizedEvaluator.ABS.getName());
        allFunctions.put(LocalizedEvaluator.ACOSINE, LocalizedEvaluator.ACOSINE.getName());
        allFunctions.put(LocalizedEvaluator.ASINE, LocalizedEvaluator.ASINE.getName());
        allFunctions.put(LocalizedEvaluator.ATAN, LocalizedEvaluator.ATAN.getName());
        allFunctions.put(LocalizedEvaluator.AVERAGE, LocalizedEvaluator.AVERAGE.getName());
        allFunctions.put(LocalizedEvaluator.CEIL, LocalizedEvaluator.CEIL.getName());
        allFunctions.put(LocalizedEvaluator.COSINE, LocalizedEvaluator.COSINE.getName());
        allFunctions.put(LocalizedEvaluator.COSINEH, LocalizedEvaluator.COSINEH.getName());
        allFunctions.put(LocalizedEvaluator.FLOOR, LocalizedEvaluator.FLOOR.getName());
        allFunctions.put(LocalizedEvaluator.LN, LocalizedEvaluator.LN.getName());
        allFunctions.put(LocalizedEvaluator.LOG, LocalizedEvaluator.LOG.getName());
        allFunctions.put(LocalizedEvaluator.MAX, LocalizedEvaluator.MAX.getName());
        allFunctions.put(LocalizedEvaluator.MIN, LocalizedEvaluator.MIN.getName());
        allFunctions.put(LocalizedEvaluator.TANGENTH, LocalizedEvaluator.TANGENTH.getName());
        allFunctions.put(LocalizedEvaluator.TANGENT, LocalizedEvaluator.TANGENT.getName());
        allFunctions.put(LocalizedEvaluator.SUM, LocalizedEvaluator.SUM.getName());
        allFunctions.put(LocalizedEvaluator.SINEH, LocalizedEvaluator.SINEH.getName());
        allFunctions.put(LocalizedEvaluator.SINE, LocalizedEvaluator.SINE.getName());
        allFunctions.put(LocalizedEvaluator.ROUND, LocalizedEvaluator.ROUND.getName());
        allFunctions.put(LocalizedEvaluator.RANDOM, LocalizedEvaluator.RANDOM.getName());

....


public static ArrayList<String> getVariables(String input) {

        for (String operator : allOperators) {
            input = input.replace(operator.trim(), "");
        }

        for (Map.Entry<Function, String> entry : allFunctions.entrySet()) {
            String translated = entry.getValue();
            input = myReplace(input, translated, "");
        }

        for (String bracket : allBrackets) {
            input = input.replace(bracket.trim(), "");
        }

        input = input.trim();

        String[] words = input.split("\\s+");
        
        ArrayList<String> result = new ArrayList<>();

        for (String word : words) {
            word = word.trim();
            if (!isNumeric(word)) {
                //
                word = word.replaceAll("\\d", "");

                //
                result.add(word);
            }
        }
        
        return result;

    }




KenobySky avatar Feb 28 '24 19:02 KenobySky

Hi, I'm not sure to exactly understand your question, but maybe what you need is just to override the AbstractEvaluator.evaluate(Constant ,Object) method of your evaluator.

Here is an example based on DoubleEvaluator:

import java.util.*;
import com.fathzer.soft.javaluator.*;

public class Test {
	private static class MyEvaluator extends DoubleEvaluator {
		private static final Parameters PARAMS;
		private static final Map<String, Double> MY_CONSTANTS;
		
		static {
			MY_CONSTANTS = new HashMap<>();
			MY_CONSTANTS.put("workHours", 2.0);
			MY_CONSTANTS.put("workHours1", 1.0);
			MY_CONSTANTS.put("workers", 10.0);
			PARAMS = DoubleEvaluator.getDefaultParameters();
			for (String constant : MY_CONSTANTS.keySet()) {
				PARAMS.add(new Constant(constant));
			}
		}
		
		protected MyEvaluator() {
			super(PARAMS);
		}
		
		@Override
		protected Double evaluate(Constant constant, Object evaluationContext) {
			Double result = MY_CONSTANTS.get(constant.getName());
			if (result==null) {
				result = super.evaluate(constant, evaluationContext);
			}
			if (evaluationContext instanceof Set) {
				((Set<String>) evaluationContext).add(constant.getName());
			}
			return result;
		}
		
	}
	
	public static void main(String[] args) {
		final MyEvaluator myEval = new MyEvaluator();
		test(myEval, "(workHours^2 * workers)/100");
		test(myEval, "(workHours1^2 * workers)/100");
	}
	
	private static void test(MyEvaluator myEval, String expression) {
		final Set<String> used = new HashSet<>();
		final Double result = myEval.evaluate(expression, used);
		System.out.println(expression + "="+result+" with use of "+used);
	}
}

It gives the following output:

(workHours^2 * workers)/100=0.4 with use of [workHours, workers]
(workHours1^2 * workers)/100=0.1 with use of [workHours1, workers]

Hope this could help.
Best regards,

fathzer avatar Feb 29 '24 14:02 fathzer