Как определить часть определения управляющей переменной Manipulate для уменьшения дублирования кода

Это немного связано с этим вопросом

Определить элемент управления как переменную в Mathematica

Но приведенный выше вопрос не дал ответа на мою проблему, поскольку он говорит об определении полного элемента управления. (Я также пробовал некоторые из показанных там уловок, но они не работают с моей проблемой).

Я сейчас спрашиваю об определении только части контроля. (Также очень сложно следить за старым вопросом, используя этот формат форума. Поскольку, используя крошечную область комментариев, трудно задавать и показывать больше, как при задании нового вопроса, где пространство больше, и можно вставить код и изображений).

Все мои попытки не работают. Я начну с простого примера, чтобы объяснить проблему.

Предположим, кто-то хочет написать

Clear["Global`*"];

Manipulate[Plot[f*g, {x, -1, 1}],
 Grid[{
   {Style["f(x)="], 
    PopupMenu[Dynamic[f], {x, x^2, x^3}, ImageSize -> Tiny]},{Style["g(x)="], 
    PopupMenu[Dynamic[g], {x, x^2, x^3}, ImageSize -> Tiny]}
   }]
 ]

, вы можете видеть, что в каждом определении элемента управления выделено дублирование кода. (такие вещи, как ImageSize, Spacings-> и многие другие настройки декорации, повторяются снова и снова для каждого элемента управления.

enter image description here

Что было бы замечательно, если бы я мог написать что-то вроде

Manipulate[Plot[f*g, {x, -1, 1}],
 Grid[{
   {Style["f(x)="], PopupMenu[Dynamic[f], Evaluate@Sequence@v]},
   {Style["g(x)="], PopupMenu[Dynamic[g], Evaluate@Sequence@v]}
   }],

 Initialization :>
  (
   v = {{x, x^2, x^3}, ImageSize -> Tiny}
   )
 ]

Но это не работает. Я пробую много других вещи в соответствии с приведенной выше строкой, и ничего не работает. Например,

{Style["f(x)="], PopupMenu[Dynamic[f], v]},

,

{Style["f(x)="], PopupMenu[Dynamic[f], Evaluate@v]}

и

Manipulate[Plot[f*g, {x, -1, 1}],

 {{v, {{x, x^2, x^3}, ImageSize -> Tiny}}, None},
 Grid[{
   {Style["f(x)="], PopupMenu[Dynamic[f], Evaluate@v]},
   {Style["g(x)="], PopupMenu[Dynamic[g], v]}
   }]
 ]

не могут заставить его работать.

Но вот правила игры: Это будет для демонстрации, поэтому , Код должен начинаться с Manipulate . Не может иметь модуль вне Manipulate. Кроме того, не может использовать Hold и его друзей . Но может использовать Unevaluated.

Я надеялся, что эксперты здесь может быть трюк, чтобы сделать это.Это уменьшит размер кода, если это возможно, поскольку многие элементы управления, которые у меня есть, содержат много одинаковых `` параметров '', подобных приведенным выше, и возможность сделать это сделает код более легким для чтения и управления. .

спасибо,

пс. То, о чем я прошу, похоже на то, что делают, скажем, для параметров графика, где можно использовать SetOptions для установки некоторых общих параметров по умолчанию, чтобы им не приходилось каждый раз дублировать их для каждой команды графика. Но в данном случае такого нет.

update

Используя метод, показанный Леонидом ниже (трюк с макросами), я хотел использовать его, чтобы помочь мне определить количество элементов управления с использованием одной общей настройки. Вот что я пробовал:

Manipulate[{x, y},

 Evaluate@With[
   {
    control1 = Function[{var, initialValue, str, from, to, incr},
      {
       {{var, initialValue, str}, from, to, incr, ImageSize -> Tiny}
       }
      ,
      HoldAll
      ]
    },

   {
      First@control1[x, 0, "x=", 0, 1, .1],
      First@control1[y, 0, "y=", 0, 2, .1],
      First@control1[z, 0, "z=", 0, 10, .1]
    }, 

   ]
 ]

Проблема просто в дополнительном {} вокруг всего этого, иначе это сработает. Буду продолжать попытки решить эту проблему. Но приближаюсь. Пробовал Sequence [], Flatten [.., 1] и тому подобное, но пока не могу. Приготовление еще кофе должно помочь.

Обновление 2

Ниже приведен пример использования метода Саймона для определения общего определения для более чем одного элемента управления. Таким образом, его можно использовать для уменьшения дублирования кода для общих опций в наборе отдельных элементов управления.

Обратите внимание, что для управления им пришлось использовать Control [] .

Manipulate[{x, y, z},

 Dynamic[Grid[{
    {control1[x, 0, "x=", 0, 1, .1]},
    {control1[y, 0, "y=", 0, 2, .1]},
    {control1[z, 0, "z=", 0, 10, .1]}
    }]],

 {{control1, 
   Function[{var, initialValue, str, from, to, incr}, 
    Control[{{var, initialValue, str}, from, to, incr, 
      ImageSize -> Tiny}], HoldFirst]}, None}

 ]

enter image description here

Обновление 3

И заставил метод Леонида работать также на нескольких элементах управления. Уловка заключается в использовании Control [] . Невозможно использовать простой старый {{x, 0, "x"}, ...} [ИЗМЕНИТЬ, да, можно, просто нужен метод Sequence @@, как показано ниже обновлением Леонида.] .

Вот он:

Manipulate[{x, y, z},

 Evaluate@With[
   {
    control1 = Function[{var, initialValue, str, from, to, incr},
      Control[{{var, initialValue, str}, from, to, incr, 
        ImageSize -> Tiny}]
      , HoldAll
      ]
    },

   Grid[{
     {control1[x, 0, "x=", 0, 1, .1]},
     {control1[y, 0, "y=", 0, 2, .1]},
     {control1[z, 0, "z=", 0, 10, .1]}
     }]

   ]
 ]

enter image description here

Я попытаюсь интегрировать один из этих методов в свою основную демонстрацию (на данный момент содержит более 600 строк кода только для макета элемента управления и растет с каждой минутой, надеюсь, эти методы уменьшат это совсем немного)

Обновление 26.09.11. 19:00

Я подумал, что опубликую «с высоты птичьего полета» вид сохранения кода с помощью «макросов» для определения элементов управления, которые содержат много общих шаблонных кодов. Вот снимок экрана до и после.

Еще раз спасибо за ответы и помощь.

enter image description here

12
задан Community 23 May 2017 в 10:30
поделиться