<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Graph-tool tutorial
The following tutorial demonstrates working with graphs using the graph-tool python module. In the process, you will learn how to
Step1:  Show datasets in collection
Step2:  Another graph example
Step3:  Social graph drawing 101
Step4:  Create a graph using Python iterations
Below is a slow and tedious version of what can be done with a single call to add_edge_list(...) on a Graph.
Step5:  Fast graph construction
<ASSISTANT_TASK:>
Python Code:
import graph_tool.all as gt
import pandas as pd
import numpy as np
from IPython.display import display
%matplotlib inline
print("graph-tool version: {}".format(gt.__version__.split(' ')[0]))
Explanation: Graph-tool tutorial
The following tutorial demonstrates working with graphs using the graph-tool python module. In the process, you will learn how to:
create a graph 'by-hand'
perform basic network analysis
visualize graphs and their properties
End of explanation
with pd.option_context('display.max_colwidth', -1):
    display(pd.DataFrame.from_records(gt.collection.descriptions,
                                      index=['description']).transpose())
g = gt.collection.data['karate']
g
# construct a simple drawing of this graph
Explanation: Show datasets in collection
End of explanation
# If you run this for the first time, download the data with the command below
#!wget https://git.skewed.de/count0/graph-tool/raw/2c8c9899dd05549eaef728dabd93dc0759a2d4e0/doc/search_example.xml
gs = gt.load_graph("search_example.xml")
# TODO: print available edge and vertex properties
# TODO: visualize edge weight and names
Explanation: Another graph example
End of explanation
X_knows = {
    'Mary': ['Peter', 'Albert', 'DavidF', 'Peter'],
    'Judy': ['Bob', 'Alan'],
    'Peter': ['Mary', 'DavidF', 'Jon'],
    'DavidF': ['Albert', 'Joseph', 'Peter', 'Mary'],
    'Jon': ['Peter', 'Joseph', 'DavidE'],
    'DavidE': ['Jon', 'Joseph', 'Albert'],
    'Joseph': ['DavidE', 'Jon', 'DavidF'],
    'Bob': ['Judy', 'Alan'],
    'Alan': ['Bob', 'Mary', 'Judy'],
    'Albert': ['DavidF', 'Mary', 'DavidE'],
}
g = gt.Graph(directed=True)
Explanation: Social graph drawing 101
End of explanation
# Create edge tuples and list of unique names
X_edges = list((n,k) for n in X_knows for k in X_knows[n])
from functools import reduce
X_names = reduce(lambda a,b: set(a).union(b),
                 (X_knows[n] for n in X_knows)
                ).union(X_knows.keys())
X_names = list(X_names)
# Construct a 'StringIndexer' to convert strings to integers
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
lem = le.fit(list(X_names))
X_edges = list(map(lem.transform, X_edges))
# Create Graph object and add a string property for names
g2 = gt.Graph()
v_name = g2.new_vertex_property('string')
g2.vertex_properties['name'] = v_name
for vn in lem.classes_:
    v = g2.add_vertex()
    v_name[v] = vn
for f,t in X_edges:
    g2.add_edge(f,t)
# TODO: Same as above, make a tidy, undirectional drawing of this graph
Explanation: Create a graph using Python iterations
Below is a slow and tedious version of what can be done with a single call to add_edge_list(...) on a Graph.
End of explanation
# TODO: find one-line call to g.add_edge_list that constructs the X_knows graph
# hint: use nested list comprehension to reshape the dictionary
# TODO: Create an undirected view of this graph
# Tidy up parallel edges
# Try two different layouts presented in the tutorial
# Produce a tidy drawing of the undirected graph
Explanation: Fast graph construction
End of explanation
<END_TASK>