Is there an equivalent of MATLAB's Workspace window in Mathematica?

54

44

For example, in MATLAB, a panel is available where one can see straightaway which variables are used and their dimension sizes. Is such a feature available in Mathematica? I really find it hard to scroll up and down to see where things are in Mathematica; I just want to see at a glance what's been used.

sebastian c.

Posted 2012-11-28T22:28:33.520

Reputation: 1 873

windows? Why restrict this question to windows and not something more commonly used by developers like Unix? – Pinocchio – 2015-08-08T04:33:59.173

2

You might be interested in this Stack Overflow question: Profiling memory usage in Mathematica and especially the answer by Alexey Popkov.

– au700 – 2012-11-29T00:47:50.927

I know we had a question on Stackoverflow about a convenient inspector tool to drill through variables that may exist in nested lists and so, but I can't find it at the moment. @mr.wizard, how's your memory? – Sjoerd C. de Vries – 2012-12-28T10:32:52.767

Answers

50

An ugly hack, look at all things in Global context, keep in table if Dimensions didn't return {}

Grid[Select[{#, Dimensions[ToExpression@#]} & /@ 
   Names["Global`*"], #[[2]] != {} &], Alignment -> Left]

Output

For this to be helpful it needs to be updated dynamically and preferably be in a palette to avoid scrolling up all the time. Instead of displaying just lists this displays everything other than those with Head Symbol. It also shows the Head for all variables, for numbers it shows the value, for lists the dimension and for strings the length.

CreateWindow@PaletteNotebook@Dynamic[Grid[
    Select[
     With[{expr = ToExpression@#},
        {#,
         Head[expr],
         Which[
          ListQ[expr], Dimensions[expr],
          NumericQ[expr], expr,
          StringQ[expr], StringLength[expr],
          True, "-"]}] & /@ Names["Global`*"],
     (#[[2]] =!= Symbol) &],
    Alignment -> Left],
    UpdateInterval -> 10, TrackedSymbols->{}]

version2

Or you could have it update only when clicking a button:

CreateWindow@
 PaletteNotebook[{Button["Refresh", 
    vars = Framed[
      Grid[Select[With[{expr = ToExpression@#}, {#, Head[expr],
            Which[
             ListQ[expr], Dimensions[expr],
             NumericQ[expr], expr,
             StringQ[expr], StringLength[expr],
             True, "-"]}] & /@ 
         Names["Global`*"], (#[[2]] =!= Symbol) &], 
       Alignment -> Left], FrameStyle -> None, FrameMargins -> 5]],
   Dynamic[vars]},
  WindowElements -> {"VerticalScrollBar"},
  WindowTitle -> "Global`*"]

manual

EDIT: In a palette and dynamic, thanks acl.

ssch

Posted 2012-11-28T22:28:33.520

Reputation: 16 150

Thanks ssch, I only wished the other stackexchanges are as responsive. But I guess after executing this, I still need to scroll back up to see it once I am further into my coding. – sebastian c. – 2012-11-28T22:52:23.603

eg Dynamic[ Grid[ Select[{#, Dimensions[ToExpression@#]} & /@ Names["Global*"], #[[2]] != {} &], Alignment -> Left], UpdateInterval -> 1 ]` – acl – 2012-11-28T22:54:59.537

ie, wrap it in Dynamic and add UpdateInterval->1 (say). @sebastianc. to see it constantly, you can eg execute it in another window or make it into a palette – acl – 2012-11-28T22:55:41.003

if you simply prepend CreateWindow@PaletteNotebook@ to your code you get a nice floating window (and the Dynamic wrapper from my other comment) – acl – 2012-11-28T22:59:02.517

1@acl Works like a charm, added it to the answer – ssch – 2012-11-28T23:02:58.840

Is it scrollable? I cannot see all the variables in the list? The update is around 10 sec or so whenever I do a Clear[variable] before the list updates? Could be I have a large number of variables? I notice it seems to have a noticeable performance issue when this is running? i.e my notebook's cursor drags a lot even.. – sebastian c. – 2012-11-28T23:32:08.213

@sebastianc. It's not scrollable because the Options are inherited from PaletteNotebook. Remove the "PaletteNotebook@" portion and you'll get an ordinary, scrollable notebook. You could add options to set the size, title, and position to your liking. – Mark McClure – 2012-11-29T00:30:13.523

@sebastianc the update interval in seconds is the number that comes after UpdateInterval->10. You could always try to understand how this works and modify it, too (although that might be a little tedious if you're unfamiliar with mathematica front-end programming) – acl – 2012-11-29T00:31:31.320

@sebastianc. I made a scrollable version that only updates when a button is clicked – ssch – 2012-11-29T08:57:46.067

HI @ssh I am not sure why when executing the above (with Refresh) a window opens up only showing a small var window but no actual variables been used, even though I have many variable used? – sebastian c. – 2012-12-28T13:35:12.027

@sebastianc.Local notebook context? what does Context[] say? make sure you check for thoose vars – ssch – 2012-12-28T22:50:11.603

Hi @ssch it returns Global` – sebastian c. – 2012-12-29T20:46:47.653

@sebastianc. why don't you accept this answer? You have asked 36 questions and accepted 6; any reason? – chris – 2013-01-06T17:10:35.320

@sebastianc. Missed your last comment, anything happens when you click refresh? (in that case I guess it would be simple to populate var when creating the table) – ssch – 2013-01-06T17:17:06.230

@ssh I recall it did work once, before but since Mathematica 9 not sure why even starting from scratch with new file, it simply opens up a blank pop up menu of vars but nothing else. – sebastian c. – 2013-01-07T12:55:45.563

Hi @ssh, for some reason on Mathematica 9, the size of the pop up menu would only grow to accommodate 16 variables and no more, and also when more variables are being used, since the scrolling doesn't seem to work, I cannot see more variables being used? And updating seems surprisingly long? What about if another .NB file is open in current session? Will it update that too? – sebastian c. – 2013-01-07T15:55:16.513

@sebastianc. I don't have Mathematica 9 so I can't test, but try adding the option WindowSize -> {Fit, 300} (increase 300 to whatever size you need) – ssch – 2013-01-07T16:07:21.477

@ssh. Thanks. Works only thing is I added "HorizontalScrollBar" but still don't see it, only the VerticalScrollBar present: WindowElements -> {"VerticalScrollBar", "HorizontalScrollBar", "StatusArea"}, WindowTitle -> "Global`*", WindowSize -> {Fit, 220}] – sebastian c. – 2013-01-07T16:18:02.083

Hi @ssh, for speed improvement, what about actively or selecting a large file array which I already know the size of, to be excluded from the list as it is taking a long time to see updates, minutes even... – sebastian c. – 2013-01-07T18:32:00.743

Hi ssh, when I made the Module into a function as in f:=Module[ ], then clicking the Refresh button opens up another pop up on top of the current pop up? – sebastian c. – 2013-01-18T17:21:52.127

25

Below is something posted on Mathgroup by Jason McKenzie Alexander. I made a few tiny changes and corresponded about this with Jason for a short while. He sent me his final version, which I post here with his permission. The original (linked above) is really only a few lines of code and can be studied to grasp the principle. The code below is a full package.

Mathematica graphics

BeginPackage["Inspector`"]

StateInspector::usage="Create a dynamic state inspector for the Global` context.";

StateInspectorViewer::usage="Show a dynamic state inspector for the Global` context.";

Begin["`Private`"]

AddNewSymbolHook[]:=$NewSymbol=(If[#2=="Global`",
(#1=#2)&[Symbol["Inspector`Variables`"<>#1],False];
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`up"],True];
(*
Much of the time the OwnValues of a symbol isn't interesting,
so the default on whether to show it is False.
*)
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`own"],False];
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`down"],True];
]&);

UpValuesQ[s_String]:=If[ToExpression[s,StandardForm,UpValues]=!={},True,False]
OwnValuesQ[s_String]:=If[ToExpression[s,StandardForm,OwnValues]=!={},True,False]
DownValuesQ[s_String]:=If[ToExpression[s,StandardForm,DownValues]=!={},True,False]

MakeUpValueView[s_String]:=
If[UpValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"UpValues",
Framed[Dynamic[ToExpression[s,StandardForm,UpValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`up]"]
]
]

MakeOwnValueView[s_String]:=
If[OwnValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"OwnValues",
Framed[Dynamic[ToExpression[s,StandardForm,OwnValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`own]"]
]
]

MakeDownValueView[s_String]:=
If[DownValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"DownValues",
Framed[Dynamic[ToExpression[s,StandardForm,DownValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`down]"]
]
]

ConstructColumn[s_String]:=If[
UpValuesQ[s]===False&&OwnValuesQ[s]===False&&DownValuesQ[s]===False,
Framed[Dynamic[Symbol[s]],ImageSize->Scaled[1],Background->White],
Column[
DeleteCases[
{
Framed[Dynamic[Symbol[s]],ImageSize->Scaled[1],Background->White],
MakeUpValueView[s],
MakeOwnValueView[s],
MakeDownValueView[s]
},ToClobberNull
]
]
]

StateInspector[]:=(AddNewSymbolHook[];StateInspector["Global`"])

StateInspector[s_String]:=(AddNewSymbolHook[];Dynamic@Refresh[
Grid[
Partition[
(OpenerView[
{
Row[{
Style[#,FontFamily->"Arial"],
Spacer[6],
Button[Style["Clear",10],ToExpression["Clear["<>#<>"]"],Appearance->"Palette"],
Spacer[6],
Button[Style["Remove",10],
ToExpression["Remove["<>#<>","
<>"Inspector`Variables`"<>#<>","
<>"Inspector`Variables`"<>#<>"`up,"
<>"Inspector`Variables`"<>#<>"`own,"
<>"Inspector`Variables`"<>#<>"`down]"],
Appearance->"Palette"
],
(*Button[Style["Remove",10],ToExpression["Remove["<>#<>"]"],Appearance->"Palette"]*)
}],
Inspector`Private`ConstructColumn[#]
},ToExpression["Dynamic[Inspector`Variables`"<>#<>"]"]
]&)/@Names[s<>"*"],3,3,{1,1},{}
],
Alignment->{Left,Baseline},Background->{Automatic,{{RGBColor[0.98996, 0.950057, 0.785382],RGBColor[1, 0.983169, 0.877287]}}},
ItemSize->Scaled[.333]
],
UpdateInterval->1
])

StateInspectorViewer[]:=(AddNewSymbolHook[];StateInspectorViewer["Global`"])

StateInspectorViewer[s_String]:=(AddNewSymbolHook[];CreateDocument@Pane@Column[{
Row[{
Style["Mathematica",Italic,"Title"],
Style[" state inspector","Title"]
}],
Row[{
Style["Context: ","Subtitle"],
Spacer[6],
Style[s,"Subtitle",FontFamily->"Courier"]
}],
Spacer[6],
StateInspector[s]
}])

End[]

EndPackage[]

Sjoerd C. de Vries

Posted 2012-11-28T22:28:33.520

Reputation: 63 549

Perhaps a candidate for the new package repository? – Dr. belisarius – 2015-09-23T14:21:21.410

@belisarius perhaps, yes. Have to figure out how github works though. Have never used it before. – Sjoerd C. de Vries – 2015-09-23T16:41:19.157

2Nice package. I'd perhaps also add a checkbox with an option to hide symbols matching *$ or *$number. I usually don't care much for temporary symbols generated by Module and it only takes up useful space in the display – rm -rf – 2013-04-01T20:54:22.283

8

You could do this:

Names["Global`*"]

It looks for symbols in the Global context which is where "global variables" are defined. The * is a wildcart which you can modify to narrow down the search. Look at the docs for Names.

Jens

Posted 2012-11-28T22:28:33.520

Reputation: 93 191

Names["`*"] also can give a same result. – yode – 2017-04-15T02:49:58.143

10That is so V5! Where's the Panel, the Grid, the groovy buttons that automatically display the variable contents as tooltip? Of course, it has the advantage of being simple and effective. :) – Mark McClure – 2012-11-29T00:06:48.557

5@MarkMcClure At least we don't need the cloud to do this ... yet. – Jens – 2012-11-29T01:03:52.167

2

Here is my try:

wscount = Length[Notebooks["Currently Defined Variables"]];

While[wscount > 0,
  NotebookClose[Notebooks["Currently Defined Variables"][[1]]];
  wscount = wscount - 1;
  ];

CreateWindow[
  PaletteNotebook[
   Dynamic[Grid[
     Prepend[Select[
       With[{expr = ToExpression@#}, {#, Head[expr], 
           Which[ListQ[expr], Dimensions[expr], NumericQ[expr], 
            N[expr, 5], StringQ[expr], StringTake[expr, 15], True, 
            "-"]}] & /@ 
        Names["Global`*"], (#[[2]] =!= Symbol) &], {Style["Variable", 
        Bold, Blue, 16], Style["Type", Bold, Blue, 16], 
       Style["Value", Bold, Blue, 16]}], 
     ItemStyle -> Directive[FontSize -> 12], Spacings -> {2, 2}, 
     Dividers -> "|", ItemSize -> {{12, 4, 8}}, 
     Alignment -> {{Left, Center, Left}, 
       Automatic, {{1, 1} -> Center, {1, 3} -> Center}}], 
    UpdateInterval -> 1, TrackedSymbols -> {}], 
   WindowTitle -> "Currently Defined Variables", Saveable -> False, 
   WindowSize -> {400, 
     SystemInformation["Devices", "ScreenInformation"][[1]][[1]][[
         2]][[2]][[2]] - 35}, WindowElements -> "VerticalScrollBar"], 
  WindowFloating -> False];

wscount =.

Often I have definitions like this:

v1=3
v2=v1

If anyone has a good idea how to make v2 show up as v2=v1 rather than v2=3, that would be great!

Fabian

Posted 2012-11-28T22:28:33.520

Reputation: 77