当我使用Manipulate时,我可以这样做:
Manipulate[x, {u, 1, 10}]
Run Code Online (Sandbox Code Playgroud)
实际上我的控件很复杂,所以我更喜欢将它们的定义从Manipulate表达式中取出,如下所示:
control = {u, 1, 10}
Manipulate[x, control]
Run Code Online (Sandbox Code Playgroud)
但这确实会导致错误:
Manipulate argument control does not have the correct form for a \
variable specification.
Run Code Online (Sandbox Code Playgroud)
为什么不这样做?
我需要在一个大的Mathematica代码库(数十万行代码)上做一些元编程,并且不想编写一个完整的解析器,所以我想知道如何最好地从Mathematica笔记本中获取代码用一种易于解析的语法.
是否可以在FullForm
语法中导出Mathematica笔记本,或者在语法中保存所有定义FullForm
?
该文档的Save
说,它可以在唯一的出口InputForm
语法,这是不平凡的解析.
到目前为止,我所拥有的最佳解决方案是评估笔记本,然后使用DownValues
参数提取重写规则(但这会错过符号定义),如下所示:
DVs[_] := {}
DVs[s_Symbol] := DownValues[s]
stream = OpenWrite["FullForm.m"];
WriteString[stream,
DVs[Symbol[#]] & /@ Names["Global`*"] // Flatten // FullForm];
Close[stream];
Run Code Online (Sandbox Code Playgroud)
到目前为止,我尝试了各种方法,但没有一种方法效果很好.Mathematica中的元编程似乎非常困难,因为它一直在评估我想要保持不被评估的事物.例如,我想获取无穷大符号的字符串名称,SymbolName[Infinity]
但是将Infinity
得到的值计算为非符号,并且调用SymbolName
带有错误的die.因此,我希望用更合适的语言进行元编程.
编辑
最好的解决方案似乎是手动将笔记本保存为包(.m)文件,然后使用以下代码进行翻译:
stream = OpenWrite["EverythingFullForm.m"];
WriteString[stream, Import["Everything.m", "HeldExpressions"] // FullForm];
Close[stream];
Run Code Online (Sandbox Code Playgroud) 我不确定如何初始化Mathematica中的结构以与Manipulate一起使用,以帮助我更好地组织我拥有的许多控制变量.
我将举几个例子,这有助于说明问题.
这是最基本的操作:
方法1
Clear["Global`*"]
Manipulate[process[a, b],
{{a, 1, "a"}, -10, 10, 1},
{{b, 2, "b"}, -10, 10, 1},
Initialization :>
{
process[a_, b_] := Module[{}, Row[{"a=", a, " b=", b}]]
}
]
Run Code Online (Sandbox Code Playgroud)
在我写的一个演示中,我有更多的控件.一些函数(例如上面名为process []的函数)最终必须使用15个或更多参数调用,这使得我很难维护.(我别无选择,不能真正考虑它).
所以,我正在尝试使用结构来收集这些变量.相关问题是这样的
所以,接下来我尝试了下面的内容:(我知道在Mathematica中制作结构的选择不是最好的,但我想先看看它是否可行)
方法2
Clear["Global`*"]
Manipulate[process[myData],
{{myData["a"], 1, "a"}, -10, 10, 1},
{{myData["b"], 1, "b"}, -10, 10, 1},
Initialization :>
{
process[myData_] :=
Module[{}, Row[{"a=", myData["a"], " b=", myData["b"]}]]
}
]
Run Code Online (Sandbox Code Playgroud)
但上述方法无效.我明白了
Manipulate::vsform does not have the correct form for a variable specification
Run Code Online (Sandbox Code Playgroud)
所以,我想,好吧,让我自己填写结构,然后调用process []函数,所以我这样做了: …
V 8.04.这Manipulate
仅限于使用.
下面是一个使用Item将控件放在UI中使用Manipulate在不同位置的简单示例
Manipulate[Plot[Sin[z], {z, -Pi, Pi}, ImageSize -> 100],
Item[Control[{{x, 0, "x="}, 0, 10, 1,ImageSize->Tiny}],ControlPlacement->Left],
Item[Control[{{y, 0, "y="}, 0, 10, 1,ImageSize->Tiny}],ControlPlacement->Right]
]
Run Code Online (Sandbox Code Playgroud)
但是,我使用Leonid的宏方法(链接在这里)来帮助我构建我的UI控件,所以我想做类似的事情
Manipulate[Plot[Sin[z], {z, -Pi, Pi}],
Evaluate@With[{im = ImageSize -> Tiny},
Item[Control[{{x, 0, "x="}, 0, 10, 1, im}],ControlPlacement -> Left],
Item[Control[{{y, 0, "y="}, 0, 10, 1, im}], ControlPlacement -> Right]
]
]
Run Code Online (Sandbox Code Playgroud)
上面的方法不起作用,因为我们不再有一个表达式来使With
快乐,它具有语法
With[{x=x0}, expression ]
Run Code Online (Sandbox Code Playgroud)
而在上面,2 Item
s现在不是一个表达式,而是2.
仅当我想Item
用于控制放置时,才会出现此问题.否则,我会Grid[]
在里面使用和组合我不同的东西Grid
,然后问题就解决了.
但我当然不能Item
在网格中使用,以使每个Item
位于不同的位置.整体Grid …
我喜欢使用With[]
我需要在两个不同的地方使用的常量.
我没有在2个地方输入相同长的常量列表,而是试图计算如何使用这个列表的变量,然后在我想要使用列表的几个地方使用这个变量.
问题是我需要Hold
列表,然后ReleaseHold
在需要时间时使用它,但我无法正确使用这部分.(尝试过很多东西,对我没用)
这是一个例子:
With[{$age = 2, $salary = 3},
x = $age
]
With[{$age = 2, $salary = 3},
y = $age
]
Run Code Online (Sandbox Code Playgroud)
我不想在周围键入相同的常量(在我的情况下,这些常量非常长),我试图做这样的事情:
c = HoldForm[{$age = 2, $salary = 3}]
With[Release[c],
x = $age
]
With[Release[c],
y = $age
]
Run Code Online (Sandbox Code Playgroud)
我尝试了上面的许多其他组合.如此多的Hold*和Release*版本,我发现它们都非常令人困惑.
问题是:任何人都知道如何做到这一点,所以我可以在不止一个地方重复使用该列表而不实际复制它?
为了将其置于上下文中,以下是需要这样的示例:
我不能用With
Manipulate 环绕一切:(而且我不能把With
外面的操作放在我正在做的事情上,一切都必须在里面Manipulate
)
Manipulate[
Evaluate@With[{$age = 2, $salary = 3},
x;
$age,
{{x, $age, "age="}, 0, 10, 1}
]
]
Run Code Online (Sandbox Code Playgroud)
语法无效.(由于","需要将Manipulate
表达式与控件分开).(它现在认为有3个参数) …
我正在使用Leonid的宏方法(见这里)来帮助我管理控制变量的布局Manipulate
.
但我发现从宏中,我无法使用其他地方定义的另一个宏.所以我想知道是否有办法在另一个宏中使用宏?
为了解释这个问题,我将首先使用一个级别的宏显示一个非常简单的Manipulate,然后我将通过尝试使用另一个宏中的宏来显示问题.
Manipulate[Text["ok"],
Evaluate@With[{
x = Function[{}, (*----> macro x *)
TabView[{
"x" -> "working on x"
}], HoldAll
],
y = Function[{}, (*----> macro y *)
TabView[{
"y" -> "working on y"
}], HoldAll
]
},(*WITH*)
(* now use the above macros *)
Grid[{
{SetterBar[Dynamic[choice], {1, 2}]},
{Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
}]
],
{{choice, 1}, None},
ContentSize -> 300
]
Run Code Online (Sandbox Code Playgroud)
现在为复选框添加一个宏,然后尝试从上面的'x'宏中使用它:
操纵[文字[ "确定"],
Evaluate@With[{
checkBox = Function[{}, Checkbox[Dynamic[c]], HoldAll], …
Run Code Online (Sandbox Code Playgroud)