# Buggy code
def get_device_info(self):
    device_info = {}

    device_info["network_os"] = "nxos"
    reply = self.get("show version | json")
    data = json.loads(reply)
    platform_reply = self.get("show inventory | json")
    platform_info = json.loads(platform_reply)

    device_info["network_os_version"] = data.get("sys_ver_str") or data.get(
        "kickstart_ver_str"
    )
    device_info["network_os_model"] = data["chassis_id"]
    device_info["network_os_hostname"] = data["host_name"]
    device_info["network_os_image"] = data.get("isan_file_name") or data.get(
        "kick_file_name"
    )

    inventory_table = platform_info["TABLE_inv"]["ROW_inv"]
    for info in inventory_table:
        if "Chassis" in info["name"]:
            device_info["network_os_platform"] = info["productid"]

    return device_info


# Traceback (TypeError)
<192.168.1.1> attempting to start connection
<192.168.1.1> using connection plugin network_cli
<192.168.1.1> found existing local domain socket, using it!
<192.168.1.1> updating play_context for connection
<192.168.1.1>
<192.168.1.1> local domain socket path is /.ansible/pc/d894e2db50
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/network/nxos/nxos_facts.py
<192.168.1.1> ESTABLISH LOCAL CONNECTION FOR USER: ataylor
<192.168.1.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856 `" &amp;&amp; echo ansible-tmp-1529632472.4-112453209332856="` echo /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856 `" ) &amp;&amp; sleep 0'
<192.168.1.1> PUT /.ansible/tmp/ansible-local-1557eZYAor/tmpDQvtIM TO /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856/nxos_facts.py
<192.168.1.1> EXEC /bin/sh -c 'chmod u+x /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856/ /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856/nxos_facts.py &amp;&amp; sleep 0'
<192.168.1.1> EXEC /bin/sh -c '/usr/bin/python /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856/nxos_facts.py &amp;&amp; sleep 0'
<192.168.1.1> EXEC /bin/sh -c 'rm -f -r /.ansible/tmp/ansible-local-1557eZYAor/ansible-tmp-1529632472.4-112453209332856/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py", line 602, in <module>
main()
File "/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py", line 585, in main
inst.populate()
File "/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py", line 255, in populate
self.facts['memtotal_mb'] = int(data['memory_usage_total']) / 1024
TypeError: string indices must be integers

fatal: [192.168.1.1]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py\", line 602, in <module>\n    main()\n  File \"/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py\", line 585, in main\n    inst.populate()\n  File \"/tmp/ansible_dt6HU3/ansible_module_nxos_facts.py\", line 255, in populate\n    self.facts['memtotal_mb'] = int(data['memory_usage_total']) / 1024\nTypeError: string indices must be integers\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1

# Fixed code
def get_device_info(self):
    device_info = {}

    device_info["network_os"] = "nxos"
    reply = self.get("show version")
    platform_reply = self.get("show inventory")

    match_sys_ver = re.search(r"\s+system:\s+version (\S+)", reply, re.M)
    if match_sys_ver:
        device_info["network_os_version"] = match_sys_ver.group(1)
    else:
        match_kick_ver = re.search(r"\s+kickstart:\s+version (\S+)", reply, re.M)
        if match_kick_ver:
            device_info["network_os_version"] = match_kick_ver.group(1)

    if "network_os_version" not in device_info:
        match_sys_ver = re.search(r"\s+NXOS:\s+version (\S+)", reply, re.M)
        if match_sys_ver:
            device_info["network_os_version"] = match_sys_ver.group(1)

    match_chassis_id = re.search(r"Hardware\n\s+cisco\s+(\S+\s+\S+)", reply, re.M)
    if match_chassis_id:
        device_info["network_os_model"] = match_chassis_id.group(1)

    match_host_name = re.search(r"\s+Device name:\s+(\S+)", reply, re.M)
    if match_host_name:
        device_info["network_os_hostname"] = match_host_name.group(1)

    match_isan_file_name = re.search(r"\s+system image file is:\s+(\S+)", reply, re.M)
    if match_isan_file_name:
        device_info["network_os_image"] = match_isan_file_name.group(1)
    else:
        match_kick_file_name = re.search(
            r"\s+kickstart image file is:\s+(\S+)", reply, re.M
        )
        if match_kick_file_name:
            device_info["network_os_image"] = match_kick_file_name.group(1)

    if "network_os_image" not in device_info:
        match_isan_file_name = re.search(r"\s+NXOS image file is:\s+(\S+)", reply, re.M)
        if match_isan_file_name:
            device_info["network_os_image"] = match_isan_file_name.group(1)

    match_os_platform = re.search(
        r'NAME: "Chassis",\s+DESCR: "NX-OSv Chassis\s?"\s+\n'
        r"PID:\s+(\S+)",
        platform_reply,
        re.M,
    )
    if match_os_platform:
        device_info["network_os_platform"] = match_os_platform.group(1)

    return device_info