[pukiwiki]
[[こちらの記事の続きです:http://boxheadroom.com/2009/10/08/mathlink]]
Mathematica Playerで遊ぶのに、毎回 ソースを書き直すのがめんどくさかったので、対話的に作業できるように、ちょっとしたフロントエンドをIronPythonで書いてみました
人生初 .netアプリ (汗
Python用の開発環境、IDLEの操作に似せてあります
[/pukiwiki]
[pukiwiki]
*基本操作
-カーソルが最終行に有るときにEnter またはeval ボタン
最終行をMathematica Playerのエンジンで評価
-カーソルが最終行 ”以外”に有るときにEnter
現在行の内容を 最終行へ追加
(Basicみたく、現在行を評価したほうが素直かな? IDLEに似せてあります)
-文字列を選択してEnter または eval ボタン
選択中の文字列を評価
複数行にまたがる命令を入力するときに使用
-Ctrl + Enter で改行文字の入力
上記とあわせて使用
*特殊コマンド説明
! 1文字目がビックリマークだと Pythonの式として評価 (eval)
!exe ( “文” ) exec命令により Pythonの文として評価
(変数への代入などに必要)
!pretty() # 結果をちょっと凝った表示に
!simple() # 結果表示をシンプルに (デフォルト)
*特殊変数
_ # アンダースコアに、最期に評価した結果を格納。 Pythonで使用可能
*Todo
入力文字を評価するだけのプログラムのつもりが、だんだん肥大化(汗
Mathematicaアカデミック版なら3万円ぐらいらしいので、本格的に使うのであれば、あまり手をかけると、手間のほうがアレですが。
-リサイズに対応
-演算結果を、output[idx] みたいな配列に保存して再利用可能に
-結果文字列が長いときの省略表示 (上記とあわせて)
-結果文字列をパースしてPythonで利用するためのパーサ
-GUI部分のコードを、もう少しきれいに。
*LANでWebサービス版
むしろ、CGIHttpServerモジュールなどを使って、Web経由で使えるようにしたほうが、ローカルでの使い手があるかも。Firefoxなどでは、 MathMLを使って数式表示できますし。
(IronPythonは、インストーラ版のみ、CPythonの標準ライブラリ同等品が付いてきます。)
参考
[[Python Snippet(アクセンス):http://omake.accense.com/wiki/Python/Snippet/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF]]
[/pukiwiki]
こんな短いプログラムで数式処理(っぽいこと)ができるなんて、、、時代に進歩にびっくり
(コメントと、ライブラリのインポートが半分ぐらいなので、実質のコード量はかなり少ないです)
# -*- coding: cp932 -*-
"""
mathform.py
MathematicaPlayer intaractive shell
Enter-key on last line : execute last line
Enter-key on previous line : copy previous line to last line
(IDLE like)
Selection and Enter key : execute selection
(for multiline evaluation)
python mode
if first charactor is ! eval as python
!expression : eval(expression) in python
!exe( statement) : exec statement in python
!setq( name, val) : name=val in python
!setq( name , val,index) : name[index]=val
input Enter : Ctrl + Enter
Output mode
!simple() : use EvaluateToOutputForm (default)
!pretty() : use EvaluateToInputForm
print prettify
"""
import clr , System
require=clr.AddReferenceByPartialName
#require=clr.AddReferenceToFile
require("System.Windows.Forms")
from System.Windows.Forms import Form,Button,TextBox,Application
require("Wolfram.NETLink")
from Wolfram.NETLink import *
require("System.Drawing")
from System.Drawing import Font
LN=System.Environment.NewLine
frm=Form(Height = 400,Width = 640)
frm.Text="Simple Window"
fnt = Font("MS ゴシック", 12);
frm.Show()
t1=TextBox(Left=20, Top=35, Width=600,Height=300,Font=fnt)
t1.Text=""
def q(sender, args):
kernelLink.Close()
frm.Close()
b2 = Button(Text="&Quit", Left=500, Top=340)
b2.Click+=q
t1.Multiline = True
t1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
b1 = Button(Text="&Eval", Left=300, Top=340)
kernelLink=MathLinkFactory.CreateKernelLink()
kernelLink.WaitAndDiscardAnswer()
modedict={}
modedict["output"]=0
def setq(name,val,index=None):
if index is None:
globals()[name]=val
else :
globals()[name][index]=val
return val
def exe(txt):
exec txt in globals()
return ""
_=""
def evaluate(txt):
global _
if not txt : return ""
if txt.split()[0].startswith("!"):
_=eval(txt[1:])
else :
if not modedict["output"] : #simple
_= kernelLink.EvaluateToInputForm( txt, 0)
else : #pretty
_=kernelLink.EvaluateToOutputForm( txt, 0)
return _
def mode(key,mode):
modedict[key]=mode
return key,mode
def pretty():
mode("output",1)
return "use EvaluateToOutputForm"
def simple():
mode("output",0)
return "use EvaluateToInputForm"
def b1_onclick(sender, args):
sel=t1.SelectedText
if sel :
next= LN+str(evaluate(sel))+LN+LN
else :
lines=t1.Text.splitlines()
ln=t1.GetLineFromCharIndex(t1.SelectionStart)
next=""
l=t1.Text.Length
if not lines : return
if l and ln==t1.GetLineFromCharIndex(l):
# execute last line
t1.Text+=LN
txt=lines[-1]
s=txt.split()
if s and s[0] and s[0]!=LN :
next= LN+str(evaluate(txt))+LN+LN
else:
#copy current line to last line
next=lines[ln]
t1.Text+=next
t1.SelectionStart=t1.Text.Length
t1.ScrollToCaret()
b1.Click+=b1_onclick
frm.AcceptButton=b1
frm.Controls.Add(t1)
frm.Controls.Add(b1)
frm.Controls.Add(b2)
Application.Run(frm)