code: import math
  import sys
  
  import matplotlib
  
  matplotlib.use('Agg')  # Avoid tkinter dependency
  import matplotlib.pyplot as plt
  
  from . import charset as cset
  
  
  def string_sequentiality(string, charset, plot_scatterplot=False):
      """
      Computes how much a string contains sequence of consecutive or distance-fixed characters
  
      :param string: the string
      :param charset: a charset as a string
      :param plot_scatterplot: optional boolean, if true plots a scatterplot
  
      :return: sequentiality index, 0 (low sequentiality) to 1 (high sequentiality)
      :rtype: float
      """
      if len(string) <= 2:
          return 0
      string_length = len(string)
      window_size = math.floor(math.log(string_length))
      window_size = int(window_size)
      counter = 0
      buckets = {}
      for j in range(1, len(string)):
          for i in range(max(j - window_size, 0), j):
              diff = math.fabs((ord(string[j]) - ord(string[i])))
              buckets[diff] = buckets.get(diff, 0) + 1
              counter += 1
  
      # normalize histogram
      for key in buckets.keys():
          buckets[key] = buckets[key] / counter
  
      # Calculate MSE
      charset_buckets = cset.get_char_distance_distribution(charset)
      mse = 0
      for key in charset_buckets.keys():
          diff = buckets.get(key, 0) - charset_buckets.get(key, 0)
          square_diff = diff ** 2
          mse += square_diff / len(charset_buckets.keys())
  
      if plot_scatterplot:
          # Plot the scatterplot
          subplot = plt.subplot(111)
          subplot.set_xlabel("Average distance from other characters")
          subplot.set_ylabel("% of chars at distance x from the others")
          s1 = s2 = None
          for v in charset_buckets.items():
              x = v[0]
              y = v[1]
              s1 = plt.scatter(x, y * 100, alpha=0.6, color='r', label='charset')
  
          for v in buckets.items():
              x = v[0]
              y = v[1]
              s2 = plt.scatter(x, y * 100, alpha=0.6, color='g', label='string')
  
          plt.legend(handles=[s1, s2])
          plt.show()
  
      return mse
  
  
  def weighted_sequentiality(string, charset):
      """
      Returns the string sequentiality weighted by the string length. I.e.
      ABC is less meaningful than ABCDEFGHIJKLMNO
  
      :param string:
      :param charset:
      :return:
      """
      return string_sequentiality(string, charset) * len(string)
  
  
  def multiple_string_sequentiality(item_charset_dict):
      """
      Calculates the sequentiality for a list of strings
  
      :param item_charset_dict: list of string:charset
      :return: string:sequentiality dictionary
      :rtype: dict
      """
      items = {}
      for item in item_charset_dict:
          items[item] = (string_sequentiality(item[0], item[1]))
      return items
  
  
  def main(argv):
      if len(argv) != 2:
          print("Usage: python {0} string_to_be_computed".format(argv[0]))
          return
      else:
          print(
              "Sequentiality index: {0}".format(string_sequentiality(argv[1], cset.get_narrower_charset(argv[1]), True)))
  
  
  if __name__ == '__main__':
      main(sys.argv)
  
apis: matplotlib.pyplot.legend matplotlib.pyplot.subplot matplotlib.pyplot.show matplotlib.use matplotlib.pyplot.scatter