# Indirection on components?

**URL:** <https://forum.inductiveautomation.com/t/indirection-on-components/77453>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [August 4, 2023, 3:39pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453 "2023-08-04T15:39:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 3:39pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/1 "2023-08-04T15:39:17Z")

</div>

Good day all. I have this python code:

```auto
line = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65]
quad = ["A","B","C","D"]
	
for i in line:
    for n in quad:
        TWQuadOpName = system.tag.readBlocking("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator Name")[0].value
        TWQuadOpBadgeNum = system.tag.readBlocking("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator BadgeNum")[0].value	

```

The tag read works great, I am curious if I could use that same read function have conditions that only write values into certain containers if they have only certain contents. Hopefully this shows what im wanting to do, but in a much more condensed format:

```auto
###### CoordinateContainer has TW1 - 12 ######
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_A_OpName = TWQuadOpName
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_A_OpNum = TWQuadOpBadgeNum
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_B_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_B_OpNum
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_C_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_C_OpNum
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_D_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW1").props.params.Quad_D_OpNum
	
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_A_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_A_OpNum
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_B_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_B_OpNum
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_C_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_C_OpNum
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_D_OpName
	self.parent.getChild("CoordinateContainer").getChild("TW2").props.params.Quad_D_OpNum
	
	###### CoordinateContainer_0 has TW13 - 24 ######
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_A_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_A_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_B_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_B_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_C_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_C_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_D_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_D_OpNum
		
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_A_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_A_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_B_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_B_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_C_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_C_OpNum
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_D_OpName
	self.parent.getChild("CoordinateContainer_0").getChild("TW14").props.params.Quad_D_OpNum

```

So, you can see that CoordinateContainer has TW1 - 12 and 1-12 will have the same 8 parms and will continue for CoordinateContainer\_0 which will have TW13-24, CoordinateContainer\_1 which will have TW25-40, CoordinateContainer\_2 which will have TW41-56 and CoordinateContainer\_3 which will have TW57-65. Those same 8 parms will be in each TW.

How can I make this happen?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 4, 2023, 4:07pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/2 "2023-08-04T16:07:14Z")

</div>

Two pieces of advice:

1. Batch your tag reads. Pass all your tag paths at once to `system.tag.readBlocking`, or you're _killing_ your performance.
2. You can read parameters by string easily, e.g. these are equivalent:  
`self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params.Quad_A_OpName`  
`self.parent.getChild("CoordinateContainer_0").getChild("TW13").props.params['Quad_A_OpName']`  
Which you should be able to use to assemble a string path to read as long as you're okay making the assumption that your UI elements will have the correct name all the time.

---

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 4:11pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/3 "2023-08-04T16:11:05Z")

</div>

Alright, so Ive been playing around and came up with something like this:

```auto
	system.tag.writeBlocking("[default]Twisters/Selected Shift From Assigner",'K')
		
line = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65]
quad = ["A","B","C","D"]
		
for i in line:
    for n in quad:
        TWQuadOpName = system.tag.readBlocking("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator Name")[0].value
        TWQuadOpBadgeNum = system.tag.readBlocking("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator BadgeNum")[0].value	
		
tw_ranges = [(1, 12), (13, 24), (25, 40), (41, 56), (57, 65)]
	
for cc_index, (tw_start, tw_end) in enumerate(tw_ranges):
    for tw_num in range(tw_start, tw_end + 1):
        for n in quad:
            self.parent.getChild("CoordinateContainer_""+str(cc_index)+").getChild("TW"+str(tw_num)+"").props.params.Quad_A_OpName = TWQuadOpName
            self.parent.getChild("CoordinateContainer_""+str(cc_index)+").getChild("TW"+str(tw_num)+"").props.params.Quad_A_OpNum = TWQuadOpBadgeNum

```

Any advice? @paul-griffith I will look at Batch reading

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 4, 2023, 4:17pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/4 "2023-08-04T16:17:50Z")

</div>

I will work on an optimized version of this, but I would be really surprised if this code actually executes.

This:

`self.parent.getChild("CoordinateContainer_""+str(cc_index)+")`

Is not valid python. I think you mean

```auto
self.parent.getChild("CoordinateContainer_" + str(cc_index))

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 4, 2023, 5:07pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/5 "2023-08-04T17:07:18Z")

</div>

> [@mjohnson0238](#):
>
> ```auto
> line = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65]
> 
> ```

This is the same as `line = range(1, 66)` by the way.

---

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 5:28pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/6 "2023-08-04T17:28:38Z")

</div>

that would be super helpful sir, thank you

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [August 4, 2023, 5:45pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/7 "2023-08-04T17:45:36Z")

</div>

And you can reduce the number of tag reads to one.

```auto
tags = []
for i in range(1, 66):
    for n in quad:
        tags.append("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator Name")
        tags.append("[default]Twisters/TW"+str(i)+"/Operator Assignments/Quad_"+str(n)+" J Shift Operator BadgeNum")
system.tag.readBlocking(tags)

```

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 5:51pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/8 "2023-08-04T17:51:19Z")

</div>

I suggest this

```python
from itertools import product, chain

line = range(66)
quad = list("ABCD")

paths = list(chain.from_iterable(
    [
        "[default]Twisters/TW{}/Operator Assignments/Quad_{} J Shift Operator Name".format(l, q),
        "[default]Twisters/TW{}/Operator Assignments/Quad_{} J Shift Operator BadgeNum".format(l, q)
    ] for l, q in product(line, quad)
))

values = [qval.value for qval in system.tag.readBlocking(paths)]

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 4, 2023, 5:53pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/9 "2023-08-04T17:53:19Z")

</div>

> [@pascal.fragnoud](#):
>
> ```auto
> quad = list("ABCD")
> 
> ```

Probably don't need that `list()` even, since strings are iterable.

And if you really want to golf it, you could have `("Name", "BadgeNum")` as another element in the `product()` call.

---

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 5:55pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/10 "2023-08-04T17:55:17Z")

</div>

I want to use the indirection on the left side of the = sign. I am trying to do it like this but am getting an error:

```auto
tw_ranges = [(1, 12), (13, 24), (25, 40), (41, 56), (57, 65)]
quad = ["A", "B", "C", "D"]
        
for cc_index, (tw_start, tw_end) in enumerate(tw_ranges):
    for tw_num in range(tw_start, tw_end + 1):
        for n in quad:
        	self.parent.getChild("CoordinateContainer_{}").getChild("TW{}").props.params.Quad_{}_OpName.format(cc_index, tw_num, n) = TWQuadOpName
	        self.parent.getChild("CoordinateContainer_{}").getChild("TW{}").props.params.Quad_{}_OpNum.format(cc_index, tw_num, n) = TWQuadOpBadgeNum

```

the error comes in this area  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/5/251a296b30a3495b355fa59d6543bf92a3c17043.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 4, 2023, 6:01pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/11 "2023-08-04T18:01:03Z")

</div>

> [@mjohnson0238](#):
>
> `Quad_{}_OpNum.format(cc_index, tw_num, n)`

Right, because that's not a valid identifier.  
You need to be creating a string, and then passing that string within square brackets, like I mentioned in my first post:

```python
self.parent.getChild("CoordinateContainer_" + cc_index).getChild("TW" + tw_num).props.params['Quad_{}_OpName'.format(n)] = TWQuadOpName

```

Because at each `.` you're accessing a different object.

---

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 6:05pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/12 "2023-08-04T18:05:56Z")

</div>

Sorry @paul-griffith I didnt notice that. apologies. I have this now:

```auto
def runAction(self, event):
	system.tag.writeBlocking("[default]Twisters/Selected Shift From Assigner",'J')
	
	line = range(1,65)
	quad = ["A", "B", "C", "D"]
   			
	for i in line:
	    for n in quad:
	        TWQuadOpName = system.tag.readBlocking("[default]Twisters/TW" + str(i) + "/Operator Assignments/Quad_" + str(n) + " J Shift Operator Name")[0].value
	        TWQuadOpBadgeNum = system.tag.readBlocking("[default]Twisters/TW" + str(i) + "/Operator Assignments/Quad_" + str(n) + " J Shift Operator BadgeNum")[0].value
	   			
		tw_ranges = [(1, 12), (13, 24), (25, 40), (41, 56), (57, 65)]
		quad = ["A", "B", "C", "D"]
			        
		for cc_index, (tw_start, tw_end) in enumerate(tw_ranges):
		    for tw_num in range(tw_start, tw_end + 1):
		        for n in quad:
		        	self.parent.getChild("CoordinateContainer_" + cc_index).getChild("TW" + tw_num).props.params['Quad_{}_OpName'.format(n)] = TWQuadOpName
			        self.parent.getChild("CoordinateContainer_" + cc_index).getChild("TW" + tw_num).props.params['Quad_{}_OpNum'.format(n)] = TWQuadOpName

```

does this look ok?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 4, 2023, 6:26pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/13 "2023-08-04T18:26:09Z")

</div>

You're still issuing a bunch of sequential calls to `system.tag.readBlocking`. Every single one of those is a major performance penalty, and you're doing them in series, rather than parallel.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 4, 2023, 6:40pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/14 "2023-08-04T18:40:45Z")

</div>

Okay, so I happen to have a couple of functions that I use for this type of thing.

The first one will take an itterable and return multiple iterables of the given size.

```auto
def chunks(it,size):
    from itertools import izip_longest as zipl
    return zipl(*[iter(it)] * size)

```

So `chunks(['A','B','C','D'],2)` would return ('A','B'),('C','D')

The second basically does what @pascal.fragnoud showed except it takes in a number of times to repeat the group.

```auto
def rangeGroup(it,start,n):
    from itertools import repeat
    from itertools.chain import from_iterable as chainIt

   for i,j in zip(chainIt(repeat(k,len(it)) for k in xrange(start,n)),chainIt(repeat(it,n))):
        yield (i,j)

```

Using these I have done as much as I could to reduce the number of iterations through lists, I also only make one call to `system.tag.readBlocking()`

```auto
quad = ['A','B','C','D']
path = '[default]Twisters/TW{}/Operator Assignments/Quad_{} {}'
tags = ['J Shift Operator Name','J Shift Operator BadgeNum']

paths = [path.format(i,n,tag) for i,n in rangeGroup(quad,0,66) for tag in tags]

tagValues = [qv.value for qv in system.tag.readBlocking(paths)]

#I incremented the end value here rather than in the loop.
tw_ranges = [(1,13),(13,25),(25,41),(41,57),(57,66)]

for cc_index,(tw_start,tw_end) in enumerate(tw_ranges):
    for tw_num,quad in rangeGroup(quad,tw_start,tw_end):
       cont = 'CoordinateContainer_{}'.format(cc_index)
       tw = 'TW{}'.format(tw_num)
       nameQuad = 'Quad_{}_OpName'.format(quad)
       numQud = 'Quad_{}_OpNum'.format(quad)

       for opName,opNum in chunks(tagValues,2):
           self.parent.getChild(cont).getChild(tw).props.params[nameQuad] = opName
           self.parent.getChile(cont).getChild(tw).props.params[numQuad] = opNum

```

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 6:51pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/15 "2023-08-04T18:51:48Z")

</div>

You're right, I was trying kevin's 'half-assing' methodology.

```python
from itertools import product, chain

line = range(3)
quad = "AB"
tags = ["Name", "BadgeNum"]
paths = list(
    chain(
        "[default]Twisters/TW{}/Operator Assignments/Quad_{} J Shift Operator {}".format(l, q, t)
        for l, q, t in product(line, quad, tags)
    )
)

values = [qval.value for qval in system.tag.readBlocking(paths)]

```

Or, to push the golf mode to where it shouldn't go:

```python
values = [
    qval.value for qval in system.tag.readBlocking(
        list(
            chain(
                "[default]Twisters/TW{}/Operator Assignments/Quad_{} J Shift Operator {}".format(l, q, t)
                for l, q, t in product(range(66), "ABCD", {"Name", "BadgeNum"})
            )
        )
    )
]

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 4, 2023, 7:44pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/16 "2023-08-04T19:44:38Z")

</div>

> [@pascal.fragnoud](#):
>
> to push the golf mode

Hey! That's looking like some of my Sim Aids V2 examples!

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 8:36pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/17 "2023-08-04T20:36:15Z")

</div>

Well it actually doesn't look half as bad as I imagined before typing it.  
It's mainly the `list(chain())` induced nesting that makes me twitch a little. Could probably be made more readable by putting them on the same level, or removing `list()` if `readBlocking` can take a generator (but I don't think it can).  
And maybe by extracting the constant part of the tag path.

I still have to try Sim Aid :X

---

<div class="post-metadata">

**Author:** ![mjohnson0238](https://avatars.discourse-cdn.com/v4/letter/m/4bbf92/32.png) [@mjohnson0238](https://forum.inductiveautomation.com/u/mjohnson0238)\
**Post date:** [August 4, 2023, 9:14pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/18 "2023-08-04T21:14:55Z")

</div>

Would the structure look like this:

```auto
def runAction(self, event):
def chunks(it,size):
	from itertools import izip_longest as zipl
	return zipl(*[iter(it)] * size)
def rangeGroup(it,start,n):
	from itertools import repeat
	from itertools.chain import from_iterable as chainIt
	
	   for i,j in zip(chainIt(repeat(k,len(quad)) for k in xrange(start,n)),chainIt(repeat(quad,n))):
	        yield (i,j)
	        
	        quad = ['A','B','C','D']
	        path = '[default]Twisters/TW{}/Operator Assignments/Quad_{} {}'
	        tags = ['J Shift Operator Name','J Shift Operator BadgeNum']
	        
	        paths = [path.format(i,n,tag) for i,n in rangeGroup(quad,0,66) for tag in tags]
	        
	        tagValues = [qv.value for qv in system.tag.readBlocking(paths)]
	        
	        #I incremented the end value here rather than in the loop.
	        tw_ranges = [(1,13),(13,25),(25,41),(41,57),(57,66)]
	        
	        for cc_index,(tw_start,tw_end) in enumerate(tw_ranges):
	            for tw_num,quad in rangeGroup(quad,tw_start,tw_end):
	               cont = 'CoordinateContainer_{}'.format(cc_index)
	               tw = 'TW{}'.format(tw_num)
	               nameQuad = 'Quad_{}_OpName'.format(quad)
	               numQuad = 'Quad_{}_OpNum'.format(quad)
	        
	               for opName,opNum in chunks(tagValues,2):
	                   self.parent.getChild(cont).getChild(tw).props.params[nameQuad] = opName
	                   self.parent.getChile(cont).getChild(tw).props.params[numQuad] = opNum

```

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 9:17pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/19 "2023-08-04T21:17:46Z")

</div>

Props to you for using `itertools`, thanks for helping spread the good word !  
But please don't import IN the functions :X

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 4, 2023, 9:19pm UTC](https://forum.inductiveautomation.com/t/indirection-on-components/77453/20 "2023-08-04T21:19:21Z")

</div>

> [@pascal.fragnoud](#):
>
> But please don't import IN the functions

Concur. Those belong at the top level of a project library script. An import inside a function is a "code smell".

[Next page](https://forum.inductiveautomation.com/t/indirection-on-components/77453.md?page=2)
