Python issue replacing an empty key

#1

Hello to all! Python novice here back with another problem… :frowning:

Here’s the script:

data = jsonDict['data'][0]
operDict = jsonDict['data'][0]['operations'] 
rows = []
FMT = '%Y-%m-%d %H:%M:%S' 
for row in operDict:
	newrow = []
	newrow.append(row['fwork-code'])
	newrow.append(row['fwork-id'])
	newrow.append(row['fwork-dscr'])
	newrow.append(row['from']) 
	newrow.append(row['to'])
	d1 = row['from']
	d2 = row['to']
	newrow.append(datetime.strptime(d2, FMT) - datetime.strptime(d1, FMT))
	newrow.append(round(row['actualtime']/3600.0,2))
	newrow.append(row['status'])
	rows.append([str(r) for r in newrow])

headers = ['OP Code', 'ID', 'Description', 'Start', 'End', 'Elapsed', 'Labor Hrs', 'Status']
dataset = system.dataset.toDataSet(headers, rows)
event.source.parent.getComponent('Oper_Table').data = dataset

It works perfectly, right up until it hits an empty “from” or “to”

I’ve tried ‘if else’, ‘try and except’, and just can’t get past the error. Here’s my try and except:


	newrow.append(row['fwork-dscr'])
	try:
		newrow.append(row['from']) 
	except:
		datetime.strptime(datetime.now(),FMT)
	try:
		newrow.append(row['to'])
	except:
		datetime.strptime(datetime.now(),FMT)

But I still get this error:

Traceback (most recent call last):
  File "<event:actionPerformed>", line 33, in <module>
  File "C:\Users\rforshey\.ignition\cache\gwhaycic_8088_443_main\C0\pylib\datetime.py", line 1499, in strptime
    return cls(*(_time.strptime(date_string, format))[0:6])
ValueError: time data did not match format:  data=  fmt=%Y-%m-%d %H:%M:%S

Any ideas from the Python experts out there?

Thanks!!

0 Likes

#2

A technique like this should work:

if row['from']: # row value is 'truthy', ie, not an empty string or null value (None)
	d1 = datetime.strptime(row['from'], FMT)
else:
	d1 = datetime.strptime(system.date.now(), FMT)
newrow.append(d1)

Although, that still won’t protect you from a value being present that isn’t a valid datestring for your format specifier - to catch that, wrap it all in a try/except:

try:
	if row['from']: # row value is 'truthy', ie, not an empty string or null value (None)
		d1 = datetime.strptime(row['from'], FMT)
	else:
		d1 = datetime.strptime(system.date.now(), FMT)
except ValueError:
	d1 = "Invalid date"
newrow.append(d1)

Also, not a big deal, but if you’re posting code on the forums it’s best to put it inside triple backticks so formatting isn’t lost:

```
code

```
1 Like

#3

Also datetime.now() doesn’t return a string,

from datetime import datetime
FMT = '%Y-%m-%d %H:%M:%S' 
print datetime.now()
datetime.strptime(str(datetime.now()),FMT)

If you check the type of datetime it’s <class ‘datetime.datetime’>

1 Like

#4

Oh, yeah, I didn’t even notice you were using datetime objects. For general sanity/interoperability reasons, you’re probably better off using our system.date functions, rather than the datetime library for Python.

2 Likes

#5

You guys are awesome, thanks for the help!

0 Likes

#6

A follow on question:

The Dictionary has basically 3 levels and using the strategy given before, I’m able to get all of the rows from the second and third levels. But I am not able to use the script for the first level. I’ve come up with a temporary work around (Select 1, 2 3) but would rather not use this in the long run. As you can see in the below script, I’m getting the data from “data” and operDict. I’ve tried setting up the “data” portion of the script with the newrow type stuff from later in the script but it fails. Any ideas?

from urllib import urlencode
from datetime import datetime
FMT = '%Y-%m-%d %H:%M:%S'
if event.source.parent.getComponent('Select 1').selected:
	x = 0
if event.source.parent.getComponent('Select 2').selected:
	x = 1
if event.source.parent.getComponent('Select 3').selected:
	x = 2	
#Salord = event.source.parent.getComponent('Work_Order').selectedStringValue
Salord = event.source.parent.getComponent('WO_List').selectedStringValue
args = {"sales-order": Salord, "token": "cfapiKnJ4Td2WQ8hf"}
Server = event.source.parent.getComponent('Table_Select').Server
response = system.net.httpGet("http://" + Server + ":8080/cellfusion/api/v1/orders/details?" + urlencode(args))

#stores jsonString into a python object/dict
jsonDict = system.util.jsonDecode(response)

#Assigns the variable, data, to the dictionary inside of jsonDict
data = jsonDict['data'][x]
operDict = jsonDict['data'][x]['operations'] 

id = str(data['id'])
mfgstatusCode = str(data['mfgstatus-code'])
assemblyid = str(data['assembly-id'])
assemblyCode = str(data['assembly-code'])
qty = str(data['mfgqty'])
description = str(data['assembly-dscr'])
workorder = str(data['salord'])
status = str(data['mfgstatus-dscr'])
opsopen = str(data['opsopen'])
opsclosed = str(data['opsclosed'])
currentop = str(data['currentop-code'])
laborhrs = str(round(data['actualtime']/3600.0,2))

headers = ['ID', 'Status Code', 'Assembly ID', 'Top Level PN', 'Quantity', 'Description', 'Work Order', 'Status', 'Ops Open', 'Ops Closed', 'Current Op', 'Labor Hrs' ]
rows = [
[ id, mfgstatusCode, assemblyid, assemblyCode, qty, description, workorder, status, opsopen, opsclosed, currentop, laborhrs ] ,  
]

dataset = system.dataset.toDataSet(headers, rows)
event.source.parent.getComponent('Head_Table').data = dataset

# create holder list
rows = []
 
for row in operDict:
	newrow = []
	newrow.append(row['fwork-code'])
	newrow.append(row['fwork-id'])
	newrow.append(row['fwork-dscr'])
	newrow.append(row['from']) 
	newrow.append(row['to'])
	try:
		if row['from']:
			d1 = row['from']
		else:
			d1 = "No Date"
	except ValueError:
		d1 = "No Date"
	try:
		if row['to']:
			d2 = row['to']
		else:
			d2 = "No Date"
	except ValueError:
		d2 = "No Date"
	try:
		if row['from']:
			newrow.append(datetime.strptime(d2, FMT) - datetime.strptime(d1, FMT))
		else: 
			newrow.append('0')
	except ValueError:
		"No Value"
	try: 
		if row['actualtime']:
			newrow.append(round(row['actualtime']/3600.0,2))
		else:
			newrow.append('0')
	except ValueError:
		'0'
	newrow.append(row['status'])

# add our new row (casting each element to a string) to the overall rows list
	rows.append([str(r) for r in newrow])

headers = ['OP Code', 'ID', 'Description', 'Start', 'End', 'Elapsed', 'Labor Hrs', 'Status']
dataset = system.dataset.toDataSet(headers, rows)
event.source.parent.getComponent('Oper_Table').data = dataset
0 Likes

#7

can you snippet the json structure you’re working with?

Unless the structure is different between 1,2, and 3- it shouldn’t matter.

0 Likes