1

そのため、ユーザー入力として式を受け取り、プログラム内で値が変化するにつれてその式を評価する必要があるプログラムの作成に取り組んでいます。こういった表現が多いでしょう。時間を進めるための「再生」機能があるので、通常は「他の誰かが書いたものを見つける」ことを意味するものを速く(っぽい)保ちたいと思いますが、私は自分のものを書くことに反対していません.

このようなものを入力として期待しています

input> sin(currentTime()*360) - (plant.height*5 + root.depth**2)

トークン化や ast の構築などを検討しましたが、複数の入力が変更されたときに何度も評価できる関数を取得する最後のステップが欠落しているようです。

正しい一般的な方向への突き出しが最も役立ちます。ありがとう!

4

2 に答える 2

0

イベントに対して任意のフィルタリング ルールを適用して、それに応じてアクションを実行する必要があるかどうかを確認するために、このようなことを行いました。イベントと関連するコンテキストは、ラムダでラップされた任意の式からコンパイルされた関数に引数として渡されます。

# API consists of the variables:
# - plant
# - root
# - currentTime
# math.* and random.* are imported

exprs = """\
sin(currentTime()*360) - (plant.height*5 + root.depth**2)
cos(currentTime()*180) - (plant.height*3 + root.depth**(1.5 + random()*0.5))""".splitlines()

# function to 'compile' expression into an executable function
def makeFunction(expr):
    # define args that are supported in the expression
    api = "plant,root"
    return eval("lambda %s : %s" % (api, expr))

# compile given expressions into functions
fns = [makeFunction(e) for e in exprs]

大規模なプログラムでこれがどのように見えるかを示すモック ラッパーを次に示します。

from math import *
from random import *

# mock up simple classes and vars to simulate larger program
def simpleClass(clsname, **kwargs):
    classDefn = "class %s:\n  %s=%s" % (clsname, ','.join(kwargs.keys()), 
                                        ','.join(map(str,kwargs.values())))
    print classDefn
    exec(classDefn, globals())

def mockProgramVars():
    # define some simple classes for API variables
    simpleClass("Plant", height=0, stem=0)
    simpleClass("Root", depth=0, thickness=0, radius=0)
    return Plant(), Root()

plant, root = mockProgramVars()


# loop through time, evaluating functions as plant and root grow
for T in range(0,10):
    # note, local vars become implicit part of API for functions
    def currentTime():
        return T

    # define explicit args
    args = (plant, root)

    # invoke compiled functions
    print T, ":", 
    for i,fn in enumerate(fns, start=1):
        print fn(*args),
    print

    # have plant grow a bit before next time
    plant.height += 0.1
    root.depth += 0.2

プリント:

class Plant:
  stem,height=0,0
class Root:
  depth,radius,thickness=0,0,0
0 : 0.0 1.0
1 : 0.418915723414 -0.948727984564
2 : -1.70407169644 -1.12048780375
3 : -2.5102191366 -0.418297794419
4 : -1.72700555043 -2.69830945686
5 : -3.36779764724 -2.4337532978
6 : -5.42800370907 -2.38542932493
7 : -5.03162665152 -4.90632786047
8 : -5.81504769652 -4.46741225807
9 : -8.59104601264 -5.02132453755

もちろん、eval の使用に関する標準的な警告はすべて適用されます。

于 2013-09-05T08:08:46.390 に答える