59
$\begingroup$

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.

$\endgroup$
3
  • 2
    $\begingroup$ You might be interested in this Stack Overflow question: Profiling memory usage in Mathematica and especially the answer by Alexey Popkov. $\endgroup$
    – au700
    Nov 29, 2012 at 0:47
  • $\begingroup$ 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? $\endgroup$ Dec 28, 2012 at 10:32
  • $\begingroup$ windows? Why restrict this question to windows and not something more commonly used by developers like Unix? $\endgroup$ Aug 8, 2015 at 4:33

4 Answers 4

52
$\begingroup$

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.

$\endgroup$
20
  • $\begingroup$ 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. $\endgroup$ Nov 28, 2012 at 22:52
  • $\begingroup$ eg Dynamic[ Grid[ Select[{#, Dimensions[ToExpression@#]} & /@ Names["Global*"], #[[2]] != {} &], Alignment -> Left], UpdateInterval -> 1 ]` $\endgroup$
    – acl
    Nov 28, 2012 at 22:54
  • $\begingroup$ 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 $\endgroup$
    – acl
    Nov 28, 2012 at 22:55
  • $\begingroup$ if you simply prepend CreateWindow@PaletteNotebook@ to your code you get a nice floating window (and the Dynamic wrapper from my other comment) $\endgroup$
    – acl
    Nov 28, 2012 at 22:59
  • 1
    $\begingroup$ @acl Works like a charm, added it to the answer $\endgroup$
    – ssch
    Nov 28, 2012 at 23:02
26
$\begingroup$

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[]
$\endgroup$
4
  • 2
    $\begingroup$ Nice 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 $\endgroup$
    – rm -rf
    Apr 1, 2013 at 20:54
  • $\begingroup$ Perhaps a candidate for the new package repository? $\endgroup$ Sep 23, 2015 at 14:21
  • $\begingroup$ @belisarius perhaps, yes. Have to figure out how github works though. Have never used it before. $\endgroup$ Sep 23, 2015 at 16:41
  • $\begingroup$ Many years later, this code still works with mma v12.3 though it unfortunately displays all variables also internal ones...Perhaps there has been a newer version made since then :)? $\endgroup$ Feb 6, 2022 at 16:35
9
$\begingroup$

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.

$\endgroup$
3
  • 10
    $\begingroup$ That 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. :) $\endgroup$ Nov 29, 2012 at 0:06
  • 5
    $\begingroup$ @MarkMcClure At least we don't need the cloud to do this ... yet. $\endgroup$
    – Jens
    Nov 29, 2012 at 1:03
  • $\begingroup$ Names["`*"] also can give a same result. $\endgroup$
    – yode
    Apr 15, 2017 at 2:49
2
$\begingroup$

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!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.