I have a dictionary of providers, which will contain elements like the one below:
{ 'p_4_0_0': {'technicians': ['683707d2-be18-49b7-bf67-a32048103ca1', '23d06b03-41f4-48cc-b83f-347ebfcb3084']}, 'p_4_0_1': {'technicians': ['d226a9b6-58f3-4f94-bf81-abd4dc825dca']}, ... }
The format used for the keys is string_id_level_pid
, and I use secrets.choice
to get a random element where the level
part of the string is equal to the current level in my loop. However, I get the following error:
Traceback (most recent call last): File "path/to/file/graph.py", line 122, in generate_graph(100) File "path/to/file/graph.py", line 112, in generate_graph provider = providers[secrets.choice(list({k:v for (k,v) in providers.items() if (k.split('_'))[2] == str(level)}))] File "C:\Users\\AppData\Local\Programs\Python\Python37\lib\random.py", line 261, in choice raise IndexError('Cannot choose from an empty sequence') from None IndexError: Cannot choose from an empty sequence [Finished in 1.564s]
The full working code is here:
import networkx as nx
import matplotlib.pyplot as plt
from random import randrange,choices,randint
from pathlib import Path
import random
import secrets
import uuid
import math
import json
import os
# ============================================================================ #
# create a technician with id and provider id
def create_technician():
return str(uuid.uuid4())
# create a provider with n technicians
def create_provider(region_id, level, number, n):
id = 'p_'+str(region_id)+'_'+str(level)+'_'+str(number)
# Create n technicians
technicians = []
for i in range(n):
technicians.append(create_technician())
return {id:{'technicians': technicians}}
def create_nmi_technicians(n):
technicians = []
for i in range(n):
technicians.append(create_technician())
return technicians
# Create report with parents + technician
def create_report(device_id, level, technician, parents):
return {'id': device_id, 'level': level, 'technician': technician, 'parents': parents}
# n = number of field devices
def generate_graph(num_field_devices):
max_chain_length = int(2*math.log(num_field_devices, 10))
## Info ##
# ====== #
# Field level = 0
# NMI = max_chain_length-1
nmi_level = str(max_chain_length-1)
regions = {
'USA': {'id': '1', 'NMI': {'level': nmi_level, 'acronym': 'NIST', 'technicians': create_nmi_technicians(5)}},
'UK': {'id': '2', 'NMI': {'level': nmi_level, 'acronym': 'NPL', 'technicians': create_nmi_technicians(4)}},
'China': {'id': '3', 'NMI': {'level': nmi_level, 'acronym': 'NIM', 'technicians': create_nmi_technicians(3)}},
'France': {'id': '4', 'NMI': {'level': nmi_level, 'acronym': 'LNE', 'technicians': create_nmi_technicians(3)}}
}
# For each region, create a set of
# 1 to m calibration service
# providers for each level up to
# the field level
for region, data in regions.items():
# Create providers dict
providers = {}
# For range between field (0) and
# max_chain_length-2, create providers
for i in range(0, max_chain_length-1):
# Choose between 2 and 5 providers
m = randint(2, 5)
x = 0
for j in range(m):
# create provider with 1-3 technicians
providers.update(create_provider(data['id'], i, x, randint(1,3)))
x = x + 1
# Add providers to region
data.update({'providers': providers})
#print(json.dumps(regions, indent=4))
# Cool, now this is done, create the calibration
# reports for the chain!
devices = {}
for level in range(max_chain_length):
devices.update({level: []})
# Field level
if level == 0:
for i in range(num_field_devices):
devices[level].append(str(uuid.uuid4()))
else:
k = int(math.pow((2/3), level) * num_field_devices)
for i in range(k):
devices[level].append(str(uuid.uuid4()))
# Create reports for these devices with parents + technician
reports = {}
for level,devs in devices.items():
for device in devs:
if level == 0:
# Choose 2-3 parents from upper level
parents = choices(devices[level+1], k=randrange(2,4))
elif level == max_chain_length-1:
# NMI level has no parents
parents = []
else:
# Choose 1-2 parents from upper level
parents = choices(devices[level+1], k=randrange(1,3))
# Choose random region
region = regions[secrets.choice(list(regions))]
# Choose random provider at same level
providers = region['providers']
provider = providers[secrets.choice(list({k:v for (k,v) in providers.items() if (k.split('_'))[2] == str(level)}))]
# Choose technician at the same level
technician = secrets.choice(provider['technicians'])
reports.update({'id': create_report(device, level, technician, parents)})
print(reports)
## Run ##
# ===== #
generate_graph(100)
Aucun commentaire:
Enregistrer un commentaire