2011-08-21 4 views
7

Lorsque j'utilise Manipulez je peux faire:Définir le contrôle comme variable dans Mathematica

Manipulate[x, {u, 1, 10}] 

En réalité, mes contrôles sont nombreux et complexes, donc je préférerais prendre leur définition de l'expression Manipulez, comme ça :

control = {u, 1, 10} 
Manipulate[x, control] 

Mais cela ne résulte en une erreur:

Manipulate argument control does not have the correct form for a \ 
variable specification. 

Pourquoi cela ne fonctionne-t-il pas de cette façon?

+1

L'exemple que vous avez fourni, et ce que je vois dans la plupart des réponses est que la complexité du code est pas réduit du tout. Certaines des réponses créent un morceau de code très complexe en utilisant significativement plus de caractères, un tas de constructions supplémentaires, etc. Je pense qu'améliorer la _layout_ de votre code (chaque contrôle sur sa propre ligne, regrouper visuellement les contrôles liés etc.) dans la plupart des cas suffisent. –

+0

Grâce aux réponses, je comprends mieux ce qui se passe, mais vous avez parfaitement raison: aucune des constructions ne simplifie vraiment le code. Ce qui me rend fou est la profondeur d'imbrication des parenthèses dans mon code. Probablement c'est la manière de Lisp de le faire, mais n'y a-t-il pas un moyen de rendre mes programmes plus linéaires? –

+1

@Sjoerd bien, si un morceau de code apparaît dans un endroit, alors je suis d'accord avec vous. Cela a généralement du sens si a) vous utilisez le code à plus d'un endroit, ou b) le code complet devient trop long pour être facilement modifié. Par exemple, j'ai un cahier avec un «Manipuler» le code pour lequel ne figure pas sur l'écran de 13 pouces de mon macbook. Je dois soit utiliser un truc comme celui-ci, ou essayer de charger le tout dans ma tête chaque fois que j'ai besoin de le modifier.Comme je dois déjà réfléchir au problème que je suis en train de résoudre, je préfère réduire la complexité du code en ajoutant quelques caractères. – acl

Répondre

10

Ce

con = {u, 1, 10}; 
Manipulate[ 
u, 
[email protected] 
] 

fonctionne. Je suppose que cela ne fonctionne pas sans Evaluate parce

Attributes[Manipulate] 

montre que Manipulate a l'attribut HoldAll (mais je peux me tromper). Pour voir l'effet de cet attribut, essayez ceci:

SetAttributes[f, HoldAll] 
f[con] 
f[[email protected]] 
g[con] 
(* 
f[con] 
f[{u, 1, 10}] 
g[{u, 1, 10}] 
*) 

Ainsi, il apparaît qu'en raison de la HoldAll atribute, Manipulate ne voit tout simplement pas « à l'intérieur » con à moins que vous évaluez explicitement.

+1

Vous m'avez battu par * ça * beaucoup! Donc, +1 – Simon

+0

@Simon merci! +1 pour vous aussi. Je suppose que je vais finir avec moins de upvotes de toute façon :) – acl

+0

Merci, cela fonctionne quand je copie et colle ton exemple dans une nouvelle feuille de travail. Dans ma vieille feuille de calcul, je devais appuyer sur Maj + Entrée sur chaque ligne avant que cela fonctionne, même sur la ligne avec contrôle = {u, 1, 10}, qui n'avait pas changé. Pourquoi dois-je réévaluer les lignes? –

11

Manipulate a le HoldAll attribute. Vous pouvez forcer control à évaluer et tout fonctionne ok

control = {u, 1, 10}; 
Manipulate[x[u], Evaluate[control]] 

Le problème est que la u variable est pas correctement localisée, donc si vous avez déjà défini, par exemple, quelque part u=1, le Manipulate renvoie une erreur .

Il peut être préférable d'utiliser des constructions de cadrage appropriées telles que With ou DynamicModule en fonction de ce que vous essayez de faire exactement.

Ceci est peut-être exagéré, mais il assure que u est locale et se déplace control en dehors de la manipulation:

DynamicModule[{u}, With[{control = {u, 1, 10}}, Manipulate[x[u], control]]] 
Questions connexes