I have written a project that calculates different functions like sine,MCM etc without using existing packages like math in java
now I want to get an expression from the user in form of a string and then print out the result
like :
import java.util.Scanner;
public class Phase2main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String expression ;
double result = 0 ;
System.out.println(" Enter your desired expression from the available functions ");
expression = s.nextLine();
System.out.println("Result is : " + result);
}
}
then it should run like this:
Enter an Expression: ADD(DIV(SIN(FACT(3)),CEIL(TAN(MUL(1.5,FIB(4))))),GCD(2,10))
The Result is: 1.94
how can I make the program to identify my functions like CEIL and their input ?
I've checked many of the similar questions but the ones that I found are rather libraries that are too complex for me to understand or do basic arithmetic without identifying functions and their inputs
so how can I write a simple evaluator for this specific problem?
May be use JavaScript interpreter?
First create engine instance and init:
// Manager creates engines by mime/language names.
// It has own global scope for engiges created by it.
ScriptEngineManager manager = new ScriptEngineManager();
// Create JavaScript interpreter instance.
// (Nashorn is bundled JavaScript interpreter)
ScriptEngine scope = manager.getEngineByName("JavaScript");
// Define functions you need
String initialScript = "cos = Math.cos;" // ; or \n
+ "sin = Math.sin;"
+ "tg = Math.tan;"
+ "PI = Math.PI;"
// Any other function
+ "ctg = function (x) { return cos(x)/sin(x); };";
// ...
try {
// Add these functions to scope
scope.eval(initialScript);
} catch(ScriptException ex) {
// Evaluating exceptions, syntax errors are thrown here
}
And then you can evaluate expressions in the "scope" many times:
try {
double d = (double)scope.eval("sin(PI/2) + cos(PI/2)");
System.out.println("Calculated: " + d);
} catch(ScriptException e) {
// ...
}
Be warned:
There is language interpreting - user can pass any script and...
... it can reduce perfomance of application.
You can also use, for example, Jython or JRuby as interpreter.
You could use the Java Scripting API, and for instance use JavaScript, or BeanShell (java like).
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
try {
engine.eval("print('Result: ' + java.lang.Math.sin(0.8))");
double y = ((Number) engine.eval("java.lang.Math.sin(0.8)")).doubleValue();
} catch (ScriptException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
JavaScript can use imports. As you can see, calling java is quite simple.
I'm not sure if there is any simple way to identify and evaluate generic inputed expressions without using libraries.
If you want to develop your own way to evaluate math expressions take a look on this page, it should show you the way to go: http://cogitolearning.co.uk/?p=565
And if you change your mind and want to use an library, check this link: Evaluating a math expression given in string form
I've done this when I built a java compiler, that way I could read and evaluate any expression, but it wasn't simple...
Related
tl;dr:
How do/can I store the function-handles of multiple js-functions in java for using them later? Currently I have two ideas:
Create multipe ScriptEngine instances, each containing one loaded function. Store them in a map by column, multiple entries per column in a list. Looks like a big overhead depending on how 'heavy' a ScriptEngine instance is...
Some Javascript solution to append methods of the same target field to an array. Dont know yet how to access that from the java-side, but also dont like it. Would like to keep the script files as stupid as possible.
var test1 = test1 || [];
test1.push(function(input) { return ""; });
???
Ideas or suggestions?
Tell me more:
I have a project where I have a directory containing script files (javascript, expecting more than hundred files, will grow in future). Those script files are named like: test1;toupper.js, test1;trim.js and test2;capitalize.js. The name before the semicolon is the column/field that the script will be process and the part after the semicolon is a human readable description what the file does (simplified example). So in this example there are two scripts that will be assigned to the "test1" column and one script to the "test2" column. The js-function template basically looks like:
function process(input) { return ""; };
My idea is, to load (and evaluate/compile) all script files at server-startup and then use the loaded functions by column when they are needed. So far, so good.
I can load/evaluate a single function with the following code. Example uses GraalVM, but should be reproducable with other languages too.
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
final Invocable invocable = (Invocable) engine;
engine.eval("function process(arg) { return arg.toUpperCase(); };");
var rr0 = invocable.invokeFunction("process", "abc123xyz"); // rr0 = ABC123XYZ
But when I load/evaluate the next function with the same name, the previous one will be overwritten - logically, since its the same function name.
engine.eval("function process(arg) { return arg + 'test'; };");
var rr1 = invocable.invokeFunction("process", "abc123xyz"); // rr1 = abc123xyztest
This is how I would do it.
The recommended way to use Graal.js is via the polyglot API: https://www.graalvm.org/reference-manual/embed-languages/
Not the same probably would work with the ScriptEngine API, but here's the example using the polyglot API.
Wrap the function definition in ()
return the functions to Java
Not pictured, but you probably build a map from the column name to a list of functions to invoke on it.
Call the functions on the data.
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value toUpperCase = context.eval("js", "(function process(arg) { return arg.toUpperCase(); })");
Value concatTest = context.eval("js", "(function process(arg) { return arg + 'test'; })");
String text = "HelloWorld";
text = toUpperCase.execute(text).asString();
text = concatTest.execute(text).asString();
System.out.println(text);
}
}
}
Now, Value.execute() returns a Value, which I for simplicity coerce to a Java String with asString(), but you don't have to do that and you can operate on Value (here's the API for Value: https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html).
Since Java's assert keyword is fundamentally broken on Android, I am about to implement an assertion class that can be configured to check assertions in release builds as well.
Now I can do something like:
MyAssertion.assert(a != 2)
which throws an AssertionException when the expression is false. But how can I get a String representation of the expression to pass to the error message?
The only way is to add a String parameter to your assert method:
MyAssertion.assert(a != 2, "a must not be equal to 2");
What you get as input for assert is either true or false so you can't build a representative String from that.
Otherwise, you could implement assert like this:
MyAssertion.assertNotEquals(a, 2);
When this fails, you know that it is because what you tested was equal to 2 and you can build an informative message (though you won't know what specifically was equal to 2).
If you want to somehow be able to construct a meaningful message from an assertion, the only way I see it possible is to construct an String expression, ask the JavaScript engine to evaluate it and build a message if the expression evaluates to false. Note that will degrade a lot performance as launching the JavaScript engine takes a lot of time. This could be solved with a mechanism of disabling assertions in production.
The following is an example of that. Note that I'm using the new Java 8 Nashorn JavaScript engine but this should work with the older Rhino.
Usage example:
int value = 3;
String str = "test";
Assertions.assertTrue("$1 == 3", value);
Assertions.assertTrue("$1 == 3 && $2 == 'test'", value, str);
Assertions.assertTrue("$1 == 4 && $2 == 'test'", value, str);
This will throw for the 3rd assertion:
An assertion has failed: 3 == 4 && 'test' == 'test'
The idea is that you can write any JavaScript-friendly expression that can be evaluated to a boolean. The placeholders $i will be replaced by what's given as a parameter to the method ($1 will be replaced by the first parameter, etc.).
This is the class. It could be improved (handle error conditions like not enough parameters, etc.) but this should be enough to get you started.
public final class Assertions {
private static final ScriptEngine ENGINE = new ScriptEngineManager().getEngineByName("nashorn");
private Assertions() { }
public static void assertTrue(String expression, Object... values) {
for (int i = 0; i < values.length; i++) {
ENGINE.put("$" + (i+1), values[i]);
}
try {
boolean pass = (Boolean) ENGINE.eval(expression);
if (!pass) {
for (int i = 0; i < values.length; i++) {
expression = expression.replace("$" + (i+1), stringRepresentation(values[i]));
}
throw new AssertionError("An assertion has failed: " + expression);
}
} catch (ScriptException e) {
throw new InternalError(e);
} finally {
for (int i = 0; i < values.length; i++) {
ENGINE.getBindings(ScriptContext.ENGINE_SCOPE).remove("$" + (i+1));
}
}
}
private static String stringRepresentation(Object o) {
if (o instanceof String) {
return "'" + o + "'";
}
return o.toString();
}
}
Annotation processing can do this. You'd create an annotation e.g. #InlineAssertExpressions. Then write a processor that parses your source file and creates a string representing the expression and adds it to the call to your assert method, which you could overload to take an optional String argument. This way is quite optimal performance-wise, since the inlining happens compile-time. Annotation processing is a bit overlooked, but I think this is a great use for it.
(1) Simple to use, but hard to implement. Java 8 required. You can use lambda expressions:
Assert.isTrue(() => a != 2)
On evaluation failure your implementation of Assert.isTrue method should repeat all steps as IDEs do - (a) discover bytecode of lambda class, (b) decompile e.g. with JAD, (c) discover sources if available
(2) Simple to use, simple to implement, but does not fully cover your requirements. You can use CodeStyle rules to check & force correct assertions usage. One regexp will check there is no single-argument assertions, the second (using regexp back refs) will check code and text description are similar.
(3) Simple to use, simple to implement, but relies on your build system. You can automatically check and fix source code during project build.
E.g. for Maven build system you can create your own plugin to check and fix assertions usage in sources on process-sources stage.
I think you cannot access the internal java expression, which was passed to method call.
You can, however, use some expression language libraries and do a custom expression handling for your assertion implementation.
Here is a list of some expression language libraries:
http://java-source.net/open-source/expression-languages
Hope that helps :)
I access my database that has several fields:
rabbit2013
rabbit2014
rabbit2015
etc.
I am trying to create a program in Java to read the variable of the current year (rabbit2015 here). I have the current year in my variable year. How do I return the value of "rabbit"+year?
I tried this but doesn't work:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = null;
try {
result = engine.eval("rabbit"+year);
}
catch (ScriptException e){
e.printStackTrace();
}
System.out.println(result);
Have you got any ideas?
EDIT:
Error : ReferenceError: "rabbit2015" is not defined in <eval> at line number 1
result = engine.eval("\"rabbit\"+year");
The way you had it, Java was evaluating "rabbit"+year, then passing that to the eval method.
Assuming "year" is a java variable, you'll also need to put it on the ScriptEngine binding...
Bindings bindings = engine.createBindings();
bindings.put("year", year);
Then you pass the bindings in as a second parameter when you call eval()...
result = engine.eval("\"rabbit\"+year", bindings);
I find the answer of my question :
PS : When i talk you about rabits, it were examples, here it's "aRealiserEn"+year
I think I was not well enough explained my problem (promiss i will do better next). I thank all the same people who took time to read me and answer me (especially Phil Anderson and Biffen).
This is related to this other question:
Last evaluated expression in Javascript
But I wanted to provide more details about what I wanted to do and show how I finally solved the problem as some users requested in the comments.
I have snippets of Javascript that are written by users of my app. This snippets need to go to a kind of template like this:
var foo1 = function(data, options) {
<snippet of code written by user>
}
var foo2 = function(data, options) {
<snippet of code written by user>
}
...
Expressions can be very different, from simple things like this:
data.price * data.qty
To more complex tings like this:
if (data.isExternal) {
data.email;
} else {
data.userId;
}
The value returned by the function should be always the last evaluated expression.
Before we had something like this:
var foo1 = function(data, options) {
return eval(<snippet of code written by user>);
}
But due to optimizations and changes we are making, we cannot keep using eval, but we need to return the last evaluated expression.
Just adding a 'return' keyword won't work because expressions can have several statements. So I need to make those functions return the last evaluated expressions.
Restrictions and clarification:
I cannot force users to add the 'return' keyword to all the scripts they have because there are many scripts written already and it is not very intuitive for simple expressions like 'a * b'.
I'm using Java and Rhino to run Javascripts on server side.
As people pointed out in Last evaluated expression in Javascript, getting the last evaluated expression is not possible in standard Javascript.
What I finally ended up doing, as suggested by FelixKling, was to manipulate the AST of the script written by the user. This way I store the user written script and the modified version, which is the one I finally run.
For manipulating the AST I used Rhino and basically modify all EXPR_RESULT nodes to store the result in a variable that I finally return at the end of the script. Here is the code to do that:
public class ScriptsManipulationService {
private static final Logger logger = LoggerFactory.getLogger(ScriptsManipulationService.class);
public String returnLastExpressionEvaluated(String script) {
Parser jsParser = new Parser();
try {
AstRoot ast = jsParser.parse(script, "script", 1);
ast.getType();
ast.visitAll(new NodeVisitor() {
#Override
public boolean visit(AstNode node) {
if (node.getType() == Token.EXPR_RESULT) {
ExpressionStatement exprNode = (ExpressionStatement) node;
Assignment assignmentNode = createAssignmentNode("_returnValue", exprNode.getExpression());
assignmentNode.setParent(exprNode);
exprNode.setExpression(assignmentNode);
}
return true;
}
});
StringBuilder result = new StringBuilder();
result.append("var _returnValue;\n");
result.append(ast.toSource());
result.append("return _returnValue;\n");
return result.toString();
} catch (Exception e) {
logger.debug(LogUtils.format("Error parsing script"), e);
return script;
}
}
private Assignment createAssignmentNode(String varName, AstNode rightNode) {
Assignment assignmentNode = new Assignment();
assignmentNode.setType(Token.ASSIGN);
Name leftNode = new Name();
leftNode.setType(Token.NAME);
leftNode.setIdentifier(varName);
leftNode.setParent(assignmentNode);
assignmentNode.setLeft(leftNode);
rightNode.setParent(assignmentNode);
assignmentNode.setRight(rightNode);
return assignmentNode;
}
}
This way, if you pass the following script:
data.price * data.qty;
You will get back:
var _returnValue;
_returnValue = data.price * data.qty;
return _returnValue;
Or if you pass:
var _returnValue;
if (data.isExternal) {
_returnValue = data.email;
} else {
_returnValue = data.userId;
}
return _returnValue;
Please keep in mind that I haven't done an exhaustive testing and will be polishing it over time, but this should show the general idea.
I have a question regarding structuring of code.
I have let us say three types of packages A,B and C.
Now, classes in package A contains classes which contain the main() function. These classes
need some command line arguments to run.
In package B, there are classes which contains some public variables, which need to be configured, at different times. For example before calling function A, the variable should be set or reset, the output differs according to this variable.
In package C, uses the classes in package B to perform some tasks. They do configure their variables as said before. Not only when the object is created, but also at intermediate stage.
Package A also has classes which in turn use classes from package B and package C. In order to configure the variables in classes of B and C, class in package A containing the main() function, reads command line arguments and passes the correct values to respective class.
Now, given this scenario, I want to use Apache Commons CLI parser.
I am unable to understand how exactly I should write my code to be structured in an elegant way. What is a good design practice for such scenario.
Initially I wrote a class without Apache to parse the command line arguments.
Since I want a suggestion on design issue, I will give an excerpt of code rather than complete code.
public class ProcessArgs
{
private String optionA= "default";
private String optionB= "default";
private String optionC= "default";
public void printHelp ()
{
System.out.println ("FLAG : DESCRIPTION : DEFAULT VALUE");
System.out.println ("-A <Option A> : Enable Option A : " + optionA);
System.out.println ("-B <Option B> : Enable Option B : " + optionB);
System.out.println ("-C <Option C> : Enable Option C : " + optionC);
}
public void printConfig()
{
System.out.println ("Option A " + optionA);
System.out.println ("Option B " + optionB);
System.out.println ("Option C " + optionC);
}
public void parseArgs (String[] args)
{
for (int i=0;i<args.length;i++)
{
if (args[i].equalsIgnoreCase ("-A"))
optionA = args[++i];
else if (args[i].equalsIgnoreCase ("-B"))
optionB = args[++i];
else if (args[i].equalsIgnoreCase ("-C"))
optionC = args[++i];
else
throw new RuntimeException ("Wrong Argument : " + args[i] + " :: -h for Help.");
}
}
}
Points to note -
I already have 50+ command line options and they are all in one place.
Every class uses only a group of command line options.
I tried to write an interface, somehow but I am unsuccessful. I am not sure if this is a good way to do it or not. I need some design guidelines.
Here is the code which I wrote -
public interface ClassOptions
{
Options getClassOptions();
void setClassOptions(Options options);
}
public class Aclass implements ClassOptions
{
private String optionA="defaultA";
private String optionB="defaultB";
public Options getClassOptions()
{
Options options = new Options();
options.addOption("A", true, "Enable Option A");
options.addOption("B", true, "Enable Option B");
return options;
}
public void setClassOptions(Options options, String args[])
{
CommandLineParser parser = new BasicParser();
CommandLine cmd=null;
try
{
cmd = parser.parse( options, args);
} catch (ParseException e)
{
// TODO Auto-generated catch block
// e.printStackTrace();
System.out.println("ignored option");
}
if(cmd.hasOption("A"))
optionA = "enabled";
if(cmd.hasOption("B"))
optionB = "enabled";
}
}
I think the problems in such writing of code are -
There are different types of arguments like int, double, string, boolean. How to handle them all.
getClassOption() and setClassOption() both contain the arguments "A", "B" for example. This code is prone to errors made while writing code, which I would like to eliminate.
I think the code is getting repetitive here, which could be encapsulated somehow in another class.
Not all the arguments are required, but can be ignored.
Thank You !
I would recommend to you JCommander.
I think it's a really good Argument Parser for Java.
You define all the Argument stuff within annotations and just call JCommander to parse it.
On top of that it also (based on your annotations) can print out the corresponding help page.
You don't have to take care about anything.
I believe you will love it! :)
Take a look at it: http://jcommander.org/
There are a lot of examples and such!
Good Luck! :)
simple example for command line argument
class CMDLineArgument
{
public static void main(String args[])
{
int length=args.length();
String array[]=new String[length];
for(int i=0;i<length;i++)
{
array[i]=args[i];
}
for(int i=0;i<length;i++)
{
System.out.println(array[i]);
}