def main():

    for side in ['L','R']:
        attribute_name = 'ikFk'

        joint = 'locator_foot_%s' % side

        cmds.addAttr('CNT_FOOT_ROLL_1_%s' % side, ln = attribute_name, min = 0, max = 1, k = True)
        cmds.connectAttr('CNT_FOOT_ROLL_1_%s.%s' % (side, attribute_name), '%s.switch' % joint)
        cmds.connectAttr('%s.switch' % joint, 'joint_leg_%s.switch' % side)

        #This is needed so it doesn't get hidden with the ik/fk switching.
        cmds.parent('xform_CNT_FOOT_ROLL_1_%s' % side, 'CNT_SUB_GROUND_2_C')


import pygame

from configs import get_value, add_from_dict, get_config_dict, add_value
from default_configs import fonts as default_fonts

fonts = {}
break_chars = get_value("DISPLAY", "Text", "break-chars",
                        r"-.!?+=_,:;()[]{}`~@\\$%^&*|<>")
default_color = get_value("DISPLAY", "Textboxes", "color", (255, 255, 255))
default_border_size = get_value("DISPLAY", "Textboxes", "border-size", -1)
default_scroll_amount = get_value("DISPLAY", "Textboxes", "scroll-amount", .5)
default_zoom_scale = get_value("DISPLAY", "Textboxes", "zoom-scale", 1)
min_font_size = get_value("DISPLAY", "Text", "min-font-size", 3)
max_font_size = get_value("DISPLAY", "Text", "max-font-size", 500)

def reload_fonts():
    """Pulls the latest fonts from the config"""
    global fonts
    fonts = {}

def get_font_dict(font_name, font_resize=0):
    """Updates font dict to include font object and returns dict"""
    global fonts

    actual_size = None

    if isinstance(font_name, type(None)):
        font_name = "default"
    if font_name not in fonts:
        # Update fonts if not in list
        add_from_dict(
            default_fonts)  # Update config to include all default fonts
        fonts = get_config_dict()[
            "FONTS"]  # Update fonts list to include conf fonts
        if font_name not in fonts:
            # Font missing from default)_fonts/config
            raise Exception("Font: '" + font_name + "' not found in fonts list")
    # font_name is in fonts
    if "font object" not in fonts[font_name] or font_resize != 0:
        # Need to add pygame font object to font's dict.
        # has not been created yet

        # Get/add each necessary variable to fonts dict
        if "bold" not in fonts[font_name]:
            fonts[font_name]["bold"] = False
        font_bold = fonts[font_name]["bold"]

        if "italic" not in fonts[font_name]:
            fonts[font_name]["italic"] = False
        font_italic = fonts[font_name]["italic"]

        if "size" not in fonts[font_name]:
            fonts[font_name]["size"] = fonts["Default"]["size"]
        font_size = fonts[font_name]["size"]

        if "color" not in fonts[font_name]:
            fonts[font_name]["color"] = fonts["Default"]["color"]

        if "highlight color" not in fonts[font_name]:
            fonts[font_name]["highlight color"] = None

        try:
            # Create the font
            new_font_size = font_size + int(font_resize)
            actual_size = min(max(new_font_size, min_font_size), max_font_size)
            font = pygame.font.SysFont(fonts[font_name]["name"], actual_size,
                                       font_bold,
                                       font_italic)
        except OSError:
            if font_name == "Default":
                raise Exception("Default font could not be loaded. "
                                "Change in config.")
            # Font is not default, use default instead
            print("Could not load font: '" + font_name + ",' using Default "
                                                         "font instead.")
            font, actual_size = get_font_dict("Default")
            font = font["font object"]
        fonts[font_name]["font object"] = font

    return fonts[font_name], actual_size

class Text(object):
    """Stores variables and methods for displaying pygame text"""

    def __init__(self, text="\n", font_name=None, hover_text_list=None,
                 animations=None):
        self.text = text
        self.whole = text
        self.font_name = font_name
        self.hover_text_list = hover_text_list
        self.pos = None
        self.label = None
        self.width = None
        self.height = None

        self.color_override = None
        self.font_resize = 0

        self.animations = animations
        if isinstance(animations, type(None)):
            self.animations = []

    def set_color(self, color, perma=False):
        if perma:
            fonts[self.font_name]["color"] = color
        self.color_override = color
        self.label = None

    def resize(self, size, perma=False):
        font_dict, actual_size = get_font_dict(self.font_name)
        old_size = font_dict["size"]
        self.font_resize = size - old_size
        self.label = None
        if perma:
            fonts[self.font_name]["size"] = size

    def get_color(self):
        font_dict, actual_size = get_font_dict(self.font_name)
        return font_dict["color"]

    def get_text(self):
        return self.text

    def copy(self, text=None):
        """Returns a copy of the text object with new text"""
        if isinstance(text, type(None)):
            text = self.text
        new_text = Text(text, self.font_name, self.hover_text_list)
        new_text.whole = self.whole
        new_text.animations = self.animations
        new_text.font_resize = self.font_resize
        new_text.color_override = self.color_override
        return new_text

    def break_line(self, remaining_width, font_resize=0):
        """Breaks into two texts where overflows remaining_width"""
        word = ""
        dash = ""
        for char in self.text:
            word += char
            if self.copy(word).get_dimensions(font_resize)[0] > remaining_width:
                if len(word) >= 3 and word[-3] != " ":
                    dash = "-"
                    word = word[:-2]
                else:
                    word = word[:-1]
                break
        word2 = self.text[len(word):]
        return self.copy(word + dash), self.copy(word2)

    def break_chars(self, break_char="\n"):
        """Breaks text into separate words at break_char"""
        words = []
        word = ""
        i = 0
        for char in self.text:
            i += 1
            word += char
            if char == break_char or len(self.text) == i:
                words.append(self.copy(word))
                word = ""
        return words

    def get_dimensions(self, font_resize=0):
        """Returns dimensions of text, generates new dimensions if necessary"""
        if isinstance(self.width, type(None)):
            font, actual_size = get_font_dict(self.font_name, font_resize)
            font = font["font object"]
            self.width, self.height = font.size(self.text)
        return self.width, self.height

    def get_label(self, font_resize=0):
        """Generates if necessary and returns a label

        :param font_resize: amount to resize fonts by for zooming
        """
        actual_size = None

        if isinstance(self.label, type(None)) or font_resize != 0:
            font_dict, actual_size = get_font_dict(self.font_name, font_resize)
            font = font_dict["font object"]
            color = font_dict["color"]
            if not isinstance(self.color_override, type(None)):
                color = self.color_override
            self.label = font.render(self.text.strip().replace("\n", ""), 1,
                                     color, font_dict["highlight color"])
        return self.label, actual_size

    def clear_for_pickle(self):
        """Clears the label in order to not mess with the pickling process"""
        self.label = None

    def render(self, display, pos, font_resize):
        """Renders text to given display"""
        self.pos = pos
        _font_resize = font_resize
        if self.font_resize != 0:
            _font_resize = self.font_resize
        label, actual_size = self.get_label(_font_resize)
        display.blit(label, pos)
        return actual_size

    def is_hovered(self, mouse_pos):
        """Checks whether text is being hovered"""
        if isinstance(self.pos, type(None)):
            print("Warning: Text not yet rendered when click attempted")
            # TODO: Does this ever occur and is it a problem?
            return False
        width, height = self.get_dimensions()
        if self.pos[0] <= mouse_pos[0] <= self.pos[0] + width:
            if self.pos[1] <= mouse_pos[1] <= self.pos[1] + height:
                return True
        return False

    def get_hover_text(self):
        return self.hover_text_list

class Textbox:

    def __init__(self, x_pin, y_pin, x2_pin, y2_pin, text_list=None, name=None,
                 color=None, border_size=None, scroll_amount=None,
                 zoom_scale=None, allow_zoom=False):
        self.name = name
        self.x_pin = x_pin
        self.y_pin = y_pin
        self.x2_pin = x2_pin
        self.y2_pin = y2_pin

        self.color = color
        if isinstance(color, type(None)):
            self.color = default_color
        self.border_size = border_size
        if isinstance(border_size, type(None)):
            self.border_size = default_border_size
        self.scroll_amount = scroll_amount  # Number of lines to scroll
        if isinstance(scroll_amount, type(None)):
            self.scroll_amount = default_scroll_amount
        self.zoom_scale = zoom_scale  # Multiply zoom amount by this
        if isinstance(zoom_scale, type(None)):
            self.zoom_scale = default_zoom_scale

        self.text_list = []
        self.whole_text_list = []
        if not isinstance(text_list, type(None)):
            self.add_text_list(text_list)
        self.lines = []
        self.line_num = 0  # Current line scroll is on
        self.current_scroll = 0
        # ^ Must reach 1/self.scroll_amount if self.scroll_amount < 0 to scroll

        self.width = None
        self.height = None
        self.screen_width = None
        self.screen_height = None

        self.font_resize = 0
        self.zoom_amount = 0

        self.zoom_switch = None
        self.zoom_limit = None

        self.allow_zoom = allow_zoom

        self.rect = None

        # TODO: Allow saving of multiple self.lines for easily redisplaying tooltips?

    def get_all_contained_texts(self):
        texts = []
        texts += self.text_list
        texts += self.whole_text_list
        for line in self.lines:
            texts += line
        return texts

    def get_color(self):
        for text in self.whole_text_list:
            if "color" in text.animations:
                return text.get_color()
        return self.whole_text_list[0].get_color()

    def set_color(self, color, perma=False):
        for text in self.get_all_contained_texts():
            if "color" in text.animations:
                text.set_color(color, perma)

    def resize(self, size, perma=False):
        for text in self.get_all_contained_texts():
            if "size" in text.animations:
                text.resize(size, perma)
        self.rewrap()

    def get_pos(self):
        if isinstance(self.rect, type(None)):
            return None
        return list(int(val) for val in self.rect)

    def set_pos(self, point):
        """Moves upper left corner to point"""
        self.x_pin = point[0] / self.screen_width
        self.y_pin = point[1] / self.screen_height
        self.x2_pin = (point[0] + self.rect[1]) / self.screen_width
        self.y2_pin = (point[1] + self.rect[3]) / self.screen_height

    def within_bounds(self, pos, display):
        width = display.get_width()
        height = display.get_height()
        bounds = [int(self.x_pin * width),
                  int(self.y_pin * height),
                  int(self.x2_pin * width),
                  int(self.y2_pin * height)]

        if bounds[2] >= pos[0] >= bounds[0]:
            if bounds[3] >= pos[1] >= bounds[1]:
                return True
        return False

    def handle_event(self, event, display):
        cursor_pos = pygame.mouse.get_pos()
        if self.within_bounds(cursor_pos, display):
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 4:
                    # Scroll down in box
                    self.scroll(False)
                elif event.button == 5:
                    # Scroll up in box
                    self.scroll()

    def scroll(self, up=True):
        # Allow for scroll amounts of less than zero which scroll every interval
        ctrl_held = pygame.key.get_mods() & pygame.KMOD_CTRL
        if ctrl_held and self.allow_zoom:
            if not up:
                if self.zoom_limit != 1:
                    # Zoom instead of scroll
                    if self.zoom_limit == -1:
                        self.zoom_limit = None
                    if self.zoom_switch == -1:
                        self.zoom_amount = 0
                    self.zoom_switch = 1
                    if self.zoom_amount == 0:
                        self.zoom_amount = self.zoom_scale
                    self.zoom_amount *= self.zoom_scale
                    self.zoom_amount *= self.zoom_scale
                    self.font_resize += self.zoom_amount
                    self.rewrap()
            else:
                if self.zoom_limit != -1:
                    if self.zoom_limit == 1:
                        self.zoom_limit = None
                    if self.zoom_switch == 1:
                        self.zoom_amount = 0
                    self.zoom_switch = -1
                    if self.zoom_amount == 0:
                        self.zoom_amount = self.zoom_scale
                    self.zoom_amount *= self.zoom_scale
                    self.font_resize -= self.zoom_amount
                    self.rewrap()
        else:
            scroll_int = 0
            scroll_amount = self.scroll_amount
            if self.scroll_amount < 1:
                scroll_int = 1 / self.scroll_amount
                scroll_amount = 1
            self.current_scroll += 1
            if self.current_scroll >= scroll_int:
                self.current_scroll = 0
                if not up:
                    self.line_num -= int(scroll_amount)
                else:
                    self.line_num += int(scroll_amount)
                self.check_scroll()

    def add_text_list(self, text_list):
        self.text_list += text_list
        self.whole_text_list += text_list

    def get_dimensions(self):
        if isinstance(self.width, type(None)):
            raise Exception("Access to dimensions attempted before rendering "
                            "for textbox: '" + self.name + "'.")
        return self.width, self.height

    def update_dimensions(self, display):
        # Update dimensions if necessary
        width = display.get_width()
        height = display.get_height()
        changed = False
        if width != self.screen_width:
            # Width has been changed
            self.screen_width = width
            self.width = (self.x2_pin * width) - (self.x_pin * width)
            changed = True
        if height != self.screen_height:
            # Width has been changed
            self.screen_height = height
            self.height = (self.y2_pin * height) - (self.y_pin * height)
            changed = True
        if changed:
            self.rewrap()

    def render(self, display):
        self.update_dimensions(display)  # Will always rewrap on first render
        self.wrap()

        x = self.x_pin * display.get_width()
        y = self.y_pin * display.get_height()
        x2 = self.x2_pin * display.get_width()
        y2 = self.y2_pin * display.get_height()
        rect = [x, y, x2 - x, y2 - y]

        self.rect = rect

        pygame.draw.rect(display, self.color, rect, self.border_size)
        self.check_scroll()

        _y = y
        for line in self.lines[self.line_num:]:
            line_height = self.get_line_dimensions(line)[1]
            if _y + line_height > y2:
                break
            else:
                _x = x
                for word in line:
                    word_size = word.render(display, (_x, _y), self.font_resize)
                    if not isinstance(word_size, type(None)):
                        if word_size == max_font_size:
                            self.zoom_limit = 1
                        elif word_size == min_font_size:
                            self.zoom_limit = -1
                    _x += word.get_dimensions(self.font_resize)[0]
            _y += line_height
        if not isinstance(self.zoom_limit, type(None)):
            self.zoom_amount = 0

    def get_line_dimensions(self, line=None):
        if isinstance(line, type(None)):
            line = self.lines[0]
        height = 0
        width = 0
        for word in line:
            height = max(height, word.get_dimensions(self.font_resize)[1])
            width += word.get_dimensions(self.font_resize)[0]
        return width, height

    def check_scroll(self):
        if self.line_num >= len(self.lines):
            self.line_num = len(self.lines) - 1
        if self.line_num < 0:
            self.line_num = 0

    def rewrap(self):
        """Rewraps all lines in the event of a resolution change."""
        self.lines = []
        self.text_list = self.whole_text_list[:]
        self.wrap()

    def check_line_can_fit(self, text):
        """Checks whether given text can fit in last line"""
        if len(self.lines[-1]) > 0 and self.lines[-1][-1].get_text().endswith(
                "\n"):
            return False  # Last line ended with new line char
        width = 0
        for _text in self.lines[-1]:
            width += _text.get_dimensions(self.font_resize)[0]
        if width + text.get_dimensions(self.font_resize)[0] <= \
                self.get_dimensions()[0]:
            return True
        return False

    def wrap(self):
        """Wraps all text left in text_list, does not affect previous lines
        except where new text fits on last line.
        """
        break_char_ind = 0
        while len(self.text_list) > 0:
            text = self.text_list.pop(0)  # Get first text in queue
            words = text.break_chars()  # Break at newlines
            while len(words) > 0:
                word = words[0]

                # Add initial line
                if len(self.lines) == 0:
                    self.lines.append([])
                    continue

                # Check if fits on previous line
                elif self.check_line_can_fit(word):
                    # It fits, don't continue
                    self.lines[-1].append(word)

                # Try breaking at spaces
                elif " " in word.get_text()[1:-1]:
                    # Test whether space is within word (not at ends)
                    words.pop(0)
                    for w in word.break_chars(" ")[::-1]:
                        words.insert(0, w)
                    continue

                # Try making new line
                elif len(self.lines[-1]) > 0:
                    self.lines.append([])
                    continue

                # Try breaking at break chars
                elif break_char_ind < len(break_chars):
                    break_char = break_chars[break_char_ind]
                    if break_char in word.get_text()[1:-1]:
                        # Test whether char is within word (not at ends)
                        words.pop(0)
                        for w in word.break_chars(break_char)[::-1]:
                            words.insert(0, w)
                    break_char_ind += 1
                    continue

                # Try breaking at char closest to edge
                else:
                    char_width = word.copy("W").get_dimensions(
                        self.font_resize)[0]

                    if char_width <= self.width:
                        # Single char can fit on screen
                        if len(self.lines[-1]) == 0 and len(self.lines) > 1:
                            # Remove previously added empty line
                            self.lines.pop()
                        previous_width = self.get_line_dimensions(self.lines[
                                                                      -1])[0]
                        char_line_width = previous_width + char_width
                        can_fit_char = char_line_width < self.width
                        previous_line_exists = len(self.lines[-1]) > 0
                        previous_newline = False
                        if previous_line_exists:
                            previous_newline = self.lines[-1][-1].get_text(). \
                                endswith("\n")
                        if previous_line_exists and can_fit_char \
                                and not previous_newline:
                            # Previous line has room for chars,
                            # not newline char
                            words.pop(0)
                            for w in word.break_line(
                                    self.width - previous_width,
                                    self.font_resize)[::-1]:
                                words.insert(0, w)
                            continue
                        else:
                            self.lines.append([])
                            words.pop(0)
                            for w in word.break_line(self.width,
                                                     self.font_resize)[::-1]:
                                words.insert(0, w)
                            continue
                    else:
                        # Skip word, font too large
                        pass

                # TODO: Wrap at wrap points

                # Word was added, did not continue
                break_char_ind = 0
                words.pop(0)
                if word.get_text().endswith("\n"):
                    self.lines.append([])


import os
import os.path as op
import shutil
import yaml
from pybombs.commands import CommandBase
from pybombs.utils import dict_merge
from pybombs.utils import subproc
from pybombs.utils import confirm
from pybombs import fetcher

### Parser Helpers
def setup_subsubparser_initsdk(parser):
    parser.add_argument(
        'sdkname',
        help="SDK Package Name",
        nargs=1,
    )

def setup_subsubparser_init(parser):
    parser.add_argument(
        'path',
        help="Path to the new prefix (defaults to CWD).",
        nargs="?",
        default=os.getcwd(),
    )
    parser.add_argument(
        '--sdk',
        dest='sdkname',
        help="Initialize prefix with SDK Package",
    )
    parser.add_argument(
        '-a', '--alias',
        help="If specified, store an alias to this new prefix in the local config file.",
    )
    parser.add_argument(
        '--virtualenv', action='store_true',
        help="Use this to make the new prefix also a virtualenv. Args for virtualenv may be passed in here",
    )

### Class definition
class Prefix(CommandBase):
    """
    Prefix operations
    """
    cmds = {
        'prefix': 'Prefix commands',
    }

    @staticmethod
    def setup_subparser(parser, cmd=None):
        """
        Set up a subparser for a specific command
        """
        ###### Start of setup_subparser()
        subparsers = parser.add_subparsers(
                help="Prefix Commands:",
                dest='prefix_command',
        )
        for cmd_name, cmd_info in Prefix.prefix_cmd_name_list.iteritems():
            subparser = subparsers.add_parser(
                    cmd_name,
                    help=cmd_info['help']
            )
            cmd_info['parser'](subparser)
        return parser

    def __init__(self, cmd, args):
        CommandBase.__init__(self,
                cmd, args,
                load_recipes=True,
                require_prefix=(args.prefix_command != 'init'),
        )

    def run(self):
        """ Go, go, go! """
        self.prefix_cmd_name_list[self.args.prefix_command]['run'](self)

    def _print_prefix_info(self):
        """
        pybombs prefix info
        """
        self.log.info('Prefix dir: {}'.format(self.prefix.prefix_dir))

    def _print_prefix_env(self):
        """
        pybombs prefix env
        """
        print('Prefix env:')
        for k, v in self.prefix.env.iteritems():
            print("{}={}".format(k, v))

    def _run_installsdk(self):
        """
        pybombs prefix install-sdk
        """
        self._install_sdk_to_prefix(
            self.args.sdkname[0],
        )

    def _run_init(self):
        """
        pybombs prefix init
        """
        # Make sure the directory is writable
        path = op.abspath(op.normpath(self.args.path))
        if not op.isdir(path):
            self.log.info("Creating directory `{0}'".format(path))
            os.mkdir(path)
        assert op.isdir(path)
        if not os.access(path, os.W_OK|os.X_OK):
            self.log.error("Cannot write to prefix path `{0}'.".format(path))
            exit(1)

        # Make sure that a pybombs directory doesn't already exist
        test_path = op.join(path, ".pybombs")
        if op.exists(test_path):
            self.log.error("Ignoring. A prefix already exists in `{0}'".format(path))
            return

        # Copy template
        # TODO: I'm not too happy about this, all the hard coded stuff. Needs
        # cleaning up, for sure. Especially that setup_env.sh stuff at the end.
        # Ideally, we could switch prefix templates.
        self.log.info("Initializing PyBOMBS prefix in `{0}'...".format(path))
        skel_dir = op.join(self.cfg.module_dir, 'skel')
        for p in os.listdir(skel_dir):
            if op.exists(op.join(path, p)):
                self.log.obnoxious("Skipping {0}".format(p))
                continue
            self.log.obnoxious("Copying {0}".format(p))
            p_full = op.join(skel_dir, p)
            if op.isdir(p_full):
                shutil.copytree(
                    p_full, op.join(path, p),
                    ignore=shutil.ignore_patterns('.ignore')
                )
            else:
                shutil.copy(p_full, path)
        open(op.join(path, 'setup_env.sh'), 'w').write(
            open(op.join(skel_dir, 'setup_env.sh')).read().format(
                prefix_dir=path,
            )
        )
        # Register alias
        if self.args.alias is not None:
            if self.prefix is not None and \
                self.prefix.prefix_aliases.get(self.args.alias) is not None \
                and not confirm("Alias `{0}' already exists, overwrite?".format(self.args.alias)):
                    self.log.warn('Aborting.')
                    return 1
            self.cfg.update_cfg_file({'prefix_aliases': {self.args.alias: path}})
        # Create virtualenv if so desired
        if self.args.virtualenv:
            self.log.info("Creating Python virtualenv in prefix...")
            venv_args = ['virtualenv']
            venv_args.append(path)
            subproc.monitor_process(args=venv_args)
        # Install SDK if so desired
        if self.args.sdkname is not None:
            self.log.info("Reloading configuration...")
            self.cfg.load(select_prefix=path)
            self.prefix = self.cfg.get_active_prefix()
            self.inventory = self.prefix.inventory
            self._install_sdk_to_prefix(self.args.sdkname)

    def _install_sdk_to_prefix(self, sdkname):
        """
        Read recipe for sdkname, and install the SDK to the prefix.
        """
        from pybombs import recipe
        src_dir = self.prefix.src_dir
        cfg_file = self.prefix.cfg_file
        ### Get the recipe
        r = recipe.get_recipe(sdkname, target='sdk')
        try:
            self.log.obnoxious("Switching CWD to {0}".format(src_dir))
            if not op.isdir(src_dir):
                os.mkdir(src_dir)
            os.chdir(src_dir)
        except:
            self.log.error("Source dir required to install SDK.")
            return -1
        ### Install the actual SDK file
        self.log.debug("Fetching SDK `{sdk}'".format(sdk=sdkname))
        fetcher.Fetcher().fetch(r)
        self.log.info("Installing SDK `{sdk}'".format(sdk=sdkname))
        # Install command
        cmd = r.var_replace_all(r.get_command('install'))
        if subproc.monitor_process(cmd, shell=True, env=os.environ) == 0:
            self.log.debug("Installation successful")
        else:
            self.log.error("Error installing SDK. Aborting.")
            return -1
        # Clean up
        files_to_delete = [op.normpath(op.join(src_dir, r.var_replace_all(x))) for x in r.clean]
        if len(files_to_delete):
            self.log.info("Cleaning up files...")
        for ftd in files_to_delete:
            if op.commonprefix((src_dir, ftd)) != src_dir:
                self.log.warn("Not removing {ftd} -- outside source dir!".format(ftd=ftd))
                continue
            self.log.debug("Removing {ftd}...".format(ftd=ftd))
            if op.isdir(ftd):
                shutil.rmtree(ftd)
            elif op.isfile(ftd):
                os.remove(ftd)
            else:
                self.log.error("Not sure what this is: {ftd}".format(ftd=ftd))
                return -1
        ### Update the prefix-local config file
        self.log.debug("Updating config file with SDK recipe info.")
        try:
            old_cfg_data = yaml.safe_load(open(cfg_file).read()) or {}
        except IOError:
            self.log.debug("There doesn't seem to be a config file yet for this prefix.")
            old_cfg_data = {}
        # Filter out keys we don't care about:
        sdk_recipe_keys_for_config = ('config', 'packages', 'categories', 'env')
        sdk_cfg_data = {k: v for k, v in r.get_dict().iteritems() if k in sdk_recipe_keys_for_config}
        self.log.obnoxious("New data: {new}".format(new=sdk_cfg_data))
        cfg_data = dict_merge(old_cfg_data, sdk_cfg_data)
        self.log.debug("Writing updated prefix config to `{0}'".format(cfg_file))
        open(cfg_file, 'wb').write(yaml.dump(cfg_data, default_flow_style=False))

    #########################################################################
    # Sub-commands:
    prefix_cmd_name_list = {
        'info': {
            'help': 'Display information on the currently used prefix.',
            'parser': lambda p: None,
            'run': _print_prefix_info,
        },
        'init': {
            'help': 'Create and initialize a prefix.',
            'parser': setup_subsubparser_init,
            'run': _run_init,
        },
        'env': {
            'help': 'Print the environment variables used in this prefix.',
            'parser': lambda p: None,
            'run': _print_prefix_info,
        },
        'install-sdk': {
            'help': 'Install an SDK into the prefix.',
            'parser': setup_subsubparser_initsdk,
            'run': _run_installsdk,
        },
    }
    #########################################################################


import argparse
import os

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--file', default=None, type=str, help="path to txt file that we want to split")
parser.add_argument('--num', default=2, type=int, help="number of target files")
parser.add_argument('--output-dir', default='output', type=str, help='dir to store output files')

args = parser.parse_args()
assert args.file, "file path is nesserary."

if not os.path.exists(args.output_dir):
    os.makedirs(args.output_dir)

input_filename = args.file.split('/')[-1].split('.')[0]
output_filenames = [input_filename + '_' + str(i) for i in range(args.num)]

file_counter = 0
with open(args.file, 'r') as f_in:
    full_lines = f_in.readlines()
    assert len(full_lines) % args.num == 0, 'cannot split into %d files with %d lines input.' % (args.num, len(full_lines))
    each_num = len(full_lines) // args.num
    line_counter = 0
    for line in full_lines:
        line = line.strip()
        if line_counter >= each_num:
            file_counter += 1
            line_counter = 0
        output_file = os.path.join(args.output_dir, output_filenames[file_counter] + '.txt')
        with open(output_file, 'a') as f_out:
            f_out.writelines(line + '\n')
        line_counter += 1


# -*- coding: utf-8 -*-
"""
Created on Sun Feb 19 13:21:29 2023

@author: JSS-SHN
"""

import hashlib
from tkinter import *
from tkinter import filedialog

# create a tkinter window
root = Tk()
root.title("File Encryption System")
root.geometry("500x300")
root.config(bg="#e6e6e6")

# function to apply MD5 hash algorithm
def apply_md5():
    # open file dialog to select a text file
    text_file = filedialog.askopenfilename(title="Select a Text File", filetypes=(("Text Files", "*.txt"),))
    print(f"Selected File: {text_file}")

    # read the contents of the file
    with open(text_file, 'r') as f:
        contents = f.read()
        contents = contents.encode('utf-8')

    # apply md5 algorithm on the contents of the file
    md5_hash = hashlib.md5(contents).hexdigest()
    print(f"MD5 Hash: {md5_hash}")

    # create a new file to store the md5 hash
    with open('md5.txt', 'w') as f:
        f.write(md5_hash)

# function to apply SHA256 hash algorithm
def apply_sha256():
    # open file dialog to select a text file
    text_file = filedialog.askopenfilename(title="Select a Text File", filetypes=(("Text Files", "*.txt"),))
    print(f"Selected File: {text_file}")

    # read the contents of the file
    with open(text_file, 'r') as f:
        contents = f.read()
        contents = contents.encode('utf-8')

    # apply sha256 algorithm on the contents of the file
    sha256_hash = hashlib.sha256(contents).hexdigest()
    print(f"SHA256 Hash: {sha256_hash}")

    # create a new file to store the sha256 hash
    with open('sha256.txt', 'w') as f:
        f.write(sha256_hash)

# create a button to apply md5 algorithm
btn = Button(root, text="Apply MD5", bg="gray", fg="white", relief=FLAT, command=apply_md5)
btn.pack(pady=10)

# create a button to apply sha256 algorithm
btn1 = Button(root, text="Apply SHA256", bg="gray", fg="white", relief=FLAT, command=apply_sha256)
btn1.pack(pady=10)

root.mainloop()


import numpy as np
import pandas as pd
import pytest
import os
import sys

current_path = os.path.dirname(os.path.abspath(__file__))
new_path = os.path.join(current_path, "..")
sys.path.append(new_path)

from sbc import sbc_class

data = pd.read_csv("data/sales_train_clean.csv")

def test_raise_empty_data_df():
    ## ndim == 2
    input_data = pd.DataFrame()
    with pytest.raises(ValueError):
        sbc_class.sbc_class(input_data)

def test_raise_empty_data_list():
    ## ndim == 1
    input_data = []
    with pytest.raises(ValueError):
        sbc_class.sbc_class(input_data)

def test_null_object():
    input_data = None
    with pytest.raises(ValueError):
        sbc_class.sbc_class(input_data)

def test_plot_value():
    df = data.iloc[:,1:3]
    type = ['line_plot']
    with pytest.raises(ValueError):
        sbc_class.sbc_class(df, plot_type=type)

def test_reproducible():
    df = data.iloc[:, 1]
    df1 = data.iloc[:,1]
    out1 = sbc_class.sbc_class(df)
    out2 = sbc_class.sbc_class(df1)

    assert out1.equals(out2)


import arcpy
from tempfile import mkdtemp
from os import remove, rmdir
from urllib2 import Request, urlopen, HTTPHandler, build_opener
from base64 import b64encode
from json import dumps
previewPage = """
<!doctype html>

		<meta charset='utf-8'/>
		<title>
			ESRI To Couch
		</title>
		<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />

"""
design = dumps({
   "_id": "_design/geojson",
   "spatial": {
       "geo": "function(doc){\n       if(doc.geometry){ emit(doc.geometry,doc)};\n            }"
   },
   "views": {
       "geometry": {
           "map": "function(doc) {\n  if(doc.geometry){\nemit(doc.geometry,doc);\n}\n}"
       }
   },
   "rewrites": [
       {
           "to": "/_list/geojson/geometry",
           "from": "/all"
       },
       {
           "to": "/index.html",
           "from": "/"
       }
   ],
   "_attachments": {
        "index.html" : {
            "content_type" : "text/html",
            "data" : b64encode(previewPage)
        }
    },
   "lists": {
       "geojson": "function(head, req) {\n    var row, out, sep = '\\n';\n    if (req.headers.Accept.indexOf('application/json')!=-1) {\n        start({\"headers\":{\"Content-Type\" : \"application/json\"}});\n    }    else {\n        start({\"headers\":{\"Content-Type\" : \"text/plain\"}});\n    }\n    if ('callback' in req.query) {\n        send(req.query['callback'] + \"(\");\n    }    send('{\"type\": \"FeatureCollection\", \"features\":[');\n    while (row = getRow()) {\n        out = {type: \"Feature\", geometry: row.value.geometry};\n\t\t\t\tdelete row.value.geometry;\n               out.properties= row.value\n        send(sep + JSON.stringify(out));        sep = ',\\n';\n    }\n    send(\"]}\");\n    if ('callback' in req.query) {\n        send(\")\");}};\n"
   },
   "validate_doc_update": "function(newDoc, oldDoc, userCtx) {  if (userCtx.roles.indexOf('_admin') !== -1) {    return;  } else {    throw({forbidden: 'Only admins may edit the database'});  }}"
})

def doStuff(inFile,dbUrl,tbx,login,createDB):
    arcpy.ImportToolbox(tbx)
    base = mkdtemp()
    outFile = base+'//output.json'
    arcpy.esri2open(inFile,outFile)
    postToCouch(dbUrl,outFile,login,createDB)
    cleanUp(base,outFile)

def cleanUp(p,f):
    remove(f)
    rmdir(p)

def dealLogin(req,login):
    if login == 'NONE':
        return
    req.add_header('Authorization','Basic '+b64encode(login))

def postToCouch(url,outFile,login,createDB):
    if createDB=='true' and login != 'NONE':
        opener = build_opener(HTTPHandler)
        res3 = Request(url)
        dealLogin(res3,login)
        res3.get_method = lambda: 'PUT'
        opener.open(res3)
        arcpy.AddMessage("Created DB")
    newUrl = url + '//_bulk_docs'
    baseFile = open(outFile,'r')
    data = baseFile.read()
    baseFile.close()
    req = Request(newUrl)
    dealLogin(req,login)
    req.add_header('Content-Type', 'application/json')
    urlopen(req,data)
    arcpy.AddMessage("Added Rows")
    if login != 'NONE':
        req2 = Request(url)
        dealLogin(req2,login)
        req2.add_header('Content-Type', 'application/json')
        urlopen(req2,design)
        arcpy.AddMessage("Added Design Doc")
        arcpy.AddMessage("View it at "+url+"/_design/geojson/_rewrite/")

doStuff(arcpy.GetParameterAsText(0),arcpy.GetParameterAsText(1),arcpy.GetParameterAsText(2),arcpy.GetParameterAsText(3),arcpy.GetParameterAsText(4))


#列表元素可以按照某种算法推算出来，那可以在循环的过程中不断推算出后续的元素
#这样就不必创建完整的list，从而节省大量的空间。

L = [x * x for x in range(10)];
print(L); #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

g = (x * x for x in range(10));
print(g); #<generator object <genexpr> at 0x000002086AEC6ED0>

print(next(g));

#著名的斐波拉契数列（Fibonacci），除第一个和第二个数外，任意一个数都可由前两个数相加得到：
#1, 1, 2, 3, 5, 8, 13, 21, 34, ...

def fib(max):
    n,a,b=0,0,1
    while n <max:
        print(b)
        a,b=b,a+b
        n = n+1
    return 'done'

fib(6);

    #t = (b, a + b) # t是一个tuple
    #a = t[0]
    #b = t[1]


class Solution:
    def canMakeArithmeticProgression(self, arr: list[int]) -> bool:
        arr.sort()
        diff = arr[0] - arr[1]
        left = 0
        right = 1
        while (len(arr)) > right:
            if diff != (arr[left] - arr[right]):
                return False
            left += 1
            right += 1
        return True

arr = [0, 0]
print(Solution(). canMakeArithmeticProgression(arr=arr, ))


#program for accepting list of names and sort the names in ascending order by anonymous functions

def readvalues():
    lst=[]
    n=int(input("enter how many number of values u want: "))
    if(n<=0):
        return lst
    else:
        for i in range(1,n+1):
            value=input("enter values for list: ")
            lst.append(value)
        return lst

sort=lambda lst:sorted(lst)

res1=readvalues()
res2=sort(res1)
print(res2)


from math import ceil

T = int(input())

for i in range(T):
    floor , room , guest = map(int,input().split())
    a = guest % floor
    b = (guest // floor) +1
    if a == 0:
        a = floor
        b -= 1
    print(a*100 + b)


import sys

def check(i, preamble, array):
	for x in range(i-preamble, i):
		for y in range(i-preamble, i):
			if x is not y:
				if array[x] + array[y] == array[i]:
					return True
	return False

def solve(array, preamble):
	# from 25 to n
	for i in range(preamble, len(array)):
		if(not check(i, preamble, array)):
			return array[i]
	return 'err'

lines = []
for line in sys.stdin:
	lines.append(int(line))
print(solve(lines, 25))


import os
import json
import subprocess

git_dir = subprocess.check_output(["git","rev-parse","--show-toplevel"]).decode().strip()
text_files = [
    "SingleMuon_2018A", "SingleMuon_2018B", "TTJets_UL2018", "SingleMuon_2018C",
    "SingleMuon_2018D", "WJets_UL2018"
]
mc_dict = {
    "TTJets_UL2018": {
        "nevts_total": 296_610_126
    },
    "WJets_UL2018": {
        "nevts_total": 81_051_269
    }
}
d = {}

for dataset_name in text_files:
    file_path = os.path.join(git_dir,"analysis/samples",dataset_name + ".txt")
    fin = open(file_path, mode='r')
    is_mc = dataset_name in mc_dict

    if dataset_name.find("2016") >= 0:
        year = 2016
    elif dataset_name.find("2017") >= 0:
        year = 2017
    elif dataset_name.find("2018") >= 0:
        year = 2018
    else:
        print("No valid year found")

    # d[dataset_name] = {
        # "variations": {},
        # "is_data": True,
    # }

    d[dataset_name] = {}
    d[dataset_name]["variations"] = {}
    d[dataset_name]["is_data"] = not is_mc
    d[dataset_name]["year"] = year

    # d[dataset_name]["variations"] = {"nominal": {"nevts_total": -1, "files": []} }
    # d[dataset_name]["variations"]["nominal"] = {"nevts_total": -1, "files": []}

    if is_mc:
        numb_evts = mc_dict[dataset_name]["nevts_total"]
    else:
        numb_evts = -1

    d[dataset_name]["variations"]["nominal"] = {"nevts_total": numb_evts, "files": []}

    for x in fin.readlines():
        x = x.strip()

        y = {"path" : "root://xcache/" + x, "nevts": -1}
        print(y)
        d[dataset_name]["variations"]["nominal"]["files"].append(y)

    print(d[dataset_name]["variations"]["nominal"]["files"])

fout = open("Run2_data.json", mode = "w")
json.dump(d,fout,indent = 4)


import uuid
from enum import Enum
from http import HTTPStatus
from typing import (
    TYPE_CHECKING,
    Annotated,
    Any,
    Dict,
    Iterable,
    List,
    Optional,
    Type,
    Union,
)

import pytest
from fastapi import APIRouter, FastAPI, Query
from fastapi.params import Depends
from pydantic import BaseModel, Field
from pydantic.main import ModelMetaclass
from starlette.testclient import TestClient

from furiousapi.core.api.controllers import CBV, ModelController, action
from furiousapi.core.db.fields import SortableFieldEnum
from furiousapi.core.db.models import FuriousPydanticConfig
from furiousapi.core.db.repository import BaseRepository, RepositoryConfig
from furiousapi.core.pagination import AllPaginationStrategies, PaginatedResponse
from furiousapi.core.responses import BulkResponseModel
from furiousapi.core.types import TEntity, TModelFields

if TYPE_CHECKING:
    from fastapi.dependencies.models import Dependant
    from fastapi.routing import APIRoute

class MyCBV(CBV):
    @action("/endpoint1")
    def endpoint1(self, query_param: str = Query(...)):
        pass

    @action("/endpoint2")
    def endpoint2(self, query_param: str = Query(...)):
        pass

def test_cbv__when_no_api_router__then_initialize():
    assert isinstance(MyCBV.api_router, APIRouter)

static_api_router = APIRouter()

class MyCBV2(MyCBV):
    my_dep = Depends(lambda x: x)
    api_router = static_api_router

def test_cbv__when_api_router__then_use_it():
    assert id(MyCBV2.api_router) == id(static_api_router)

def test_cbv__actions_are_defined():
    my = MyCBV()
    assert len(MyCBV.api_router.routes) == 2  # noqa: PLR2004
    route1: APIRoute = my.api_router.routes[0]
    route2: APIRoute = my.api_router.routes[1]
    assert route1.path == "/endpoint1"
    assert route2.path == "/endpoint2"
    dependant: Dependant = route1.dependant

    assert dependant.query_params[0].type_ == str
    assert dependant.query_params[0].name == "query_param"
    assert dependant.query_params[0].required is True

def test_cbv__when_class_dependency_defined_and_not_passed__then_raise_type_error():
    with pytest.raises(TypeError):
        MyCBV2()

def test_cbv__when_class_dependency_defined__then_init_changed():
    try:
        MyCBV2(my_dep=Depends(repository_dependency))  # type: ignore[call-arg]
    except Exception:  # noqa: BLE001
        pytest.fail("something happened")

class MyModel(BaseModel):
    id: Optional[str] = Field(alias="_id")
    my_param: str

    class Config(FuriousPydanticConfig):
        pass

# TODO:
# mypy issue with Generic[TEntity]
class InMemoryDBRepository(BaseRepository[TEntity]):  # type: ignore[misc]
    def __init__(self) -> None:
        self._store: Dict[Union[str, int, Dict[str, Any], tuple], TEntity] = {}

    async def get(
        self,
        identifiers: Union[int, str, Dict[str, Any], tuple],
        fields: Optional[Iterable[Enum]] = None,  # noqa: ARG002
        *,
        should_error: bool = True,  # noqa: ARG002
    ) -> Optional[TEntity]:
        return self._store.get(identifiers)

    async def list(
        self,
        pagination: AllPaginationStrategies,  # noqa: ARG002
        fields: Optional[Iterable[TModelFields]] = None,  # noqa: ARG002
        sorting: Optional[List[SortableFieldEnum]] = None,  # noqa: ARG002
        filtering: Optional[TEntity] = None,  # noqa: ARG002
    ) -> PaginatedResponse[TEntity]:
        return PaginatedResponse[TEntity](total=len(self._store), items=list(self._store.values()), index=0, next=None)

    async def add(self, entity: TEntity) -> TEntity:

        if entity.id in self._store:  # type: ignore[attr-defined]
            raise ValueError(f"Key {entity.id} already exists")  # type: ignore[attr-defined]
        entity.id = str(uuid.uuid4())  # type: ignore[attr-defined]
        self._store[entity.id] = entity  # type: ignore[attr-defined]
        return entity

    async def update(self, entity: TEntity, **kwargs) -> Optional[TEntity]:
        if entity.id not in self._store:  # type: ignore[attr-defined]
            raise KeyError(f"Key {entity.id} does not exist")  # type: ignore[attr-defined]
        self._store[entity.id] = entity  # type: ignore[attr-defined]
        return entity

    async def delete(self, entity: Union[TEntity, str, int], **kwargs) -> None:

        if entity.id not in self._store:  # type: ignore[union-attr]
            raise KeyError(f"Key {entity.id} does not exist")  # type: ignore[union-attr]
        del self._store[entity.id]  # type: ignore[union-attr]

    async def bulk_create(self, bulk: List[TEntity]) -> BulkResponseModel:  # type: ignore[empty-body]
        pass

    async def bulk_delete(self, bulk: List[Union[TEntity, Any]]) -> List:  # type: ignore[empty-body]
        pass

    async def bulk_update(self, bulk: List[TEntity]) -> List:  # type: ignore[empty-body]
        pass

class MyRepository(InMemoryDBRepository[MyModel]):  # type: ignore[type-arg]
    class Config(RepositoryConfig):
        @staticmethod
        def model_to_query(x: Type[MyModel]) -> Type[MyModel]:
            return x

        filter_model = ModelMetaclass

repository = MyRepository()

def repository_dependency() -> MyRepository:
    return repository

class MyController(ModelController):
    repository: Depends = Depends(repository_dependency, use_cache=True)

class MyController2(ModelController):
    repository: Annotated[MyRepository, Depends] = Depends(repository_dependency)  # type: ignore[assignment]
    __enabled_routes__ = ("get",)

@pytest.fixture()
def controller() -> MyController:
    return MyController(repository=MyRepository())

def test_controller_repository__is_initialized(controller: MyController):
    assert isinstance(controller.repository, MyRepository)

def test_create(controller: MyController):
    create: APIRoute = next(filter(lambda x: x.name == "create", controller.api_router.routes))
    assert create.dependant.body_params[0].type_ == MyModel
    assert create.response_model == MyModel

def test_list(controller: MyController):
    route: APIRoute = next(filter(lambda x: x.name == "list", controller.api_router.routes))
    pagination = route.dependant.dependencies[1]
    assert pagination.name == "pagination"
    for param, dep in zip(["limit", "type", "next"], pagination.query_params):
        assert param == dep.name

    filtering = route.dependant.query_params[2]
    assert filtering.name == "filtering"

    fields = route.dependant.query_params[0]
    assert fields.name == "fields"
    assert fields.type_ is controller.repository.__fields__
    sorting = route.dependant.query_params[1]
    assert sorting.name == "sorting"
    assert sorting.type_ is controller.repository.__sort__
    assert route.response_model == PaginatedResponse[MyModel]

def test_get(controller: MyController):
    get: APIRoute = next(filter(lambda x: x.name == "get", controller.api_router.routes))
    fields = get.dependant.query_params[0]
    assert get.response_model is MyModel
    assert fields.type_ is controller.repository.__fields__

@pytest.mark.asyncio()
async def test_app():
    app = FastAPI()
    app.include_router(MyController.api_router)
    model = MyModel(my_param="1")

    client = TestClient(app)

    create_response = client.post("/", json=model.dict())
    assert create_response.status_code == HTTPStatus.OK
    doc = create_response.json()
    model.id = doc["_id"]
    get_response = client.get(f"/{doc['_id']}")
    assert get_response.status_code == HTTPStatus.OK
    assert get_response.json() == model.dict(by_alias=True)

    list_response = client.get("/")
    assert list_response.status_code == HTTPStatus.OK
    assert list_response.json()["items"][0] == model.dict(by_alias=True)

def test_api_router():
    assert id(MyController.api_router) != id(MyController2.api_router)

def test_model_controller__when__routes_defined__then_only_routes_defined():
    routes = MyController2.api_router.routes
    assert len(routes) == 1
    assert routes[0].name == "get"

def test_controller_no_overlapped_mixin():
    routes = [i.name for i in MyController.api_router.routes]
    duplicates = {x for x in routes if routes.count(x) > 1}
    assert not duplicates


import numpy as np

def run(self,Input):
  """
    This method computes the final status of this simplified LB LOCA event
    @ In, Input, dict, dictionary of inputs from RAVEN
    @ Out, None
  """
  self.ACCstatus = Input['ACC_status'][0]
  self.timeLPI   = Input['time_LPI'][0]
  self.timeLPR   = Input['time_LPR'][0]

  timeToCDLPI = 6.
  timeToCDLPR = 11.

  if self.ACCstatus == 1.:
    self.out = 1.
    self.LPI_status = 1.
    self.LPR_status = 1.
  else:
    self.LPIact = self.timeLPI + 1.
    if self.LPIact > timeToCDLPI:
      self.out = 1.
      self.LPI_status = 1.
      self.LPR_status = 1.
    else:
      self.LPI_status = 0.
      self.LPRact = self.LPIact + self.timeLPR
      if self.LPRact > timeToCDLPR:
        self.out = 1.
        self.LPR_status = 1.
      else:
        self.out = 0.
        self.LPR_status = 0.


import sys
import os
from dataclasses import dataclass

import numpy as np
import pandas as pd

from src.exception import CustomException
from src.logger import logging
from src.utils import save_object, evaluate_model

from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, AdaBoostRegressor
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from catboost import CatBoostRegressor
from xgboost import XGBRegressor

from sklearn.metrics import r2_score
from src.config.hyper_parameter_tuning import params

@dataclass
class ModelTrainingConfig:
    trained_model_file_path = os.path.join("artifacts","model.pkl")

class ModelTrainer:
    def __init__(self):
        self.model_trainer_config=ModelTrainingConfig()

    def initiate_model_trainer(self,train_array,test_array):
        try:
            logging.info("Splitting train and test data")
            X_train,y_train,X_test,y_test = (
                train_array[:,:-1],
                train_array[:,-1],
                test_array[:,:-1],
                test_array[:,-1]
            )
            logging.info("Splitting train and test data Completed")

            models = {
                "Decision Tree": DecisionTreeRegressor(),
                "Random Forest":RandomForestRegressor(),
                "Linear Regression":LinearRegression(),
                "Gradient Boosting":GradientBoostingRegressor(),
                "AdaBoost Regressor": AdaBoostRegressor(),
                "CatBoosting Regressor": CatBoostRegressor(verbose=False),
                "XGBoost Regressor": XGBRegressor()
            }

            model_report:dict = evaluate_model(X_train=X_train, y_train=y_train, X_test=X_test, y_test=y_test,
                                               models=models, params=params)

            best_model_score = max(sorted(model_report.values()))

            best_model_name = list(model_report.keys())[
                list(model_report.values()).index(best_model_score)
            ]

            best_model = models[best_model_name]

            if best_model_score<0.6:
                raise CustomException("No good model found")
            logging.info(f"Best found model on both training and testing dataset")
            logging.info("Best model is [{0}] with r2_score [{1}]".format(best_model_name,best_model_score))
            save_object(
                file_path=self.model_trainer_config.trained_model_file_path,
                obj=best_model
            )

            predicted=best_model.predict(X_test)

            r2_square = r2_score(y_test, predicted)
            return r2_square

        except Exception as e:
            CustomException(e,sys)


"""
给定一个字符串S，通过将字符串S中的每个字母转变大小写，
我们可以获得一个新的字符串。返回所有可能得到的字符串集合。

示例：
输入：S = "a1b2"
输出：["a1b2", "a1B2", "A1b2", "A1B2"]

输入：S = "3z4"
输出：["3z4", "3Z4"]
"""

def letterCasePermutation(S: str):
    ans = []
    # 先将所有字母转换为小写，避免回溯时麻烦
    S = list(S.lower())

    def helper(first: int):
        if first == len(S):
            ans.append(''.join(S))
            return
        if S[first].isalpha():
            S[first] = S[first].upper()
            helper(first + 1)
            S[first] = S[first].lower()
        helper(first + 1)

    helper(0)
    return ans

print(letterCasePermutation("C"))


class ListNode:
    def __init__(self,data):
       self.data = data
       self.next = None

class LinkedList:

    def __init__(self):
        self.head = None

    def printNode(self):
        curr = self.head
        while curr:
           print(curr.data, end="->")
           curr = curr.next

    def addNode(self,data):
        newNode = ListNode(data)

        if self.head is None:
            self.head = newNode
            return
        last = self.head

        while last.next:
            last = last.next
        last.next = newNode

class Solution:
    def mergeTwoLists(self, head1, head2):

    	# create a temp node NULL
    	temp = None

    	# List1 is empty then return List2
    	if head1 is None:
    		return head2

    	# if List2 is empty then return List1
    	if head2 is None:
    		return head1

    	# If List1's data is smaller or
    	# equal to List2's data
    	if head1.data <= head2.data:

    		# assign temp to List1's data
    		temp = head1

    		# Again check List1's data is smaller or equal List2's
    		# data and call mergeLists function.
    		temp.next = self.mergeTwoLists(head1.next, head2)

    	else:
    		# If List2's data is greater than List1's
    		# data assign temp to head2
    		temp = head2

    		# Again check List2's data is greater or equal List's
    		# data and call mergeLists function.
    		temp.next = self.mergeTwoLists(head1, head2.next)

    	# return the temp list.
    	return temp

    def mergeTwoLists2(self, l1, l2):
        if not l1 or not l2:
            return l1 or l2
        if l1.data < l2.data:
            l1.next = self.mergeTwoLists2(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists2(l1, l2.next)
            return l2

llist_1 = LinkedList()
llist_1.addNode(1)
llist_1.addNode(2)
llist_1.addNode(4)

llist_2 = LinkedList()
llist_2.addNode(1)
llist_2.addNode(3)
llist_2.addNode(4)

llist_3 = LinkedList()

test1 = Solution()
llist_3.head = test1.mergeTwoLists(llist_1.head, llist_2.head)
print("\n Merged Linked List is : ", end="")
llist_3.printNode()

llist_1 = LinkedList()
llist_1.addNode(10)
llist_1.addNode(20)
llist_1.addNode(30)
llist_1.addNode(40)
llist_1.addNode(50)

llist_2 = LinkedList()
llist_2.addNode(5)
llist_2.addNode(15)
llist_2.addNode(18)
llist_2.addNode(35)
llist_2.addNode(60)

llist_3 = LinkedList()

test1 = Solution()
llist_3.head = test1.mergeTwoLists2(llist_1.head, llist_2.head)
print("\n Merged Linked List is : ", end="")
llist_3.printNode()


def tree_is_visible(forest: list, position_x: int, position_y: int) -> bool:
    isVisible = True
    search_x_pos = 0
    current_tree = forest[position_x][position_y]
    while isVisible and search_x_pos < position_x:
        isVisible = forest[search_x_pos][position_y] < current_tree
        search_x_pos += 1
    if isVisible:
        return True

    isVisible = True
    search_x_pos = len(forest[position_x]) - 1
    while isVisible and search_x_pos > position_x:
        isVisible = forest[search_x_pos][position_y] < current_tree
        search_x_pos -= 1
    if isVisible:
        return True

    isVisible = True
    seatch_y_pos = 0
    while isVisible and seatch_y_pos < position_y:
        isVisible = forest[position_x][seatch_y_pos] < current_tree
        seatch_y_pos += 1
    if isVisible:
        return True

    isVisible = True
    search_y_pos = len(forest[search_x_pos]) - 1
    while isVisible and search_y_pos > position_y:
        isVisible = forest[position_x][search_y_pos] < current_tree
        search_y_pos -= 1
    if isVisible:
        return True

    return False

input_file = open("input.txt", "r")
matrix = []

for line in input_file:
    if line[-1]=='\n':
        matrix.append(list(line)[:-1])
    else:
        matrix.append(list(line))

for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        matrix[i][j]= int(matrix[i][j])

print(matrix)

total_sum = 0

for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        total_sum = total_sum + 1 if tree_is_visible(matrix, i, j) else total_sum

print("Trees can be seen: ",total_sum)


class Solution(object):
    def reverseOnlyLetters(self, S):
        """
        :type S: str
        :rtype: str
        NOTE TO SELF: TRY TO USE A STACK MAYBE?
        """
        end = len(S)-1
        start = 0
        while start < end:
            while start < end and not S[start].isalpha():
                start += 1
            while start < end and not S[end].isalpha():
                end -= 1
            if start < end:
                Slist = list(S)
                Slist[start], Slist[end] = Slist[end], Slist[start]
                S = "".join(Slist)
                start += 1
                end -= 1
        return S


# -*- coding: utf-8 -*-
import argparse
from datetime import datetime

import pandas as pd

from zvt import init_log, zvt_config
from zvt.api.data_type import Region, Provider, EntityType
from zvt.api.quote import get_kdata_schema, get_kdata
from zvt.domain import Stock, StockKdataCommon, Stock1dHfqKdata
from zvt.contract import IntervalLevel, AdjustType
from zvt.contract.recorder import FixedCycleDataRecorder
from zvt.recorders.joinquant.common import to_jq_trading_level, to_jq_entity_id
from zvt.database.api import get_db_session
from zvt.networking.request import jq_get_token, jq_get_bars
from zvt.utils.pd_utils import pd_is_not_null
from zvt.utils.time_utils import to_time_str, now_pd_timestamp, PD_TIME_FORMAT_DAY, PD_TIME_FORMAT_ISO8601

class JqChinaStockKdataRecorder(FixedCycleDataRecorder):
    # 数据来自jq
    region = Region.CHN
    provider = Provider.JoinQuant
    entity_schema = Stock
    # 只是为了把recorder注册到data_schema
    data_schema = StockKdataCommon

    def __init__(self,
                 exchanges=['sh', 'sz'],
                 entity_ids=None,
                 codes=None,
                 batch_size=10,
                 force_update=True,
                 sleeping_time=0,
                 default_size=zvt_config['batch_size'],
                 real_time=False,
                 fix_duplicate_way='ignore',
                 start_timestamp=None,
                 end_timestamp=None,
                 level=IntervalLevel.LEVEL_1WEEK,
                 kdata_use_begin_time=False,
                 close_hour=15,
                 close_minute=0,
                 one_day_trading_minutes=4 * 60,
                 adjust_type=AdjustType.qfq,
                 share_para=None) -> None:
        level = IntervalLevel(level)
        adjust_type = AdjustType(adjust_type)
        self.data_schema = get_kdata_schema(entity_type=EntityType.Stock, level=level, adjust_type=adjust_type)
        self.jq_trading_level = to_jq_trading_level(level)

        super().__init__(EntityType.Stock, exchanges, entity_ids, codes, batch_size, force_update, sleeping_time,
                         default_size, real_time, fix_duplicate_way, start_timestamp, end_timestamp, close_hour,
                         close_minute, level, kdata_use_begin_time, one_day_trading_minutes, share_para=share_para)
        self.adjust_type = adjust_type

        jq_get_token(zvt_config['jq_username'], zvt_config['jq_password'], force=True)

    def recompute_qfq(self, entity, qfq_factor, last_timestamp):
        # 重新计算前复权数据
        if qfq_factor != 0:
            kdatas = get_kdata(region=self.region,
                               provider=self.provider,
                               entity_id=entity.id,
                               level=self.level.value,
                               order=self.data_schema.timestamp.asc(),
                               return_type='domain',
                               filters=[self.data_schema.timestamp < last_timestamp])
            if kdatas:
                self.logger.info('recomputing {} qfq kdata,factor is:{}'.format(entity.code, qfq_factor))
                for kdata in kdatas:
                    kdata.open = round(kdata.open * qfq_factor, 2)
                    kdata.close = round(kdata.close * qfq_factor, 2)
                    kdata.high = round(kdata.high * qfq_factor, 2)
                    kdata.low = round(kdata.low * qfq_factor, 2)
                session = get_db_session(region=self.region,
                                         provider=self.provider,
                                         data_schema=self.data_schema)
                session.bulk_save_objects(kdatas)
                session.commit()

    def generate_domain_id(self, entity, df, time_fmt=PD_TIME_FORMAT_DAY):
        format = PD_TIME_FORMAT_DAY if self.level >= IntervalLevel.LEVEL_1DAY else PD_TIME_FORMAT_ISO8601
        return entity.id + '_' + df[self.get_evaluated_time_field()].dt.strftime(format)

    def record(self, entity, start, end, size, timestamps, http_session):
        if self.adjust_type == AdjustType.hfq:
            fq_ref_date = '2000-01-01'
        else:
            fq_ref_date = to_time_str(now_pd_timestamp(Region.CHN))

        if not self.end_timestamp:
            df = jq_get_bars(to_jq_entity_id(entity),
                             count=size,
                             unit=self.jq_trading_level,
                             # fields=['date', 'open', 'close', 'low', 'high', 'volume', 'money'],
                             fq_ref_date=fq_ref_date)
        else:
            end_timestamp = to_time_str(self.end_timestamp)
            df = jq_get_bars(to_jq_entity_id(entity),
                             count=size,
                             unit=self.jq_trading_level,
                             # fields=['date', 'open', 'close', 'low', 'high', 'volume', 'money'],
                             end_date=end_timestamp,
                             fq_ref_date=fq_ref_date)
        # self.logger.info("record {} for {}, size:{}".format(self.data_schema.__name__, entity.id, len(df)))

        if pd_is_not_null(df):
            # start_timestamp = to_time_str(df.iloc[1]['timestamp'])
            # end_timestamp = to_time_str(df.iloc[-1]['timestamp'])

            # 判断是否需要重新计算之前保存的前复权数据
            if self.adjust_type == AdjustType.qfq:
                check_df = df.head(1)
                check_date = check_df['timestamp'][0]
                current_df = get_kdata(region=self.region,
                                       entity_id=entity.id,
                                       provider=self.provider,
                                       start_timestamp=check_date,
                                       end_timestamp=check_date,
                                       limit=1,
                                       level=self.level,
                                       adjust_type=self.adjust_type)
                if pd_is_not_null(current_df):
                    old = current_df.iloc[0, :]['close']
                    new = check_df['close'][0]
                    # 相同时间的close不同，表明前复权需要重新计算
                    if round(old, 2) != round(new, 2):
                        qfq_factor = new / old
                        last_timestamp = pd.Timestamp(check_date)
                        self.recompute_qfq(entity, qfq_factor=qfq_factor, last_timestamp=last_timestamp)
            return df

        return None

    def format(self, entity, df):
        df.rename(columns={'money': 'turnover', 'date': 'timestamp'}, inplace=True)

        if 'timestamp' not in df.columns:
            df['timestamp'] = pd.to_datetime(df[self.get_original_time_field()])
        elif not isinstance(df['timestamp'].dtypes, datetime):
            df['timestamp'] = pd.to_datetime(df['timestamp'])

        # df.update(df.select_dtypes(include=[np.number]).fillna(0))

        df['entity_id'] = entity.id
        df['provider'] = self.provider.value
        df['code'] = entity.code
        df['name'] = entity.name
        df['level'] = self.level.value

        df['id'] = self.generate_domain_id(entity, df)
        return df

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--level', help='trading level', default='1d', choices=[item.value for item in IntervalLevel])
    parser.add_argument('--codes', help='codes', default=['000001'], nargs='+')

    args = parser.parse_args()

    level = IntervalLevel(args.level)
    codes = args.codes

    init_log('jq_china_stock_{}_kdata.log'.format(args.level))
    JqChinaStockKdataRecorder(level=level, sleeping_time=0, codes=codes, real_time=False,
                              adjust_type=AdjustType.hfq).run()

    print(get_kdata(region=Region.CHN, entity_id='stock_sz_000001', limit=10, order=Stock1dHfqKdata.timestamp.desc(),
                    adjust_type=AdjustType.hfq))

# the __all__ is generated
__all__ = ['JqChinaStockKdataRecorder']


# http://stackoverflow.com/questions/10657383/stitching-photos-together
from PIL import Image

def merge_images(file1, file2, file3):
    """Merge two images into one, displayed side by side
    :param file1: path to first input image file
    :param file2: path to second input image file
    :param file3: path to output image file
    """
    image1 = Image.open(file1)
    image2 = Image.open(file2)

    (width1, height1) = image1.size
    (width2, height2) = image2.size

    result_width = width1 + width2
    result_height = max(height1, height2)

    result = Image.new('RGB', (result_width, result_height), color=(255,255,255,255))
    result.paste(im=image1, box=(0, 0))
    result.paste(im=image2, box=(width1, 0))

    result.save (file3)

def merge_horizontal(input_paths, outpath):
    """Horizontally merge several images into one, displayed side by side
    :param input_paths: list of path to input image files
    :param outpath: path to output image file
    """
    result_width = 0
    result_height = 0

    for path in input_paths:
      image = Image.open(path)
      (width, height) = image.size
      result_width += width
      result_height = max(result_height, height)

    result = Image.new('RGB', (result_width, result_height), color=(255,255,255,255))

    xpos = 0
    for path in input_paths:
      image = Image.open(path)
      (width, height) = image.size
      result.paste(im=image, box=(xpos, 0))
      xpos += width

    result.save (outpath)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# This script is used for testing on an arm machine.
# Please change the constant values according to your environment.
import os
import subprocess
import sys
import time
from glob import glob

from parse import parse

OK = '\033[92m'
FAIL = '\033[91m'
END = '\033[0m'

TIMEOUT = 100
ROUND = 1

scenes = ['function_test2020', 'function_test2021',
          'performance_test2021-public', 'performance_test2021-private']
scene = scenes[int(sys.argv[1])]

testcase = os.path.join('/home/pi/compiler2021/公开用例与运行时库', scene)
compiler = '/home/pi/kobayashi-compiler/build/compiler'
runtime = '/home/pi/kobayashi-compiler/runtime/sylib.c /home/pi/kobayashi-compiler/runtime/armv7/thread.S'
cc = 'gcc -march=armv7ve'

try:
    testcases = sorted([os.path.splitext(os.path.basename(file))[0]
                        for file in glob(os.path.join(testcase, '*.sy'))], key=lambda x: int(x.split('_')[0]))
except:
    testcases = sorted(os.path.splitext(os.path.basename(file))[
                       0] for file in glob(os.path.join(testcase, '*.sy')))

for base in testcases:
    fails = list()

    # names
    try:
        case = base.split('_')
        case[0] = str(int(case[0])).zfill(3)
        case = '_'.join(case)
    except:
        case = base
    print(f'{case}  ', end='', flush=True)

    sy_file = os.path.join(testcase, f'{base}.sy')
    in_file = os.path.join(testcase, f'{base}.in')
    ans_file = os.path.join(testcase, f'{base}.out')

    # compile
    os.system(
        ' '.join([compiler, sy_file, '-o', 'asm.s'] + sys.argv[2:]))
    os.system(f'{cc} asm.s {runtime} -o main')
    os.system(f'touch {in_file}')

    # time
    avg = 0
    for i in range(ROUND):
        print(f'\b{i}', end='', flush=True)
        p = subprocess.Popen(f'./main', stdin=open(in_file),
                             stdout=open('out.txt', 'w'), stderr=open('time.txt', 'w'))
        try:
            p.wait(TIMEOUT)
        except subprocess.TimeoutExpired:
            p.kill()
        ret = p.returncode
        with open('time.txt') as f:
            timing = list(filter(None, f.read().strip().split('\n')))
        if timing:
            h, m, s, us = map(int, parse(
                'TOTAL: {}H-{}M-{}S-{}us', timing[-1]))
            timing = ((h * 60 + m) * 60 + s) * 1000000 + us
            timing /= 1000000
        else:
            timing = 0.0
        avg += timing
    avg /= ROUND

    # judge
    with open('out.txt') as f:
        out = f.read().strip()
    with open(ans_file) as f:
        ans = f.read().strip().split('\n')
    ans_out, ans_ret = '\n'.join(ans[:-1]).strip(), int(ans[-1])
    if ans_out == out and ans_ret == ret:
        print(f'\r[{OK}OK{END}]      {round(avg, 4):7.3f} | {case}')
    else:
        print(f'\r[{FAIL}FAILED{END}]  {round(avg, 4):7.3f} | {case}')
        fails.append(case)
    os.remove('main')

if not fails:
    print(f'All {scene} passed!')
else:
    for fail in fails:
        print(f'{FAIL}{fail}{END} failed!')


# from base.base_dataset import TextObjectImageDataset
from OATrans.base.base_dataset_region_mem import TextObjectImageDataset
import pandas as pd
import os

class ConceptualCaptions3M(TextObjectImageDataset):
    """
    Conceptual Captions dataset. Split files are specific to my download regime.
    """

    def _load_metadata(self):
        # download specific
        metadata_dir = './meta_data'
        split_files = {
            'train': 'cc3m_training_success_full.tsv',
            'val': 'cc3m_validation_success_full.tsv',            # there is no test
        }
        target_split_fp = split_files[self.split]
        metadata = pd.read_csv(os.path.join(metadata_dir, target_split_fp), sep='\t')

        if self.subsample < 1:
            metadata = metadata.sample(frac=self.subsample)
        # elif self.split == 'val':
        #     metadata = metadata.sample(1000, random_state=0)  # 15k val is unnecessarily large, downsample.

        self.metadata = metadata

    def _get_video_path(self, sample):
        # conceptual captions uses this hashing to create the filename
        rel_dir = 'training'
        if self.split != 'train':
            rel_dir = 'validation'
        rel_fp = os.path.join(rel_dir, sample[1])
        #rel_fp = os.path.join(rel_dir, str(zlib.crc32(sample['thumbnailUrl'].encode('utf-8')) & 0xffffffff))
        return os.path.join(self.data_dir, rel_fp), rel_fp

    def _get_caption(self, sample):
        return sample[0]
        #return sample['caption']

    def _get_object_path(self, sample):
        """
        get the object npy path
        Args:
            sample (dict):
        Returns:
            abs path
        """
        # pre = sample[1].split('_')[0]
        # pre = pre.zfill(7)
        # rel_object_fp = os.path.join(pre[:4], sample[1])
        # rel_object_fp = os.path.join(pre[:4], sample[1] + '_1.npz')
        rel_object_fp = sample[1]
        full_object_fp = os.path.join(self.object_dir, self.split, rel_object_fp)
        return os.path.join(self.split, rel_object_fp), full_object_fp


#!/usr/bin/python
# coding=utf-8
import xml.etree.ElementTree

def get_words(file_path):
    with open(file_path, 'r') as xml_file:
        e = xml.etree.ElementTree.parse(xml_file).getroot()

        inner_dictionary = {}
        for chunk in e.findall('chunk'):
            for sentence in chunk.findall('sentence'):
                for tok in sentence.findall('tok'):
                    is_proper_name = False
                    for ann in tok.findall('ann'):
                        if ann.attrib['chan'] == 'nam' and ann.text != '0':
                            is_proper_name = True
                    for orth in tok.find('orth'):
                        if orth.text not in inner_dictionary:
                            inner_dictionary[orth.text] = is_proper_name
                    for lex in tok.findall('lex'):
                        if lex.find('base').text not in inner_dictionary:
                            inner_dictionary[lex.find('base').text] = is_proper_name
        return inner_dictionary

with open('../data/kpwr-1.2.7-names-disamb-nam-flatten/index_names.txt', 'rU') as f:
    file_ = open('../data/prepared/AllFlattenNamWords.csv', 'w')
    file_.truncate()
    book = {}
    for line in f:
        words = get_words("../data/kpwr-1.2.7-names-disamb-nam-flatten/" + line.decode("utf-8").rstrip('\n'))
        for key in words:
            if key not in book:
                book[key] = words[key]
        print ("Finished crawling " + line.decode("utf-8").rstrip('\n'))
    for word in book:
        # if word != "," and word != "." and word != "(" and word != ")" and word != "?" and word != "-" and word != ":" and word != "′" and word != ">" and word != "<" and word != "_":
        if len(word) > 1 and "." not in word and "-" not in word and "/" not in word:
            if book[word]:
                if word.istitle():
                    file_.write((word + ",1,1\n").encode("utf-8"))
                else:
                    file_.write((word + ",0,1\n").encode("utf-8"))
            else:
                if word.istitle():
                    file_.write((word + ",1,0\n").encode("utf-8"))
                else:
                    file_.write((word + ",0,0\n").encode("utf-8"))
    file_.close()


import time

# Simulating log sources with sample data
log_sources = {
    "Server_A": ["Data processed", "Error occurred"],
    "Server_B": ["Connection established","Error occurred"],
    "Server_C": ["Error occurred","Connection established"]
}

# Log capturing and event correlation
def capture_and_correlate_logs(log_sources):
    # Record logs with timestamps
    logs_with_timestamps = {}
    for server, logs in log_sources.items():
        timestamp = int(time.time())
        logs_with_timestamps[server] = [(log, timestamp) for log in logs]

    # Event correlation - Find patterns or associations
    correlation_results = {}
    for server, logs in logs_with_timestamps.items():
        for log, timestamp in logs:
            if log not in correlation_results:
                correlation_results[log] = []
            correlation_results[log].append((server, timestamp))

    # Display the correlated events
    print("Correlated Events:")
    for log, servers in correlation_results.items():
        print(f"{log}:")
        for server, timestamp in servers:
            print(f"  - Occurred on {server} at {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp))}")

if __name__ == "__main__":
    capture_and_correlate_logs(log_sources)


import os, sys

sys.path.insert(0, os.getcwd())
from src.client.comet import add_metrics
from src.visualizations.visualization import plots
from src.client import start_experiment
from src.features import load_df_shots
from sklearn.model_selection import train_test_split
import pandas as pd
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, roc_auc_score, precision_score, recall_score

df_2016 = load_df_shots(2016)
df_2017 = load_df_shots(2017)
df_2018 = load_df_shots(2018)
df_2019 = load_df_shots(2019)

# len(pd.concat([df_2016, df_2017, df_2018]))

df = pd.concat([df_2016, df_2017, df_2018]).reset_index(drop=True)
df.Shot_angle = df.Shot_angle.abs()
df_2019.Shot_angle = df_2019.Shot_angle.abs()

# print(len(pd.concat([df_2016, df_2017, df_2018])) / len(df))

# X_train, X_val, y_train, y_val = train_test_split(df.Shot_distance, df.Goal, test_size=0.23, random_state=42)

X_train = df[['Shot_distance','Shot_angle']]
# X_train = df[['Shot_angle']]
y_train = df.Goal
X_val = df_2019[['Shot_distance','Shot_angle']]
# X_val = df_2019[['Shot_angle']]
y_val = df_2019.Goal
val_labels = y_val.values.reshape(-1,1)

bst = XGBClassifier()
bst.fit(X_train, y_train)

preds = bst.predict(X_val)
probs = bst.predict_proba(X_val)[:,1]

# accuracy_score(y_val, preds)
# roc_auc_score(y_val, probs)
# precision_score(y_val, preds)
# recall_score(y_val, preds)

df = pd.concat([df_2016, df_2017, df_2018, df_2019]).reset_index(drop=True)
X_train = df[['Shot_distance','Shot_angle']].abs()
y_train = df.Goal

bst = XGBClassifier()
bst.fit(X_train, y_train)
bst.save_model('model/xgb.model.json')

# print(y_val.values)

exp = start_experiment()
exp.set_name(f'xgd-distance-angle-{exp.get_name()}')
add_metrics(
        exp,
        accuracy_score(y_val, preds),
        roc_auc_score(y_val, probs),
        precision_score(y_val, preds),
        recall_score(y_val, preds))
exp.log_model("xgb", "model/xgb.model.json")
exp.add_tags(['XGB', 'Distance', 'Angle'])
plots(val_labels, probs, f'xgd-distance-angle', exp)

# plots(val_labels, probs, f'xgd-distance')


from random import randint
opponent = randint(1,9)

print("***** This is a game played by two players. \nThey are both given the chance to choose a stand in a Tic Tac Toe board, one at a time. \nA chosen stand cannot be chosen again by any of the players *****\n\n\n")
board = [1,2,3,
        4,5,6,
        7,8,9] # This is the board that controls the game

def show():   # This function displays the board of the Tic Tac Toe game
    print("\n",board[0],board[1],board[2])
    print(" -----")
    print("",board[3],board[4],board[5])
    print(" -----")
    print("",board[6],board[7],board[8],"\n")
show()

##def winner():
##    if board[0]=='x' and board[1]=='x' and board[2]=='x':
##        print("Congratulation !!!  You are the winner")
##    if board[0]=='x' and board[3]=='x' and board[7]=='x':
##        print("Congratulation !!!  You are the winner")
##    if board[3]=='x' and board[6]=='x' and board[9]=='x':
##        print("Congratulation !!!  You are the winner")
##    if board[7]=='x' and board[8]=='x' and board[9]=='x':
##        print("Congratulation !!!  You are the winner")
##    if board[0]=='x' and board[4]=='x' and board[9]=='x':
##        print("Congratulation !!!  You are the winner")

indicator = ['x','o']

def main(): # This function runs the whole game itself
    while True:
        player1 = int(input("Player one, enter the position of your choice: "))

##        if board[player1] == indicator[0]:
##            print("error movement, this position has been taken already")
        if player1<1 or player1>9:
            print("This is an invalid stand")
        if 1<=player1<=9:
            board[player1-1] = indicator[0]
        show()
        player2 = int(input("Player two, enter the position of your choice: "))
##        if board[player2] == indicator[1]:
##            print("error movement, this position has been taken already")
        if player2<1 or player2>9:
            print("This is an invalid stand")
        if 1<=player2<=9:
            board[player2-1] = indicator[1]
        show()
main()


from sklearn.svm import SVC

import numpy as np
import tensorflow as tf
import argparse
import pickle
import json
import collections
import os

class DocumentSpace:
    class_sess = tf.Session()

    def __init__(self, language_model, lang_mod_order, span):
        self.train_vectors = list()  # structure: [(type, vector)]
        self.test_vectors = list()  # structure: [(type, vector)]
        self.span = span
        self.lang_mod_order = lang_mod_order  # list of words of the language model (to know which
        # word an embedding represents)

        with DocumentSpace.class_sess.as_default(), \
                    tf.device('/cpu:0'):

            self.language_model = tf.nn.l2_normalize(language_model,
                                                     1).eval()  # Word embeddings used to get vectors from text.

    def get_abs_vectors(self, papers):

        """ Generates a vector for every abstract to be classified.
        :parameter papers: JSON array (python list) containing
        the processed papers, represented as dicts."""

        labels = [paper["classification"] for paper in papers]  # ground truth

        print("Calculating abstracts' vectors...")
        parsed = 0
        n_abstracts = len(papers)
        print("started vector build")
        rel_freqs = []
        pooled_vectors = list()
        append_rel_freqs = rel_freqs.append
        lmo = self.lang_mod_order
        span = self.span
        asarr = np.asarray
        for paper in papers:  # 10000
            word_mtx = list()
            words = paper["abstract"].split()
            abs_count = collections.Counter(words)
            word_count = 0
            i = 0
            while word_count < self.span and i < len(words):
                word = words[i]
                if word in lmo:
                    index = self.lang_mod_order.index(word)
                else:
                    index = 0
                word_mtx.append(self.language_model[index])
                word_count += 1
                i += 1
            try:
                dim_mtx = np.transpose(word_mtx) #transposed : rows:value for every word at a given dimension
                pooled_vector = [max(dimension) for dimension in dim_mtx]
            except TypeError:
                pooled_vector = [0] * 10
            pooled_vectors.append(pooled_vector)
            if not parsed % 1000:
                print("{}/{}".format(parsed, n_abstracts))
            parsed += 1
        assert n_abstracts == parsed
        print("Finished calculating abstracts' vectors.")
        return list(zip(labels, pooled_vectors))

    @staticmethod
    def slice(vectors):
        data = [t[1] for t in vectors]
        labels = [t[0] for t in vectors]

        return data, labels

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Classify papers.")
    parser.add_argument("--model_path", help="Path to a folder containing everything related to the model, namely "
                                             "embeddings and vocab files.",
                        required=True)
    parser.add_argument("--span", help="Number of words used for classification, counting from "
                                       "the start of the abstract", type=int, default=10)
    parser.add_argument("--KNN_papers_set", help="Path to the KNN paper set.",
                        required=True)

    if os.path.exists("test_data"):
        print("opening previous data")
        with open("train_data", "rb") as trd, \
                open("train_labels", "rb") as trl, \
                open("test_data", "rb") as ted, \
                open("test_labels", "rb") as tel:
            train_data = pickle.load(trd)
            train_labels = pickle.load(trl)
            test_data = pickle.load(ted)
            test_labels = pickle.load(tel)

        args = parser.parse_args()

    else:
        args = parser.parse_args()

        path_to_model = args.model_path
        path_to_papers = args.KNN_papers_set
        join_path = os.path.join

        with open(join_path(path_to_model, "embeddings"), 'rb') as embeddings, \
                open(join_path(path_to_model, "vocab.txt")) as vocab, \
                open(join_path(path_to_papers, "train_papers")) as train_set, \
                open(join_path(path_to_papers, "test_papers")) as test_set:

            model = pickle.load(embeddings)
            model_order = [line.split()[0].strip("b'") for line in vocab]

            train = json.load(train_set)
            test = json.load(test_set)

        fthousand = []
        ps = 0
        sr = 0
        i = 0
        while ps < 5000 or sr < 5000:
            if test[i]["classification"] == "primary-study" and ps < 5000:
                fthousand.append(test[i])
                ps += 1
            elif test[i]["classification"] == "systematic-review" and sr < 5000:
                fthousand.append(test[i])
                sr += 1
            i += 1
        print(len(fthousand))

        Space = DocumentSpace(model, model_order, args.span)
        Space.train_vectors = Space.get_abs_vectors(train)
        Space.test_vectors = Space.get_abs_vectors(fthousand)
        train_data, train_labels = Space.slice(Space.train_vectors)
        test_data, test_labels = Space.slice(Space.test_vectors)

        with open("train_data", "wb") as trd, \
                open("train_labels", "wb") as trl, \
                open("test_data", "wb") as ted, \
                open("test_labels", "wb") as tel:
            pickle.dump(train_data, trd)
            pickle.dump(train_labels, trl)
            pickle.dump(test_data, ted)
            pickle.dump(test_labels, tel)

    classifier = SVC()
    print("fitting")
    classifier.fit(np.asarray(train_data), np.asarray(train_labels))
    print("predicting")
    predictions = classifier.predict(np.asarray(test_data))
    classes = [ "primary-study",
                 "systematic-review"]

    if len(test_labels) != len(predictions):
        print("dimensions error. labels: {}, predictions: {}".format(len(test_labels),
                                                                      len(predictions)))

    class_dimension = len(classes)
    conf_mtx = np.zeros([class_dimension, class_dimension])
    for i in range(0, len(predictions)):
        predicted_class = classes.index(predictions[i])
        actual_class = classes.index(test_labels[i])
        conf_mtx[actual_class][predicted_class] += 1
    np.set_printoptions(suppress=True)
    print(conf_mtx)

    hits = 0
    for l, p in zip(test_labels, predictions):
        if l == p:
            hits += 1
    accuracy = hits / len(test_labels) #saved for output
    print(accuracy)

    recall = lambda i: (conf_mtx[i][i]/sum(conf_mtx[i][j] for j in range(0,class_dimension)))
    recall_sum = 0
    recall_list = []
    for i in range(0,class_dimension):
        rcl = recall(i)
        if not np.isnan(rcl):
            recall_sum += rcl
        recall_list.append((i, rcl))
        print('Recall {}: {:.5f}'.format(i, rcl))
    print()
    recall_mean = recall_sum/class_dimension
    print('Recall mean: {:.5f}'.format(recall_mean))

    precision = lambda i: (conf_mtx[i][i]/sum(conf_mtx[j][i] for j in range(0,class_dimension)))
    precision_sum = 0
    precision_list = list()
    for i in range(0,class_dimension):
        label_precision = precision(i)
        if not np.isnan(label_precision):
            precision_sum += label_precision
        precision_list.append((i, label_precision))
        print('Precision {}: {:.5f}'.format(i, label_precision))
    print()
    precision_mean = precision_sum/class_dimension
    print('Precision mean: {:.5f}'.format(precision_mean))

    output = ''
    output += 'Model: {}\n'.format(args.model_path)
    output += 'span = {}\n'.format(args.span)
    output += 'Set: {}\n'.format(args.KNN_papers_set)
    output += 'Accuracy : {}\n'.format(accuracy)
    output += "RECALL\n"
    for rcl in recall_list:
        output += 'Recall {}: {:.5f}\n'.format(rcl[0], rcl[1])
    output += 'Recall mean: {:.5f}\n'.format(recall_mean)
    output += "PRECISION\n"
    for pcsn in precision_list:
        output += 'Precision {}: {:.5f}\n'.format(pcsn[0], pcsn[1])
    output += 'Precision mean: {:.5f}\n'.format(precision_mean)
    output += 'CONFUSSION MATRIX\n'
    output += str(conf_mtx)

    with open("output{}.txt".format(args.model_path.split('/')[-2]), "w") as out_file:
        out_file.write(output)


def my_agent(observation, configuration):
    def get_all_windows(board,configuration):
        windows=[]
        #horizontal windows
        for i in range(configuration.rows):
            for j in range(configuration.columns-configuration.inarow+1):
                new_window=[]
                for k in range(configuration.inarow):
                    new_window.append((i,j+k))
                windows.append(new_window)
        #vertical windows
        for i in range(configuration.rows-configuration.inarow+1):
            for j in range(configuration.columns):
                new_window=[]
                for k in range(configuration.inarow):
                    new_window.append((i+k,j))
                windows.append(new_window)
        #diagonal windows
        for i in range(configuration.rows-configuration.inarow+1):
            for j in range(configuration.columns-configuration.inarow+1):
                new_window=[]
                for k in range(configuration.inarow):
                    new_window.append((i+k,j+k))
                #print(new_window)
                windows.append(new_window)
                new_window=[]
                for k in range(configuration.inarow):
                    new_window.append((i+k,j+configuration.inarow-k-1))
                windows.append(new_window)
                #print(new_window)
        return windows

    def get_heuristic_eval(board,windows,mark,next_to_move):
        ev=0
        available=[]
        for j in range(len(board[0])):
            for h in range(len(board)):
                if board[h][j]==0 and (h==len(board)-1  or board[h+1][j]!=0):
                    available.append((h,j))
        #print(available)
        for window in windows:
            window_eval=0
            our_cnt,other_cnt,avails=(0,0,0)
            for (x,y) in window:
                if (x,y) in available:
                    avails+=1
                if board[x][y]==mark:
                    our_cnt+=1
                elif board[x][y]==mark%2+1:
                    other_cnt+=1
            if other_cnt>0 and our_cnt>0:
                continue
            ourCoef,otherCoef=(1,1)
            if mark==next_to_move:
                ourCoef=25
            else:
                otherCoef=25

            if other_cnt==4:
                window_eval=-10000000000000
            elif (other_cnt==3 and avails==1):
                window_eval=-1000000*otherCoef/ourCoef
            elif other_cnt==3:
                window_eval=-200*otherCoef/ourCoef
            elif other_cnt==2:
                window_eval=-1
            elif our_cnt==4:
                window_eval=10000000000000
            elif (our_cnt==3 and avails==1):
                window_eval=1000000*ourCoef/otherCoef
            elif our_cnt==3:
                window_eval=200*ourCoef/otherCoef
            elif our_cnt==2:
                window_eval=1
            ev+=window_eval
        return ev

    def drop_piece(board,col,mark,configuration):
        next_board=board.copy()
        for row in range(configuration.rows-1,-1,-1):
            if next_board[row][col]==0:
                break
        next_board[row][col]=mark
        return next_board

    def game_finished(board,windows,mark):
        available=[]
        for j in range(len(board[0])):
            for h in range(len(board)):
                if board[h][j]==0 and (h==len(board)-1  or board[h+1][j]!=0):
                    available.append((h,j))
        if(len(available)==0):
            return True
        for window in windows:
            our_cnt,other_cnt=(0,0)
            for (x,y) in window:
                if board[x][y]==mark:
                    our_cnt+=1
                elif board[x][y]==mark%2+1:
                    other_cnt+=1
            if(our_cnt==len(windows[0]) or other_cnt==len(windows[0])):
                return True
        return False

    def get_minimax_eval(board,configuration,windows,depth,mark,next_to_move,alpha=-10**50,beta=10**50):
        if(depth==0):
            return get_heuristic_eval(board,windows,mark,next_to_move)
        if(game_finished(board,windows,mark)):
            return get_heuristic_eval(board,windows,mark,next_to_move)
        ev={}
        heur={}
        for c in range(configuration.columns):
            if board[0][c]==0:
                next_board=drop_piece(board,c,next_to_move,configuration)
                heur[c]=get_heuristic_eval(next_board,windows,mark,next_to_move%2+1)
        orderedItems=sorted(heur,key=heur.get,reverse=mark==next_to_move)
        #print(orderedItems)
        #ev={}
        #for c in range(configuration.columns):
        for c in orderedItems:
            if board[0][c]==0:
                next_board=drop_piece(board,c,next_to_move,configuration)
                ev[c]=get_minimax_eval(next_board,configuration,windows,depth-1,mark,next_to_move%2+1,alpha,beta)
                if next_to_move==mark:
                    alpha=max(alpha,ev[c])
                else:
                    beta=min(beta,ev[c])
                if alpha>=beta:
                    break
                #if(depth==2):
                #    print("(depth "+str(depth)+") eval for c:",c,":",ev[c])
        if next_to_move!=mark:
            return min(ev.values())
        else:
            return max(ev.values())

    from random import choice
    import numpy as np
    board=np.asarray(observation.board).reshape(configuration.rows,configuration.columns)
    windows=get_all_windows(board,configuration)
    #ev=get_heuristic_eval(board,windows,observation.mark,observation.mark)
    ev={}
    for c in range(configuration.columns):
        if board[0][c]==0:
            next_board=drop_piece(board,c,observation.mark,configuration)
            #ev[c]=get_heuristic_eval(next_board,windows,observation.mark,observation.mark%2+1)
            #print("getting eval for:",c)
            ev[c]=get_minimax_eval(next_board,configuration,windows,4,observation.mark,observation.mark%2+1)
            #print("eval is:",ev[c])
            #print(c,"ev:",ev[c])
    maxes=[c for c in ev.keys() if ev[c]==max(ev.values())]
    return maxes[0]