def _set_marks(container: i3ipc.Con, marks: List[str]):
    container.marks = marks
    if not marks:
        return
    container.command('mark "{}"'.format(marks[0]))
    for mark in marks[1:]:
        _add_mark(container, mark)
def adjust_container(container: i3ipc.Con, ideal_dim: float,
                     direction: str) -> Tuple[str, i3ipc.CommandReply, float]:
    """
    Function to deterministically adjust a single container

    Args:
        container (i3ipc.Con): i3ipc.Container to adjust
        ideal_dim (float): Target dimension in pixels
        direction (str): Direction in which growing/shrinking should happen

    Returns:
        msg (str): Command sent out to i3
        reply (i3ipc.CommandReply): Reply of resizing command given to i3
        diff (float): Difference metric applied in resizing
    """
    # Retrieve dimensions of provided container
    current_dims = [container.rect.width, container.rect.height]
    # Adjust containers by either resizing rightwards or downwards
    # since i3 tree layout provides containers from left to right
    # and consequently from upwards to downwards
    if direction == "width":
        # If width is to be adjusted, compute difference and adjust
        diff = ideal_dim - current_dims[0]
        if diff >= 0:
            msg = "resize grow right %d px" % diff
        else:
            msg = "resize shrink right %d px" % abs(diff)
    elif direction == "height":
        # If height is to be adjusted, compute difference and adjust
        diff = ideal_dim - current_dims[1]
        if diff >= 0:
            msg = "resize grow down %d px" % diff
        else:
            msg = "resize shrink down %d px" % abs(diff)
    # Capture the reply of the command to check success
    reply = container.command(msg)
    # Return both reply and the actual message, in case an error occurs
    return msg, reply, diff
def _add_mark(container: i3ipc.Con, mark: str):
    container.command('mark --add "{}"'.format(mark))