0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

processingでevalをするjasminライブラリ

Last updated at Posted at 2021-10-28

はじめに

 電卓のようなものを作りたいとき、数式をプログラムに認識させる必要があります。数式をコードとして書く場合、いちいち、止めて、再実行する必要があり面倒です。しかし、実行中に、数式を認識させるには、数字や演算記号やカッコを認識させる必要があり、これも面倒。
 で、evalという便利な関数を見つけましたが、javascriptやpythonでは実装されているものの、java,Processingにはありません。ですが、いいライブラリがあったので、メモします。

環境

Mac OSX 11.6
Processing 3.5.4

ライブラリ(Processingの管理ツールからインストール)
ControlP5 2.2.6
Jasmine 1.1

jasmine開発者サイト
http://www.lagers.org.uk/jasmine/index.html

実装例

 テキストボックスに数式を書いてエンターで、その式の結果を表示します。基本的な算術関数も全て網羅されているので、困ることはないでしょう。変数表記も使えます。
 驚いたことに、このControlP5のテキストボックスは履歴が遡れます。カーソルキーの上を押すと履歴が出るので、Unixのコマンドラインのような使い方ができて、自前実装する手間が省けました。
evil.png

eval.pde
import controlP5.*;
import org.quark.jasmine.*;

ControlP5 cp5;
PFont font;

void setup() {
  background(0);
  size(400, 300);
  font = createFont("Arial", 24);

  cp5 = new ControlP5(this);
  cp5.addTextfield("input")
    .setFont(font)
    .setSize(200, 24);

  textFont(font);
}

void draw() {
}

void keyPressed() {
  if (key == ENTER) {
    background(0);
    String s = cp5.get(Textfield.class, "input").getText();
    text(s, 20, 100);

    //eval
    Expression e = Compile.expression(s, false);
    float f = e.eval().answer().toFloat();
    text(f, 20, 150);
  }
}

変数ありの方程式

x,yの2変数がある式の場合、eval(2,3)のように値を受け渡す。

processing
import org.quark.jasmine.*;

String s = "x^2+y^2";
Expression e = Compile.expression(s, false);
float f = e.eval(2, 3).answer().toFloat();
print(f); //13.0

おまけ

 このライブラリで「1/3*3」を計算したところ、0.999ではなく、1と出ました。優秀です。

愚かな自分へのメモ

また、同じ調べ物をしてしまった。
2021年10月28日にこれを投稿したのを忘れて、再度、evalについて調べ直していた。そして、自分の記事にたどり着いた。2023年9月19日

追加で得た情報をメモする
javaからjavascriptを呼び出す方法がある。

se.pde
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");

try {
  double ans = (Double)engine.eval("1.1*1.1");
  print(ans);
}
catch (ScriptException e) {
  e.printStackTrace();
}

ただし、processing4では動かず、processing3では動く。
processing3はjava8
processing4はjava17
であることが原因。
jsの部分をNashorn,Graal.js,v8,ChakraCoreに変えてみてもp4では全部ダメ。
コードの互換性として、不安が残る。
また、sqrtとかpowとか^は使えない。

「jasmineライブラリはsqrtとかpowとか^とか使える」
素晴らしい。

同じ作者が作る別のライブラリ「QScript」を見つけた。
こちらは、VBのようなスクリプトを書いておき、processingプログラム実行中に、スクリプトを編集できるようなシロモノ。

その他、python modeでevalを使い、コマンドラインで引数を渡そうと思ったけど、コンパイルできそうにないので、却下。

jasminで複素数は扱えない

log(-1)はNan(非数)になる。

print(log(-1));  //NaN

jasminでlog(-1)を計算すると、やはりNaNになる。

import org.quark.jasmine.*;

String s = "log(-1)";
Expression e = Compile.expression(s, false);
println(e.eval().answer().toFloat());  //NaN

複素数を使いたいときは、complexnumberライブラリを使う

import complexnumbers.*;

Complex z = new Complex(-1,0);
z=z.ln();
println(z);  //3.141592653589793i
double r = z.re;  //0.0
double i = z.im;  //3.141592653589793
println(r,i);

import java.io.*;

// write
try{
  OutputStream os = createOutput("out.dat");
  DataOutputStream dos = new DataOutputStream(os);
  dos.writeDouble(r);
  dos.writeDouble(i);
  dos.flush();
  dos.close();
}catch(IOException e){
  e.printStackTrace();
}

// load
try{
  InputStream is = createInput("out.dat");
  DataInputStream dis = new DataInputStream(is);
  double r2 = dis.readDouble();
  double i2 = dis.readDouble();
  dis.close();
  println(r2,i2);
}catch(IOException e){
  e.printStackTrace();
}
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?