stu_crnt = state.student_env.context<EOL>sol_crnt = state.solution_env.context<EOL>stu_new = stu_crnt.update(kwargs)<EOL>sol_new = sol_crnt.update(kwargs)<EOL>return state.to_child(<EOL>student_env=stu_new, solution_env=sol_new, highlight=state.highlight<EOL>)<EOL>

Update/set environemnt variables for student and solution environments.

    When ``has_equal_x()`` is used after this, the variables specified through this function will
    be available in the student and solution process. Note that you will not see these variables
    in the student process of the state produced by this function: the values are saved on the state
    and are only added to the student and solution processes when ``has_equal_ast()`` is called.

    :Example:

        Student and Solution Code::

            a = 1
            if a > 4:
                print('pretty large')

        SCT::

            # check if condition works with different values of a
            Ex().check_if_else().check_test().multi(
                set_env(a = 3).has_equal_value(),
                set_env(a = 4).has_equal_value(),
                set_env(a = 5).has_equal_value()
            )

            # equivalent SCT, by setting extra_env in has_equal_value()
            Ex().check_if_else().check_test().\\
                multi([has_equal_value(extra_env={'a': i}) for i in range(3, 6)])


def check_object(<EOL>state, index, missing_msg=None, expand_msg=None, typestr="<STR_LIT>"<EOL>):

<EOL>if v2_only():<EOL><INDENT>extra_msg = "<STR_LIT>"<EOL>state.assert_root("<STR_LIT>", extra_msg=extra_msg)<EOL><DEDENT>if missing_msg is None:<EOL><INDENT>missing_msg = "<STR_LIT>"<EOL><DEDENT>if expand_msg is None:<EOL><INDENT>expand_msg = "<STR_LIT>"<EOL><DEDENT>if (<EOL>not isDefinedInProcess(index, state.solution_process)<EOL>and state.has_different_processes()<EOL>):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% index<EOL>)<EOL><DEDENT>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": {"<STR_LIT:index>": index, "<STR_LIT>": typestr}}<EOL>fallback = lambda: ObjectAssignmentParser.get_part(index)<EOL>stu_part = state.ast_dispatcher("<STR_LIT>", state.student_ast).get(index, fallback())<EOL>sol_part = state.ast_dispatcher("<STR_LIT>", state.solution_ast).get(index, fallback())<EOL>_msg = state.build_message(missing_msg, append_message["<STR_LIT>"])<EOL>state.do_test(DefinedProcessTest(index, state.student_process, Feedback(_msg)))<EOL>child = part_to_child(<EOL>stu_part, sol_part, append_message, state, node_name="<STR_LIT>"<EOL>)<EOL>return child<EOL>

Check object existence (and equality)

    Check whether an object is defined in the student's process, and zoom in on its value in both
    student and solution process to inspect quality (with has_equal_value().

    In ``pythonbackend``, both the student's submission as well as the solution code are executed, in separate processes.
    ``check_object()`` looks at these processes and checks if the referenced object is available in the student process.
    Next, you can use ``has_equal_value()`` to check whether the objects in the student and solution process correspond.

    Args:
        index (str): the name of the object which value has to be checked.
        missing_msg (str): feedback message when the object is not defined in the student process.
        expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains.

    :Example:

        Suppose you want the student to create a variable ``x``, equal to 15: ::

            x = 15

        The following SCT will verify this: ::

            Ex().check_object("x").has_equal_value()

        - ``check_object()`` will check if the variable ``x`` is defined in the student process.
        - ``has_equal_value()`` will check whether the value of ``x`` in the solution process is the same as in the student process.

        Note that ``has_equal_value()`` only looks at **end result** of a variable in the student process.
        In the example, how the object ``x`` came about in the student's submission, does not matter.
        This means that all of the following submission will also pass the above SCT: ::

            x = 15
            x = 12 + 3
            x = 3; x += 12

    :Example:

        As the previous example mentioned, ``has_equal_value()`` only looks at the **end result**. If your exercise is
        first initializing and object and further down the script is updating the object, you can only look at the final value!

        Suppose you want the student to initialize and populate a list `my_list` as follows: ::

            my_list = []
            for i in range(20):
                if i % 3 == 0:
                    my_list.append(i)

        There is no robust way to verify whether `my_list = [0]` was coded correctly in a separate way.
        The best SCT would look something like this: ::

            msg = "Have you correctly initialized `my_list`?"
            Ex().check_correct(
                check_object('my_list').has_equal_value(),
                multi(
                    # check initialization: [] or list()
                    check_or(
                        has_equal_ast(code = "[]", incorrect_msg = msg),
                        check_function('list')
                    ),
                    check_for_loop().multi(
                        check_iter().has_equal_value(),
                        check_body().check_if_else().multi(
                            check_test().multi(
                                set_context(2).has_equal_value(),
                                set_context(3).has_equal_value()
                            ),
                            check_body().set_context(3).\\
                                set_env(my_list = [0]).\\
                                has_equal_value(name = 'my_list')
                        )
                    )
                )
            )

        - ``check_correct()`` is used to robustly check whether ``my_list`` was built correctly.
        - If ``my_list`` is not correct, **both** the initialization and the population code are checked.

    :Example:

        Because checking object correctness incorrectly is such a common misconception, we're adding another example: ::

            import pandas as pd
            df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
            df['c'] = [7, 8, 9]

        The following SCT would be **wrong**, as it does not factor in the possibility that the 'add column ``c``' step could've been wrong: ::

            Ex().check_correct(
                check_object('df').has_equal_value(),
                check_function('pandas.DataFrame').check_args(0).has_equal_value()
            )

        The following SCT would be better, as it is specific to the steps: ::

            # verify the df = pd.DataFrame(...) step
            Ex().check_correct(
                check_df('df').multi(
                    check_keys('a').has_equal_value(),
                    check_keys('b').has_equal_value()
                ),
                check_function('pandas.DataFrame').check_args(0).has_equal_value()
            )

            # verify the df['c'] = [...] step
            Ex().check_df('df').check_keys('c').has_equal_value()

    :Example:

        pythonwhat compares the objects in the student and solution process with the ``==`` operator.
        For basic objects, this ``==`` is operator is properly implemented, so that the objects can be effectively compared.
        For more complex objects that are produced by third-party packages, however, it's possible that this equality operator is not implemented in a way you'd expect.
        Often, for these object types the ``==`` will compare the actual object instances: ::

            # pre exercise code
            class Number():
                def __init__(self, n):
                    self.n = n

            # solution
            x = Number(1)

            # sct that won't work
            Ex().check_object().has_equal_value()

            # sct
            Ex().check_object().has_equal_value(expr_code = 'x.n')

            # submissions that will pass this sct
            x = Number(1)
            x = Number(2 - 1)

        The basic SCT like in the previous example will notwork here.
        Notice how we used the ``expr_code`` argument to _override_ which value `has_equal_value()` is checking.
        Instead of checking whether `x` corresponds between student and solution process, it's now executing the expression ``x.n``
        and seeing if the result of running this expression in both student and solution process match.


def is_instance(state, inst, not_instance_msg=None):

state.assert_is(["<STR_LIT>"], "<STR_LIT>", ["<STR_LIT>"])<EOL>sol_name = state.solution_parts.get("<STR_LIT:name>")<EOL>stu_name = state.student_parts.get("<STR_LIT:name>")<EOL>if not_instance_msg is None:<EOL><INDENT>not_instance_msg = "<STR_LIT>"<EOL><DEDENT>if not isInstanceInProcess(sol_name, inst, state.solution_process):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% (sol_name, inst.__name__)<EOL>)<EOL><DEDENT>_msg = state.build_message(not_instance_msg, {"<STR_LIT>": inst})<EOL>feedback = Feedback(_msg, state)<EOL>state.do_test(InstanceProcessTest(stu_name, inst, state.student_process, feedback))<EOL>return state<EOL>

Check whether an object is an instance of a certain class.

    ``is_instance()`` can currently only be used when chained from ``check_object()``, the function that is
    used to 'zoom in' on the object of interest.

    Args:
        inst (class): The class that the object should have.
        not_instance_msg (str): When specified, this overrides the automatically generated message in case
            the object does not have the expected class.
        state (State): The state that is passed in through the SCT chain (don't specify this).

    :Example:

        Student code and solution code::

            import numpy as np
            arr = np.array([1, 2, 3, 4, 5])

        SCT::

            # Verify the class of arr
            import numpy
            Ex().check_object('arr').is_instance(numpy.ndarray)


def check_df(<EOL>state, index, missing_msg=None, not_instance_msg=None, expand_msg=None<EOL>):

child = check_object(<EOL>state,<EOL>index,<EOL>missing_msg=missing_msg,<EOL>expand_msg=expand_msg,<EOL>typestr="<STR_LIT>",<EOL>)<EOL>is_instance(child, pd.DataFrame, not_instance_msg=not_instance_msg)<EOL>return child<EOL>

Check whether a DataFrame was defined and it is the right type

    ``check_df()`` is a combo of ``check_object()`` and ``is_instance()`` that checks whether the specified object exists
    and whether the specified object is pandas DataFrame.

    You can continue checking the data frame with ``check_keys()`` function to 'zoom in' on a particular column in the pandas DataFrame:

    Args:
        index (str): Name of the data frame to zoom in on.
        missing_msg (str): See ``check_object()``.
        not_instance_msg (str): See ``is_instance()``.
        expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains.

    :Example:

        Suppose you want the student to create a DataFrame ``my_df`` with two columns.
        The column ``a`` should contain the numbers 1 to 3,
        while the contents of column ``b`` can be anything: ::

            import pandas as pd
            my_df = pd.DataFrame({"a": [1, 2, 3], "b": ["a", "n", "y"]})

        The following SCT would robustly check that: ::

            Ex().check_df("my_df").multi(
                check_keys("a").has_equal_value(),
                check_keys("b")
            )

        - ``check_df()`` checks if ``my_df`` exists (``check_object()`` behind the scenes) and is a DataFrame (``is_instance()``)
        - ``check_keys("a")`` zooms in on the column ``a`` of the data frame, and ``has_equal_value()`` checks if the columns correspond between student and solution process.
        - ``check_keys("b")`` zooms in on hte column ``b`` of the data frame, but there's no 'equality checking' happening

        The following submissions would pass the SCT above: ::

            my_df = pd.DataFrame({"a": [1, 1 + 1, 3], "b": ["a", "l", "l"]})
            my_df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]})


def check_keys(state, key, missing_msg=None, expand_msg=None):

state.assert_is(["<STR_LIT>"], "<STR_LIT>", ["<STR_LIT>", "<STR_LIT>"])<EOL>if missing_msg is None:<EOL><INDENT>missing_msg = "<STR_LIT>"<EOL><DEDENT>if expand_msg is None:<EOL><INDENT>expand_msg = "<STR_LIT>"<EOL><DEDENT>sol_name = state.solution_parts.get("<STR_LIT:name>")<EOL>stu_name = state.student_parts.get("<STR_LIT:name>")<EOL>if not isDefinedCollInProcess(sol_name, key, state.solution_process):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% (key, sol_name)<EOL>)<EOL><DEDENT>_msg = state.build_message(missing_msg, {"<STR_LIT:key>": key})<EOL>state.do_test(<EOL>DefinedCollProcessTest(<EOL>stu_name, key, state.student_process, Feedback(_msg, state)<EOL>)<EOL>)<EOL>def get_part(name, key, highlight):<EOL><INDENT>if isinstance(key, str):<EOL><INDENT>slice_val = ast.Str(s=key)<EOL><DEDENT>else:<EOL><INDENT>slice_val = ast.parse(str(key)).body[<NUM_LIT:0>].value<EOL><DEDENT>expr = ast.Subscript(<EOL>value=ast.Name(id=name, ctx=ast.Load()),<EOL>slice=ast.Index(value=slice_val),<EOL>ctx=ast.Load(),<EOL>)<EOL>ast.fix_missing_locations(expr)<EOL>return {"<STR_LIT>": expr, "<STR_LIT>": highlight}<EOL><DEDENT>stu_part = get_part(stu_name, key, state.student_parts.get("<STR_LIT>"))<EOL>sol_part = get_part(sol_name, key, state.solution_parts.get("<STR_LIT>"))<EOL>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": {"<STR_LIT:key>": key}}<EOL>child = part_to_child(stu_part, sol_part, append_message, state)<EOL>return child<EOL>

Check whether an object (dict, DataFrame, etc) has a key.

    ``check_keys()`` can currently only be used when chained from ``check_object()``, the function that is
    used to 'zoom in' on the object of interest.

    Args:
        key (str): Name of the key that the object should have.
        missing_msg (str): When specified, this overrides the automatically generated
            message in case the key does not exist.
        expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains.
        state (State): The state that is passed in through the SCT chain (don't specify this).

    :Example:

        Student code and solution code::

            x = {'a': 2}

        SCT::

            # Verify that x contains a key a
            Ex().check_object('x').check_keys('a')

            # Verify that x contains a key a and a is correct.
            Ex().check_object('x').check_keys('a').has_equal_value()


return _test(<EOL>state,<EOL>incorrect_msg or MSG_INCORRECT_LOOP,<EOL>exact_names,<EOL>tv_name="<STR_LIT>",<EOL>highlight_name="<STR_LIT:target>",<EOL>)<EOL>

When dispatched on loops, has_context the target vars are the attribute _target_vars.

    Note: This is to allow people to call has_context on a node (e.g. for_loop) rather than
          one of its attributes (e.g. body). Purely for convenience.


@_has_context.register(State.SUBCLASSES["<STR_LIT>"])<EOL>def has_context_with(state, incorrect_msg, exact_names):

for i in range(len(state.solution_parts["<STR_LIT>"])):<EOL><INDENT>ctxt_state = check_part_index(state, "<STR_LIT>", i, "<STR_LIT>")<EOL>_has_context(ctxt_state, incorrect_msg or MSG_INCORRECT_WITH, exact_names)<EOL><DEDENT>return state<EOL>

When dispatched on with statements, has_context loops over each context manager.

    Note: This is to allow people to call has_context on the with statement, rather than
          having to manually loop over each context manager.

          e.g. Ex().check_with(0).has_context() vs Ex().check_with(0).check_context(0).has_context()


def has_equal_part_len(state, name, unequal_msg):

d = dict(<EOL>stu_len=len(state.student_parts[name]), sol_len=len(state.solution_parts[name])<EOL>)<EOL>if d["<STR_LIT>"] != d["<STR_LIT>"]:<EOL><INDENT>_msg = state.build_message(unequal_msg, d)<EOL>state.report(Feedback(_msg, state))<EOL><DEDENT>return state<EOL>

Verify that a part that is zoomed in on has equal length.

    Typically used in the context of ``check_function_def()``

    Arguments:
        name (str): name of the part for which to check the length to the corresponding part in the solution.
        unequal_msg (str): Message in case the lengths do not match.
        state (State): state as passed by the SCT chain. Don't specify this explicitly.

    :Examples:

        Student and solution code::

            def shout(word):
                return word + '!!!'

        SCT that checks number of arguments::

            Ex().check_function_def('shout').has_equal_part_len('args', 'not enough args!')


def has_equal_ast(state, incorrect_msg=None, code=None, exact=True, append=None):

if utils.v2_only():<EOL><INDENT>state.assert_is_not(["<STR_LIT>"], "<STR_LIT>", ["<STR_LIT>"])<EOL>state.assert_is_not(["<STR_LIT>"], "<STR_LIT>", ["<STR_LIT>"])<EOL><DEDENT>if code and incorrect_msg is None:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if (<EOL>append is None<EOL>):  <EOL><INDENT>append = incorrect_msg is None<EOL><DEDENT>if incorrect_msg is None:<EOL><INDENT>incorrect_msg = "<STR_LIT>"<EOL><DEDENT>def parse_tree(tree):<EOL><INDENT>crnt = (<EOL>tree.body[<NUM_LIT:0>]<EOL>if isinstance(tree, ast.Module) and len(tree.body) == <NUM_LIT:1><EOL>else tree<EOL>)<EOL>return ast.dump(crnt.value if isinstance(crnt, ast.Expr) else crnt)<EOL><DEDENT>stu_rep = parse_tree(state.student_ast)<EOL>sol_rep = parse_tree(state.solution_ast if not code else ast.parse(code))<EOL>fmt_kwargs = {<EOL>"<STR_LIT>": state.solution_code if not code else code,<EOL>"<STR_LIT>": state.student_code,<EOL>}<EOL>_msg = state.build_message(incorrect_msg, fmt_kwargs, append=append)<EOL>if exact and not code:<EOL><INDENT>state.do_test(EqualTest(stu_rep, sol_rep, Feedback(_msg, state)))<EOL><DEDENT>elif not sol_rep in stu_rep:<EOL><INDENT>state.report(Feedback(_msg, state))<EOL><DEDENT>return state<EOL>

Test whether abstract syntax trees match between the student and solution code.

    ``has_equal_ast()`` can be used in two ways:

    * As a robust version of ``has_code()``. By setting ``code``, you can look for the AST representation of ``code`` in the student's submission.
      But be aware that ``a`` and ``a = 1`` won't match, as reading and assigning are not the same in an AST.
      Use ``ast.dump(ast.parse(code))`` to see an AST representation of ``code``.
    * As an expression-based check when using more advanced SCT chain, e.g. to compare the equality of expressions to set function arguments.

    Args:
        incorrect_msg: message displayed when ASTs mismatch. When you specify ``code`` yourself, you have to specify this.
        code: optional code to use instead of the solution AST.
        exact: whether the representations must match exactly. If false, the solution AST
               only needs to be contained within the student AST (similar to using test student typed).
               Defaults to ``True``, unless the ``code`` argument has been specified.

    :Example:

        Student and Solution Code::

            dict(a = 'value').keys()

        SCT::

            # all pass
            Ex().has_equal_ast()
            Ex().has_equal_ast(code = "dict(a = 'value').keys()")
            Ex().has_equal_ast(code = "dict(a = 'value')", exact = False)

        Student and Solution Code::

            import numpy as np
            arr = np.array([1, 2, 3, 4, 5])
            np.mean(arr)

        SCT::

            # Check underlying value of arugment a of np.mean:
            Ex().check_function('numpy.mean').check_args('a').has_equal_ast()

            # Only check AST equality of expression used to specify argument a:
            Ex().check_function('numpy.mean').check_args('a').has_equal_ast()


def has_code(state, text, pattern=True, not_typed_msg=None):

if not not_typed_msg:<EOL><INDENT>if pattern:<EOL><INDENT>not_typed_msg = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>not_typed_msg = "<STR_LIT>" % text<EOL><DEDENT><DEDENT>student_code = state.student_code<EOL>_msg = state.build_message(not_typed_msg)<EOL>state.do_test(<EOL>StringContainsTest(student_code, text, pattern, Feedback(_msg, state))<EOL>)<EOL>return state<EOL>

Test the student code.

    Tests if the student typed a (pattern of) text. It is advised to use ``has_equal_ast()`` instead of ``has_code()``,
    as it is more robust to small syntactical differences that don't change the code's behavior.

    Args:
        text (str): the text that is searched for
        pattern (bool): if True (the default), the text is treated as a pattern. If False, it is treated as plain text.
        not_typed_msg (str): feedback message to be displayed if the student did not type the text.

    :Example:

        Student code and solution code::

            y = 1 + 2 + 3

        SCT::

            # Verify that student code contains pattern (not robust!!):
            Ex().has_code(r"1\\s*\\+2\\s*\\+3")


student_imports = state.ast_dispatcher("<STR_LIT>", state.student_ast)<EOL>solution_imports = state.ast_dispatcher("<STR_LIT>", state.solution_ast)<EOL>if name not in solution_imports:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% name<EOL>)<EOL><DEDENT>fmt_kwargs = {"<STR_LIT>": name, "<STR_LIT>": solution_imports[name]}<EOL>_msg = state.build_message(not_imported_msg, fmt_kwargs)<EOL>state.do_test(DefinedCollTest(name, student_imports, _msg))<EOL>if same_as:<EOL><INDENT>_msg = state.build_message(incorrect_as_msg, fmt_kwargs)<EOL>state.do_test(EqualTest(solution_imports[name], student_imports[name], _msg))<EOL><DEDENT>return state<EOL>

Checks whether student imported a package or function correctly.

    Python features many ways to import packages.
    All of these different methods revolve around the ``import``, ``from`` and ``as`` keywords.
    ``has_import()`` provides a robust way to check whether a student correctly imported a certain package.

    By default, ``has_import()`` allows for different ways of aliasing the imported package or function.
    If you want to make sure the correct alias was used to refer to the package or function that was imported,
    set ``same_as=True``.

    Args:
        name (str): the name of the package that has to be checked.
        same_as (bool): if True, the alias of the package or function has to be the same. Defaults to False.
        not_imported_msg (str): feedback message when the package is not imported.
        incorrect_as_msg (str): feedback message if the alias is wrong.

    :Example:

        Example 1, where aliases don't matter (defaut): ::

            # solution
            import matplotlib.pyplot as plt

            # sct
            Ex().has_import("matplotlib.pyplot")

            # passing submissions
            import matplotlib.pyplot as plt
            from matplotlib import pyplot as plt
            import matplotlib.pyplot as pltttt

            # failing submissions
            import matplotlib as mpl

        Example 2, where the SCT is coded so aliases do matter: ::

            # solution
            import matplotlib.pyplot as plt

            # sct
            Ex().has_import("matplotlib.pyplot", same_as=True)

            # passing submissions
            import matplotlib.pyplot as plt
            from matplotlib import pyplot as plt

            # failing submissions
            import matplotlib.pyplot as pltttt


def has_output(state, text, pattern=True, no_output_msg=None):

if not no_output_msg:<EOL><INDENT>no_output_msg = "<STR_LIT>"<EOL><DEDENT>_msg = state.build_message(no_output_msg)<EOL>state.do_test(StringContainsTest(state.raw_student_output, text, pattern, _msg))<EOL>return state<EOL>

Search student output for a pattern.

    Among the student and solution process, the student submission and solution code as a string,
    the ``Ex()`` state also contains the output that a student generated with his or her submission.

    With ``has_output()``, you can access this output and match it against a regular or fixed expression.

    Args:
        text (str): the text that is searched for
        pattern (bool): if True (default), the text is treated as a pattern. If False, it is treated as plain text.
        no_output_msg (str): feedback message to be displayed if the output is not found.

    :Example:

        As an example, suppose we want a student to print out a sentence: ::

            # Print the "This is some ... stuff"
            print("This is some weird stuff")

        The following SCT tests whether the student prints out ``This is some weird stuff``: ::

            # Using exact string matching
            Ex().has_output("This is some weird stuff", pattern = False)

            # Using a regular expression (more robust)
            # pattern = True is the default
            msg = "Print out ``This is some ... stuff`` to the output, " + \\
                  "fill in ``...`` with a word you like."
            Ex().has_output(r"This is some \w* stuff", no_output_msg = msg)


def has_printout(<EOL>state, index, not_printed_msg=None, pre_code=None, name=None, copy=False<EOL>):

extra_msg = "<STR_LIT>"<EOL>state.assert_root("<STR_LIT>", extra_msg=extra_msg)<EOL>if not_printed_msg is None:<EOL><INDENT>not_printed_msg = (<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>try:<EOL><INDENT>sol_call_ast = state.ast_dispatcher("<STR_LIT>", state.solution_ast)[<EOL>"<STR_LIT>"<EOL>][index]["<STR_LIT>"]<EOL><DEDENT>except (KeyError, IndexError):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>".format(<EOL>index, utils.get_ord(index + <NUM_LIT:1>)<EOL>)<EOL>)<EOL><DEDENT>out_sol, str_sol = getOutputInProcess(<EOL>tree=sol_call_ast,<EOL>process=state.solution_process,<EOL>context=state.solution_context,<EOL>env=state.solution_env,<EOL>pre_code=pre_code,<EOL>copy=copy,<EOL>)<EOL>sol_call_str = state.solution_ast_tokens.get_text(sol_call_ast)<EOL>if isinstance(str_sol, Exception):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>".format(sol_call_str, type(out_sol), str_sol)<EOL>)<EOL><DEDENT>_msg = state.build_message(not_printed_msg, {"<STR_LIT>": sol_call_str})<EOL>has_output(state, out_sol.strip(), pattern=False, no_output_msg=_msg)<EOL>return state<EOL>

Check if the right printouts happened.

    ``has_printout()`` will look for the printout in the solution code that you specified with ``index`` (0 in this case), rerun the ``print()`` call in
    the solution process, capture its output, and verify whether the output is present in the output of the student.

    This is more robust as ``Ex().check_function('print')`` initiated chains as students can use as many
    printouts as they want, as long as they do the correct one somewhere.

    Args:
        index (int): index of the ``print()`` call in the solution whose output you want to search for in the student output.
        not_printed_msg (str): if specified, this overrides the default message that is generated when the output
          is not found in the student output.
        pre_code (str): Python code as a string that is executed before running the targeted student call.
          This is the ideal place to set a random seed, for example.
        copy (bool): whether to try to deep copy objects in the environment, such as lists, that could
          accidentally be mutated. Disabled by default, which speeds up SCTs.
        state (State): state as passed by the SCT chain. Don't specify this explicitly.

    :Example:

        Suppose you want somebody to print out 4: ::

            print(1, 2, 3, 4)

        The following SCT would check that: ::

            Ex().has_printout(0)

        All of the following SCTs would pass: ::

            print(1, 2, 3, 4)
            print('1 2 3 4')
            print(1, 2, '3 4')
            print("random"); print(1, 2, 3, 4)

    :Example:

        Watch out: ``has_printout()`` will effectively **rerun** the ``print()`` call in the solution process after the entire solution script was executed.
        If your solution script updates the value of `x` after executing it, ``has_printout()`` will not work.

        Suppose you have the following solution: ::

            x = 4
            print(x)
            x = 6

        The following SCT will not work: ::

            Ex().has_printout(0)

        Why? When the ``print(x)`` call is executed, the value of ``x`` will be 6, and pythonwhat will look for the output `'6`' in the output the student generated.
        In cases like these, ``has_printout()`` cannot be used.

    :Example:

        Inside a for loop ``has_printout()``

        Suppose you have the following solution: ::

            for i in range(5):
                print(i)

        The following SCT will not work: ::

            Ex().check_for_loop().check_body().has_printout(0)

        The reason is that ``has_printout()`` can only be called from the root state. ``Ex()``.
        If you want to check printouts done in e.g. a for loop, you have to use a `check_function('print')` chain instead: ::

            Ex().check_for_loop().check_body().\\
                set_context(0).check_function('print').\\
                check_args(0).has_equal_value()


state.assert_root("<STR_LIT>")<EOL>if state.reporter.errors:<EOL><INDENT>_msg = state.build_message(<EOL>incorrect_msg, {"<STR_LIT:error>": str(state.reporter.errors[<NUM_LIT:0>])}<EOL>)<EOL>state.report(Feedback(_msg, state))<EOL><DEDENT>return state<EOL>

Check whether the submission did not generate a runtime error.

    If all SCTs for an exercise pass, before marking the submission as correct pythonwhat will automatically check whether
    the student submission generated an error. This means it is not needed to use ``has_no_error()`` explicitly.

    However, in some cases, using ``has_no_error()`` explicitly somewhere throughout your SCT execution can be helpful:

    - If you want to make sure people didn't write typos when writing a long function name.
    - If you want to first verify whether a function actually runs, before checking whether the arguments were specified correctly.
    - More generally, if, because of the content, it's instrumental that the script runs without
      errors before doing any other verifications.

    Args:
        incorrect_msg: if specified, this overrides the default message if the student code generated an error.

    :Example:

        Suppose you're verifying an exercise about model training and validation: ::

            # pre exercise code
            import numpy as np
            from sklearn.model_selection import train_test_split
            from sklearn import datasets
            from sklearn import svm

            iris = datasets.load_iris()
            iris.data.shape, iris.target.shape

            # solution
            X_train, X_test, y_train, y_test = train_test_split(
                iris.data, iris.target, test_size=0.4, random_state=0)

        If you want to make sure that ``train_test_split()`` ran without errors,
        which would check if the student typed the function without typos and used
        sensical arguments, you could use the following SCT: ::

            Ex().has_no_error()
            Ex().check_function('sklearn.model_selection.train_test_split').multi(
                check_args(['arrays', 0]).has_equal_value(),
                check_args(['arrays', 0]).has_equal_value(),
                check_args(['options', 'test_size']).has_equal_value(),
                check_args(['options', 'random_state']).has_equal_value()
            )

        If, on the other hand, you want to fall back onto pythonwhat's built in behavior,
        that checks for an error before marking the exercise as correct, you can simply
        leave of the ``has_no_error()`` step.


if not issubclass(type(correct), int):<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>student_process = state.student_process<EOL>if not isDefinedInProcess(MC_VAR_NAME, student_process):<EOL><INDENT>raise InstructorError("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>selected_option = getOptionFromProcess(student_process, MC_VAR_NAME)<EOL>if not issubclass(type(selected_option), int):<EOL><INDENT>raise InstructorError("<STR_LIT>")<EOL><DEDENT>if selected_option < <NUM_LIT:1> or correct < <NUM_LIT:1>:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>if selected_option > len(msgs) or correct > len(msgs):<EOL><INDENT>raise InstructorError("<STR_LIT>")<EOL><DEDENT>feedback_msg = msgs[selected_option - <NUM_LIT:1>]<EOL>state.reporter.success_msg = msgs[correct - <NUM_LIT:1>]<EOL>state.do_test(EqualTest(selected_option, correct, feedback_msg))<EOL><DEDENT>

Test multiple choice exercise.

    Test for a MultipleChoiceExercise. The correct answer (as an integer) and feedback messages
    are passed to this function.

    Args:
        correct (int): the index of the correct answer (should be an instruction). Starts at 1.
        msgs (list(str)): a list containing all feedback messages belonging to each choice of the
                          student. The list should have the same length as the number of options.


append_missing = missing_msg is None<EOL>append_params_not_matched = params_not_matched_msg is None<EOL>if missing_msg is None:<EOL><INDENT>missing_msg = MISSING_MSG<EOL><DEDENT>if expand_msg is None:<EOL><INDENT>expand_msg = PREPEND_MSG<EOL><DEDENT>if params_not_matched_msg is None:<EOL><INDENT>params_not_matched_msg = SIG_ISSUE_MSG<EOL><DEDENT>stu_out = state.ast_dispatcher("<STR_LIT>", state.student_ast)<EOL>sol_out = state.ast_dispatcher("<STR_LIT>", state.solution_ast)<EOL>student_mappings = state.ast_dispatcher("<STR_LIT>", state.student_ast)<EOL>fmt_kwargs = {<EOL>"<STR_LIT>": get_times(index + <NUM_LIT:1>),<EOL>"<STR_LIT>": get_ord(index + <NUM_LIT:1>),<EOL>"<STR_LIT:index>": index,<EOL>"<STR_LIT>": get_mapped_name(name, student_mappings),<EOL>}<EOL>try:<EOL><INDENT>sol_parts = {**sol_out[name][index]}<EOL><DEDENT>except KeyError:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% name<EOL>)<EOL><DEDENT>except IndexError:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% (index + <NUM_LIT:1>, name)<EOL>)<EOL><DEDENT>try:<EOL><INDENT>stu_parts = {**stu_out[name][index]}<EOL><DEDENT>except (KeyError, IndexError):<EOL><INDENT>_msg = state.build_message(missing_msg, fmt_kwargs, append=append_missing)<EOL>state.report(Feedback(_msg, state))<EOL><DEDENT>if signature:<EOL><INDENT>signature = None if isinstance(signature, bool) else signature<EOL>get_sig = partial(<EOL>getSignatureInProcess,<EOL>name=name,<EOL>signature=signature,<EOL>manual_sigs=state.get_manual_sigs(),<EOL>)<EOL>try:<EOL><INDENT>sol_sig = get_sig(<EOL>mapped_name=sol_parts["<STR_LIT:name>"], process=state.solution_process<EOL>)<EOL>sol_parts["<STR_LIT:args>"] = bind_args(sol_sig, sol_parts["<STR_LIT:args>"])<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise InstructorError(<EOL>"<STR_LIT>"<EOL>% (get_ord(index + <NUM_LIT:1>), name, e)<EOL>)<EOL><DEDENT>try:<EOL><INDENT>stu_sig = get_sig(<EOL>mapped_name=stu_parts["<STR_LIT:name>"], process=state.student_process<EOL>)<EOL>stu_parts["<STR_LIT:args>"] = bind_args(stu_sig, stu_parts["<STR_LIT:args>"])<EOL><DEDENT>except Exception:<EOL><INDENT>_msg = state.build_message(<EOL>params_not_matched_msg, fmt_kwargs, append=append_params_not_matched<EOL>)<EOL>state.report(<EOL>Feedback(<EOL>_msg, StubState(stu_parts["<STR_LIT>"], state.highlighting_disabled)<EOL>)<EOL>)<EOL><DEDENT><DEDENT>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": fmt_kwargs}<EOL>child = part_to_child(<EOL>stu_parts, sol_parts, append_message, state, node_name="<STR_LIT>"<EOL>)<EOL>return child<EOL>

Check whether a particular function is called.

    ``check_function()`` is typically followed by:

    - ``check_args()`` to check whether the arguments were specified.
      In turn, ``check_args()`` can be followed by ``has_equal_value()`` or ``has_equal_ast()``
      to assert that the arguments were correctly specified.
    - ``has_equal_value()`` to check whether rerunning the function call coded by the student
      gives the same result as calling the function call as in the solution.

    Checking function calls is a tricky topic. Please visit the
    `dedicated article <articles/checking_function_calls.html>`_ for more explanation,
    edge cases and best practices.

    Args:
        name (str): the name of the function to be tested. When checking functions in packages, always
            use the 'full path' of the function.
        index (int): index of the function call to be checked. Defaults to 0.
        missing_msg (str): If specified, this overrides an automatically generated feedback message in case
            the student did not call the function correctly.
        params_not_matched_msg (str): If specified, this overrides an automatically generated feedback message
            in case the function parameters were not successfully matched.
        expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains.
        signature (Signature): Normally, check_function() can figure out what the function signature is,
            but it might be necessary to use ``sig_from_params()`` to manually build a signature and pass this along.
        state (State): State object that is passed from the SCT Chain (don't specify this).

    :Examples:

        Student code and solution code::

            import numpy as np
            arr = np.array([1, 2, 3, 4, 5])
            np.mean(arr)

        SCT::

            # Verify whether arr was correctly set in np.mean
            Ex().check_function('numpy.mean').check_args('a').has_equal_value()

            # Verify whether np.mean(arr) produced the same result
            Ex().check_function('numpy.mean').has_equal_value()


def check_part(state, name, part_msg, missing_msg=None, expand_msg=None):

if missing_msg is None:<EOL><INDENT>missing_msg = "<STR_LIT>"<EOL><DEDENT>if expand_msg is None:<EOL><INDENT>expand_msg = "<STR_LIT>"<EOL><DEDENT>if not part_msg:<EOL><INDENT>part_msg = name<EOL><DEDENT>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": {"<STR_LIT>": part_msg}}<EOL>has_part(state, name, missing_msg, append_message["<STR_LIT>"])<EOL>stu_part = state.student_parts[name]<EOL>sol_part = state.solution_parts[name]<EOL>assert_ast(state, sol_part, append_message["<STR_LIT>"])<EOL>return part_to_child(stu_part, sol_part, append_message, state)<EOL>

Return child state with name part as its ast tree


def check_part_index(state, name, index, part_msg, missing_msg=None, expand_msg=None):

if missing_msg is None:<EOL><INDENT>missing_msg = "<STR_LIT>"<EOL><DEDENT>if expand_msg is None:<EOL><INDENT>expand_msg = "<STR_LIT>"<EOL><DEDENT>ordinal = get_ord(index + <NUM_LIT:1>) if isinstance(index, int) else "<STR_LIT>"<EOL>fmt_kwargs = {"<STR_LIT:index>": index, "<STR_LIT>": ordinal}<EOL>fmt_kwargs.update(part=render(part_msg, fmt_kwargs))<EOL>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": fmt_kwargs}<EOL>has_part(state, name, missing_msg, fmt_kwargs, index)<EOL>stu_part = state.student_parts[name]<EOL>sol_part = state.solution_parts[name]<EOL>if isinstance(index, list):<EOL><INDENT>for ind in index:<EOL><INDENT>stu_part = stu_part[ind]<EOL>sol_part = sol_part[ind]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>stu_part = stu_part[index]<EOL>sol_part = sol_part[index]<EOL><DEDENT>assert_ast(state, sol_part, fmt_kwargs)<EOL>return part_to_child(stu_part, sol_part, append_message, state)<EOL>

Return child state with indexed name part as its ast tree.

    ``index`` can be:

    - an integer, in which case the student/solution_parts are indexed by position.
    - a string, in which case the student/solution_parts are expected to be a dictionary.
    - a list of indices (which can be integer or string), in which case the student parts are indexed step by step.


def check_args(state, name, missing_msg=None):

if missing_msg is None:<EOL><INDENT>missing_msg = "<STR_LIT>"<EOL><DEDENT>if name in ["<STR_LIT>", "<STR_LIT>"]:  <EOL><INDENT>return check_part(state, name, name, missing_msg=missing_msg)<EOL><DEDENT>else:<EOL><INDENT>if isinstance(name, list):  <EOL><INDENT>if name[<NUM_LIT:0>] == "<STR_LIT:args>":<EOL><INDENT>arg_str = "<STR_LIT>".format(<EOL>get_ord(name[<NUM_LIT:1>] + <NUM_LIT:1>)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>arg_str = "<STR_LIT>".format(name[<NUM_LIT:1>])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>arg_str = (<EOL>"<STR_LIT>".format(get_ord(name + <NUM_LIT:1>))<EOL>if isinstance(name, int)<EOL>else "<STR_LIT>".format(name)<EOL>)<EOL><DEDENT>return check_part_index(state, "<STR_LIT:args>", name, arg_str, missing_msg=missing_msg)<EOL><DEDENT>

Check whether a function argument is specified.

    This function can follow ``check_function()`` in an SCT chain and verifies whether an argument is specified.
    If you want to go on and check whether the argument was correctly specified, you can can continue chaining with
    ``has_equal_value()`` (value-based check) or ``has_equal_ast()`` (AST-based check)

    This function can also follow ``check_function_def()`` or ``check_lambda_function()`` to see if arguments have been
    specified.

    Args:
        name (str): the name of the argument for which you want to check it is specified. This can also be
            a number, in which case it refers to the positional arguments. Named argumetns take precedence.
        missing_msg (str): If specified, this overrides an automatically generated feedback message in case
            the student did specify the argument.
        state (State): State object that is passed from the SCT Chain (don't specify this).

    :Examples:

        Student and solution code::

            import numpy as np
            arr = np.array([1, 2, 3, 4, 5])
            np.mean(arr)

        SCT::

            # Verify whether arr was correctly set in np.mean
            # has_equal_value() checks the value of arr, used to set argument a
            Ex().check_function('numpy.mean').check_args('a').has_equal_value()

            # Verify whether arr was correctly set in np.mean
            # has_equal_ast() checks the expression used to set argument a
            Ex().check_function('numpy.mean').check_args('a').has_equal_ast()

        Student and solution code::

            def my_power(x):
                print("calculating sqrt...")
                return(x * x)

        SCT::

            Ex().check_function_def('my_power').multi(
                check_args('x') # will fail if student used y as arg
                check_args(0)   # will still pass if student used y as arg
            )


def check_call(state, callstr, argstr=None, expand_msg=None):

state.assert_is(<EOL>["<STR_LIT>", "<STR_LIT>"],<EOL>"<STR_LIT>",<EOL>["<STR_LIT>", "<STR_LIT>"],<EOL>)<EOL>if expand_msg is None:<EOL><INDENT>expand_msg = "<STR_LIT>"<EOL><DEDENT>stu_part, _argstr = build_call(callstr, state.student_parts["<STR_LIT>"])<EOL>sol_part, _ = build_call(callstr, state.solution_parts["<STR_LIT>"])<EOL>append_message = {"<STR_LIT>": expand_msg, "<STR_LIT>": {"<STR_LIT>": argstr or _argstr}}<EOL>child = part_to_child(stu_part, sol_part, append_message, state)<EOL>return child<EOL>

When checking a function definition of lambda function,
    prepare has_equal_x for checking the call of a user-defined function.

    Args:
        callstr (str): call string that specifies how the function should be called, e.g. `f(1, a = 2)`.
           ``check_call()`` will replace ``f`` with the function/lambda you're targeting.
        argstr (str): If specified, this overrides the way the function call is refered to in the expand message.
        expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains.
        state (State): state object that is chained from.

    :Example:

        Student and solution code::

            def my_power(x):
                print("calculating sqrt...")
                return(x * x)

        SCT::

            Ex().check_function_def('my_power').multi(
                check_call("f(3)").has_equal_value()
                check_call("f(3)").has_equal_output()
            )


sig = inspect.signature(f)<EOL>@wraps(f)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>ba = sig.bind_partial(*args, **kwargs)<EOL>process = ba.arguments.get("<STR_LIT>")<EOL>if process:<EOL><INDENT>ba.arguments["<STR_LIT>"] = None<EOL>pf = partial(wrapper, *ba.args, **ba.kwargs)<EOL>return process.executeTask(pf)<EOL><DEDENT>return f(*ba.args, **ba.kwargs)<EOL><DEDENT>return wrapper<EOL>

Decorator to (optionally) run function in a process.


def getResultFromProcess(res, tempname, process):

if not isinstance(res, (UndefinedValue, Exception)):<EOL><INDENT>value = getRepresentation(tempname, process)<EOL>return value, res<EOL><DEDENT>else:<EOL><INDENT>return res, str(res)<EOL><DEDENT>

Get a value from process, return tuple of value, res if succesful


if len(self) > <NUM_LIT:1>:<EOL><INDENT>return "<STR_LIT>".format("<STR_LIT:U+002CU+0020>".join(self._od.keys()))<EOL><DEDENT>else:<EOL><INDENT>return "<STR_LIT>".join(self._od.keys())<EOL><DEDENT>


return self.__class__(<EOL>[(k, v) for k, v in self.items() if v is not self.EMPTY], is_empty=False<EOL>)<EOL>

Return copy of instance, omitting entries that are EMPTY


for line in node.body:<EOL><INDENT>self.visit(line)<EOL><DEDENT>

This function is called when a Module node is encountered when traversing the tree.

Args:
    node (ast.Module): The node which is visited.


pass<EOL>

This function is called when all other nodes are encountered when traversing the tree.
When inheriting form this standard parser, this function will make the parser ignore
all nodes that are not relevant.

Args:
    node (ast.Node): The node which is visited.


def __init__(self, string, search_string, pattern, feedback):

super().__init__(feedback)<EOL>self.string = string<EOL>self.search_string = search_string<EOL>self.pattern = pattern<EOL>

Initialize with a string to look for, a string to search and whether or not to look for a pattern.

Args:
    string (regex/str):  The string to look for will be set to this.
    search_string (str): The string to search in will be set to this.
    pattern (bool): The pattern boolean will be set to this.
    feedback (str): The failure message will be set to this.


State.root_state.reporter.success_msg = message<EOL>

Set the succes message of the sct. This message will be the feedback if all tests pass.
Args:
        message (str): A string containing the feedback message.


@wraps(f)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>args = (<EOL>args[<NUM_LIT:0>] if len(args) == <NUM_LIT:1> and isinstance(args[<NUM_LIT:0>], (list, tuple)) else args<EOL>)<EOL>for arg in args:<EOL><INDENT>if isinstance(arg, Node) and arg.parent.name is "<STR_LIT:root>":<EOL><INDENT>arg.parent.remove_child(arg)<EOL>arg.update_child_calls()<EOL><DEDENT><DEDENT>return f(*args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

Decorator for multi to remove nodes for original test functions from root node


self.root = Node(name="<STR_LIT:root>")<EOL>self.crnt_node = self.root<EOL>

Represent a tree of nodes, by holding the currently active node.

This class is necessary to put sub-tests onto a graph, because they may
exist inside of function calls. By getting the currently active node
from the tree, Probe instances may add subtests as children on that node,
and update it when recursing over sub-tests.


def __init__(self, child_list=None, data=None, name="<STR_LIT>", arg_name="<STR_LIT>"):

self.parent = None<EOL>self.name = name<EOL>self.arg_name = arg_name<EOL>self.child_list = [] if child_list is None else child_list<EOL>self.data = {} if data is None else data<EOL>self.updated = False<EOL>

Hold a function call with its bound arguments, along with child nodes.


ba = self.data["<STR_LIT>"]<EOL>if state:<EOL><INDENT>func = self.data["<STR_LIT>"]<EOL>ba = inspect.signature(func).bind(state, *ba.args[<NUM_LIT:1>:], **ba.kwargs)<EOL>func(*ba.args, **ba.kwargs)<EOL>return state<EOL><DEDENT>else:<EOL><INDENT>self.data["<STR_LIT>"](*ba.args, **ba.kwargs)<EOL>ba.apply_defaults()<EOL>return ba.arguments["<STR_LIT:state>"]<EOL><DEDENT>

Call original function with its arguments, and optional state


ba = self.data["<STR_LIT>"]<EOL>return state_partial(self.data["<STR_LIT>"], *ba.args[<NUM_LIT:1>:], **ba.kwargs)<EOL>

Return partial of original function call


for node in filter(lambda n: len(n.arg_name), self.child_list):<EOL><INDENT>self.data["<STR_LIT>"].arguments[node.arg_name] = node.partial()<EOL><DEDENT>self.updated = True<EOL>

Replace child nodes on original function call with their partials


if include_me:<EOL><INDENT>yield self<EOL><DEDENT>for child in self.child_list:<EOL><INDENT>yield child<EOL>yield from child.descend()<EOL><DEDENT>

Descend depth first into all child nodes


if (len(args) > <NUM_LIT:0> and not isinstance(args[<NUM_LIT:0>], State)) or len(args) == <NUM_LIT:0>:<EOL><INDENT>args = ['<STR_LIT>'] + list(args)<EOL><DEDENT>bound_args = inspect.signature(self.f).bind(*args, **kwargs)<EOL>data = dict(bound_args=bound_args, func=self.f)<EOL>this_node = Node(data=data, name=self.test_name)<EOL>if self.tree is not None:<EOL><INDENT>self.tree.crnt_node.add_child(this_node)<EOL><DEDENT>arguments = bound_args.arguments<EOL>for subtest in self.sub_tests:  <EOL><INDENT>if subtest in arguments and arguments[subtest]:<EOL><INDENT>self.build_sub_test_nodes(arguments[subtest], self.tree, this_node, subtest)<EOL><DEDENT><DEDENT>for node in this_node.descend(include_me=True):<EOL><INDENT>if node.updated:  <EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>node.update_child_calls()<EOL><DEDENT><DEDENT>if self.eval_on_call:<EOL><INDENT>return this_node()<EOL><DEDENT>else:<EOL><INDENT>return this_node<EOL><DEDENT>

Bind arguments to original function signature, and store in a Node

        This is used to discover what tests and sub-tests the SCT would like to
        call, and defer them for later execution via their node instance. Node
        instances are assembled into a tree.


if app.builder.format != "<STR_LIT:html>":<EOL><INDENT>return<EOL><DEDENT>src = source[<NUM_LIT:0>]<EOL>rendered = app.builder.templates.render_string(src, app.config.html_context)<EOL>source[<NUM_LIT:0>] = rendered<EOL>

Render our pages as a jinja template for fancy templating goodness.


v = _Validator(schemas.pin)<EOL>if v.validate(pin):<EOL><INDENT>return<EOL><DEDENT>else:<EOL><INDENT>raise schemas.DocumentError(errors=v.errors)<EOL><DEDENT>

Validate the given pin against the schema.

    :param dict pin: The pin to validate:
    :raises pypebbleapi.schemas.DocumentError: If the pin is not valid.


def send_shared_pin(self, topics, pin, skip_validation=False):

if not self.api_key:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if not skip_validation:<EOL><INDENT>validate_pin(pin)<EOL><DEDENT>response = _request('<STR_LIT>',<EOL>url=self.url_v1('<STR_LIT>' + pin['<STR_LIT:id>']),<EOL>user_agent=self.user_agent,<EOL>api_key=self.api_key,<EOL>topics_list=topics,<EOL>json=pin,<EOL>)<EOL>_raise_for_status(response)<EOL>

Send a shared pin for the given topics.

:param list topics: The list of topics.
:param dict pin: The pin.
:param bool skip_validation: Whether to skip the validation.
:raises pypebbleapi.schemas.DocumentError: If the validation process failed.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


if not self.api_key:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>response = _request('<STR_LIT>',<EOL>url=self.url_v1('<STR_LIT>' + pin_id),<EOL>user_agent=self.user_agent,<EOL>api_key=self.api_key,<EOL>)<EOL>_raise_for_status(response)<EOL>

Delete a shared pin.

:param str pin_id: The id of the pin to delete.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


def send_user_pin(self, user_token, pin, skip_validation=False):

if not skip_validation:<EOL><INDENT>validate_pin(pin)<EOL><DEDENT>response = _request('<STR_LIT>',<EOL>url=self.url_v1('<STR_LIT>' + pin['<STR_LIT:id>']),<EOL>user_agent=self.user_agent,<EOL>user_token=user_token,<EOL>json=pin,<EOL>)<EOL>_raise_for_status(response)<EOL>

Send a user pin.

:param str user_token: The token of the user.
:param dict pin: The pin.
:param bool skip_validation: Whether to skip the validation.
:raises pypebbleapi.schemas.DocumentError: If the validation process failed.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


def delete_user_pin(self, user_token, pin_id):

response = _request('<STR_LIT>',<EOL>url=self.url_v1('<STR_LIT>' + pin_id),<EOL>user_agent=self.user_agent,<EOL>user_token=user_token,<EOL>)<EOL>_raise_for_status(response)<EOL>

Delete a user pin.

:param str user_token: The token of the user.
:param str pin_id: The id of the pin to delete.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


response = _request('<STR_LIT:POST>',<EOL>url=self.url_v1('<STR_LIT>' + topic),<EOL>user_agent=self.user_agent,<EOL>user_token=user_token,<EOL>)<EOL>_raise_for_status(response)<EOL>

Subscribe a user to the given topic.

:param str user_token: The token of the user.
:param str topic: The topic.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


def unsubscribe(self, user_token, topic):

response = _request('<STR_LIT>',<EOL>url=self.url_v1('<STR_LIT>' + topic),<EOL>user_agent=self.user_agent,<EOL>user_token=user_token,<EOL>)<EOL>_raise_for_status(response)<EOL>

Unsubscribe a user from the given topic.

:param str user_token: The token of the user.
:param str topic: The topic.
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


Get the list of the topics which a user is subscribed to.

:param str user_token: The token of the user.
:return: The list of the topics.
:rtype: list
:raises `requests.exceptions.HTTPError`: If an HTTP error occurred.


return '<STR_LIT>' + name<EOL>

Convert an icon name to the corresponding URI.

:param str name: The name of the icon.
:return: The corresponding URI.
:rtype: str


self.errors = errors<EOL>message = "<STR_LIT>"<EOL>message += pformat(errors)<EOL>self.errors = errors<EOL>super(DocumentError, self).__init__(message)<EOL>

Initialize DocumentError with an `errors` object.


def create_from_array(self, blockname, array, Nfile=None, memorylimit=<NUM_LIT> * <NUM_LIT> * <NUM_LIT>):

size = len(array)<EOL>sizeperfile = <NUM_LIT:32> * <NUM_LIT> * <NUM_LIT><EOL>if Nfile is None:<EOL><INDENT>Nfile = (size + sizeperfile - <NUM_LIT:1>) // sizeperfile<EOL><DEDENT>dtype = numpy.dtype((array.dtype, array.shape[<NUM_LIT:1>:]))<EOL>itemsize = dtype.itemsize<EOL>itemlimit = memorylimit // dtype.itemsize // <NUM_LIT> * <NUM_LIT><EOL>with self.create(blockname, dtype, size, Nfile) as b:<EOL><INDENT>for i in range(<NUM_LIT:0>, len(array), itemlimit):<EOL><INDENT>b.write(i, numpy.array(array[i:i+itemlimit]))<EOL><DEDENT><DEDENT>return self.open(blockname)<EOL>

create a block from array like objects
            The operation is well defined only if array is at most 2d.

            Parameters
            ----------
            array : array_like,
                array shall have a scalar dtype.
            blockname : string
                name of the block
            Nfile : int or None
                number of physical files. if None, 32M items per file
                is used.
            memorylimit : int
                number of bytes to use for the buffering. relevant only if
                indexing on array returns a copy (e.g. IO or dask array)


if self.comm.rank == <NUM_LIT:0>:<EOL><INDENT>self._blocks = self.list_blocks()<EOL><DEDENT>else:<EOL><INDENT>self._blocks = None<EOL><DEDENT>self._blocks = self.comm.bcast(self._blocks)<EOL>

Refresh the list of blocks to the disk, collectively


size = self.comm.allreduce(len(array))<EOL>sizeperfile = <NUM_LIT:32> * <NUM_LIT> * <NUM_LIT><EOL>if Nfile is None:<EOL><INDENT>Nfile = (size + sizeperfile - <NUM_LIT:1>) // sizeperfile<EOL><DEDENT>offset = sum(self.comm.allgather(len(array))[:self.comm.rank])<EOL>dtype = numpy.dtype((array.dtype, array.shape[<NUM_LIT:1>:]))<EOL>itemsize = dtype.itemsize<EOL>itemlimit = memorylimit // dtype.itemsize // <NUM_LIT> * <NUM_LIT><EOL>with self.create(blockname, dtype, size, Nfile) as b:<EOL><INDENT>for i in range(<NUM_LIT:0>, len(array), itemlimit):<EOL><INDENT>b.write(offset + i, numpy.array(array[i:i+itemlimit]))<EOL><DEDENT><DEDENT>return self.open(blockname)<EOL>


log.debug('<STR_LIT>', name)<EOL>self.name = name<EOL>self.transform_str = transform<EOL>

:param string name: A name for this Normalization
:param string transform: Reaction SMARTS to define the transformation.


def __init__(self, normalizations=NORMALIZATIONS, max_restarts=MAX_RESTARTS):

log.debug('<STR_LIT>')<EOL>self.normalizations = normalizations<EOL>self.max_restarts = max_restarts<EOL>

Initialize a Normalizer with an optional custom list of :class:`~molvs.normalize.Normalization` transforms.

        :param normalizations: A list of  :class:`~molvs.normalize.Normalization` transforms to apply.
        :param int max_restarts: The maximum number of times to attempt to apply the series of normalizations (default
                                 200).


return self.normalize(mol)<EOL>

Calling a Normalizer instance like a function is the same as calling its normalize(mol) method.


log.debug('<STR_LIT>')<EOL>fragments = []<EOL>for fragment in Chem.GetMolFrags(mol, asMols=True):<EOL><INDENT>fragments.append(self._normalize_fragment(fragment))<EOL><DEDENT>outmol = fragments.pop()<EOL>for fragment in fragments:<EOL><INDENT>outmol = Chem.CombineMols(outmol, fragment)<EOL><DEDENT>Chem.SanitizeMol(outmol)<EOL>return outmol<EOL>

Apply a series of Normalization transforms to correct functional groups and recombine charges.

        A series of transforms are applied to the molecule. For each Normalization, the transform is applied repeatedly
        until no further changes occur. If any changes occurred, we go back and start from the first Normalization
        again, in case the changes mean an earlier transform is now applicable. The molecule is returned once the entire
        series of Normalizations cause no further changes or if max_restarts (default 200) is reached.

        :param mol: The molecule to normalize.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The normalized fragment.
        :rtype: rdkit.Chem.rdchem.Mol


mols = [mol]<EOL>for n in six.moves.range(<NUM_LIT:20>):<EOL><INDENT>products = {}<EOL>for mol in mols:<EOL><INDENT>for product in [x[<NUM_LIT:0>] for x in rule.RunReactants((mol,))]:<EOL><INDENT>if Chem.SanitizeMol(product, catchErrors=True) == <NUM_LIT:0>:<EOL><INDENT>products[Chem.MolToSmiles(product, isomericSmiles=True)] = product<EOL><DEDENT><DEDENT><DEDENT>if products:<EOL><INDENT>mols = [products[s] for s in sorted(products)]<EOL><DEDENT>else:<EOL><INDENT>return mols[<NUM_LIT:0>] if n > <NUM_LIT:0> else None<EOL><DEDENT><DEDENT>

Repeatedly apply normalization transform to molecule until no changes occur.

        It is possible for multiple products to be produced when a rule is applied. The rule is applied repeatedly to
        each of the products, until no further changes occur or after 20 attempts. If there are multiple unique products
        after the final application, the first product (sorted alphabetically by SMILES) is chosen.


<EOL>mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Standardizer().standardize(mol)<EOL>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL>

Return a standardized canonical SMILES string given a SMILES string.

    Note: This is a convenience function for quickly standardizing a single SMILES string. It is more efficient to use
    the :class:`~molvs.standardize.Standardizer` class directly when working with many molecules or when custom options
    are needed.

    :param string smiles: The SMILES for the molecule.
    :returns: The SMILES for the standardized molecule.
    :rtype: string.


<EOL>mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Standardizer().standardize(mol)<EOL>tautomers = TautomerEnumerator().enumerate(mol)<EOL>return {Chem.MolToSmiles(m, isomericSmiles=True) for m in tautomers}<EOL>

Return a set of tautomers as SMILES strings, given a SMILES string.

    :param smiles: A SMILES string.
    :returns: A set containing SMILES strings for every possible tautomer.
    :rtype: set of strings.


<EOL>mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Standardizer().standardize(mol)<EOL>tautomer = TautomerCanonicalizer().canonicalize(mol)<EOL>return Chem.MolToSmiles(tautomer, isomericSmiles=True)<EOL>

Return a standardized canonical tautomer SMILES string given a SMILES string.

    Note: This is a convenience function for quickly standardizing and finding the canonical tautomer for a single
    SMILES string. It is more efficient to use the :class:`~molvs.standardize.Standardizer` class directly when working
    with many molecules or when custom options are needed.

    :param string smiles: The SMILES for the molecule.
    :returns: The SMILES for the standardize canonical tautomer.
    :rtype: string.


log.debug('<STR_LIT>')<EOL>self.normalizations = normalizations<EOL>self.acid_base_pairs = acid_base_pairs<EOL>self.charge_corrections = charge_corrections<EOL>self.tautomer_transforms = tautomer_transforms<EOL>self.tautomer_scores = tautomer_scores<EOL>self.max_restarts = max_restarts<EOL>self.max_tautomers = max_tautomers<EOL>self.prefer_organic = prefer_organic<EOL>

Initialize a Standardizer with optional custom parameters.

        :param normalizations: A list of Normalizations to apply (default: :data:`~molvs.normalize.NORMALIZATIONS`).
        :param acid_base_pairs: A list of AcidBasePairs for competitive reionization (default:
                                :data:`~molvs.charge.ACID_BASE_PAIRS`).
        :param charge_corrections: A list of ChargeCorrections to apply (default:
                                :data:`~molvs.charge.CHARGE_CORRECTIONS`).
        :param tautomer_transforms: A list of TautomerTransforms to apply (default:
                                    :data:`~molvs.tautomer.TAUTOMER_TRANSFORMS`).
        :param tautomer_scores: A list of TautomerScores used to determine canonical tautomer (default:
                                :data:`~molvs.tautomer.TAUTOMER_SCORES`).
        :param max_restarts: The maximum number of times to attempt to apply the series of normalizations (default 200).
        :param max_tautomers: The maximum number of tautomers to enumerate (default 1000).
        :param prefer_organic: Whether to prioritize organic fragments when choosing fragment parent (default False).


return self.standardize(mol)<EOL>

Calling a Standardizer instance like a function is the same as calling its
        :meth:`~molvs.standardize.Standardizer.standardize` method.


mol = copy.deepcopy(mol)<EOL>Chem.SanitizeMol(mol)<EOL>mol = Chem.RemoveHs(mol)<EOL>mol = self.disconnect_metals(mol)<EOL>mol = self.normalize(mol)<EOL>mol = self.reionize(mol)<EOL>Chem.AssignStereochemistry(mol, force=True, cleanIt=True)<EOL>return mol<EOL>

Return a standardized version the given molecule.

        The standardization process consists of the following stages: RDKit
        :py:func:`~rdkit.Chem.rdmolops.RemoveHs`, RDKit :py:func:`~rdkit.Chem.rdmolops.SanitizeMol`,
        :class:`~molvs.metal.MetalDisconnector`, :class:`~molvs.normalize.Normalizer`,
        :class:`~molvs.charge.Reionizer`, RDKit :py:func:`~rdkit.Chem.rdmolops.AssignStereochemistry`.

        :param mol: The molecule to standardize.
        :type mol: rdkit.Chem.rdchem.Mol
        :returns: The standardized molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def tautomer_parent(self, mol, skip_standardize=False):

if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>tautomer = self.canonicalize_tautomer(mol)<EOL>tautomer = self.standardize(tautomer)<EOL>return tautomer<EOL>

Return the tautomer parent of a given molecule.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The tautomer parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def fragment_parent(self, mol, skip_standardize=False):

if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>fragment = self.largest_fragment(mol)<EOL>return fragment<EOL>

Return the fragment parent of a given molecule.

        The fragment parent is the largest organic covalent unit in the molecule.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The fragment parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def stereo_parent(self, mol, skip_standardize=False):

if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>else:<EOL><INDENT>mol = copy.deepcopy(mol)<EOL><DEDENT>Chem.RemoveStereochemistry(mol)<EOL>return mol<EOL>

Return the stereo parent of a given molecule.

        The stereo parent has all stereochemistry information removed from tetrahedral centers and double bonds.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The stereo parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def isotope_parent(self, mol, skip_standardize=False):

if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>else:<EOL><INDENT>mol = copy.deepcopy(mol)<EOL><DEDENT>for atom in mol.GetAtoms():<EOL><INDENT>atom.SetIsotope(<NUM_LIT:0>)<EOL><DEDENT>return mol<EOL>

Return the isotope parent of a given molecule.

        The isotope parent has all atoms replaced with the most abundant isotope for that element.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The isotope parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def charge_parent(self, mol, skip_standardize=False):

<EOL>if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>fragment = self.fragment_parent(mol, skip_standardize=True)<EOL>if fragment:<EOL><INDENT>uncharged = self.uncharge(fragment)<EOL>uncharged = self.standardize(uncharged)<EOL>return uncharged<EOL><DEDENT>

Return the charge parent of a given molecule.

        The charge parent is the uncharged version of the fragment parent.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The charge parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def super_parent(self, mol, skip_standardize=False):

if not skip_standardize:<EOL><INDENT>mol = self.standardize(mol)<EOL><DEDENT>mol = self.charge_parent(mol, skip_standardize=True)<EOL>mol = self.isotope_parent(mol, skip_standardize=True)<EOL>mol = self.stereo_parent(mol, skip_standardize=True)<EOL>mol = self.tautomer_parent(mol, skip_standardize=True)<EOL>mol = self.standardize(mol)<EOL>return mol<EOL>

Return the super parent of a given molecule.

        THe super parent is fragment, charge, isotope, stereochemistry and tautomer insensitive. From the input
        molecule, the largest fragment is taken. This is uncharged and then isotope and stereochemistry information is
        discarded. Finally, the canonical tautomer is determined and returned.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :param bool skip_standardize: Set to True if mol has already been standardized.
        :returns: The super parent molecule.
        :rtype: rdkit.Chem.rdchem.Mol


return MetalDisconnector()<EOL>

:returns: A callable :class:`~molvs.metal.MetalDisconnector` instance.


return Normalizer(normalizations=self.normalizations, max_restarts=self.max_restarts)<EOL>

:returns: A callable :class:`~molvs.normalize.Normalizer` instance.


return Reionizer(acid_base_pairs=self.acid_base_pairs, charge_corrections=self.charge_corrections)<EOL>

:returns: A callable :class:`~molvs.charge.Reionizer` instance.


return Uncharger(acid_base_pairs=self.acid_base_pairs)<EOL>

:returns: A callable :class:`~molvs.charge.Uncharger` instance.


return FragmentRemover()<EOL>

:returns: A callable :class:`~molvs.fragment.FragmentRemover` instance.


return LargestFragmentChooser(prefer_organic=self.prefer_organic)<EOL>

:returns: A callable :class:`~molvs.fragment.LargestFragmentChooser` instance.


return TautomerEnumerator(transforms=self.tautomer_transforms, max_tautomers=self.max_tautomers)<EOL>

:returns: A callable :class:`~molvs.tautomer.TautomerEnumerator` instance.


return TautomerCanonicalizer(transforms=self.tautomer_transforms, scores=self.tautomer_scores,<EOL>max_tautomers=self.max_tautomers)<EOL>

:returns: A callable :class:`~molvs.tautomer.TautomerCanonicalizer` instance.


<EOL>parser = MolvsParser(epilog='<STR_LIT>')<EOL>subparsers = parser.add_subparsers(title='<STR_LIT>')<EOL>common_parser = MolvsParser(add_help=False)<EOL>common_parser.add_argument('<STR_LIT>', nargs='<STR_LIT:?>', help='<STR_LIT>', type=argparse.FileType('<STR_LIT:r>'), default=sys.stdin)<EOL>common_parser.add_argument('<STR_LIT>', '<STR_LIT>', help='<STR_LIT>', choices=FILETYPES)<EOL>common_parser.add_argument('<STR_LIT>', '<STR_LIT>', help='<STR_LIT>', metavar='<STR_LIT>')<EOL>common_parser.add_argument('<STR_LIT>', '<STR_LIT>', help='<STR_LIT>', type=argparse.FileType('<STR_LIT:w>'), default=sys.stdout, metavar='<STR_LIT>')<EOL>standardize_parser = subparsers.add_parser('<STR_LIT>', help='<STR_LIT>', parents=[common_parser])<EOL>standardize_parser.add_argument('<STR_LIT>', '<STR_LIT>', help='<STR_LIT>', choices=FILETYPES)<EOL>standardize_parser.set_defaults(func=standardize_main)<EOL>validate_parser = subparsers.add_parser('<STR_LIT>', help='<STR_LIT>', parents=[common_parser])<EOL>validate_parser.set_defaults(func=validate_main)<EOL>args = parser.parse_args()<EOL>try:<EOL><INDENT>args.func(args)<EOL><DEDENT>except Exception as e:<EOL><INDENT>sys.stderr.write('<STR_LIT>'.encode() % e.message)<EOL>parser.print_help()<EOL>sys.exit(<NUM_LIT:2>)<EOL><DEDENT>

Main function for molvs command line interface.


mol = Chem.MolFromSmiles(smiles)<EOL>mesomers = ResonanceEnumerator().enumerate(mol)<EOL>return {Chem.MolToSmiles(m, isomericSmiles=True) for m in mesomers}<EOL>

Return a set of resonance forms as SMILES strings, given a SMILES string.

    :param smiles: A SMILES string.
    :returns: A set containing SMILES strings for every possible resonance form.
    :rtype: set of strings.


def __init__(self, kekule_all=False, allow_incomplete_octets=False, unconstrained_cations=False,<EOL>unconstrained_anions=False, allow_charge_separation=False, max_structures=MAX_STRUCTURES):

self.kekule_all = kekule_all<EOL>self.allow_incomplete_octets = allow_incomplete_octets<EOL>self.unconstrained_cations = unconstrained_cations<EOL>self.unconstrained_anions = unconstrained_anions<EOL>self.allow_charge_separation = allow_charge_separation<EOL>self.max_structures = max_structures<EOL>

:param bool allow_incomplete_octets: include resonance structures whose octets are less complete than the the most octet-complete structure.
:param bool allow_charge_separation: include resonance structures featuring charge separation also when uncharged resonance structures exist.
:param bool kekule_all: enumerate all possible degenerate Kekule resonance structures (the default is to include just one).
:param bool unconstrained_cations: if False positively charged atoms left and right of N with an incomplete octet are acceptable only if the conjugated group has a positive total formal charge.
:param bool unconstrained_anions: if False, negatively charged atoms left of N are acceptable only if the conjugated group has a negative total formal charge.
:param int max_structures: Maximum number of resonance forms.


return self.enumerate(mol)<EOL>

Calling a ResonanceEnumerator instance like a function is the same as calling its enumerate(mol) method.


flags = <NUM_LIT:0><EOL>if self.kekule_all:<EOL><INDENT>flags = flags | Chem.KEKULE_ALL<EOL><DEDENT>if self.allow_incomplete_octets:<EOL><INDENT>flags = flags | Chem.ALLOW_INCOMPLETE_OCTETS<EOL><DEDENT>if self.allow_charge_separation:<EOL><INDENT>flags = flags | Chem.ALLOW_CHARGE_SEPARATION<EOL><DEDENT>if self.unconstrained_anions:<EOL><INDENT>flags = flags | Chem.UNCONSTRAINED_ANIONS<EOL><DEDENT>if self.unconstrained_cations:<EOL><INDENT>flags = flags | Chem.UNCONSTRAINED_CATIONS<EOL><DEDENT>results = []<EOL>for result in Chem.ResonanceMolSupplier(mol, flags=flags, maxStructs=self.max_structures):<EOL><INDENT>Chem.SanitizeMol(result)<EOL>results.append(result)<EOL><DEDENT>return results<EOL>

Enumerate all possible resonance forms and return them as a list.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: A list of all possible resonance forms of the molecule.
        :rtype: list of rdkit.Chem.rdchem.Mol


<EOL>for a in fragment.GetAtoms():<EOL><INDENT>if a.GetAtomicNum() == <NUM_LIT:6>:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Return true if fragment contains at least one carbon atom.

    :param fragment: The fragment as an RDKit Mol object.


self.name = name<EOL>self.smarts_str = smarts<EOL>

Initialize a FragmentPattern with a name and a SMARTS pattern.

        :param name: A name for this FragmentPattern.
        :param smarts: A SMARTS pattern.


def __init__(self, fragments=REMOVE_FRAGMENTS, leave_last=LEAVE_LAST):

log.debug('<STR_LIT>')<EOL>self.fragments = fragments<EOL>self.leave_last = leave_last<EOL>

Initialize a FragmentRemover with an optional custom list of :class:`~molvs.fragment.FragmentPattern`.

        Setting leave_last to True will ensure at least one fragment is left in the molecule, even if it is matched by a
        :class:`~molvs.fragment.FragmentPattern`. Fragments are removed in the order specified in the list, so place
        those you would prefer to be left towards the end of the list. If all the remaining fragments match the same
        :class:`~molvs.fragment.FragmentPattern`, they will all be left.

        :param fragments: A list of :class:`~molvs.fragment.FragmentPattern` to remove.
        :param bool leave_last: Whether to ensure at least one fragment is left.


return self.remove(mol)<EOL>

Calling a FragmentRemover instance like a function is the same as calling its remove(mol) method.


log.debug('<STR_LIT>')<EOL>for frag in self.fragments:<EOL><INDENT>if mol.GetNumAtoms() == <NUM_LIT:0> or (self.leave_last and len(Chem.GetMolFrags(mol)) <= <NUM_LIT:1>):<EOL><INDENT>break<EOL><DEDENT>removed = Chem.DeleteSubstructs(mol, frag.smarts, onlyFrags=True)<EOL>if not mol.GetNumAtoms() == removed.GetNumAtoms():<EOL><INDENT>log.info('<STR_LIT>', frag.name)<EOL><DEDENT>if self.leave_last and removed.GetNumAtoms() == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT>mol = removed<EOL><DEDENT>return mol<EOL>

Return the molecule with specified fragments removed.

        :param mol: The molecule to remove fragments from.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The molecule with fragments removed.
        :rtype: rdkit.Chem.rdchem.Mol


log.debug('<STR_LIT>')<EOL>self.prefer_organic = prefer_organic<EOL>

If prefer_organic is set to True, any organic fragment will be considered larger than any inorganic fragment. A
fragment is considered organic if it contains a carbon atom.

:param bool prefer_organic: Whether to prioritize organic fragments above all others.


return self.choose(mol)<EOL>

Calling a LargestFragmentChooser instance like a function is the same as calling its choose(mol) method.


log.debug('<STR_LIT>')<EOL>fragments = Chem.GetMolFrags(mol, asMols=True)<EOL>largest = None<EOL>for f in fragments:<EOL><INDENT>smiles = Chem.MolToSmiles(f, isomericSmiles=True)<EOL>log.debug('<STR_LIT>', smiles)<EOL>organic = is_organic(f)<EOL>if self.prefer_organic:<EOL><INDENT>if largest and largest['<STR_LIT>'] and not organic:<EOL><INDENT>continue<EOL><DEDENT>if largest and organic and not largest['<STR_LIT>']:<EOL><INDENT>largest = None<EOL><DEDENT><DEDENT>atoms = <NUM_LIT:0><EOL>for a in f.GetAtoms():<EOL><INDENT>atoms += <NUM_LIT:1> + a.GetTotalNumHs()<EOL><DEDENT>if largest and atoms < largest['<STR_LIT>']:<EOL><INDENT>continue<EOL><DEDENT>weight = rdMolDescriptors.CalcExactMolWt(f)<EOL>if largest and atoms == largest['<STR_LIT>'] and weight < largest['<STR_LIT>']:<EOL><INDENT>continue<EOL><DEDENT>if largest and atoms == largest['<STR_LIT>'] and weight == largest['<STR_LIT>'] and smiles > largest['<STR_LIT>']:<EOL><INDENT>continue<EOL><DEDENT>log.debug('<STR_LIT>', smiles, atoms)<EOL>largest = {'<STR_LIT>': smiles, '<STR_LIT>': f, '<STR_LIT>': atoms, '<STR_LIT>': weight, '<STR_LIT>': organic}<EOL><DEDENT>return largest['<STR_LIT>']<EOL>

Return the largest covalent unit.

        The largest fragment is determined by number of atoms (including hydrogens). Ties are broken by taking the
        fragment with the higher molecular weight, and then by taking the first alphabetically by SMILES if needed.

        :param mol: The molecule to choose the largest fragment from.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The largest fragment.
        :rtype: rdkit.Chem.rdchem.Mol


return self.disconnect(mol)<EOL>

Calling a MetalDisconnector instance like a function is the same as calling its disconnect(mol) method.


log.debug('<STR_LIT>')<EOL>for smarts in [self._metal_nof, self._metal_non]:<EOL><INDENT>pairs = mol.GetSubstructMatches(smarts)<EOL>rwmol = Chem.RWMol(mol)<EOL>orders = []<EOL>for i, j in pairs:<EOL><INDENT>orders.append(int(mol.GetBondBetweenAtoms(i, j).GetBondTypeAsDouble()))<EOL>rwmol.RemoveBond(i, j)<EOL><DEDENT>mol = rwmol.GetMol()<EOL>for n, (i, j) in enumerate(pairs):<EOL><INDENT>chg = orders[n]<EOL>atom1 = mol.GetAtomWithIdx(i)<EOL>atom1.SetFormalCharge(atom1.GetFormalCharge() + chg)<EOL>atom2 = mol.GetAtomWithIdx(j)<EOL>atom2.SetFormalCharge(atom2.GetFormalCharge() - chg)<EOL>log.info('<STR_LIT>', atom1.GetSymbol(), atom2.GetSymbol())<EOL><DEDENT><DEDENT>Chem.SanitizeMol(mol)<EOL>return mol<EOL>

Break covalent bonds between metals and organic atoms under certain conditions.

        The algorithm works as follows:

        - Disconnect N, O, F from any metal.
        - Disconnect other non-metals from transition metals + Al (but not Hg, Ga, Ge, In, Sn, As, Tl, Pb, Bi, Po).
        - For every bond broken, adjust the charges of the begin and end atoms accordingly.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The molecule with metals disconnected.
        :rtype: rdkit.Chem.rdchem.Mol


raise NotImplementedError('<STR_LIT>')<EOL>

The SMARTS pattern as a string. Subclasses must implement this.


<EOL>mol = Chem.MolFromSmiles(smiles)<EOL>logs = Validator().validate(mol)<EOL>return logs<EOL>

Return log messages for a given SMILES string using the default validations.

    Note: This is a convenience function for quickly validating a single SMILES string. It is more efficient to use
    the :class:`~molvs.validate.Validator` class directly when working with many molecules or when custom options
    are needed.

    :param string smiles: The SMILES for the molecule.
    :returns: A list of log messages.
    :rtype: list of strings.


self.logs.append(record)<EOL>


self.acquire()<EOL>try:<EOL><INDENT>self.logs = []<EOL><DEDENT>finally:<EOL><INDENT>self.release()<EOL><DEDENT>


self.flush()<EOL>logging.Handler.close(self)<EOL>


def __init__(self, validations=VALIDATIONS, log_format=SIMPLE_FORMAT, level=logging.INFO, stdout=False, raw=False):

self.raw = raw<EOL>self.log = logging.getLogger(type(self).__name__)<EOL>self.log.setLevel(level)<EOL>self.handler = LogHandler()<EOL>self.handler.setFormatter(logging.Formatter(log_format))<EOL>self.log.addHandler(self.handler)<EOL>if stdout:<EOL><INDENT>strhdlr = logging.StreamHandler(sys.stdout)<EOL>strhdlr.setFormatter(logging.Formatter(log_format))<EOL>self.log.addHandler(strhdlr)<EOL><DEDENT>self.validations = [validation(self.log) for validation in validations]<EOL>

Initialize a Validator with the following parameters:

        :param validations: A list of Validations to apply (default: :data:`~molvs.validations.VALIDATIONS`).
        :param string log_format: A string format (default: :data:`~molvs.validate.SIMPLE_FORMAT`).
        :param level: The minimum logging level to output.
        :param bool stdout: Whether to send log messages to standard output.
        :param bool raw: Whether to return raw :class:`~logging.LogRecord` objects instead of formatted log strings.


return self.validate(mol)<EOL>

Calling a Validator instance like a function is the same as calling its
        :meth:`~molvs.validate.Validator.validate` method.


attr_name = '<STR_LIT>'.format(fget.__name__)<EOL>@functools.wraps(fget)<EOL>def fget_memoized(self):<EOL><INDENT>if not hasattr(self, attr_name):<EOL><INDENT>setattr(self, attr_name, fget(self))<EOL><DEDENT>return getattr(self, attr_name)<EOL><DEDENT>return property(fget_memoized)<EOL>

Decorator to create memoized properties.


a, b = tee(iterable)<EOL>next(b, None)<EOL>return six.moves.zip(a, b)<EOL>

Utility function to iterate in a pairwise fashion.


def __init__(self, name, smarts, bonds=(), charges=(), radicals=()):

self.name = name<EOL>self.tautomer_str = smarts<EOL>self.bonds = [self.BONDMAP[b] for b in bonds]<EOL>self.charges = [self.CHARGEMAP[b] for b in charges]<EOL>

Initialize a TautomerTransform with a name, SMARTS pattern and optional bonds and charges.

        The SMARTS pattern match is applied to a Kekule form of the molecule, so use explicit single and double bonds
        rather than aromatic.

        Specify custom bonds as a string of ``-``, ``=``, ``#``, ``:`` for single, double, triple and aromatic bonds
        respectively. Specify custom charges as ``+``, ``0``, ``-`` for +1, 0 and -1 charges respectively.

        :param string name: A name for this TautomerTransform.
        :param string smarts: SMARTS pattern to match for the transform.
        :param string bonds: Optional specification for the resulting bonds.
        :param string charges: Optional specification for the resulting charges on the atoms.


def __init__(self, name, smarts, score):

self.name = name<EOL>self.smarts_str = smarts<EOL>self.score = score<EOL>

Initialize a TautomerScore with a name, SMARTS pattern and score.

        :param name: A name for this TautomerScore.
        :param smarts: SMARTS pattern to match a substructure.
        :param score: The score to assign for this substructure.


def __init__(self, transforms=TAUTOMER_TRANSFORMS, scores=TAUTOMER_SCORES, max_tautomers=MAX_TAUTOMERS):

self.transforms = transforms<EOL>self.scores = scores<EOL>self.max_tautomers = max_tautomers<EOL>

:param transforms: A list of TautomerTransforms to use to enumerate tautomers.
:param scores: A list of TautomerScores to use to choose the canonical tautomer.
:param max_tautomers: The maximum number of tautomers to enumerate, a limit to prevent combinatorial explosion.


return self.canonicalize(mol)<EOL>

Calling a TautomerCanonicalizer instance like a function is the same as calling its canonicalize(mol) method.


<EOL>tautomers = self._enumerate_tautomers(mol)<EOL>if len(tautomers) == <NUM_LIT:1>:<EOL><INDENT>return tautomers[<NUM_LIT:0>]<EOL><DEDENT>highest = None<EOL>for t in tautomers:<EOL><INDENT>smiles = Chem.MolToSmiles(t, isomericSmiles=True)<EOL>log.debug('<STR_LIT>', smiles)<EOL>score = <NUM_LIT:0><EOL>ssr = Chem.GetSymmSSSR(t)<EOL>for ring in ssr:<EOL><INDENT>btypes = {t.GetBondBetweenAtoms(*pair).GetBondType() for pair in pairwise(ring)}<EOL>elements = {t.GetAtomWithIdx(idx).GetAtomicNum() for idx in ring}<EOL>if btypes == {BondType.AROMATIC}:<EOL><INDENT>log.debug('<STR_LIT>')<EOL>score += <NUM_LIT:100><EOL>if elements == {<NUM_LIT:6>}:<EOL><INDENT>log.debug('<STR_LIT>')<EOL>score += <NUM_LIT><EOL><DEDENT><DEDENT><DEDENT>for tscore in self.scores:<EOL><INDENT>for match in t.GetSubstructMatches(tscore.smarts):<EOL><INDENT>log.debug('<STR_LIT>', tscore.score, tscore.name)<EOL>score += tscore.score<EOL><DEDENT><DEDENT>for atom in t.GetAtoms():<EOL><INDENT>if atom.GetAtomicNum() in {<NUM_LIT:15>, <NUM_LIT:16>, <NUM_LIT>, <NUM_LIT>}:<EOL><INDENT>hs = atom.GetTotalNumHs()<EOL>if hs:<EOL><INDENT>log.debug('<STR_LIT>', -hs, atom.GetSymbol())<EOL>score -= hs<EOL><DEDENT><DEDENT><DEDENT>if not highest or highest['<STR_LIT>'] < score or (highest['<STR_LIT>'] == score and smiles < highest['<STR_LIT>']):<EOL><INDENT>log.debug('<STR_LIT>', smiles, score)<EOL>highest = {'<STR_LIT>': smiles, '<STR_LIT>': t, '<STR_LIT>': score}<EOL><DEDENT><DEDENT>return highest['<STR_LIT>']<EOL>

Return a canonical tautomer by enumerating and scoring all possible tautomers.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The canonical tautomer.
        :rtype: rdkit.Chem.rdchem.Mol


def __init__(self, transforms=TAUTOMER_TRANSFORMS, max_tautomers=MAX_TAUTOMERS):

self.transforms = transforms<EOL>self.max_tautomers = max_tautomers<EOL>

:param transforms: A list of TautomerTransforms to use to enumerate tautomers.
:param max_tautomers: The maximum number of tautomers to enumerate (limit to prevent combinatorial explosion).


return self.enumerate(mol)<EOL>

Calling a TautomerEnumerator instance like a function is the same as calling its enumerate(mol) method.


smiles = Chem.MolToSmiles(mol, isomericSmiles=True)<EOL>tautomers = {smiles: copy.deepcopy(mol)}<EOL>kekulized = copy.deepcopy(mol)<EOL>Chem.Kekulize(kekulized)<EOL>kekulized = {smiles: kekulized}<EOL>done = set()<EOL>while len(tautomers) < self.max_tautomers:<EOL><INDENT>for tsmiles in sorted(tautomers):<EOL><INDENT>if tsmiles in done:<EOL><INDENT>continue<EOL><DEDENT>for transform in self.transforms:<EOL><INDENT>for match in kekulized[tsmiles].GetSubstructMatches(transform.tautomer):<EOL><INDENT>product = copy.deepcopy(kekulized[tsmiles])<EOL>first = product.GetAtomWithIdx(match[<NUM_LIT:0>])<EOL>last = product.GetAtomWithIdx(match[-<NUM_LIT:1>])<EOL>first.SetNumExplicitHs(max(<NUM_LIT:0>, first.GetTotalNumHs() - <NUM_LIT:1>))<EOL>last.SetNumExplicitHs(last.GetTotalNumHs() + <NUM_LIT:1>)<EOL>first.SetNoImplicit(True)<EOL>last.SetNoImplicit(True)<EOL>for bi, pair in enumerate(pairwise(match)):<EOL><INDENT>if transform.bonds:<EOL><INDENT>product.GetBondBetweenAtoms(*pair).SetBondType(transform.bonds[bi])<EOL><DEDENT>else:<EOL><INDENT>current_bond_type = product.GetBondBetweenAtoms(*pair).GetBondType()<EOL>product.GetBondBetweenAtoms(*pair).SetBondType(BondType.DOUBLE if current_bond_type == BondType.SINGLE else BondType.SINGLE)<EOL><DEDENT><DEDENT>if transform.charges:<EOL><INDENT>for ci, idx in enumerate(match):<EOL><INDENT>atom = product.GetAtomWithIdx(idx)<EOL>atom.SetFormalCharge(atom.GetFormalCharge() + transform.charges[ci])<EOL><DEDENT><DEDENT>try:<EOL><INDENT>Chem.SanitizeMol(product)<EOL>smiles = Chem.MolToSmiles(product, isomericSmiles=True)<EOL>log.debug('<STR_LIT>', transform.name, tsmiles)<EOL>if smiles not in tautomers:<EOL><INDENT>log.debug('<STR_LIT>' % smiles)<EOL>kekulized_product = copy.deepcopy(product)<EOL>Chem.Kekulize(kekulized_product)<EOL>tautomers[smiles] = product<EOL>kekulized[smiles] = kekulized_product<EOL><DEDENT>else:<EOL><INDENT>log.debug('<STR_LIT>' % smiles)<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>log.debug('<STR_LIT>', transform.name)<EOL><DEDENT><DEDENT><DEDENT>done.add(tsmiles)<EOL><DEDENT>if len(tautomers) == len(done):<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>log.warning('<STR_LIT>', self.max_tautomers)<EOL><DEDENT>for tautomer in tautomers.values():<EOL><INDENT>Chem.AssignStereochemistry(tautomer, force=True, cleanIt=True)<EOL>for bond in tautomer.GetBonds():<EOL><INDENT>if bond.GetBondType() == BondType.DOUBLE and bond.GetStereo() > BondStereo.STEREOANY:<EOL><INDENT>begin = bond.GetBeginAtomIdx()<EOL>end = bond.GetEndAtomIdx()<EOL>for othertautomer in tautomers.values():<EOL><INDENT>if not othertautomer.GetBondBetweenAtoms(begin, end).GetBondType() == BondType.DOUBLE:<EOL><INDENT>neighbours = tautomer.GetAtomWithIdx(begin).GetBonds() + tautomer.GetAtomWithIdx(end).GetBonds()<EOL>for otherbond in neighbours:<EOL><INDENT>if otherbond.GetBondDir() in {BondDir.ENDUPRIGHT, BondDir.ENDDOWNRIGHT}:<EOL><INDENT>otherbond.SetBondDir(BondDir.NONE)<EOL><DEDENT><DEDENT>Chem.AssignStereochemistry(tautomer, force=True, cleanIt=True)<EOL>log.debug('<STR_LIT>')<EOL>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>return list(tautomers.values())<EOL>

Enumerate all possible tautomers and return them as a list.

        :param mol: The input molecule.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: A list of all possible tautomers of the molecule.
        :rtype: list of rdkit.Chem.rdchem.Mol


log.debug('<STR_LIT>', name)<EOL>self.name = name<EOL>self.acid_str = acid<EOL>self.base_str = base<EOL>

Initialize an AcidBasePair with the following parameters:

        :param string name: A name for this AcidBasePair.
        :param string acid: SMARTS pattern for the protonated acid.
        :param string base: SMARTS pattern for the conjugate ionized base.


def __init__(self, name, smarts, charge):

log.debug('<STR_LIT>', name)<EOL>self.name = name<EOL>self.smarts_str = smarts<EOL>self.charge = charge<EOL>

Initialize a ChargeCorrection with the following parameters:

        :param string name: A name for this ForcedAtomCharge.
        :param string smarts: SMARTS pattern to match. Charge is applied to the first atom.
        :param int charge: The charge to apply.


def __init__(self, acid_base_pairs=ACID_BASE_PAIRS, charge_corrections=CHARGE_CORRECTIONS):

log.debug('<STR_LIT>')<EOL>self.acid_base_pairs = acid_base_pairs<EOL>self.charge_corrections = charge_corrections<EOL>

Initialize a Reionizer with the following parameter:

        :param acid_base_pairs: A list of :class:`AcidBasePairs <molvs.charge.AcidBasePair>` to reionize, sorted from
                                strongest to weakest.
        :param charge_corrections: A list of :class:`ChargeCorrections <molvs.charge.ChargeCorrection>`.


return self.reionize(mol)<EOL>

Calling a Reionizer instance like a function is the same as calling its reionize(mol) method.


log.debug('<STR_LIT>')<EOL>start_charge = Chem.GetFormalCharge(mol)<EOL>for cc in self.charge_corrections:<EOL><INDENT>for match in mol.GetSubstructMatches(cc.smarts):<EOL><INDENT>atom = mol.GetAtomWithIdx(match[<NUM_LIT:0>])<EOL>log.info('<STR_LIT>', cc.name, atom.GetSymbol(), cc.charge)<EOL>atom.SetFormalCharge(cc.charge)<EOL><DEDENT><DEDENT>current_charge = Chem.GetFormalCharge(mol)<EOL>charge_diff = Chem.GetFormalCharge(mol) - start_charge<EOL>if not current_charge == <NUM_LIT:0>:<EOL><INDENT>while charge_diff > <NUM_LIT:0>:<EOL><INDENT>ppos, poccur = self._strongest_protonated(mol)<EOL>if ppos is None:<EOL><INDENT>break<EOL><DEDENT>log.info('<STR_LIT>', self.acid_base_pairs[ppos].name)<EOL>patom = mol.GetAtomWithIdx(poccur[-<NUM_LIT:1>])<EOL>patom.SetFormalCharge(patom.GetFormalCharge() - <NUM_LIT:1>)<EOL>if patom.GetNumExplicitHs() > <NUM_LIT:0>:<EOL><INDENT>patom.SetNumExplicitHs(patom.GetNumExplicitHs() - <NUM_LIT:1>)<EOL><DEDENT>patom.UpdatePropertyCache()<EOL>charge_diff -= <NUM_LIT:1><EOL><DEDENT><DEDENT>already_moved = set()<EOL>while True:<EOL><INDENT>ppos, poccur = self._strongest_protonated(mol)<EOL>ipos, ioccur = self._weakest_ionized(mol)<EOL>if ioccur and poccur and ppos < ipos:<EOL><INDENT>if poccur[-<NUM_LIT:1>] == ioccur[-<NUM_LIT:1>]:<EOL><INDENT>log.warning('<STR_LIT>')<EOL>break<EOL><DEDENT>key = tuple(sorted([poccur[-<NUM_LIT:1>], ioccur[-<NUM_LIT:1>]]))<EOL>if key in already_moved:<EOL><INDENT>log.warning('<STR_LIT>')<EOL>break<EOL><DEDENT>already_moved.add(key)<EOL>log.info('<STR_LIT>', self.acid_base_pairs[ppos].name, self.acid_base_pairs[ipos].name)<EOL>patom = mol.GetAtomWithIdx(poccur[-<NUM_LIT:1>])<EOL>patom.SetFormalCharge(patom.GetFormalCharge() - <NUM_LIT:1>)<EOL>if patom.GetNumImplicitHs() == <NUM_LIT:0> and patom.GetNumExplicitHs() > <NUM_LIT:0>:<EOL><INDENT>patom.SetNumExplicitHs(patom.GetNumExplicitHs() - <NUM_LIT:1>)<EOL><DEDENT>patom.UpdatePropertyCache()<EOL>iatom = mol.GetAtomWithIdx(ioccur[-<NUM_LIT:1>])<EOL>iatom.SetFormalCharge(iatom.GetFormalCharge() + <NUM_LIT:1>)<EOL>if (iatom.GetNoImplicit() or<EOL>((patom.GetAtomicNum() == <NUM_LIT:7> or patom.GetAtomicNum() == <NUM_LIT:15>) and patom.GetIsAromatic()) or<EOL>iatom.GetTotalValence() not in list(Chem.GetPeriodicTable().GetValenceList(iatom.GetAtomicNum()))):<EOL><INDENT>iatom.SetNumExplicitHs(iatom.GetNumExplicitHs() + <NUM_LIT:1>)<EOL><DEDENT>iatom.UpdatePropertyCache()<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>Chem.SanitizeMol(mol)<EOL>return mol<EOL>

Enforce charges on certain atoms, then perform competitive reionization.

        First, charge corrections are applied to ensure, for example, that free metals are correctly ionized. Then, if
        a molecule with multiple acid groups is partially ionized, ensure the strongest acids ionize first.

        The algorithm works as follows:

        - Use SMARTS to find the strongest protonated acid and the weakest ionized acid.
        - If the ionized acid is weaker than the protonated acid, swap proton and repeat.

        :param mol: The molecule to reionize.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The reionized molecule.
        :rtype: rdkit.Chem.rdchem.Mol


return self.uncharge(mol)<EOL>

Calling an Uncharger instance like a function is the same as calling its uncharge(mol) method.


log.debug('<STR_LIT>')<EOL>mol = copy.deepcopy(mol)<EOL>pos_remainder = <NUM_LIT:0><EOL>neg_count = <NUM_LIT:0><EOL>for atom in mol.GetAtoms():<EOL><INDENT>while atom.GetFormalCharge() > <NUM_LIT:0> and atom.GetNumExplicitHs() > <NUM_LIT:0>:<EOL><INDENT>atom.SetNumExplicitHs(atom.GetNumExplicitHs() - <NUM_LIT:1>)<EOL>atom.SetFormalCharge(atom.GetFormalCharge() - <NUM_LIT:1>)<EOL>log.info('<STR_LIT>')<EOL><DEDENT>chg = atom.GetFormalCharge()<EOL>if chg > <NUM_LIT:0>:<EOL><INDENT>pos_remainder += chg<EOL><DEDENT>elif chg < <NUM_LIT:0>:<EOL><INDENT>neg_count += -chg<EOL><DEDENT><DEDENT>neg_skip = self._get_neg_skip(mol, pos_remainder)<EOL>for atom in mol.GetAtoms():<EOL><INDENT>log.info(atom.GetIdx())<EOL>if atom.GetIdx() in neg_skip:<EOL><INDENT>continue<EOL><DEDENT>while atom.GetFormalCharge() < <NUM_LIT:0> and neg_count > pos_remainder:<EOL><INDENT>atom.SetNumExplicitHs(atom.GetNumExplicitHs() + <NUM_LIT:1>)<EOL>atom.SetFormalCharge(atom.GetFormalCharge() + <NUM_LIT:1>)<EOL>neg_count -= <NUM_LIT:1><EOL>log.info('<STR_LIT>')<EOL><DEDENT><DEDENT>return mol<EOL>

Neutralize molecule by adding/removing hydrogens.

        :param mol: The molecule to uncharge.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The uncharged molecule.
        :rtype: rdkit.Chem.rdchem.Mol


def _get_neg_skip(self, mol, pos_count):

neg_skip = set()<EOL>if pos_count:<EOL><INDENT>for occurrence in mol.GetSubstructMatches(self.nitro):<EOL><INDENT>neg_skip.add(occurrence[-<NUM_LIT:1>])<EOL>if len(neg_skip) >= pos_count:<EOL><INDENT>return neg_skip<EOL><DEDENT><DEDENT>for position, pair in enumerate(self.acid_base_pairs):<EOL><INDENT>for occurrence in mol.GetSubstructMatches(pair.base):<EOL><INDENT>neg_skip.add(occurrence[-<NUM_LIT:1>])<EOL>if len(neg_skip) >= pos_count:<EOL><INDENT>return neg_skip<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return neg_skip<EOL>

Get negatively charged atoms to skip (up to pos_count).


mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Standardizer(prefer_organic=prefer_organic).fragment_parent(mol)<EOL>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL>

Utility function that returns the fragment parent SMILES for given a SMILES string.


mol = Chem.MolFromSmiles(smiles)<EOL>mol = FragmentRemover(leave_last=leave_last).remove(mol)<EOL>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL>

Utility function that returns the result SMILES after FragmentRemover is applied to given a SMILES string.


mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Normalizer().normalize(mol)<EOL>if mol:<EOL><INDENT>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL><DEDENT>

Utility function that runs normalization rules on a given a SMILES string.


mol = Chem.MolFromSmiles(smiles, sanitize=False)<EOL>mol = Standardizer(prefer_organic=prefer_organic).charge_parent(mol)<EOL>if mol:<EOL><INDENT>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL><DEDENT>

Utility function that returns the charge parent SMILES for given a SMILES string.


mol = Chem.MolFromSmiles(smiles)<EOL>u = Uncharger()<EOL>mol = u.uncharge(mol)<EOL>if mol:<EOL><INDENT>return Chem.MolToSmiles(mol, isomericSmiles=True)<EOL><DEDENT>

Utility function that returns the uncharged SMILES for a given SMILES string.


if (word not in self.transmissions):<EOL><INDENT>raise NoMatchError('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>trans = self.transmissions[word]<EOL>return sorted(((k, v) for k, v in trans.items() if v != <NUM_LIT:0>), <EOL>reverse=True)<EOL><DEDENT>

pass in a word string that you
would like to see probable matches for.


tdict = []<EOL>tokens = []<EOL>d = open(data, '<STR_LIT:r>')<EOL>for line in d.readlines():<EOL><INDENT>tdict.append(line.rstrip())<EOL>tokens += line.split()<EOL><DEDENT>d.close()<EOL>tokens = list(set(tokens))<EOL>return tdict, tokens<EOL>

this converts the readin lines from
sys to useable format, returns list
of token and dict of tokens


probs = {}<EOL>transmissions = {}<EOL>for word in self.en_words:<EOL><INDENT>word_poss = []<EOL>for sent in self.en_dict:<EOL><INDENT>if word in sent:<EOL><INDENT>matching = self.de_dict[self.en_dict.index(sent)]<EOL>word_poss = word_poss + matching.split()<EOL><DEDENT><DEDENT>word_poss = list(set(word_poss))<EOL>probs[word] = word_poss<EOL><DEDENT>self.probs = probs<EOL>print(self.probs)<EOL>for word in self.en_words:<EOL><INDENT>word_probs = self.probs[word]<EOL>if (len(word_probs) == <NUM_LIT:0>):<EOL><INDENT>print(word, word_probs)<EOL><DEDENT>uniform_prob = <NUM_LIT:1.0> / len(word_probs)<EOL>word_probs = dict([(w, uniform_prob) for w in word_probs])<EOL>transmissions[word] = word_probs<EOL><DEDENT>self.transmissions = transmissions<EOL>

get all probable matches
and then initialize t(f|e)