Variable in Jupyter Notebook only works within the cell - python

I have a variable that I use in one cell of the jupyter but when I call it in the next cell it says the variable cannot be found
I've tried creating an instance of the variable before reading the data from the son file. I've tried creating another variable the same as the first and using that one in the next cell.
if os.path.isfile("cointegration.json"):
with open("cointegration.json", "r") as f:
cointegration_mv = json.load(f)
else:
cointegration_mv = {}
for i in range(0, len(usd_pairs)):
pair_i = usd_pairs[i]
print(pair_i)
for j in range(0, i):
pair_j = usd_pairs[j]
print("\t+",pair_j)
if pair_i != pair_j:
code = pair_i + '_' + pair_j
print("\t\t=",code)
cointegration_mv[code] = get_cointegration(pair_i, pair_j)
json = json.dumps(cointegration_mv)
f = open("cointegration.json","w")
f.write(json)
f.close()
print(cointegration_mv.keys())
#This does print the keys
#The next cell
print(cointegration_mv.keys())
The error is:
NameError Traceback (most recent call last)
<ipython-input-15-7abb854e8cc9> in <module>
----> 1 print(cointegration_mv.keys())
NameError: name 'cointegration_mv' is not defined
This happens even when I create an instance of the variable before reading in the data (so I'd expect the keys to just be empty), and when I try duplicating the variable and passing the duplicate.

I know this question is 2 years old but for anyone new to Jupyter notebook having this problem, you most likely have to run the previous cell in order for Jupyter to initialize/declare/store those previous variables. Whenever you run a cell it DOES NOT automatically run the other cells and gets those previous variables. As the guide below explains it best:
Be aware that it is the order of execution of cells that is important in a Jupyter notebook, not the order in which they appear. Python will remember all the code that was run previously, including any variables you have defined, irrespective of the order in the notebook. Therefore if you define variables lower down the notebook and then (re)run cells further up, those defined further down will still be present
Jupyter/Python Guide

Make sure you´ve run all the cells.
For example, if a variable x is defined in the first cell you have to also run this cell. Only then the variable will be defined, ready to be used across all cells. Otherwise, it won´t exist at all.

May be that variable declared in first cell is in local scope.Thats why when calling in second cell giving not defined as error.
try putting your code in function in first cell and then call that function in second cell

Related

can not find the reason for 'name not defined' in python code

Excuse the debugging question, new to coding in general. Cannot understand why my code suddenly wont run.
I have checked for typos which seems to not be my problem.
filepath = '/proper_noun.txt'
def pluralize(word):
proper_nouns = [line.strip() for line in open (filepath)]
for item in proper_nouns: ### print out the list once.
if (item==[-1]):
break;
currently working in google colab.
At this point, I'm just trying to return the items from 'proper_nouns' into a list to get the ball rolling. Any ideas?
print (proper_nouns)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-29-c6832e0493e8> in <module>()
----> 1 print (proper_nouns)
NameError: name 'proper_nouns' is not define
Thanks guys. I hope this question follows SOF etiquette
Since you are working on Google Colab, my guesss is that you accidentally don't run the code from the beginning (from example if you selected the code starting from for item in proper_nouns: and only run the selected part, or if you split your program in different cells), and therefore proper_nouns is not defined yet.
Please make sure you run everything and tell us if that was it.
EDIT: I just thought of another option: is the line print(proper_nouns) in the pluralize function? If not, the scope of proper_nouns being the function, it's normal that it is not defined outside of the function. To access it from the outside, you must either declare it outside the function, or return it.

dask.delayed. defined variable in one cell of Jupyter notebook not working in any other

this is my first post on stackoverflow and I hope to have chosen the right category. So here is my problem:
In order to get to know Dask I decided to get started with this tutorial!
After creating the conda environment and running the python script like it was suggested in README.md, I tried the following lines:
from time import sleep
from dask import delayed
def inc(x):
sleep(1)
return x + 1
def add(x, y):
sleep(1)
return x + y
I used another cell in the Jupyter notebook to do
x = delayed(inc)(1)
y = delayed(inc)(2)
z = delayed(add)(x, y)
If I now use the same cell for
z.compute()
I get the correct result. But if I do this in yet another cell, I get a
NameError: name 'z' is not defined
I have no idea why this happens and did not find any clue elsewhere. Can you please help me.
Thanks in advance.
sgr
There is currently a bug in jupyter (or ipykernel) which means that variables defined in a cell with %%time do not survive the cell. Either downgrade, or re-run the code without timing.
ref https://github.com/dask/dask-tutorial/issues/85

How to run ipython script in python?

I'd like to run ipython script in python, ie:
code='''a=1
b=a+1
b
c'''
from Ipython import executor
for l in code.split("\n"):
print(executor(l))
that whould print
None
None
2
NameError: name 'c' is not defined
does it exists ? I searched the doc, but it does not seems to be (well) documented.
In short, depending on what you want to do and how much IPython features you want to include, you will need to do more.
First thing you need to know is that IPython separates its code into blocks.
Each block has its own result.
If you use blocks use this advice
If you don't any magic IPython provides you with and don't want any results given by each block, then you could just try to use exec(compile(script, "exec"), {}, {}).
If you want more than that, you will need to actually spawn an InteractiveShell-instance as features like %magic and %%magic will need a working InteractiveShell.
In one of my projects I have this function to execute code in an InteractiveShell-instance:
https://github.com/Irrational-Encoding-Wizardry/yuuno/blob/master/yuuno_ipython/ipython/utils.py#L28
If you want to just get the result of each expression,
then you should parse the code using the ast-Module and add code to return each result.
You will see this in the function linked above from line 34 onwards.
Here is the relevant except:
if isinstance(expr_ast.body[-1], ast.Expr):
last_expr = expr_ast.body[-1]
assign = ast.Assign( # _yuuno_exec_last_ = <LAST_EXPR>
targets=[ast.Name(
id=RESULT_VAR,
ctx=ast.Store()
)],
value=last_expr.value
)
expr_ast.body[-1] = assign
else:
assign = ast.Assign( # _yuuno_exec_last_ = None
targets=[ast.Name(
id=RESULT_VAR,
ctx=ast.Store(),
)],
value=ast.NameConstant(
value=None
)
)
expr_ast.body.append(assign)
ast.fix_missing_locations(expr_ast)
Instead doing this for every statement in the body instead of the last one and replacing it with some "printResult"-transformation will do the same for you.

Jupyter Notebook: How to relaunch all cells above when a crash occurs?

Question 1:
I am using jupyter 4 with python and I would need my script to do a relaunch all the cells above when a crash occurs.
Is this possible ?
Question 2:
If I need to relaunch all some cells, can I ask python to execute them according to some cell-id? I could then create a list of the cells id which have to be re-executed when catching an exception...
You can always relaunch all cells above the active cell using Cell > Run All Above. But when it comes to doing so programmatically and reliably, I've got both good and bad news for you.
Let's get the bad news regarding question 2 out of the way: NO
...at least not very reliably, because any ID of a cell would change if you insert or remove any other cell.
According to Execute specific cells through widgets and conditions on github:
We don't have the Ids of of cell in order to handle them
programatically.
And further down on the same post:
There are some APIs which can run cells identified by numbers, but
unfortunately the numbers change if you insert or delete a cell
somewhere above.
And now to the good news about the first question: YES
...but it's not 100% certain that it will solve your error handling needs as per the details in your question. But we'll get to that in a bit. Because the good news is that the answer to the question as it stands in the title
How to relaunch all cells above when a crash occurs?
is YES WE CAN!
The hard (maybe even impossible) part of this question is to implement it as a robust error handling method. If you're only interested in that, skip to the section The hard part at the end of my answer. For now, let's go on with the easy part that is to programmatically run the menu option Cell > Run All (as described in the answer by Nic Cottrell). You have two options:
Option 1 - Run all cells above by executing a cell:
If you insert the following snippet in a cell and run it, all cells above will be executed:
from IPython.display import Javascript
display(Javascript('IPython.notebook.execute_cells_above()'))
Option 2 - Run all cells above by clicking a button:
If you insert the following snippet in a cell and run it, all cells above will be executed when you click the appearing button:
Snippet:
from IPython.core.display import display, HTML
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run all"></form>''')
Output:
THE HARD PART
So, how can we set this up to handle an error when a crash occurs? I'm not an expert on this, but I think I've been able to make a setup that will work for you. But it will most likely depend on the type of error in question and the rest of your work flow.
The following example builds on two different error messages. The first is a NameError that occurs when you try to assign a value to a variable that does not exist. And this will be useful since re-running some cells after an error will need an iterator that resets only when the notebook is restarted completely, and not when a cell is re-run as part of an error handling method. The name error will only occur when the kernel is restarted upon a fresh restart of your notebook. As part of the error handling, the value 0 is assigned to x1. When the cell is only re-run x1 will increase by 1.
The second error will serve as a proxy for your error, and is an AssignmentError that occurs each time you try to delete an element from a list that does not exist. And this leads us to the real challenge, since if your error handler re-runs all cells above every time the error is triggered, you'll quickly end up in a bad loop. But we'll handle that with a counter that exits the looping execution of cells after a few runs.
It's also a bit problematic that there does not seem to exist a functionality to rerun your existing cell, or the cell from where the run cells above functionality is initialized. But we'll handle that with another suggestion from the same github post as earlier:
Doing the following helps me to execute the cell right below the code
cell. You can also change the values to get cells in other parts of
the notebook.
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))
Notebook with suggested work-flow:
Insert the four following snippets below in four cells. Click the menu option Cell > Run all once, and we're good to go!
Snippet 1 - Imports and setup
import sys
import os
from IPython.core.display import display, HTML
from IPython.display import Javascript
from random import randint
# Trigger to randomly raise en error in the next cell
ErrorTrigger = randint(0, 9)
# Assignment of variables at first run of the Norebook
try: x1
except NameError: x1 = None
if x1 is None:
%qtconsole # opens a qtconsole (for variable inspection and debugging)
x1 = 0 # counter for NameError
x2 = 0 # counter for assignment error (used in cells below)
mr = 0 # counter for manual relaunch by button
ErrorTriggers=[] # container for ErroTriggers
print('NameErrors = ', x1)
else:
x1 = x1 + 1
ErrorTriggers.append(ErrorTrigger)
#print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
Snippet 2 - Proxy for your error
# PROXY ERROR => INSERT YOUR CODE FROM HERE ################################################################
list1 = [1,2,3,4]
# 80 % chance of raising an error trying to delete an element that does not exist in the list
if ErrorTrigger > 2:
elemDelete = 8 # error
else:
elemDelete = 0 # not error
try:
del list1[elemDelete]
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine success on attempt', x2 + 1)
print('Error mesg: None')
ErrorTriggers=[]
x2 = 0 # reset error counter
# TO HERE #################################################################################################
except Exception:
x2 = x2 + 1
# Will end error handler after 5 attempts
if x2 < 3:
# As long as we're UNDER the attempt limit, the next cell executed by:
display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1,'+
' IPython.notebook.get_selected_index()+2)'))
else:
# If we're OVER the attempt limit, it all ends here. The next cell is NOT run.
# And NEITHER is the last cell with the button to relaunch the whole thing.
print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
print('Routine aborted after attempt', x2)
print('Error msg:', sys.exc_info()[1]) # Returns a message describing the error
# reset variables
ErrorTriggers = []
x2 = 0
Snippet 3 - Cell to rerun all cells above as error handler
display(Javascript('IPython.notebook.execute_cells_above()'))
Snippet 4 - Cell to rerun the whole thing with en error probability of 20%
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run again!"></form>''')
Screenshot after a few test runs:
I'll gladly add more details if the comments in the snippets are unclear.
But if you run the notebook a few times by clicking Run Again! and at the same time have a look at the output of cell 3, you'll quickly grasp how the whole thing is put together:
I'm running Notebook server 5.4.0 and I have an option Cell > Run All Above which seems to do exactly this.
In Jupyter, click in each of the cells you want to re-run after error and go to View > Cell Toolbar > Tags. Type 'raises-exception' (no quotes) in the box at the top of the cell and Add Tag.
In the next cell, put the following:
from IPython.display import Javascript
Javascript("IPython.notebook.execute_all_cells()")
Then select Cell > Run All.
This should catch the errors and run all the cells on an infinite loop until interrupted.
This is for jupyterlab
go to: Settings->Advanced Settings Editor->Keyboard Shortcuts
Paste the below code in the User Preferences window:
{
"shortcuts": [
{
"command": "notebook:run-all-above",
"keys": [
"Shift Backspace"
],
"selector": ".jp-Notebook.jp-mod-editMode"
}
]
}
click on save (top right of the user-preferences window)
This will be effective immediately. Here, two consecutive shift + backspace presses runs all cells above the selected line.
Notably, system defaults has empty templates for all menu commands, including this code (search for run-all-above).

Viewing Local Variables in Spyder's Variable Explorer

I'm new to python and am using Spyder's IDE. One feature I appreciate about it is it's variable explorer. However, based on some research, I found that it only shows global variables. A workaround that I found for that is by using the inspect module:
import inspect
local_vars = {}
def main():
global local_vars
a = 2
b = 4
c = a+b
local_vars = inspect.currentframe().f_locals
return c
main()
This works well, however, I have other functions that are called from within main() and I'd like to see those variables in the variable explorer as well. I mimicked what was done for the variables in the main function and the dict does not appear. I noticed that when I disable the setting to "exclude unsupported data types" in Spyder's variable explorer options, the second dict appears with the right size attribute, however, I am unable to open/view it. Any ideas on a possible work around? This is my first time posting BTW.
Thanks!!
Here is a working example of my issue and I've traced it down to pylab subplots.
import inspect, pylab
mainVars = {}
def main():
global mainVars
a = 1
b = 2
fig = pylab.figure()
subPlot = fig.add_subplot(211) ## line of interest
pylab.close('all')
mainVars = inspect.currentframe().f_locals
main()
When the line of interest is commented out, the dict is created successfully and can be viewed. It appears that the object created using fig.add_subplot() is not being handled properly by the dict. It seems to be an unsupported datatype.
Hope this helps clarify the issue.
Thanks again.
To view the contents of local variables when some of them are unsupported, you have to follow these steps:
Go to the options menu of the Variable Explorer (the last icon from left to right on it).
Select the option called Exclude unsupported data types.
Then you'll see all local variables saved in the f_locals dict, even if you're unable to double click on it.
All of these workarounds are making your code significantly harder to read for outsiders. You have two options to inspect the values of the variables inside your function. First, you could just return the variables you are interested in:
def main():
a = 2
b = 4
c = a+b
return a, b, c
a, b, c = main()
Second, if you just want to check that the function works as expected or debug it, you can debug the function and step into it. So select Run|Debug from the menu instead of running the file directly. Then you can step into the function - the values of the variables will be visible in the variable explorer when the execution is inside the function.

Categories