Handling null values

I am still getting null in certain text fields for the values, even though I wrote some code to handle this. Here is a snippet of the code. Sometimes the field will show N/A when there is a null value and at other times it shows "null". Should I use a try except block instead?

value = round(tableanalyses_data[0])
if value == 0 or None:
return "NA"
return value

Please see Wiki - how to post code on this forum and then hit the pencil icon below your post to fix it. Thanks.

The second half of this expression will never be true. I suspect you want

if value == 0 or value is None:

Or, more compactly:

if not value:
1 Like

I tried that also and I am still getting an index out of bounds error, which is when the "null" shows up as my text value. The script is telling me on line 32 which is where it shows this line of code.
(value = round(tableanalyses_data[0])
. I'm using range() and length() in my for loop so im not understanding why I keep getting this error.

def transform(self, value, quality, timestamp):

#Create Params
	thermal_params = {"measure_loc":self.view.getChild("root").custom.location}
		
		
	#Read db and convert to PyDataSet
	thermalanalyses_table = system.db.runNamedQuery("LastAtasData_SI_Chill",thermal_params)
	thermal_tableOutput = system.dataset.toPyDataSet(thermalanalyses_table)
	
	
	#Create an empty list, to house our thermalanalyses data.
	tableanalyses_data = []
	for row in range(len(thermal_tableOutput)):
		equationResults = {
			"morphologytype": thermal_tableOutput[row]["morphologytype"],
			"Chill-Eut": thermal_tableOutput[row]["Chill-Eut"],
			"Chill-Hypo": thermal_tableOutput[row]["Chill-Hypo"]
			
		}
	
	#tableanalyses_data.append(equationResults["morphologytype"])
	#create case statement here that cross references Silicon-Hyper, Silicon-Eut and Silicon-Hypo:
		
		if equationResults["morphologytype"] == 3:
				tableanalyses_data.append(equationResults["Chill-Eut"])
			
		elif equationResults["morphologytype"] == 1:
				tableanalyses_data.append(equationResults["Chill-Hypo"])
		
	
	value = round(tableanalyses_data[0])
	if value == 0 or None:
	   return "NA"
	return value

Add line
return tableanalyses_data
in line 31 to see if you've got any actual data.

Fix line 33 as Phil recommended. Yours won't work.

Please fix your original post.

There is no data being returned when I add that line. Just an empty list. Also when I run my Named Query there is a null at the moment for this particular value. So the text value should display "NA" not "null".

I updated the value in line 33 to -
if value == 0 or value is None:

but still getting the null value

Are you sure you don't have "null" as a string in there? Could some upstream transform have stringified your values?

Not from what I see. What I noticed is that when I used the return statement above this block of code to test what was being returned from tableanalyses_data list; I saw that the NA will show when there is a 0.0 float value, but not when there is null.

I find this odd, because you are using round() which if passed a string returns a type error, so in that event I wouldn't expect the script to run to completion.

In perspective, if a transform results in an error, the value of that property will read as 'null'.

Can you provide a screen shot of the binding with this transform in it? I strongly suspect that you're getting an error.

1 Like

below is the transform:

def transform(self, value, quality, timestamp):

#Create Params
	thermal_params = {"measure_loc":self.view.getChild("root").custom.location}
		
		
	#Read db and convert to PyDataSet
	thermalanalyses_table = system.db.runNamedQuery("LastAtasData_SI_Chill",thermal_params)
	thermal_tableOutput = system.dataset.toPyDataSet(thermalanalyses_table)
	
	
	#Create an empty list, to house our thermalanalyses data.
	tableanalyses_data = []
	for row in range(len(thermal_tableOutput)):
		equationResults = {
			"morphologytype": thermal_tableOutput[row]["morphologytype"],
			"Chill-Eut": thermal_tableOutput[row]["Chill-Eut"],
			"Chill-Hypo": thermal_tableOutput[row]["Chill-Hypo"]
			
		}
	
	#tableanalyses_data.append(equationResults["morphologytype"])
	#create case statement here that cross references Silicon-Hyper, Silicon-Eut and Silicon-Hypo:
		
		if equationResults["morphologytype"] == 3:
				tableanalyses_data.append(equationResults["Chill-Eut"])
			
		elif equationResults["morphologytype"] == 1:
				tableanalyses_data.append(equationResults["Chill-Hypo"])
		
		
	value = round(tableanalyses_data[0])
	if value == 0 or value is None:
		return "NA"
	return value

Notice at the bottom, under the Binding Preview it shows the result of the Query, and then the result of the Script. The result of the script says Error_ScriptEval. If you hover over that it will show you a message informing you what the error is.

Most likely something along the lines of IndexError: index out of range: 0

You are not properly guarding your attempt to access the list. If the list is empty attempting to access the item at 0 will result in an Index Error.

Try this after the loop instead:

if tableanalyses_data:
	return round(tableanalyses_data[0])
return "NA"

As an added bonus, you can change your loop to this:

for row in thermal_tableOutput:
		if row["morphologytype"] == 3:
				tableanalyses_data.append(row["Chill-Eut"])
			
		elif row["morphologytype"] == 1:
				tableanalyses_data.append(row["Chill-Hypo"])
4 Likes

I am now getting an error that states "Type Error: A float is required" if there is no value. In the last block of code where I am returning the table data results:

return round(tableanalyses_data[0])

I have tried wrapping this in a float function with no luck....

#Create Params
	thermal_params = {"measure_loc":self.view.getChild("root").custom.location}
		
		
	#Read db and convert to PyDataSet
	thermalanalyses_table = system.db.runNamedQuery("LastAtasData_SI_Chill",thermal_params)
	thermal_tableOutput = system.dataset.toPyDataSet(thermalanalyses_table)
	
	
	#Create an empty list, to house our thermalanalyses data.
	tableanalyses_data = []
	for row in range(len(thermal_tableOutput)):
		equationResults = {
			"morphologytype": thermal_tableOutput[row]["morphologytype"],
			"Chill-Eut": thermal_tableOutput[row]["Chill-Eut"],
			"Chill-Hypo": thermal_tableOutput[row]["Chill-Hypo"]
			
		}
	
	#tableanalyses_data.append(equationResults["morphologytype"])
	#create case statement here that cross references Silicon-Hyper, Silicon-Eut and Silicon-Hypo:
		
		if equationResults["morphologytype"] == 3:
				tableanalyses_data.append(equationResults["Chill-Eut"])
			
		elif equationResults["morphologytype"] == 1:
				tableanalyses_data.append(equationResults["Chill-Hypo"])
		
	if tableanalyses_data:
		return round(tableanalyses_data[0])
	elif tableanalyses_data == 0 or tableanalyses_data is None:
		return "NA"

What are the types of "Chill-Eut" and "Chill-Hypo" in the database?

Since this result is going to be displayed in a text field. This is the appropriate place to do the string formatting. So, perhaps rather than rounding it you do some type of Format operation. Really depends on how this data is being stored.

Hint: If it's being stored as a string and you expect it to be a number, then you need to change something.

1 Like

You're not using the results of the binding anywhere in that transform, which is HIGHLY suspicious.
What are you trying to do ?

2 Likes

The SQL query is posted above. I am cross-referencing columns that have integers in a specific position in one column, that coincide with a float value in another column.

You're running the same named query twice, once as a query binding, and then in the script:

You should remove that call and use the results of the binding

def transform(self, value, quality, timestamp):
	tableanalyses_data = []
	for row in system.dataset.toPyDataSet(value):
		if row["morphologytype"] == 3:
			tableanalyses_data.append(row["Chill-Eut"])
		elif row["morphologytype"] == 1:
			tableanalyses_data.append(row["Chill-Hypo"])

	if tableanalyses_data:
		return round(tableanalyses_data[0])
	return "NA"

Though I'm not quite sure what the whole thing is about if you're only using the first row in your return. Which is why I asked what you're trying to do.

1 Like

If the result from the query is 0 or null there should be "NA". I don't want the text box to show "null". I tried it this way also and I still get the null in the text component if there is a null value coming from the query result.

Then I would say it means the value in the first row is a Null, but then round should raise an exception...

I suggest you put a table on your page, and bind it's data props to the same named query, without a transform, and check in that table that everything looks like what you expect.

I just used a try except block and cast my value to an integer instead of using the round function.

value = tableanalyses_data[0]
	try:
		number_value = int(value)
		if number_value <= 0:
			return "NA"
	except Exception:
			return "NA"
	return int(value)

This worked

I'll allow myself to insist and ask again: Why are you running a loop when you're only using the very first row ?