Мне нравится использовать With[]
с константами, которые мне нужно использовать в 2 разных местах.
Вместо того, чтобы набирать один и тот же длинный список констант в 2 местах, я пытался понять, как использоватьпеременная для этого списка, а затем используйте эту переменную в тех немногих местах, где я хочу использовать список.
Проблема в том, что мне нужно Hold
список и затем ReleaseHold
позже, когда придет времяиспользуйте это, но я не могу понять эту часть правильно.(перепробовал много вещей, у меня ничего не получалось)
Вот пример:
With[{$age = 2, $salary = 3},
x = $age
]
With[{$age = 2, $salary = 3},
y = $age
]
Я не хочу набирать одни и те же константы (в моем случае, они очень длинные), и я пытался сделать что-то вроде этого:
c = HoldForm[{$age = 2, $salary = 3}]
With[Release[c],
x = $age
]
With[Release[c],
y = $age
]
Я пробовал много других комбинаций выше.Так много версий Hold * и Release *, я нахожу их всех очень запутанными.
Вопрос в том, что любой знает, как это сделать, так что я могу использовать этот список в нескольких местах безна самом деле скопировать это?
Чтобы поместить это в контекст, вот пример, где это было бы необходимо:
Я не могу все окружить With
в Манипулировать :(и я не могу поставить With
вне Manipulate для того, что я делаю, все должно быть внутри Manipulate
)
Manipulate[
Evaluate@With[{$age = 2, $salary = 3},
x;
$age,
{{x, $age, "age="}, 0, 10, 1}
]
]
Недопустимый синтаксис.(из-за "," необходимо отделить выражение Manipulate
от элементов управления).(теперь он думает, что у С есть 3 аргумента)
Я мог бы, конечно, сделать
Manipulate[
With[{$age = 2, $salary = 3},
x;
$age
],
Evaluate@With[{$age = 2, $salary = 3},
{{x, $age, "age="}, 0, 10, 1}
]
]
Но, как вы видите, мне пришлось скопировать список констант вокруг.
Если я могу понять, как определить список один раз, я могу поместить его в раздел Initialization
на Manipulate
и использовать его следующим образом:
Manipulate[
With[ReleaseHold[myList],
x;
$age
],
Evaluate@With[ReleaseHold[myList],
{{x, $age, "age="}, 0, 10, 1}
],
Initialization :>
(
myList = HoldAll[{$age = 2, $salary = 3}];
)
]
Я думаю, чтоЯ хочу сделать это возможно, я просто не могу определить правильные команды для использования в части удержания / разблокирования.
edit (1)
Я подумал, что я привел пример того, почему я хочу использовать константы в With
.
Я придумалэтот новый метод :), чтобы позволить мне моделировать запись или структуру.
Постоянными значениями будет именованное поле записи (на самом деле это просто список).
Для имени поля я даю ему порядковый номер (я начинаю с 1) иЯ использую $field=number
, а затем в коде я пишу struct[[$field]]=...
для доступа к полю.
Мне нужно передать значения именованных полей в структуру между выражением Manipulate и областью управления,так как оба должны использовать одну и ту же структуру.
Ниже приведен простой пример манипулятора, который считывает возраст и текущую зарплату из пользовательского интерфейса и выражения и назначает новую зарплату на основе текущей зарплаты и назад.
Запись используется дляпередавать данные между областью управления и функциями выражения и нижнего уровня.
В моей текущей демонстрации у меня есть сотни таких параметров (у меня фактически есть несколько демонстраций, все в одной демонстрации, и я переключаюсь междуразличные макеты пользовательского интерфейса (элементы управления), основанные на том, какой выбор выбран в пользовательском интерфейсе) и использование записей упростят мне жизнь, поскольку теперь я могу выполнять вызовы функций и просто передавать несколько параметров, записей, которые содержат параметры пользовательского интерфейса, а не сотниотдельные параметры, что я должен сделать сейчас.Как я уже говорил много раз ранее, Mathematica нуждается в реальной записи / структуре в качестве базовой структуры данных, в дополнение к List, Array и т. Д., Которые интегрированы в M.
(параметры пользовательского интерфейса должны быть отправлены, все, для более низкого уровня функций, и нет другого выбора, кроме как сделать это. Я не хочу использовать глобальные переменные. Плохой дизайн).
Теперь я также могу передать эту запись по ссылке. Если я хочучтобы обновления происходили внутри других функций гораздо более низкого уровня.Я все еще оцениваю этот метод, чтобы посмотреть, смогу ли я использовать его в своем основном коде.
(*verison 1.1*)
Manipulate[
With[{$age = 1, $salary = 2, $newSalary = 3},
updateRecord[record_] := Module[{},
(*update/process UI input*)
record[[$newSalary]] = record[[$salary]] + record[[$age]]*10;
(*return result*)
record
];
(*call lower level function to process UI parameters*)
myRecord = updateRecord[Unevaluated@myRecord];
(*display the result *)
Grid[{
{"age=", myRecord[[$age]]},
{"current salary=", myRecord[[$salary]]},
{"new salary=", myRecord[[$newSalary]]}
}]
],
(* build the UI controls *)
Evaluate@With[{$age = 1, $salary = 2, $newSalary = 3},
Grid[{
{"age=",
Manipulator[Dynamic[age, {age = #; myRecord[[$age]] = age} &],
{10, 100, 1}, ImageSize -> Tiny], Dynamic[age]},
{"salary=",
Manipulator[
Dynamic[salary, {salary = #; myRecord[[$salary]] = salary} &],
{10, 10000, 10}, ImageSize -> Tiny], Dynamic[salary]}
}
]
],
{{myRecord, {10, 100, 100}}, None},
{{age, 10}, None},
{{salary, 1000}, None},
TrackedSymbols -> {age, salary}
]

edit (2)
При попытке использовать Леонида ниже, я могу использовать его в выражении Manipulate, но не могу понять, как его использовать в области управления.
Вот оригинальный пример использования With
в 2 местах.:
Manipulate[
With[{$age = 2, $salary = 3},
x + $age
],
Evaluate@With[
{$age = 2, $salary = 3},
{{x, $age, "age="}, 0, 10, 1}
],
{x, None}
]
Теперь, используя новый метод Леонида, приведенный ниже, это то, что у меня есть:
Manipulate[
env[
x + $age
],
Evaluate@With[
{$age = 2, $salary = 3},
{{x, $age, "age="}, 0, 10, 1}
],
{x, None},
Initialization :>
(
ClearAll[makeCustomEnvironment];
SetAttributes[makeCustomEnvironment, HoldAll];
makeCustomEnvironment[values : (_Symbol = _) ..] :=
Function[code, With @@ Hold[{values}, code], HoldAll];
env = makeCustomEnvironment[$age = 2, $salary = 3];
)
]
Но возможно ли использовать его и для управления?Я не могу просто сделать это:
Manipulate[
env[
x + $age
],
env[
{$age = 2, $salary = 3},
{{x, $age, "age="}, 0, 10, 1}
],
{x, None},
Initialization :>
(
ClearAll[makeCustomEnvironment];
SetAttributes[makeCustomEnvironment, HoldAll];
makeCustomEnvironment[values : (_Symbol = _) ..] :=
Function[code, With @@ Hold[{values}, code], HoldAll];
env = makeCustomEnvironment[$age = 2, $salary = 3];
)
]
, так как выше выдает много ошибок.
редактировать (3)
удалено как было неверно
редактировать (4)
удалил содержание правки edit (3) выше, так как он содержал ошибку пользователя, сообщавшую мне о проблеме.
Вот ответ службы поддержки WRI на причину, по которой я получаю ошибку
Manipulate::vsform: Manipulate argument env[{{age,100,age},10,200,1}] does
not have the correct form for a variable specification. >>
Когда я писал следующий код:
Manipulate[
env[
record[[$age]] = age;
record[[$salary]] = 60*age;
{record[[$age]], record[[$salary]]}
],
env[
{{age, 100, "age"}, 10, 200, 1}
],
{{record, {40, 5}}, None},
{{salary, 40000}, None},
TrackedSymbols :> {age},
Initialization :>
(
makeCustomEnvironmentAlt =
Function[Null, Function[code, With @@ Hold[{##}, code], HoldAll],
HoldAll];
env = makeCustomEnvironmentAlt[$age = 1, $salary = 2];
)
]
Это объяснение поддержки, почему появилась эта ошибка:
The issue is specifically with the section:
Evaluate@env[{{age, 100, "age"}, 10, 200, 1}]
Manipulate doesn't really evaluate until it gets to the Initialization
option, but it will check its input for correct form. Mathematica reads the
main body of the Manipulate before running the Initialization option. This
is can be verified by using a Print statement:
Initialization -> (Print["Test"];
makeCustomEnvironmentAlt =
Function[Null, Function[code, With @@ Hold[{##}, code], HoldAll],
HoldAll];
env = makeCustomEnvironmentAlt[$age = 1, $salary = 2];
Print["Test"])
Test does not print.
Getting around this will be probably not be clean.
....
Having the code for the controller for age depend on evaluation of
some function which must be initialized does not appear to be possible
with simply Manipulate.
Надеюсь, эта информация поможет.И спасибо всем за помощь, а также за поддержку и объяснение WRI.