Reputation: 368
Is there an easier way to display the name and the value of all variables defined in a single cell in a pretty way?
The way I'm doing now is like this, but I waste a lot of time when there are 30 variables or more:
Upvotes: 7
Views: 9565
Reputation: 1263
So, this was a tough nut to crack. Essentially we are just trying to grab all of the lines in the current cell and extract the variables. As it turns out, we cannot use the global variables defined by IPython (e.g. _
, __
, _i<n>
etc) as suggested in Programmatically get current Ipython notebook cell output? because (as far as my experiments have shown) you can only grab values from previously executed cells and not the one currently being executed.
Luckily for us, it turns out that using the magic command %history
does grab the input of the current cell. So with the help of this and this I have created a function that does exactly what you want:
def cell_vars(offset=0):
import io
from contextlib import redirect_stdout
ipy = get_ipython()
out = io.StringIO()
with redirect_stdout(out):
ipy.magic("history {0}".format(ipy.execution_count - offset))
#process each line...
x = out.getvalue().replace(" ", "").split("\n")
x = [a.split("=")[0] for a in x if "=" in a] #all of the variables in the cell
g = globals()
result = {k:g[k] for k in x if k in g}
return result
You can test it with something like:
a = 1
b = 2
c = 3
cell_vars()
which should give {'a': 1, 'b': 2, 'c': 3}
, you can then format this and print it however you like. Obviously there are some limitations with my line processing (assumes that all variables of interest are in global scope).
Hope this is useful!
Upvotes: 6
Reputation: 7690
You can use whos
command to see all variables stored in the current kernel.
k, g, lx = .4, .8, 6.6
m = k*g*lx**2
whos
outputs:
Variable Type Data/Info
-----------------------------
g float 0.8
k float 0.4
lx float 6.6
m float 13.939200000000001
But as said, it displays all variables, so it will display other variables from earlier cells you've run.
A similar result can be achieved using locals() or globals() command from python built-in functions, which return a dictionary of variables. But the way jupyter represents is prettier.
Alternatively you can use InteractiveShell. This will change the behavior of cells and act like a python shell would, so it will output every called value (to output cell) once run.
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
k
g
... do stuff ...
lx
m
... do more stuff ...
outputs:
Out[2]: 0.4
Out[2]: 0.8
Out[2]: 6.6
Out[2]: 13.939200000000001
And finally you can return the interactivity to default by setting it to last_expr
.
InteractiveShell.ast_node_interactivity = "last_expr"
But the way you do it is probably the easiest and prettiest way, you can just remove the assignment on dataframe to make it a one liner or you can make it more compact to call by:
k, g, lx, m
Out[3]: (0.4, 0.8, 6.6, 13.939200000000001)
Upvotes: 7
Reputation: 6581
You can try something like this, using the inspect library.
import inspect
k = 0.0417
g = 0.829
lx = 6.6
m = k*g*lx**2
def get_name(lst=[]):
local_vars = inspect.currentframe().f_back.f_locals.items()
for i in local_vars:
lst.append(i)
return dict(lst)
import pandas as pd
df = pd.DataFrame(get_name(), index=[0])
result = df.T.loc[df.dtypes != object]
print(result)
0
g 0.829
k 0.0417
lx 6.6
m 1.50584
Upvotes: 2