Evaluate current cell without leaving or losing the position in it in Mathematica
Asked Answered
S

5

13

I am experimenting with logo designs in Mathematica (8 or above) using the notebook interface and I want to change the generating formula A LOT. The problem is I only know SHIFT + ENTER which makes me jump outside my current cell and lose my position.

Is there a way to evaluate the current cell without leaving it and losing your position within it? So: Evaluate a cell and land back inside the same cell at the exact position I pressed SHIFT + ENTER at.

What I once came to use was along the lines:

a = Exp[1.994 \[Pi]/(3 I)];

b = Nest[{#, a #, a\[Conjugate] #, #} &, 1, 5];

{Re[#], Im[#]} & /@ 
   Accumulate[
    Flatten[{0, a b, a\[Conjugate] b, -b}]] // {\[Rho]\[Chi], # // 
     Line} & // Graphics

NotebookFind[EvaluationNotebook[], "E" <> "xp", Previous];

but I hope there is just another key combination or sth. that I am not aware of.

Edit:

a = Exp[(*1*)1.994 \[Pi]/(3 I)];

b = Nest[{#, a #, a\[Conjugate] #, #} &, (*2*)1, (*3*)5];

{Re[#], Im[#]} & /@ 
   Accumulate[
    Flatten[{0, a b, a\[Conjugate] b, -b}]] // {\[Rho]\[Chi], # // 
     Line} & // Graphics

Do[NotebookFind[EvaluationNotebook[], "(*1*)", Previous], {2}];

is a nice little improvement to my solution as partly suggested by Chris Dengen.

Edit 2:

NotebookFind[EvaluationNotebook[], "(*1*)", EvaluationCell]

This solves:

  • these only work with cells that produce one or a known number of output cells

EvaluationCell is sparsely documented so hard to find in fact I just stumbled upon it. Using the EvaluationCell the search starts from above (eliminating the Do twice construct) as we do not come from an output cell further down the screen.

What remains to be solved:

  • one needs to do manual cell-keeping (bookkeeping at cell level) to land at places of interest
  • using comment-based landing markers clutters the input cells

Note This question is about not losing current position when one presses SHIFT + ENTER inside a Mathematica notebook cell. It is not about content or Manipulate. Sorry for not making that clear at the beginning.

Temporary Note

Now trying the following:

  1. use event handlers to define an alternative evaluation key combination
  2. when triggered, find a way to store the exact keyboard position in the current input cell
  3. evaluate the current input cell
  4. restore the position in the current input cell

I internally hope some function might just take care of the store/restore by chance being optimistic. Being realistic though, I first hope I can even find a way to get at the current keyboard position. Will follow up here if anything materializes out of my attempt.

Selfknowledge answered 12/12, 2011 at 19:0 Comment(6)
To anyone closing: Please realize that this is a question about Wolfram Mathematica, and not Mathematics!Spun
@MikeBantegui well thanks I found it odd as well. There are lots of Mathematica users / experts on SO and I hope the answer would be interesting to all.Selfknowledge
Do you have a more thorough example that we can play with, along with the parameters that you'll be adjusting?Spun
@MikeBantegui nope. It is as a said in the 2nd paragraph: just looking for SHIFT + ENTER alternative that works in any situation. Cell content is actually not relevant.Selfknowledge
I'm not sure if what you want is really possible. I've taken a look through most of the Notebook documentation and that sort of functionality isn't available. The cleanest solution would be to just format your code in such a way that it's easily editable (e.g. Manipulate or using variables for the variable portions of an expression)Spun
I am now trying it with NotebookEventHandler and a KeyDown event ... then I hope I can find a way to evaluate a cell yet still stay at its current position.Selfknowledge
B
7

You can run this cell over and over:

If[NumberQ[x], x++, x = 1];
Print[x]
Do[SelectionMove[EvaluationNotebook[], Previous, Cell], {2}]

This version places the cursor after the Exp in line 1:

a = Exp[1.994 \[Pi]/(3 I)];
b = Nest[{#, a #, a\[Conjugate] #, #} &, 1, 5];
{Re[#], Im[#]} & /@ 
   Accumulate[
    Flatten[{0, a b, a\[Conjugate] b, -b}]] // {# // 
     Line} & // Graphics
Do[NotebookFind[EvaluationNotebook[], "Exp", Previous], {3}];
SelectionMove[EvaluationNotebook[], "Exp", After];

You could also put Evaluate & move on a key combination, e.g. ctrl+r in the example below. This assignment only lasts for the current session but it can be loaded with pre-initialisation so that it is always present. (The key combo item is added to the Insert menu.)

FrontEndExecute[
 FrontEnd`AddMenuCommands[
  "DuplicatePreviousOutput", {Delimiter, 
   MenuItem["Evaluate and return", 
    FrontEnd`KernelExecute[Module[{nb}, nb = SelectedNotebook[];
      SelectionMove[nb, Previous, Cell];
      SelectionMove[nb, Next, Cell];
      SelectionEvaluate[nb];
      Do[SelectionMove[EvaluationNotebook[], Previous, Cell], {2}]]], 
    MenuKey["r", Modifiers -> {"Control"}], 
    System`MenuEvaluator -> Automatic]}]]

To set pre-initialisation save the above code to a package .m file as EvaluteReturn.m in your Documents directory and evaluate the following.

InitializationValue[$PreInitialization] = Hold[Get[
   FileNameJoin[{$HomeDirectory, "Documents", "EvaluateReturn.m"}]]]

To inspect the value

InitializationValue[$PreInitialization]

To clear the value

obj = InitializationObjects[$PreInitialization, {"Local"}]

DeleteObject[obj]
Bugbane answered 12/12, 2011 at 19:6 Comment(5)
Thanks but what I would really like is to land back inside the cell at the exact position I pressed SHIFT + ENTER at.Selfknowledge
Your final answer comes is an improvement over my initial one. One could combine yours with a marker in comments like (* HERE *) to land very close to where one is working at that moment with the added benefit of not having to split what you use in NotebookFind's 2nd argument.Selfknowledge
accepted as you were the only person that has understood the nature of the question :) and your Do suggestion helped improve the experience even if only a tiny little bit. Thanks a lot!Selfknowledge
This worked, thank you. I'm surprised that there isn't a keyboard shortcut that would do this in the application. This is standard in Jupyter notebooks, where Shift+Enter moves to the next cell, and Cmd-Enter (or Ctrl-Enter) stays in the current cell.Azikiwe
@DanKowalczyk I have added code for a keyboard shortcut which you could adapt to your requirement.Bugbane
S
4

How about using Manipulate? Something like

Manipulate[
 c = a;
 b = Nest[First@f, 1, 
   5]; {Re[#], Im[#]} & /@ 
    Accumulate[
     Flatten[{0, c b, c\[Conjugate] b, -b}]] // {Red, # // Line} & // 
  Graphics, {a, Exp[1.994 \[Pi]/(3 I)], 
  ControlType -> InputField}, {f, 
  HoldForm[{#, c #, c\[Conjugate] #, #} &], ImageSize -> Full, 
  ControlType -> InputField}]

You can just edit the values, and upon hitting enter get a new version of the plot. You can save examples you like by using the '+' button in the top-right corner of the Manipulate to either set bookmarks or paste a snapshot.

enter image description here

Sarcous answered 12/12, 2011 at 19:36 Comment(4)
This is a neat idea and one certainly I will remember to use in some cases. Yet sometimes I have matrices and all sorts of other stuff and you get no typesetting or nice formatting of such stuff in a Manipulate. It feels oddly restrictive as if I am thrown all the way out to terminal where I can only enter non-typeset plain strings.Selfknowledge
You can input using some typeset forms (radicals, powers, etc...) but I wasn't able to get nice matrices in the input field. (At least not without manually using the Insert menu item. The shortcuts to add a row/column didn't work in the input field.)Sarcous
Brett you can wrap MatrixForm around lists in InputFields and get nice rendering but of course then you need to test for it and remove it in your code. Manipulate[ If[Head[x] === MatrixForm, First[x], x], {x, MatrixForm[{{2, 3}, {1, 2}}], ControlType -> InputField} ]Parse
@Mike True. I'd probably just use Block[{MatrixForm = Identity}, ...].Sarcous
S
2

You can use dynamic to make things really nice.

The cell to display results in:

Dynamic[b = Nest[{#, a #, a\[Conjugate] #, #} &, 1, 5];]
Dynamic[{Re[#], Im[#]} & /@ 
    Accumulate[
     Flatten[{0, a b, a\[Conjugate] b, -b}]] // {\[Rho]\[Chi], # // 
      Line} & // Graphics]

The cell to edit in:

k = 1.994;
a = Exp[k \[Pi]/(2 I)];
NotebookFind[EvaluationNotebook[], ToString[k], Previous];

You can then just edit the cell below the display one. It automatically puts you right where you entered your value. If you'd like to make things even easier on yourself you can use Manipulate:

Manipulate[a = Exp[k \[Pi] / (f I)];
 b = Nest[{#, a #, a\[Conjugate] #, #} &, 1, 5];
 {Re[#], Im[#]} & /@ 
    Accumulate[
     Flatten[{0, a b, a\[Conjugate] b, -b}]] // {\[Rho]\[Chi], # // 
      Line} & // Graphics,
 {{k, 1.994}, -3, 3},
 {{f, 3}, -3, 3}]
Spun answered 12/12, 2011 at 19:25 Comment(0)
E
2

You can use low level notebook programming and a feature called docked cells to add a cell to the top of your notebook which will execute the current cell. This (in theory, haven't tried it) shouldn't take the cursor position out of the cell. to programmatically create the docked cell, create a cell which has the button that does what you want, then execute this code: SetOptions[SelectedNotebook[],"DockedCells"->{Cell[ BoxData[ToBoxes[...your code for execute button...]] , "DockedCell"]}];

I do this all the time with corporate logo as a fixed cell or "Copy as Plain Text"/"Copy as Bitmap" buttons. On notebooks which mess up the kernel heavily, I add buttons for mem management or even restarting the kernel. Just series of shortcuts. You can stack more than one Cell[] object as docked cells.

Eudo answered 12/12, 2011 at 20:13 Comment(0)
G
1

There's a function called 'evaluate in place' which allows you to select a section of a cell, and just evaluate that. On the Mac it's command-Enter, instead of control-Enter.

Look at the Evaluate menu, the menu entry should be there along with the bound shortcut key combination.

Giselagiselbert answered 12/12, 2011 at 19:16 Comment(1)
Wait, that replaces the current selection with it's evaluated expression. That's not what you were wanting, is it?Giselagiselbert

© 2022 - 2024 — McMap. All rights reserved.