# NameError: name 'product' is not defined ; error in python3 but works in python2

The code shown below is part of a lengthy script. This code works fine in python2 but in python3 it gives NameError. What changes should i do?

def TensorDotProduct(*TensorList):
''' dot product of mupltiple tensors '''
product = TensorList[-1]
print("LENGTH",len(product))
for tensor in TensorList[:-1][::-1]:
product = _TensorDotProduct_(tensor,product)
print("PRODUCT",product)
return product

def _TensorDotProduct_(Tij,Tjk):
''' dot product of two tensors '''
ni,nj = Tij.shape[:2]
mj,nk = Tjk.shape[:2]
if mj != nj:
print ("tensor shape mismatched",nj,mj)
return 0
else:
TensorExpr = [] #hold the calculation to save computing time
for i in range(ni):
VectorExpr = []
for k in range(nk):
############### Einstein Summation #################
SumConvention = '+'.join([\
'Tij[%d,%d]*Tjk[%d,%d]'%(i,j,j,k)\
for j in range(nj)])
####################################################
VectorExpr.append(SumConvention)
VectorExpr = '['+','.join(VectorExpr)+']'
TensorExpr.append(VectorExpr)
TensorExpr = '['+','.join(TensorExpr)+']'
exec('product='+TensorExpr)
return array(product)


I am getting error as shown below:

Traceback (most recent call last):
File "/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py", line 118, in <module>
uc=data.ucon()
^^^^^^^^^^^
File "/home/raman/Pictures/MikiFor2to3/pyfiles/read_data.py", line 77, in ucon
gamma = self.lorentz_gamma()
^^^^^^^^^^^^^^^^^^^^
File "/home/raman/Pictures/MikiFor2to3/pyfiles/read_data.py", line 67, in lorentz_gamma
vcov = Transpose( TensorDotProduct(gcov,vcon) )
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/raman/Pictures/MikiFor2to3/pyfiles/metric.py", line 464, in TensorDotProduct
product = _TensorDotProduct_(tensor,product)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/raman/Pictures/MikiFor2to3/pyfiles/metric.py", line 490, in _TensorDotProduct_
return array(product)
^^^^^^^
NameError: name 'product' is not defined



Refactor to avoid arbitrary code execution CVEs and other inevitable bugs that arise from using exec:

   exec('product='+TensorExpr)


What do you mean by refactor ? What should i change in code?

_TensorDotProduct_ is building a string thatâs an expression, then prefixing 'product=' onto it to make it look like an assignment state, and executing it with exec('product='+TensorExpr). (Yuck!)

The expectation is that itâll evaluate the expression and assign the result to product, a variable whose value can be passed to array: return array(product).

However, it doesnât work like that in Python 3.

The simplest fix might be to use eval instead, replacing exec('product='+TensorExpr) with product = eval(TensorExpr). (Still yuck, but less so!)

1 Like

Why do you build and execute a string like that?

You may have noticed people commenting, opaquely, about exec()
changing its behaviour in Python 3 and eval() being suggested, and
both being considered a poor way to do things (viz, the techincal
remarks such as âYuck!â).

This is because constructing expressions as strings for evaluation is
error prone, very error prone, and if youâre starting with
foreign/externally sources inputs, often subject to exploitation if
youâre even slightly careless and the attack sufficiently devious.

I suggest that instead of eval()ing or exec()ing this expression
youâve laboriously constructed, you just execute the things youâre
assembling directly like any other normal function would do.

For example, looking at your _TensorDotProduct_(Tij,Tjk) function
below:

 def _TensorDotProduct_(Tij,Tjk):
''' dot product of two tensors '''
[...]
TensorExpr = [] #hold the calculation to save computing time
for i in range(ni):
VectorExpr = []
for k in range(nk):
############### Einstein Summation #################
SumConvention = '+'.join([\
'Tij[%d,%d]*Tjk[%d,%d]'%(i,j,j,k)\
for j in range(nj)])


I am converting a lengthy python2 script to python3. This script is used for analyzing output data of Atheena++ astrophysical code. I donât know why these earlier coders have executed a string like that.

@MRAB Thank You, this worked fine for me.

If this is the general pattern of the code you are trying to convert, it would probably be better to rewrite the entire script. These entire two functions you are showing can be replaced by one or two lines of code using numpy, which you appear to already be using anyway. Specifically, this is a valid implementation of TensorDotProduct from what I can tell:

def TensorDotProduct(*TensorList):
''' dot product of mupltiple tensors '''
product = TensorList[-1]
for tensor in TensorList[:-1][::-1]:
product = tensor @ product
return product


And _TensorDotProduct_ can be deleted. (and there probably is a convenience function somewhere in numpy that does the job of TensorDotProduct)

And if it isnât quite what you need because of the way arrays with more than 2 dimension are dealt with, use tensordot or einsum to replace _TensorDotProduct_

2 Likes

My python3 code for plotting is shown below but in my directory there is no output being saved although terminal says (âSaving frameâ, âimage.0000.pngâ)
(âSaving frameâ, âbalongphi.0000.pngâ) at the end of terminal output.
What changes should i do so that it can work in python3.

# Make, name and save plot
fname = 'image.%04d.png' % t
print(('Saving frame', fname))
plt.savefig(dir + fname,bbox_inches='tight')

#        plt.show()

# Define next plot(s),
fig = plt.figure(figsize=(20, 7))
#    ax = plt.subplot(111)

# Plot B_p or B_phi at chosen R, Theta in Phi direction
bporbphi=0#0 for Bp, 1 for B_phi

plt.clf()
x1 = [i for i in range (0,nphi)]
plt.xticks(size=45)#it is fontsize
plt.yticks(size=45)
plt.tick_params(width=2, which='both', size=15)
plt.tick_params(width=4, which='major', size=22)
plt.minorticks_on()
plt.xlabel(r"$i(\varphi)$", size=60)

if bporbphi == 0:
plt.ylabel(r"B", size=60)
else:
plt.ylabel(r"B$_\varphi$", size=60)

if bporbphi == 0:
plt.plot(x1, B_p[:,jrms,irms], color='black', ls='dashdot',label=r"B$_{p}$",linewidth=6)
plt.plot(x1, br[:,jrms,irms], color='r', ls='solid',label=r"B$_{r}$",linewidth=2)
plt.plot(x1, btheta[:,jrms,irms], color='r', ls='dashed',label=r"B$_{\theta}$",linewidth=3)
plt.plot(x1, bphi[:,jrms,irms], color='r', ls='dotted',label=r"B$_{\varphi}$",linewidth=3)

# Plot a horizontal black line at y=0
x1 = np.linspace(0,70)
y1 = np.zeros(len(x1))
plt.plot(x1, y1, color='black', linewidth=1.5)
plt.legend(loc='best', fontsize='30',ncol=1)

# Make, name and save plot
fname = 'balongphi.%04d.png' % t
print(('Saving frame',fname))
plt.savefig(dir + fname,bbox_inches='tight')
#        plt.show()


I am getting following warnings while plotiing

/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:306: DeprecationWarning: interp2d is deprecated in SciPy 1.10 and will be removed in SciPy 1.14.0.

For legacy code, nearly bug-for-bug compatible replacements are
RectBivariateSpline on regular grids, and bisplrep/bisplev for
scattered 2D data.

In new code, for regular grids use RegularGridInterpolator instead.
For scattered data, prefer LinearNDInterpolator or
CloughTocher2DInterpolator.

For more details see
https://scipy.github.io/devdocs/notebooks/interp_transition_guide.html

b2_phi = b_phi(x_stream, z_stream)
('shape(b2_phi)=', (50, 1000))
('shapes of rr,x3,y3=', (288,), (288, 65), (288, 65))
('shape x,z=', (288, 128), (288, 128))
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:864: DeprecationWarning: 'scipy.integrate.cumtrapz' is deprecated in favour of 'scipy.integrate.cumulative_trapezoid' and will be removed in SciPy 1.14.0
psib = integrate.cumtrapz(np.sqrt(-gdet_grid)*br_grid*2*np.pi,
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:463: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
density = ax.pcolormesh(x, z, transpose(d[phic,:,:]),cmap=colormap,
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:468: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
pressuref = ax.pcolormesh(x, z, transpose(prs[phic,:,:]),#/d[phic,:,:]),
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:474: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
Bpfieldf = ax.pcolormesh(x, z, transpose(B_p[phic,:,:]),
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:478: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
sigmapf = ax.pcolormesh(x, z, transpose(sigmap[phic,:,:])
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:482: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
sigmatf = ax.pcolormesh(x, z, transpose(sigmat[phic,:,:])
/home/raman/Pictures/MikiFor2to3/m2c_read_athdata.py:498: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
density = ax.pcolormesh(x, z, transpose(d[phic,:,:]),
====================================
++++++++++++++++++++++++++++++++++++
('t,rsph,ryl,zcyl,phic(rad)', 18000.0, np.float64(29.989018067368654), np.float64(24.304815561226043), np.float64(-17.567502531086994), np.float64(0.04908738521234052))
('i,j,phic,theta(rad),line_angle(r,theta)[deg]=,phic(deg)', 127, 89, 0, array([-0.94493217]), array([125.859375]), np.float64(0.0))
('vr,vtheta,vphi_plasmoidcenter=', np.float64(0.019714652411814283), np.float64(0.005371713597019614), np.float64(0.18112011678931444))
++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++
('t,rsph,rcyl,zcyl,phic(rad)', 18000.0, np.float64(22.2425806999513), np.float64(19.48605976895527), np.float64(10.725011462676814), np.float64(0.0))
('i,j,phic,theta(rad),line_angle(r,theta)[deg]=,phic(deg)', 114, 43, 0, array([1.06765063]), array([61.171875]), np.float64(0.0))
('vr,vtheta,vphi_plasmoidcenter=', np.float64(-0.009327810459887252), np.float64(0.0020440667265488), np.float64(0.1980705800083126))
++++++++++++++++++++++++++++++++++++
====================================
('Saving frame', 'image.0000.png')
('Saving frame', 'balongphi.0000.png')



Are you sure that itâs saving the correct place? Try printing out the full path instead of just the filename.

Also, itâs better to build paths with os.path.join:

        plot_path = os.path.join(dir, fname)
print('Saving frame', plot_path)
plt.savefig(plot_path, bbox_inches='tight')


The warnings are for things that youâll need to update once youâve got it working because of planned future changes in SciPy.

1 Like

Sorry, I was using wrong dir. once i changes directory name it was saving files in correct folder.

Now i will make changes to eradicate warnings.

In Julia Discourse Forum there is an option to mark a post as solution to thread. How should we can have similar icon in this Python Forum.

We donât operate like that here; your thanks and your likes on posts are more than sufficient. (Please use the Discourse Feedback category for meta stuff about the forum.)

How should i modify sqrt code devison so that it donât give RuntimeWarning: ?

/home/raman/Pictures/MikiFor2to3/pyfiles/metric.py:156: RuntimeWarning: invalid value encountered in sqrt
ei0_mu0 = sqrt(sigma*delta/AA)
/home/raman/Pictures/MikiFor2to3/pyfiles/metric.py:161: RuntimeWarning: invalid value encountered in sqrt
ei1_mu1 = sqrt(sigma/delta)