Почему это не сработает? Динамический в выборе

Ок, делаю так:

Select[Range[1, 20], # > Dynamic[q] &]

И затем я создаю слайдер:

Slider[Dynamic[q], {1, 20}]

И он всегда будет возвращать пустой набор! Почему!

Обновить Целью этого является изменение набора при перемещении ползунка.


person nes1983    schedule 24.07.2009    source источник


Ответы (3)


Главное помнить, что Dynamic ничего не контролирует непосредственно в оценке. Что он делает, так это создает место на экране, которое имеет свойства оценки.

Если, например, вы должны были оценить следующее в новом сеансе Mathematica...

b=5;
Dynamic[a=b];
b=6;
Print[a];

...тогда что будет напечатано? Вместо того, чтобы оценивать его сразу, подумайте об этом, прежде чем попробовать. Подсказка... это вопрос с подвохом, но понимание подвоха поможет вам понять, что именно делает Dynamic.

Ответ, который я не буду раскрывать здесь (потому что вы действительно должны попробовать сами!), может быть объяснен тем фактом, что Динамика никогда ничего не делала, потому что она никогда не появлялась на экране. Точка с запятой препятствовала отображению Dynamic на экране, и без появления на экране оценка Dynamic ничего не дает.

Более того, если вы удалите все точки с запятой, оператор Print[] (по крайней мере, на моей машине) по-прежнему останется неизменным, но теперь по совершенно другой причине. Это связано с тем, что размещение динамического элемента на экране гарантирует, что его содержимое будет оцениваться, но не когда оно будет оцениваться. В моем примере задается условие гонки, при котором, по крайней мере, на моей машине в версии 7 побеждает оценка Shift+Enter.

Чтобы вернуться к вашему примеру,

Select[Range[1, 20], # > Dynamic[q] &]

Это не работает так, как вы думаете, потому что Dynamic в этом случае не оценивает что-то, что отображается на экране.

Вы можете тривиально продемонстрировать результат, выполнив...

Dynamic[Select[Range[1, 20], # > q &]]

но я предполагаю, что вы заинтересованы не только в отображении его на экране, но и в настройке какого-то побочного эффекта. Возможно, вы присваивали Select переменной. Есть два способа вызвать эти побочные эффекты. Один из них — поместить их во второй аргумент Dynamic. Например...

findset[x_] := (myset = Select[Range[1, 20], # > x &])
Slider[Dynamic[q, (q=#; myset = findset[q])&], {1, 20}]

Во-вторых, создать динамику, которая будет отображаться на экране, но незаметна. Например,

Row[{
    Slider[Dynamic[q], {1, 20}],
    Dynamic[myset = Select[Range[1, 20], # > q &]; ""]
}]

В этом случае Dynamic действительно отображается. Он отображается рядом с ползунком. Но вы этого не видите, потому что он отображает пустую строку. Тем не менее, он имеет все свойства автоматического обновления, которые есть у любого Dynamic.

Для получения дополнительной информации вы должны прочитать начальное и расширенное руководство по динамике в документации Mathematica. Вы также можете увидеть мой пост на comp.soft-sys.math.mathematica здесь (который я частично переформулировал для этого ответа).

person John Fultz    schedule 17.10.2009

Я думаю, вы хотите оставить «Динамический» вне выбора. Кажется, это работает, когда я играю с ним:

In[20]:= x = 5

Out[20]= 5

In[21]:= Slider[Dynamic[x], {1, 20}]

Out[21]= \!\(\*
SliderBox[Dynamic[$CellContext`x], {1, 20}]\)

In[26]:= (*manually move the slider a bit to the right *)

In[23]:= x

Out[23]= 9.36

In[24]:= Select[Range[1, 20], # > x &]

Out[24]= {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}

x = 2 (*slider moves left when I set this*)

Out[25]= 2

РЕДАКТИРОВАТЬ: Ваш фактический вопрос был «почему это не работает» вместо «как мне заставить это работать». Вот проблема:

In[12]:= q = 3

Out[12]= 3


In[13]:= (# > q) &[10]

Out[13]= True


In[14]:= (# > Dynamic[q]) &[10]

(* what you see on the screen looks like an evaluation that is held or something *)
Out[14] = 10 > 3

(* but the full form, which is conveniently what gets copied to the clipboard for
   pasting into this answer, is actually this! *)
Out[14]= 10 > \!\(\*
DynamicBox[ToBoxes[$CellContext`q, StandardForm],
ImageSizeCache->{7., {1., 8.}}]\)

Поэтому, если вы скажете «Динамический[1]», вы получите на экране «3», но на самом деле это не «3» — это какой-то элемент блокнота, который на самом деле отображает «3». '.

Результатом функции сравнения является выражение, подобное приведенному выше, которое не оценивается как True, поэтому select не принимает никаких элементов, поэтому вы получаете пустой набор.

person Eric    schedule 24.07.2009
comment
Ну, вы устанавливаете x на 3, не используя ползунок, и радуетесь тому, что ползунок двигается. Это может быть интересно, но целью или надеждой моих экспериментов было изменение НАБОРА при перемещении ползунка. - person nes1983; 25.07.2009
comment
Если вы переоцените оператор Select без «Динамического» в нем, вы получите новый набор. Если вы хотите, чтобы набор менялся сам по себе... я не знаю! - person Eric; 25.07.2009

Вы хотите, чтобы все начальное выражение Select было динамическим, потому что вы хотите обновлять выбранное подмножество всякий раз, когда изменяется значение q. Вы можете сделать это, переместив Dynamic наружу. Попробуй это:

Slider[Dynamic[q], {1, 20}]

Dynamic[Select[Range[1, 20], # > q &]]
person Pillsy    schedule 19.10.2009