# String slicing in Python script

**URL:** <https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157>\
**Category:** Ignition\
**Created:** [January 12, 2024, 1:50am UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157 "2024-01-12T01:50:58Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ematschke](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ematschke/32/7544_2.png) [@ematschke](https://forum.inductiveautomation.com/u/ematschke)\
**Post date:** [January 12, 2024, 1:50am UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/1 "2024-01-12T01:50:58Z")

</div>

In my client startup script I am trying to capture the first four characters of the PC name with this script

HostName1 = system.tag.readBlocking('[System]Client/Network/Hostname') # Grab the whole host name, Should be EVRZ-HMI-NBurn for example.  
print HostName1

HostPref = HostName1[0:3] # just grab the first four characters, this is an example of String Slicing.  
print HostPref  
print "Hello dummy"

print HostName1[:3]

According to the help, the string slice of HostName1[0:3] should work. But it just puts the whole string into HostPref. If I try HostName1[2] then it fails and says invalid index.  
PS I don't know how to post the code snippet properly.

---

<div class="post-metadata">

**Author:** ![David\_Stone](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/david_stone/32/79749_2.png) [@David\_Stone](https://forum.inductiveautomation.com/u/David_Stone)\
**Post date:** [January 12, 2024, 2:26am UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/2 "2024-01-12T02:26:27Z")

</div>

system.tag.readBlocking() returns a list of 'Qualified Value'. You need the first element `[0]`, and you need the `.value` portion of this as a string.

system.tag.readBlocking('tagpath')[0].value

```auto
HostName1 = system.tag.readBlocking('[System]Client/Network/Hostname')[0].value
print HostName1

HostPref = HostName1[0:3] # just grab the first four characters, this is an example of String Slicing.
print HostPref
print "Hello dummy"

print HostName1[:3]

```

> [@ematschke](#):
>
> ````auto
> HostName1 = system.tag.readBlocking('[System]Client/Network/Hostname') # Grab the whole host name, Should be EVRZ-HMI-NBurn for example.
> print HostName1
> 
> HostPref = HostName1[0:3] # just grab the first four characters, this is an example of String Slicing.
> print HostPref
> print "Hello dummy"
> 
> print HostName1[:3]```
> 
> ````

---

<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:** [January 12, 2024, 3:49am UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/3 "2024-01-12T03:49:46Z")

</div>

@ematschke, please see [Wiki - how to post code on this forum](https://forum.inductiveautomation.com/t/wiki-how-to-post-code-on-this-forum/77831).

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [January 12, 2024, 12:28pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/4 "2024-01-12T12:28:42Z")

</div>

> [@David\_Stone](#):
>
> system.tag.readBlocking('tagpath')[0].value

The tagpath should also be in a list:

```python
system.tag.readBlocking(['tagpath'])[0].value

```

---

<div class="post-metadata">

**Author:** ![jlandwerlen](https://avatars.discourse-cdn.com/v4/letter/j/bc8723/32.png) [@jlandwerlen](https://forum.inductiveautomation.com/u/jlandwerlen)\
**Post date:** [January 12, 2024, 12:31pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/5 "2024-01-12T12:31:18Z")

</div>

It should still work if the tag path isn't a list. It can be a string of a single tag.

[https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking](https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking)

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [January 12, 2024, 12:36pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/6 "2024-01-12T12:36:43Z")

</div>

Yes, it does. What I should be saying is, 'Always do it the same ~~darn~~ way regarless of the number of tags. Then, there are no surprises.'

EDIT Sorry about that. Almost became Canadian.

EDIT 2: Apologies to all of my Canadian friends. At least I wasn't turning Scottish.  
EDIT 3: Apologies to all my Scottish friends...

---

<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:** [January 12, 2024, 1:22pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/7 "2024-01-12T13:22:42Z")

</div>

As long as you're not turning French...

@ematschke  
People told you how to fix it, but I believe understanding what went wrong is the best way of understanding how to do it right, so... Here's a quick rundown of what was happening:

- `system.tag.readBlocking` returns a list of qualified values
- you were taking a slice of that list with `[:3]`
- slicing doesn't raise any exceptions, even if you try getting a slice bigger than the actual list, so you got a list of just one qualified value, because you're fetching data for just one tag
- when you tried printing `hostName[:3]`, you printed that single element list. It should look like `[[some_value, Good, some_date (timestamp)]]`  
the outter brackets `[]` show that you're printing a list, and the inner `[]` are part of the representation of a qualified value. The 3 values are the actual value of the tag, its quality, and the timestamp indicating when it was last modified.
- trying to access a particular element with `[x]` DOES raise an error if you're trying to access an element that doesn't exist (it raises an `IndexError`), which is why you got an error with `HostName[2]`

It should make it a bit clearer what steps you need to take if you want to slice the value of that tag:

```python
data = system.tag.readBlocking([some_path]) # data is a list of qualified values

qval = data[0] # qval is the first item in the list

hostname = qval.value # hostname is the value extracted from the qualified value

sliced_string = hostname[:3] # now you can actually get the first 3 characters of that string

# putting it all together:
sliced_string = system.tag.readBlocking([some_path])[0].value[:3]

```

---

<div class="post-metadata">

**Author:** ![ematschke](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ematschke/32/7544_2.png) [@ematschke](https://forum.inductiveautomation.com/u/ematschke)\
**Post date:** [January 12, 2024, 4:07pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/8 "2024-01-12T16:07:39Z")

</div>

I forgot to mention that this is in Ignition 8.1. This code originally came from Ignition 7.9 where it worked. I obviously tried unsuccessfully to transition to the new methods in 8.1. Life was so much simpler then.... Thanks everyone for the insight. I will clean it up and let y'all know how it goes.

---

<div class="post-metadata">

**Author:** ![jlandwerlen](https://avatars.discourse-cdn.com/v4/letter/j/bc8723/32.png) [@jlandwerlen](https://forum.inductiveautomation.com/u/jlandwerlen)\
**Post date:** [January 12, 2024, 4:11pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/9 "2024-01-12T16:11:51Z")

</div>

Even in 7.9, a tag read would return a qualified value.

[https://docs.inductiveautomation.com/display/DOC79/system.tag.read](https://docs.inductiveautomation.com/display/DOC79/system.tag.read)

---

<div class="post-metadata">

**Author:** ![ematschke](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ematschke/32/7544_2.png) [@ematschke](https://forum.inductiveautomation.com/u/ematschke)\
**Post date:** [January 12, 2024, 8:03pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/10 "2024-01-12T20:03:19Z")

</div>

Here is my old code from 7.9 that was working.

```auto
HostName1 = system.tag.read('[System]Client/Network/Hostname')	# Grab the whole host name, Should be LPCX_Vault45 for example.
HostPref = HostName1.value[:4] # just grab the first four characters

```

Here is the new code in 8.1 and with some testing, either method works.

```auto
HostName1 = system.tag.readBlocking('[System]Client/Network/Hostname')[0].value # Grab the host name VALUE, Should be 'EVRZ-HMI-NBurn' for example.
HostNamex = system.tag.readBlocking('[System]Client/Network/Hostname') # Grab the whole host name, Should be [EVRZ-HMI-NBurn, good, Fri 11:08.....] for example.
HostPref = HostName1[0:4] # grab the first four characters of the value, this is an example of String Slicing.
HostPrefx = HostNamex[0].value[0:4]	# grab the first four characters of the value of the first item in the List. (only one tag in the list anyway)

print HostPref
print HostPrefx
print HostName1 # this is just the value
print HostNamex[0].value # this is the whole qualified list including value, quality, and timestamp and we are printing just the value part.

```

My question to the experts, What is the best way to implement, HostName1 or HostNamex in the above examples? Does it matter? I guess really the only difference between 7.9 and 8.1 is that now I need to specify the List item even though the List is only one tag.

---

<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:** [January 12, 2024, 9:22pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/11 "2024-01-12T21:22:50Z")

</div>

> [@ematschke](#):
>
> Does it matter?

No, not at all. Just use whatever maps into your head the most. I personally prefer `HostName1` style for a single read.

---

<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:** [January 12, 2024, 9:35pm UTC](https://forum.inductiveautomation.com/t/string-slicing-in-python-script/84157/12 "2024-01-12T21:35:54Z")

</div>

I prefer, @JordanCClark's advice so my preference for a single tag read is

`system.tag.readBlocking(['[System]Client/Network/Hostname'])[0].value`

Then it always work and I don't have to explain to someone new to Ignition why sometimes the function uses a list and sometimes it doesn't.
