<commit_before># -*- coding: utf-8 -*-
"""
Miscellaneous utilities and tools
"""
from __future__ import absolute_import, print_function

import functools
import keyword
import os
import re
import sys
from contextlib import contextmanager
from operator import itemgetter
from distutils.filelist import FileList

from six import PY2

from .templates import licenses


@contextmanager
def chdir(path):
    """
    Contextmanager to change into a directory

    :param path: path to change into as string
    """
    curr_dir = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(curr_dir)


def is_valid_identifier(string):
    """
    Check if string is a valid package name

    :param string: package name as string
    :return: boolean
    """
    if not re.match("[_A-Za-z][_a-zA-Z0-9]*$", string):
        return False
    if keyword.iskeyword(string):
        return False
    return True


def make_valid_identifier(string):
    """
    Try to make a valid package name identifier from a string

    :param string: invalid package name as string
    :return: valid package name as string or :obj:`RuntimeError`
    """
    string = string.strip()
    string = string.replace("-", "_")
    string = string.replace(" ", "_")
    string = re.sub('[^_a-zA-Z0-9]', '', string)
    string = string.lower()
    if is_valid_identifier(string):
        return string
    else:
        raise RuntimeError("String cannot be converted to a valid identifier.")


def list2str(lst, indent=0, brackets=True, quotes=True, sep=','):
    """
    Generate a Python syntax list string with an indention

    :param lst: list
    :param indent: indention as integer
    :param brackets: surround the list expression by brackets as boolean
    :param quotes: surround each item with quotes
    :param sep: separator for each item
    :return: string
    """
    if quotes:
        lst_str = str(lst)
        if not brackets:
            lst_str = lst_str[1:-1]
    else:
        lst_str = ', '.join(lst)
        if brackets:
            lst_str = '[' + lst_str + ']'
    lb = '{}\n'.format(sep) + indent*' '
    return lst_str.replace(', ', lb)


def exceptions2exit(exception_list):
    """
    Decorator to convert given exceptions to exit messages

    This avoids displaying nasty stack traces to end-users

    :param exception_list: list of exceptions to convert
    """
    def exceptions2exit_decorator(func):
        @functools.wraps(func)
        def func_wrapper(*args, **kwargs):
            try:
                func(*args, **kwargs)
            except tuple(exception_list) as e:
                print(e)
                sys.exit(1)
        return func_wrapper
    return exceptions2exit_decorator


# from http://en.wikibooks.org/, Creative Commons Attribution-ShareAlike 3.0
def levenshtein(s1, s2):
    """<commit_msg>Add ERROR: as prefix to error message<commit_after># -*- coding: utf-8 -*-
"""
Miscellaneous utilities and tools
"""
from __future__ import absolute_import, print_function

import functools
import keyword
import os
import re
import sys
from contextlib import contextmanager
from operator import itemgetter
from distutils.filelist import FileList

from six import PY2

from .templates import licenses


@contextmanager
def chdir(path):
    """
    Contextmanager to change into a directory

    :param path: path to change into as string
    """
    curr_dir = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(curr_dir)


def is_valid_identifier(string):
    """
    Check if string is a valid package name

    :param string: package name as string
    :return: boolean
    """
    if not re.match("[_A-Za-z][_a-zA-Z0-9]*$", string):
        return False
    if keyword.iskeyword(string):
        return False
    return True


def make_valid_identifier(string):
    """
    Try to make a valid package name identifier from a string

    :param string: invalid package name as string
    :return: valid package name as string or :obj:`RuntimeError`
    """
    string = string.strip()
    string = string.replace("-", "_")
    string = string.replace(" ", "_")
    string = re.sub('[^_a-zA-Z0-9]', '', string)
    string = string.lower()
    if is_valid_identifier(string):
        return string
    else:
        raise RuntimeError("String cannot be converted to a valid identifier.")


def list2str(lst, indent=0, brackets=True, quotes=True, sep=','):
    """
    Generate a Python syntax list string with an indention

    :param lst: list
    :param indent: indention as integer
    :param brackets: surround the list expression by brackets as boolean
    :param quotes: surround each item with quotes
    :param sep: separator for each item
    :return: string
    """
    if quotes:
        lst_str = str(lst)
        if not brackets:
            lst_str = lst_str[1:-1]
    else:
        lst_str = ', '.join(lst)
        if brackets:
            lst_str = '[' + lst_str + ']'
    lb = '{}\n'.format(sep) + indent*' '
    return lst_str.replace(', ', lb)


def exceptions2exit(exception_list):
    """
    Decorator to convert given exceptions to exit messages

    This avoids displaying nasty stack traces to end-users

    :param exception_list: list of exceptions to convert
    """
    def exceptions2exit_decorator(func):
        @functools.wraps(func)
        def func_wrapper(*args, **kwargs):
            try:
                func(*args, **kwargs)
            except tuple(exception_list) as e:
                print("ERROR: {}".format(e))
                sys.exit(1)
        return func_wrapper
    return exceptions2exit_decorator


# from http://en.wikibooks.org/, Creative Commons Attribution-ShareAlike 3.0
def levenshtein(s1, s2):
    """
{'fraction_non_alphanumeric': 0.10149721448467966, 'fraction_numerical': 0.006267409470752089, 'mean_word_length': 2.713639301874596, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2087308', 'n_tokens_mistral': 1734, 'n_tokens_neox': 1655, 'n_words': 553}