# Path: pymatgen/db/vv/util.py
# class DoesLogging:
#     """Mix-in class that creates the attribute 'log', setting its qualified
#     name to the name of the module and class.
#     """
# 
#     def __init__(self, name=None):
#         if name is None:
#             if self.__module__ != "__main__":
#                 name = f"{self.__module__}.{self.__class__.__name__}"
#             else:
#                 name = self.__class__.__name__
#         self._log = logging.getLogger(name)
#         # cache whether log is debug or higher in a flag to
#         # lower overhead of debugging statements
#         self._dbg = self._log.isEnabledFor(logging.DEBUG)
#         self._trace = self._log.isEnabledFor(TRACE)
# 
# def total_size(o, handlers={}, verbose=False, count=False):
#     """Returns the approximate memory footprint an object and all of its contents.
# 
#     Automatically finds the contents of the following builtin containers and
#     their subclasses:  tuple, list, deque, dict, set and frozenset.
#     To search other containers, add handlers to iterate over their contents:
# 
#         handlers = {SomeContainerClass: iter,
#                     OtherContainerClass: OtherContainerClass.get_elements}
# 
#     Source: http://code.activestate.com/recipes/577504/ (r3)
#     """
#     # How to make different types of objects iterable
#     dict_handler = lambda d: chain.from_iterable(d.items())
#     all_handlers = {
#         tuple: iter,
#         list: iter,
#         deque: iter,
#         dict: dict_handler,
#         set: iter,
#         frozenset: iter,
#     }
#     all_handlers.update(handlers)  # user handlers take precedence
#     seen = set()  # track which object id's have already been seen
#     default_size = getsizeof(0)  # estimate sizeof object without __sizeof__
# 
#     def sizeof(o):
#         "Calculate size of `o` and all its children"
#         if id(o) in seen:  # do not double count the same object
#             return 0
#         seen.add(id(o))
#         if count:
#             s = 1
#         else:
#             s = getsizeof(o, default_size)
#         # If `o` is iterable, add size of its members
#         for typ, handler in all_handlers.items():
#             if isinstance(o, typ):
#                 s += sum(map(sizeof, handler(o)))
#                 break
#         return s
# 
#     return sizeof(o)


import pymongo
import random
import sys
import collections
import re
from .util import DoesLogging, total_size
from smoqe.query import *


class ProgressMeter:
    """Simple progress tracker"""

    def __init__(self, num, fmt):
        self._n = num
        self._subject = "?"
        self._fmt = fmt
        self._count = 0
        self._total = 0

    @property
    def count(self):
        return self._total

    def set_subject(self, subj):
        self._subject = subj

    def update(self, *args):
        self._count += 1
        self._total += 1
        if self._n == 0 or self._count < self._n:
            return
        sys.stderr.write(self._fmt.format(*args, subject=self._subject, count=self.count))
        sys.stderr.write("\n")
        sys.stderr.flush()
        self._count = 0



# Path: pymatgen/db/vv/util.py
# class DoesLogging:
#     """Mix-in class that creates the attribute 'log', setting its qualified
#     name to the name of the module and class.
#     """
# 
#     def __init__(self, name=None):
#         if name is None:
#             if self.__module__ != "__main__":
#                 name = f"{self.__module__}.{self.__class__.__name__}"
#             else:
#                 name = self.__class__.__name__
#         self._log = logging.getLogger(name)
#         # cache whether log is debug or higher in a flag to
#         # lower overhead of debugging statements
#         self._dbg = self._log.isEnabledFor(logging.DEBUG)
#         self._trace = self._log.isEnabledFor(TRACE)
# 
# def total_size(o, handlers={}, verbose=False, count=False):
#     """Returns the approximate memory footprint an object and all of its contents.
# 
#     Automatically finds the contents of the following builtin containers and
#     their subclasses:  tuple, list, deque, dict, set and frozenset.
#     To search other containers, add handlers to iterate over their contents:
# 
#         handlers = {SomeContainerClass: iter,
#                     OtherContainerClass: OtherContainerClass.get_elements}
# 
#     Source: http://code.activestate.com/recipes/577504/ (r3)
#     """
#     # How to make different types of objects iterable
#     dict_handler = lambda d: chain.from_iterable(d.items())
#     all_handlers = {
#         tuple: iter,
#         list: iter,
#         deque: iter,
#         dict: dict_handler,
#         set: iter,
#         frozenset: iter,
#     }
#     all_handlers.update(handlers)  # user handlers take precedence
#     seen = set()  # track which object id's have already been seen
#     default_size = getsizeof(0)  # estimate sizeof object without __sizeof__
# 
#     def sizeof(o):
#         "Calculate size of `o` and all its children"
#         if id(o) in seen:  # do not double count the same object
#             return 0
#         seen.add(id(o))
#         if count:
#             s = 1
#         else:
#             s = getsizeof(o, default_size)
#         # If `o` is iterable, add size of its members
#         for typ, handler in all_handlers.items():
#             if isinstance(o, typ):
#                 s += sum(map(sizeof, handler(o)))
#                 break
#         return s
# 
#     return sizeof(o)


# Path: pymatgen/db/vv/validate.py
import pymongo
import random
import sys
import collections
import re
from .util import DoesLogging, total_size
from smoqe.query import *



class ProgressMeter:
    """Simple progress tracker"""

    def __init__(self, num, fmt):
        self._n = num
        self._subject = "?"
        self._fmt = fmt
        self._count = 0
        self._total = 0

    @property
    def count(self):
        return self._total

    def set_subject(self, subj):
        self._subject = subj

    def update(self, *args):
        self._count += 1
        self._total += 1
        if self._n == 0 or self._count < self._n:
            return
        sys.stderr.write(self._fmt.format(*args, subject=self._subject, count=self.count))
        sys.stderr.write("\n")
        sys.stderr.flush()
        self._count = 0



class ConstraintSpec(DoesLogging):