Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
KenobySky opened this issue Feb 28, 2024 · 1 comment
Labels
question Further information is requested

Comments

@KenobySky
Copy link

KenobySky commented Feb 28, 2024

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;

    }




@fathzer
Copy link
Owner

fathzer commented Feb 29, 2024

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 fathzer added the question Further information is requested label May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants