# Path: guacamol/utils/data.py
# def remove_duplicates(list_with_duplicates):
#     """
#     Removes the duplicates and keeps the ordering of the original list.
#     For duplicates, the first occurrence is kept and the later occurrences are ignored.
# 
#     Args:
#         list_with_duplicates: list that possibly contains duplicates
# 
#     Returns:
#         A list with no duplicates.
#     """
# 
#     unique_set: Set[Any] = set()
#     unique_list = []
#     for element in list_with_duplicates:
#         if element not in unique_set:
#             unique_set.add(element)
#             unique_list.append(element)
# 
#     return unique_list


import logging
import re
import numpy as np
from typing import Optional, List, Iterable, Collection, Tuple
from rdkit import Chem
from rdkit import RDLogger, DataStructs
from rdkit.Chem import AllChem
from rdkit.ML.Descriptors import MoleculeDescriptors
from scipy import histogram
from scipy.stats import entropy, gaussian_kde
from guacamol.utils.data import remove_duplicates

    Returns:
        Canonicalized SMILES string, None if the molecule is invalid.
    """

    mol = Chem.MolFromSmiles(smiles)

    if mol is not None:
        return Chem.MolToSmiles(mol, isomericSmiles=include_stereocenters)
    else:
        return None


def canonicalize_list(smiles_list: Iterable[str], include_stereocenters=True) -> List[str]:
    """
    Canonicalize a list of smiles. Filters out repetitions and removes corrupted molecules.

    Args:
        smiles_list: molecules as SMILES strings
        include_stereocenters: whether to keep the stereochemical information in the canonical SMILES strings

    Returns:
        The canonicalized and filtered input smiles.
    """

    canonicalized_smiles = [canonicalize(smiles, include_stereocenters) for smiles in smiles_list]

    # Remove None elements
    canonicalized_smiles = [s for s in canonicalized_smiles if s is not None]


# Path: guacamol/utils/data.py
# def remove_duplicates(list_with_duplicates):
#     """
#     Removes the duplicates and keeps the ordering of the original list.
#     For duplicates, the first occurrence is kept and the later occurrences are ignored.
# 
#     Args:
#         list_with_duplicates: list that possibly contains duplicates
# 
#     Returns:
#         A list with no duplicates.
#     """
# 
#     unique_set: Set[Any] = set()
#     unique_list = []
#     for element in list_with_duplicates:
#         if element not in unique_set:
#             unique_set.add(element)
#             unique_list.append(element)
# 
#     return unique_list


# Path: guacamol/utils/chemistry.py
import logging
import re
import numpy as np
from typing import Optional, List, Iterable, Collection, Tuple
from rdkit import Chem
from rdkit import RDLogger, DataStructs
from rdkit.Chem import AllChem
from rdkit.ML.Descriptors import MoleculeDescriptors
from scipy import histogram
from scipy.stats import entropy, gaussian_kde
from guacamol.utils.data import remove_duplicates


    Returns:
        Canonicalized SMILES string, None if the molecule is invalid.
    """

    mol = Chem.MolFromSmiles(smiles)

    if mol is not None:
        return Chem.MolToSmiles(mol, isomericSmiles=include_stereocenters)
    else:
        return None


def canonicalize_list(smiles_list: Iterable[str], include_stereocenters=True) -> List[str]:
    """
    Canonicalize a list of smiles. Filters out repetitions and removes corrupted molecules.

    Args:
        smiles_list: molecules as SMILES strings
        include_stereocenters: whether to keep the stereochemical information in the canonical SMILES strings

    Returns:
        The canonicalized and filtered input smiles.
    """

    canonicalized_smiles = [canonicalize(smiles, include_stereocenters) for smiles in smiles_list]

    # Remove None elements
    canonicalized_smiles = [s for s in canonicalized_smiles if s is not None]


    return remove_duplicates(canonicalized_smiles)