# Buggy code
async def _replace_edge_labels_with_nodes(
    graph, next_id, interpreter, nlu_training_data
):
    """User messages are created as edge labels. This removes the labels and
    creates nodes instead.

    The algorithms (e.g. merging) are simpler if the user messages are labels
    on the edges. But it sometimes
    looks better if in the final graphs the user messages are nodes instead
    of edge labels."""

    if nlu_training_data:
        message_generator = UserMessageGenerator(nlu_training_data)
    else:
        message_generator = None

    edges = list(graph.edges(keys=True, data=True))
    for s, e, k, d in edges:
        if k != EDGE_NONE_LABEL:
            if message_generator and d.get("label", k) is not None:
                parsed_info = await interpreter.parse(d.get("label", k))
                label = message_generator.message_for_data(parsed_info)
            else:
                label = d.get("label", k)
            next_id += 1
            graph.remove_edge(s, e, k)
            graph.add_node(
                next_id,
                label=label,
                shape="rect",
                style="filled",
                fillcolor="lightblue",
                **_transfer_style(d, {"class": "intent"}),
            )
            graph.add_edge(s, next_id, **{"class": d.get("class", "")})
            graph.add_edge(next_id, e, **{"class": d.get("class", "")})


# Traceback (TypeError)
2019-05-29 12:17:24 INFO     root  - Generating grammar tables from /usr/lib/python3.6/lib2to3/Grammar.txt
2019-05-29 12:17:24 INFO     root  - Generating grammar tables from /usr/lib/python3.6/lib2to3/PatternGrammar.txt

WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.
For more information, please see:
* https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md
* https://github.com/tensorflow/addons
If you depend on functionality not listed there, please file an issue.

2019-05-29 12:17:24 WARNING  rasa.core.interpreter  - No NLU model found. Using RegexInterpreter instead.
2019-05-29 12:17:24.816998: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-05-29 12:17:24.821672: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 3591990000 Hz
2019-05-29 12:17:24.822324: I tensorflow/compiler/xla/service/service.cc:150] XLA service 0x66de000 executing computations on platform Host. Devices:
2019-05-29 12:17:24.822342: I tensorflow/compiler/xla/service/service.cc:158]   StreamExecutor device (0): <undefined>, <undefined>
Bot loaded. Visualisation at http://localhost:5006/visualization.html.
Type a message and press enter (press 'Ctr-c' to exit).
Processed Story Blocks: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1804.78it/s, # trackers=1]
? Your input -> HI
? Your NLU model classified '/HI' with intent 'HI' and there are no entities, is this correct?  Yes
------
Chat History

#    Bot                     You
─────────────────────────────────────────
1    action_listen
─────────────────────────────────────────
2                                   /HI
intent: HI 1.00


Current slots:
date_slot: None, dept: None, doc_slot: None, name: None, requested_slot: None, time: None, time_slot: None

------
2019-05-29 12:17:29 ERROR    rasa.core.training.interactive  - An exception occurred while recording messages.
Traceback (most recent call last):
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 1349, in record_messages
endpoint, sender_id, finetune, sender_ids, plot_file
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 883, in _predict_till_next_listen
sender_ids, plot_file, endpoint, unconfirmed=[ActionExecuted(action_name)]
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 1274, in _plot_trackers
event_sequences[-1], event_sequences, output_file=None, max_history=2
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/visualization.py", line 467, in visualize_neighborhood
else sanitize(message.get("intent", {})).get("name", "  ?  "),
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/visualization.py", line 364, in sanitize
return re.sub(r"""[&amp;\\\<\>"'%();+]""", "", s)
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/re.py", line 191, in sub
return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object
2019-05-29 12:17:29 ERROR    asyncio  - Task exception was never retrieved
future: <Task finished coro=<_serve_application.<locals>.run_interactive_io() done, defined at /home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py:1391> exception=TypeError('expected string or bytes-like object',)>
Traceback (most recent call last):
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 1399, in run_interactive_io
sender_id=uuid.uuid4().hex,
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 1349, in record_messages
endpoint, sender_id, finetune, sender_ids, plot_file
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 883, in _predict_till_next_listen
sender_ids, plot_file, endpoint, unconfirmed=[ActionExecuted(action_name)]
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/interactive.py", line 1274, in _plot_trackers
event_sequences[-1], event_sequences, output_file=None, max_history=2
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/visualization.py", line 467, in visualize_neighborhood
else sanitize(message.get("intent", {})).get("name", "  ?  "),
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/site-packages/rasa/core/training/visualization.py", line 364, in sanitize
return re.sub(r"""[&amp;\\\<\>"'%();+]""", "", s)
File "/home/sfrplindia1/Work/SantaFe/Raghuram/chatbots/rasa_15/lib/python3.6/re.py", line 191, in sub
return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object

# Fixed code
async def _replace_edge_labels_with_nodes(
    graph, next_id, interpreter, nlu_training_data
):
    """User messages are created as edge labels. This removes the labels and
    creates nodes instead.

    The algorithms (e.g. merging) are simpler if the user messages are labels
    on the edges. But it sometimes
    looks better if in the final graphs the user messages are nodes instead
    of edge labels."""

    if nlu_training_data:
        message_generator = UserMessageGenerator(nlu_training_data)
    else:
        message_generator = None

    edges = list(graph.edges(keys=True, data=True))
    for s, e, k, d in edges:
        if k != EDGE_NONE_LABEL:
            if message_generator and d.get("label", k) is not None:
                parsed_info = await interpreter.parse(d.get("label", k))
                label = message_generator.message_for_data(parsed_info)
            else:
                label = d.get("label", k)
            next_id += 1
            graph.remove_edge(s, e, k)
            graph.add_node(
                next_id,
                label=sanitize(label),
                shape="rect",
                style="filled",
                fillcolor="lightblue",
                **_transfer_style(d, {"class": "intent"}),
            )
            graph.add_edge(s, next_id, **{"class": d.get("class", "")})
            graph.add_edge(next_id, e, **{"class": d.get("class", "")})