NameError: global name "" not defined

I believe this is the answer you are looking for:

1 Like

Because scope.

This is probably explained in the thread @justinedwards.jle linked, but to make things short here:
Tags do not belong to a project. They're on the gateway, which exposes them to your projects.

Since they're not part of a project, they don't have access to scripts defined in a project library... unless that project has been designated as the gateway Scripting Project.

So, you can either put the scripts your tags need access to in the Global Scripting Project, or use a gateway event tag change script instead. Since those belong to a project, they have access to the project library, and can be used to trigger scripts when tags change.

3 Likes


Gateway scripting project filled with the design project name solve the problem

Keep in mind that you only get one Gateway Scripting Project. In a multi-project gateway, take care to segregate all tag functionality from other projects.

1 Like

Hello @pascal.fragnoud,

I am trying to run script on gateway tag change script but giving me NameError.

image

part of code is:

old_dict = {(item[1], item[2], item[3]): item for item in oldList}
new_dict = {(item[1], item[2], item[3]): item for item in newList}
new_records = {key: value for key, value in new_dict.items() if key not in old_dict}

Error in Line 3: Caused by: org.python.core.PyException: NameError: global name 'old_dict' is not defined.

When I run the same script on script consol, it works perfectly.
I am not sure what I am missing here.
Please suggest.
Thanks in advance.

Show us the full script.

But you should start by putting the code in a library function, then calling that function from the gateway event.
Get into the habit of not coding in gateway events.

1 Like

Bingo!!!
That worked when I put the script on project library and called it from Tag change script.
Thanks a lot.
I will keep this habit in future.
Great day :slightly_smiling_face:

well i doubt that was the solution though, my guess is some indenting were wrong that got fixed by copying it to somewhere else...

That would result in an IndentationError, not a NameError, though I stopped trying to figure out what's going on in gateway events ;p

Depends it could still be funtional code but the declaration is on a wrong indent
Like this... would result in a no defined, can't really think of something else

if False:
  something something..
  old_dict = {(item[1], item[2], item[3]): item for item in oldList}
new_dict = {(item[1], item[2], item[3]): item for item in newList}
new_records = {key: value for key, value in new_dict.items() if key not in old_dict}

but yh no point in making sense of it now if op didn't post the full code and it works now xd

Hello,
FYI, this is the full code.

newDefects = system.tag.readBlocking(["[Machine_Defects]Assembly/BAP/New_Log"])[0].value
oldDefects = system.tag.readBlocking(["[Machine_Defects]Assembly/BAP/Old_Log"])[0].value

oldList = []
newList = []

if oldDefects.getRowCount() != 0:
	oldList = [[oldDefects.getValueAt(i, "Engine"), oldDefects.getValueAt(i, "SN"), oldDefects.getValueAt(i, "Date"),
				oldDefects.getValueAt(i, "Time"), oldDefects.getValueAt(i, "Position"), oldDefects.getValueAt(i, "Z"),
				oldDefects.getValueAt(i, "X"),oldDefects.getValueAt(i, "Y"),oldDefects.getValueAt(i, "X_final"),oldDefects.getValueAt(i, "Y_final"),
				oldDefects.getValueAt(i, "Engine_type"),oldDefects.getValueAt(i, "Searching"),oldDefects.getValueAt(i, "Piston"),oldDefects.getValueAt(i, "Tightening"),
				oldDefects.getValueAt(i, "Insertion"),oldDefects.getValueAt(i, "Insertion_pos"),oldDefects.getValueAt(i, "Insertion_pos_min"),oldDefects.getValueAt(i, "Insertion_pos_max"),
				oldDefects.getValueAt(i, "Con_rod"),oldDefects.getValueAt(i, "Caps"),oldDefects.getValueAt(i, "Ref_table"),oldDefects.getValueAt(i, "OPEN_1"),
				oldDefects.getValueAt(i, "OPEN_2"),oldDefects.getValueAt(i, "CLOSE_1"),oldDefects.getValueAt(i, "CLOSE_2"),oldDefects.getValueAt(i, "CARRIER"),
				oldDefects.getValueAt(i, "Double_attempt"),oldDefects.getValueAt(i, "Stroke_1"),oldDefects.getValueAt(i, "Stroke_2"),oldDefects.getValueAt(i, "DEF Serrage piston"),
				oldDefects.getValueAt(i, "DEF Insertion"),oldDefects.getValueAt(i, "ATT plus de demande d?pose pieds 5"),oldDefects.getValueAt(i, "ATT abs demande huilage 5s"),oldDefects.getValueAt(i, "DateAndTime"),
				oldDefects.getValueAt(i, "DateAndTime_end"),oldDefects.getValueAt(i, "Duration"),oldDefects.getValueAt(i, "Day"),oldDefects.getValueAt(i, "Month"),
				oldDefects.getValueAt(i, "Year"),oldDefects.getValueAt(i, "Week"),oldDefects.getValueAt(i, "X_diff"),oldDefects.getValueAt(i, "Y_diff"),
				oldDefects.getValueAt(i, "Shift_type"),oldDefects.getValueAt(i, "Shift"),oldDefects.getValueAt(i, "Errorcat"),oldDefects.getValueAt(i, "SearchingGroup"),oldDefects.getValueAt(i, "Last_piston"),
				oldDefects.getValueAt(i, "Piston_left"),oldDefects.getValueAt(i, "Cyl_number"),oldDefects.getValueAt(i, "Cyl_position"),oldDefects.getValueAt(i, "Status")] 
				for i in range(oldDefects.getRowCount())]
				
if newDefects.getRowCount() != 0:	
	newList = [[newDefects.getValueAt(i, "Engine"), newDefects.getValueAt(i, "SN"), newDefects.getValueAt(i, "Date"),
				newDefects.getValueAt(i, "Time"), newDefects.getValueAt(i, "Position"), newDefects.getValueAt(i, "Z"),
				newDefects.getValueAt(i, "X"),newDefects.getValueAt(i, "Y"),newDefects.getValueAt(i, "X_final"),newDefects.getValueAt(i, "Y_final"),
				newDefects.getValueAt(i, "Engine_type"),newDefects.getValueAt(i, "Searching"),newDefects.getValueAt(i, "Piston"),newDefects.getValueAt(i, "Tightening"),
				newDefects.getValueAt(i, "Insertion"),newDefects.getValueAt(i, "Insertion_pos"),newDefects.getValueAt(i, "Insertion_pos_min"),newDefects.getValueAt(i, "Insertion_pos_max"),
				newDefects.getValueAt(i, "Con_rod"),newDefects.getValueAt(i, "Caps"),newDefects.getValueAt(i, "Ref_table"),newDefects.getValueAt(i, "OPEN_1"),
				newDefects.getValueAt(i, "OPEN_2"),newDefects.getValueAt(i, "CLOSE_1"),newDefects.getValueAt(i, "CLOSE_2"),newDefects.getValueAt(i, "CARRIER"),
				newDefects.getValueAt(i, "Double_attempt"),newDefects.getValueAt(i, "Stroke_1"),newDefects.getValueAt(i, "Stroke_2"),newDefects.getValueAt(i, "DEF Serrage piston"),
				newDefects.getValueAt(i, "DEF Insertion"),newDefects.getValueAt(i, "ATT plus de demande d?pose pieds 5"),newDefects.getValueAt(i, "ATT abs demande huilage 5s"),newDefects.getValueAt(i, "DateAndTime"),
				newDefects.getValueAt(i, "DateAndTime_end"),newDefects.getValueAt(i, "Duration"),newDefects.getValueAt(i, "Day"),newDefects.getValueAt(i, "Month"),
				newDefects.getValueAt(i, "Year"),newDefects.getValueAt(i, "Week"),newDefects.getValueAt(i, "X_diff"),newDefects.getValueAt(i, "Y_diff"),
				newDefects.getValueAt(i, "Shift_type"),newDefects.getValueAt(i, "Shift"),newDefects.getValueAt(i, "Errorcat"),newDefects.getValueAt(i, "SearchingGroup"),newDefects.getValueAt(i, "Last_piston"),
				newDefects.getValueAt(i, "Piston_left"),newDefects.getValueAt(i, "Cyl_number"),newDefects.getValueAt(i, "Cyl_position"),newDefects.getValueAt(i, "Status")] 
				for i in range(newDefects.getRowCount())]

# Convert old and new lists to dictionaries group by (SN, Date, Time) as keys
old_dict = {(item[1], item[2], item[3]): item for item in oldList}
new_dict = {(item[1], item[2], item[3]): item for item in newList}

new_records = {key: value for key, value in new_dict.items() if key not in old_dict}

I assume oldList and newList contain all the columns in the newDefects and oldDefects datasets ?
This should do the same thing:

new_defects, old_defects = [qv.value for qv in system.tag.readBlocking(["[Machine_Defects]Assembly/BAP/New_Log", "[Machine_Defects]Assembly/BAP/Old_Log"])]

old_dict = {
	(v['SN'], v['Date'], v['Time']): v
	for v in system.dataset.toPyDataSet(old_defects)
}

new_records = {
	(v['SN'], v['Date'], v['Time']): v
	for v in system.dataset.toPyDataSet(new_defects)
		if (v['SN'], v['Date'], v['Time']) not in old_dict
}

You may need to wrap the v in a list() call if whatever you use that for doesn't accept the row wrapper v actually is.

A few notes:

  • read tags in bulk.
  • you don't need to check if a list is empty before iterating through it. If it's empty, the resulting list will also be empty, so you don't need to initialize an empty list and wrap the comprehension in an if statement.
1 Like

Thank you @pascal.fragnoud for the very optimized code,

That worked like a snap of a finger :wink:

Now this is my updated code which looks very efficient.

new_defects, old_defects = [qv.value for qv in system.tag.readBlocking(["[Machine_Defects]Assembly/BAP/New_Log", "[Machine_Defects]Assembly/BAP/Old_Log"])]	
old_dict = {
	(v['SN'], v['Date'], v['Time']): v
	for v in system.dataset.toPyDataSet(old_defects)
}

new_records = {
	(v['SN'], v['Date'], v['Time']): v
	for v in system.dataset.toPyDataSet(new_defects)
		if (v['SN'], v['Date'], v['Time']) not in old_dict
}

query = '''INSERT INTO Bap (Engine,SN,Date,Time,Position,Z,X,Y,X_final,Y_final,Engine_type,Searching,Piston,Tightening,Insertion,Insertion_pos,Insertion_pos_min,Insertion_pos_max,Con_rod,Caps,Ref_table,OPEN_1,OPEN_2,CLOSE_1,CLOSE_2,CARRIER,Double_attempt,Stroke_1,Stroke_2,DEF_Serrage_piston,DEF_Insertion,ATT_plus_de_demande_dpose_pieds_5,ATT_abs_demande_huilage_5s,DateAndTime,DateAndTime_end,Duration,Day,Month,Year,Week,X_diff,Y_diff,Shift_type,Shift,Errorcat,SearchingGroup,Last_piston,Piston_left,Cyl_number,Cyl_position,Status,Piston_top_csv, Inserted_On) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
		
if len(new_records) > 0:
	for item in new_records.values():
		args = list(item)
		args.append('')					#Piston_top_csv
		args.append(system.date.now())	#Inserted_On
		system.db.runPrepUpdate(query, args, 'DB')

	system.tag.writeBlocking("[Machine_Defects]Assembly/BAP/Old_Log", [new_defects])