from ssqatest.src.SeleniumExtended import SeleniumExtended
from ssqatest.src.pages.components.Footer import Footer
from ssqatest.src.pages.components.Header import Header

from ssqatest.src.pages.locators.BlogPageLocators import BlogPageLocators
from ssqatest.src.pages.locators.what_is_gymnetworkPageLocators import WhatIsGymnetworkPageLocators
from ssqatest.src.pages.locators.Earn_money_with_gym_networkPageLocators import EarnMoneyWithGymnetworkPageLocators
from ssqatest.src.pages.locators.Gym_Street_And_Ecosystem_PageLocators import GymStreetAndEcosystemPageLocators
from ssqatest.src.pages.locators.Gymstreet_most_innovative_defi_projectPageLocators import GymstreetMostInnovativePageLocators
from ssqatest.src.pages.locators.Metaverse_And_Potential_PageLocators import MetaverseAndPotentialPageLocators
from ssqatest.src.helpe.BlogPageContent import BlogPageContent
from ssqatest.src.helpe.what_is_gymnetworkPageContent import WhatIsGymnetworkContent
from ssqatest.src.helpe.Earn_money_with_gym_networkPageContent import EarnMoneyWithGymNetworkContent
from ssqatest.src.helpe.Gym_street_and_its_ecosystemContent import GymStreetAndEcosystemContent
from ssqatest.src.helpe.Gymstreet_most_innovative_defi_projectPageContent import GymstreetMostInnovativeDefiProjectContent
from ssqatest.src.helpe.Metaverse_and_its_potentialPageContent import MetaverseAndPotentialContent

class BlogPage(BlogPageLocators):

    def __init__(self, driver):
        self.driver = driver

        self.url = "https://pages.gymnetwork.io/blog/"
        self.sl = SeleniumExtended(self.driver)
        self.Header_section = Header(self.driver, self.url)
        self.Footer_section = Footer(self.driver, self.url)

    def open_Blog_page(self):
        self.driver.get(self.url)

    def verify_all_Blog_Page_elements(self):

        ################## header ####################
        self.Header_section.verify_all_Header_elements()

        #################### landing section ####################
        self.sl.wait_until_element_contains_text(self.LANDING_TITLE_FIELD, BlogPageContent.landing_title_text)
        self.sl.wait_until_element_contains_text(self.LANDING_DESC_FIELD, BlogPageContent.landing_desc_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.LANDING_LINK_FIELD, 'href', BlogPageContent.landing_link_href, 'landing link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.LANDING_LINK_IMG_FIELD, 'src', BlogPageContent.landing_link_img_src, 'landing link img src is not correct')
        self.sl.wait_until_element_contains_text(self.LANDING_LINK_TITLE_FIELD, BlogPageContent.landing_link_title_text)
        self.sl.wait_until_element_contains_text(self.LANDING_LINK_DESC_FIELD, BlogPageContent.landing_link_desc_text)
        self.sl.wait_until_element_contains_text(self.LANDING_LINK_DATE_FIELD, BlogPageContent.landing_link_date_text)
        # landing btn
        self.sl.click_into_link_and_Verify_page_by_element_text(self.LANDING_LINK_FIELD, EarnMoneyWithGymnetworkPageLocators.TITLE_FIELD, EarnMoneyWithGymNetworkContent.title_tetx, timeout=15)
        assert self.driver.current_url == 'https://pages.gymnetwork.io/blog/how-can-you-earn-money-with-gym-network'
        self.driver.get(self.url)

        # blogs container
        self.sl.wait_until_element_contains_text(self.DROPDOWN_BTN, BlogPageContent.Latest_articles_btn_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.CARD1_LINK_FIELD, 'href', BlogPageContent.what_is_gymnetwork_href, 'what_is_gymnetwork link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.CARD1_LINK_IMG_FIELD, 'src', BlogPageContent.what_is_gymnetwork_img_src, 'what_is_gymnetwork img src is not correct')
        self.sl.wait_until_element_contains_text(self.CARD1_LINK_TITLE_FIELD, BlogPageContent.what_is_gymnetwork_title_text)
        self.sl.wait_until_element_contains_text(self.CARD1_LINK_DESC_FIELD, BlogPageContent.what_is_gymnetwork_desc_text)
        self.sl.wait_until_element_contains_text(self.CARD1_LINK_DATE_FIELD, BlogPageContent.what_is_gymnetwork_date_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.CARD2_LINK_FIELD, 'href', BlogPageContent.metaverse_and_its_potential_href, 'metaverse_and_its_potential link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.CARD2_LINK_IMG_FIELD, 'src', BlogPageContent.metaverse_and_its_potential_img_src, 'metaverse_and_its_potential link img src is not correct')
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_TITLE_FIELD, BlogPageContent.metaverse_and_its_potential_title_text)
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_DESC_FIELD, BlogPageContent.metaverse_and_its_potential_desc_text)
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_DATE_FIELD, BlogPageContent.metaverse_and_its_potential_date_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.CARD3_LINK_FIELD, 'href', BlogPageContent.gym_street_and_its_ecosystem_href, 'gym_street_and_its_ecosystem link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.CARD3_LINK_IMG_FIELD, 'src', BlogPageContent.gym_street_and_its_ecosystem_img_src, 'gym_street_and_its_ecosystem link img src is not correct')
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_TITLE_FIELD, BlogPageContent.gym_street_and_its_ecosystem_title_text)
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_DESC_FIELD, BlogPageContent.gym_street_and_its_ecosystem_desc_text)
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_DATE_FIELD, BlogPageContent.gym_street_and_its_ecosystem_date_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.CARD4_LINK_FIELD, 'href', BlogPageContent.earn_money_with_gym_network_href, 'earn_money_with_gym_network link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.CARD4_LINK_IMG_FIELD, 'src', BlogPageContent.earn_money_with_gym_network_img_src, 'earn_money_with_gym_network link img src is not correct')
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_TITLE_FIELD, BlogPageContent.earn_money_with_gym_network_title_text)
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_DESC_FIELD, BlogPageContent.earn_money_with_gym_network_desc_text)
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_DATE_FIELD, BlogPageContent.earn_money_with_gym_network_date_text)

        self.sl.wait_and_check_attribute_value_is_correct(self.CARD5_LINK_FIELD, 'href', BlogPageContent.gymstreet_most_innovative_defi_project_href, 'gymstreet_most_innovative_defi_project link href is not correct')
        self.sl.wait_and_check_attribute_value_is_correct(self.CARD5_LINK_IMG_FIELD, 'src', BlogPageContent.gymstreet_most_innovative_defi_project_img_src, 'gymstreet_most_innovative_defi_project link img src is not correct')
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_TITLE_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_title_text)
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_DESC_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_desc_text)
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_DATE_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_date_text)

        self.sl.scrollIntoView_and_click(self.DROPDOWN_BTN)
        self.sl.wait_and_click(self.NEWEST_FIRST_BTN)
        self.sl.wait_until_element_contains_text(self.DROPDOWN_BTN, BlogPageContent.Newest_first_btn_text)

        self.sl.wait_until_element_contains_text(self.CARD1_LINK_TITLE_FIELD, BlogPageContent.earn_money_with_gym_network_title_text)
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_TITLE_FIELD, BlogPageContent.what_is_gymnetwork_title_text)
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_TITLE_FIELD, BlogPageContent.metaverse_and_its_potential_title_text)
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_TITLE_FIELD, BlogPageContent.gym_street_and_its_ecosystem_title_text)
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_TITLE_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_title_text)

        self.sl.scrollIntoView_and_click(self.DROPDOWN_BTN)

        self.sl.wait_and_click(self.LASTES_ARTICLES_BTN)
        self.sl.wait_until_element_contains_text(self.DROPDOWN_BTN, BlogPageContent.Latest_articles_btn_text)

        self.sl.wait_until_element_contains_text(self.CARD1_LINK_TITLE_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_title_text)
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_TITLE_FIELD, BlogPageContent.what_is_gymnetwork_title_text)
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_TITLE_FIELD, BlogPageContent.metaverse_and_its_potential_title_text)
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_TITLE_FIELD, BlogPageContent.gym_street_and_its_ecosystem_title_text)
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_TITLE_FIELD, BlogPageContent.earn_money_with_gym_network_title_text)

        self.sl.scrollIntoView_and_click(self.DROPDOWN_BTN)
        self.sl.wait_and_click(self.MOST_POPULAR_BTN)
        self.sl.wait_until_element_contains_text(self.DROPDOWN_BTN, BlogPageContent.Most_popular_btn_text)

        self.sl.wait_until_element_contains_text(self.CARD1_LINK_TITLE_FIELD, BlogPageContent.earn_money_with_gym_network_title_text)
        self.sl.wait_until_element_contains_text(self.CARD2_LINK_TITLE_FIELD, BlogPageContent.what_is_gymnetwork_title_text)
        self.sl.wait_until_element_contains_text(self.CARD3_LINK_TITLE_FIELD, BlogPageContent.metaverse_and_its_potential_title_text)
        self.sl.wait_until_element_contains_text(self.CARD4_LINK_TITLE_FIELD, BlogPageContent.gym_street_and_its_ecosystem_title_text)
        self.sl.wait_until_element_contains_text(self.CARD5_LINK_TITLE_FIELD, BlogPageContent.gymstreet_most_innovative_defi_project_title_text)

        self.driver.refresh()
        self.sl.click_into_link_and_Verify_page_by_element_text(self.CARD1_LINK_TITLE_FIELD, WhatIsGymnetworkPageLocators.TITLE_FIELD, WhatIsGymnetworkContent.title_tetx)
        self.driver.get(self.url)

        self.sl.click_into_link_and_Verify_page_by_element_text(self.CARD2_LINK_TITLE_FIELD, MetaverseAndPotentialPageLocators.TITLE_FIELD, MetaverseAndPotentialContent.title_tetx)
        self.driver.get(self.url)

        self.sl.click_into_link_and_Verify_page_by_element_text(self.CARD3_LINK_TITLE_FIELD, GymStreetAndEcosystemPageLocators.TITLE_FIELD, GymStreetAndEcosystemContent.title_tetx)
        self.driver.get(self.url)

        self.sl.click_into_link_and_Verify_page_by_element_text(self.CARD4_LINK_TITLE_FIELD, EarnMoneyWithGymnetworkPageLocators.TITLE_FIELD, EarnMoneyWithGymNetworkContent.title_tetx)
        self.driver.get(self.url)

        self.sl.click_into_link_and_Verify_page_by_element_text(self.CARD5_LINK_TITLE_FIELD, GymstreetMostInnovativePageLocators.TITLE_FIELD, GymstreetMostInnovativeDefiProjectContent.title_tetx)
        self.driver.get(self.url)

        ################### footer section ####################
        self.Footer_section.verify_all_footer_elements()


import sys
import random
sys.setrecursionlimit(10000)

import itertools as I
Any_plus = '<$.+>' # this is a nonterminal
Any_one = '{$.}' # this is a terminal
def Any_not(t): return '{!%s}' % t # this is a terminal.
def is_not(t):
    if len(t) > 1:
        if  t[1] == '!':
            return t[2]
    return None

def is_not_match(letter, col_letter):
    l = is_not(letter)
    if l is not None:
        return l != col_letter
    else:
        return False

def letter_match(letter, col_letter):
    if letter == col_letter: return True
        # letter can be any: <$.+> or not: <!x>
    if letter == Any_one: return True
    if is_not_match(letter, col_letter): return True
    return False

def new_start(old_start):
    old_start_ = old_start[1:-1]
    return '<$%s>' % old_start_

def add_any(g):
    g[Any_plus] = [
            add_weight([Any_plus, Any_one], 1),
            add_weight([Any_one], 1)]
    return g

def add_start(g, old_start):
    alts = [alt for alt,w in g[old_start]]
    for alt in alts:
        g[old_start].append(add_weight(list(alt) + ['<$ .+>'], 0))
    return g

def print_g(g):
    for k in g:
        print('#',k)
        for rule in g[k]:
            print('#  ', rule)

def add_weight(rule, weight):
    assert isinstance(rule, list)
    return [tuple(rule), weight]

def add_weights_to_grammar(g):
    return {k:[add_weight(rule, 0) for rule in g[k]] for k in g}

def fix_terminal(g, t):
    nt_t = to_term(t)
    if nt_t not in g:
        g[nt_t] = [ # Any_plus already has at least 1 weight.
                add_weight([t], 0),
                add_weight([Any_plus, t], 0),
                add_weight([], 1),
                add_weight([Any_not(t)], 1)
        ]

def to_term(t): return '<$ %s>' % t

def change_t(t):
    if is_nt(t):
        return t
    else:
        return to_term(t)

def fix_weighted_terminals(g):
    keys = [k for k in g]
    for k in keys:
        for alt,w in g[k]:
            for t in alt:
                if t not in g:
                    fix_terminal(g, t)

    g_ = {}
    for k in g:
        if k[1] == '$':
            g_[k] = g[k]
        else:
            g_[k] = [(tuple([change_t(a) for a in alt]),w) for (alt,w) in g[k]]
    return g_

class Column:
    def __init__(self, index, letter):
        self.index, self.letter = index, letter
        self.states, self._unique = [], {}

    def __str__(self):
        return "%s chart[%d]\n%s" % (self.letter, self.index, "\n".join(
            str(state) for state in self.states if state.finished()))

    def add(self, state):
        if state in self._unique:
            if self._unique[state].weight > state.weight:
                # delete from self.states in fill_chart
                state.e_col = self
                self.states.append(state)
                self._unique[state] = state
            return self._unique[state]
        self._unique[state] = state
        self.states.append(state)
        state.e_col = self
        return self._unique[state]

    def remove_extra_states(self):
        my_states = []
        for state in self._unique:
            cur_states = [s for s in self.states if s == state]
            if len(cur_states) > 1:
                cur_states = sorted(cur_states, key=lambda s: s.weight)
            my_states.append(cur_states[0])
        self.states = my_states
        return

class State:
    def __init__(self, name, expr, dot, s_col, e_col=None):
        self.name, self.expr_, self.dot = name, expr, dot
        self.s_col, self.e_col = s_col, e_col
        self.expr, self.weight = expr

    def finished(self):
        return self.dot >= len(self.expr)

    def at_dot(self):
        return self.expr[self.dot] if self.dot < len(self.expr) else None

    def __str__(self):
        def idx(var):
            return var.index if var else -1

        return self.name + ':= ' + ' '.join([
            str(p)
            for p in [*self.expr[:self.dot], '|', *self.expr[self.dot:]]
            ]) + "(%d,%d):%d" % (idx(self.s_col), idx(self.e_col), self.weight)

    def copy(self):
        return State(self.name, (self.expr, self.weight), self.dot, self.s_col, self.e_col)

    def _t(self):
        return (self.name, self.expr, self.dot, self.s_col.index)

    def __hash__(self):
        return hash(self._t())

    def __eq__(self, other):
        return self._t() == other._t()

    def advance(self):
        return State(self.name, (self.expr, self.weight), self.dot + 1, self.s_col)

class Parser:
    def parse_on(self, text, start_symbol):
        raise NotImplemented()

class EarleyParser(Parser):
    def __init__(self, grammar, log=False, **kwargs):
        g_e = add_weights_to_grammar(grammar)
        # need to update terminals
        g_e = fix_weighted_terminals(g_e)
        self.epsilon = nullable(grammar)
        self._grammar = g_e
        self.log = log

        self._grammar = add_any(self._grammar)

def is_nt(k):
    if len(k) == 1: return False
    return (k[0], k[-1]) == ('<', '>')

def rem_terminals(g):
    g_cur = {}
    for k in g:
        alts = []
        for alt in g[k]:
            ts = [t for t in alt if not is_nt(t)]
            if not ts:
                alts.append(alt)
        if alts:
            g_cur[k] = alts
    return g_cur

def nullable(g):
    nullable_keys = {k for k in g if [] in g[k]}

    unprocessed  = list(nullable_keys)

    g_cur = rem_terminals(g)
    while unprocessed:
        nxt, *unprocessed = unprocessed
        g_nxt = {}
        for k in g_cur:
            g_alts = []
            for alt in g_cur[k]:
                alt_ = [t for t in alt if t != nxt]
                if not alt_:
                    nullable_keys.add(k)
                    unprocessed.append(k)
                    break
                else:
                    g_alts.append(alt_)
            if g_alts:
                g_nxt[k] = g_alts
        g_cur = g_nxt

    return nullable_keys

class EarleyParser(EarleyParser):
    def chart_parse(self, tokens, start, alt):
        chart = [Column(i, tok) for i, tok in enumerate([None, *tokens])]
        chart[0].add(State(start, alt, 0, chart[0]))
        return self.fill_chart(chart)

class EarleyParser(EarleyParser):
    def predict(self, col, sym, state):
        for alt in self._grammar[sym]:
            col.add(State(sym, alt, 0, col))
        if sym in self.epsilon:
            col.add(state.advance())

class EarleyParser(EarleyParser):
    def scan(self, col, state, letter):
        if letter_match(letter, col.letter):
            s = state.advance()
            s.expr = col.letter
            col.add(s)

class EarleyParser(EarleyParser):
    def complete(self, col, state):
        parent_states = [st for st in state.s_col.states
                 if st.at_dot() == state.name]
        for st in parent_states:
            s = st.advance()
            s.weight += state.weight
            col.add(s)

class EarleyParser(EarleyParser):
    def fill_chart(self, chart):
        for i, col in enumerate(chart):
            for state in col.states:
                if state.finished():
                    self.complete(col, state)
                else:
                    sym = state.at_dot()
                    if sym in self._grammar:
                        self.predict(col, sym, state)
                    else:
                        if i + 1 >= len(chart):
                            continue
                        self.scan(chart[i + 1], state, sym)
            col.remove_extra_states()
            if self.log: print(col, '\n')
        return chart

class EarleyParser(EarleyParser):
    def parse_prefix(self, text, start_symbol, alt):
        self.table = self.chart_parse(text, start_symbol, alt)
        for col in reversed(self.table):
            states = [st for st in col.states
                if st.name == start_symbol and st.expr == alt[0] and st.s_col.index == 0
            ]
            if states:
                return col.index, states
        return -1, []

class EarleyParser(EarleyParser):
    def parse_paths(self, named_expr, chart, frm, til):
        def paths(state, start, k, e):
            if not e:
                return [[(state, k)]] if start == frm else []
            else:
                return [[(state, k)] + r
                        for r in self.parse_paths(e, chart, frm, start)]

        *expr, var = named_expr
        starts = None
        if var not in self._grammar:
            starts = ([(var, til - len(var),
                        't')] if til > 0 and chart[til].letter == var else [])
        else:
            starts = [(s, s.s_col.index, 'n') for s in chart[til].states
                      if s.finished() and s.name == var]

        return [p for s, start, k in starts for p in paths(s, start, k, expr)]

class EarleyParser(EarleyParser):
    def forest(self, s, kind, chart):
        return self.parse_forest(chart, s) if kind == 'n' else (s, [])

    def parse_forest(self, chart, state):
        pathexprs = self.parse_paths(state.expr, chart, state.s_col.index,
                                     state.e_col.index) if state.expr else []
        return state.name, [[(v, k, chart) for v, k in reversed(pathexpr)]
                            for pathexpr in pathexprs]

class EarleyParser(EarleyParser):
    def parse_on(self, text, start_symbol):
        self._grammar = add_start(self._grammar, start_symbol)
        print_g(self._grammar)

        for alt in self._grammar[start_symbol]:
            cursor, states = self.parse_prefix(text, start_symbol, alt)
            start = next((s for s in states if s.finished()), None)

            if cursor < len(text) or not start:
                #raise SyntaxError("at " + repr(text[cursor:]))
                continue
            forest = self.parse_forest(self.table, start)
            print('weight = ', str(start))
            yield forest
            #for tree in self.extract_trees(forest):
            #    yield tree

class EarleyParser(EarleyParser):
    def extract_a_tree(self, forest_node):
        name, paths = forest_node
        if not paths:
            return (name, [])
        return (name, [self.extract_a_tree(self.forest(*p)) for p in paths[0]])

    def extract_trees(self, forest):
        yield self.extract_a_tree(forest)

class EarleyParser(EarleyParser):
    def extract_trees(self, forest_node):
        name, paths = forest_node
        if not paths:
            yield (name, [])
        results = []
        for path in paths:
            ptrees = [self.extract_trees(self.forest(*p)) for p in path]
            for p in I.product(*ptrees):
                yield (name, p)

class SimpleExtractor:
    def __init__(self, parser, text, start_symbol):
        parser._grammar = add_start(parser._grammar, start_symbol)
        self.parser = parser
        cursor, states = parser.parse_prefix(text, start_symbol, parser._grammar[start_symbol][0])
        start = next((s for s in states if s.finished()), None)
        if cursor < len(text) or not start:
            raise SyntaxError("at " + repr(cursor))
        self.my_forest = parser.parse_forest(parser.table, start)

    def extract_a_node(self, forest_node):
        name, paths = forest_node
        if not paths:
            return ((name, 0, 1), []), (name, [])
        cur_path, i, l = self.choose_path(paths)
        child_nodes = []
        pos_nodes = []
        for s, kind, chart in cur_path:
            f = self.parser.forest(s, kind, chart)
            postree, ntree = self.extract_a_node(f)
            child_nodes.append(ntree)
            pos_nodes.append(postree)

        return ((name, i, l), pos_nodes), (name, child_nodes)

    def choose_path(self, arr):
        l = len(arr)
        i = random.randrange(l)
        res = sorted([(self.cost_of_path(a),a) for a in arr], key=lambda a: a[0])
        return res[0][1], None, None

    def cost_of_path(self, p):
        states = [s for s,kind,chart in p if kind == 'n']
        return sum([s.weight for s in states])

    def extract_a_tree(self):
        pos_tree, parse_tree = self.extract_a_node(self.my_forest)
        return parse_tree

class O:
    def __init__(self, **keys): self.__dict__.update(keys)
    def __repr__(self): return str(self.__dict__)

Options = O(F='|', L='+', V='|', H='-', NL='\n')

def format_newlines(prefix, formatted_node):
    replacement = ''.join([Options.NL, '\n', prefix])
    return formatted_node.replace('\n', replacement)

def format_tree(node, format_node, get_children, prefix=''):
    children = list(get_children(node))
    next_prefix = ''.join([prefix, Options.V, '   '])
    for child in children[:-1]:
        fml = format_newlines(next_prefix, format_node(child))
        yield ''.join([prefix, Options.F, Options.H, Options.H, ' ', fml])
        tree = format_tree(child, format_node, get_children, next_prefix)
        for result in tree:
            yield result
    if children:
        last_prefix = ''.join([prefix, '    '])
        fml = format_newlines(last_prefix, format_node(children[-1]))
        yield ''.join([prefix, Options.L, Options.H, Options.H, ' ', fml])
        tree = format_tree(children[-1], format_node, get_children, last_prefix)
        for result in tree:
            yield result

def format_parsetree(node,
          format_node=lambda x: repr(x[0]),
          get_children=lambda x: x[1]):
    lines = I.chain([format_node(node)], format_tree(node, format_node, get_children), [''],)
    return '\n'.join(lines)

grammar = {
    '<start>': [['<expr>']],
    '<expr>': [
        ['<term>', '+', '<expr>'],
        ['<term>', '-', '<expr>'],
        ['<term>']],
    '<term>': [
        ['<fact>', '*', '<term>'],
        ['<fact>', '/', '<term>'],
        ['<fact>']],
    '<fact>': [
        ['<digits>'],
        ['(','<expr>',')']],
    '<digits>': [
        ['<digit>','<digits>'],
        ['<digit>']],
    '<digit>': [["%s" % str(i)] for i in range(10)],
}
START = '<start>'

# Modifications:
# Each rule gets a weight
# The start gets changed to:
# <$start>  := [0] <start>
#            | [0] <start> <$.+>
# <$.+>     := [1] <$.+> <$.>
#            | [1] <$.>
# Each terminal gets converted to a nonterminal

#ep = EarleyParser(grammar, log=False)
#cursor, columns = ep.parse_prefix('0', START, add_weight(grammar[START][0], 0))
#print(cursor)
#for c in columns:
#    print(c)

myg = EarleyParser(grammar)
inp = 'xz+yz'
print(repr(inp))
x = SimpleExtractor(myg, inp, START)
t = x.extract_a_tree()
print(format_parsetree(t))
#forests = myg.parse_on(inp, START)
#for forest in forests:
#    print('parse:', inp)
#    for v in myg.extract_trees(forest):
#        print(format_parsetree(v))
#        print('||||||||||||||||||\n')


import torchsort
from .pytorch_ops import soft_rank, soft_sort
from .gumbel_ops import my_gumbel_sinkhorn, my_matching
import torch
import torch.nn as nn
import torch.nn.functional as F

class importance_generator_sr(nn.Module):
    def __init__(self, structure=None, wn_flag=True):
        super(importance_generator_sr, self).__init__()

        self.bn1 = nn.LayerNorm([256])

        self.structure = structure

        self.Bi_GRU = nn.GRU(64, 128,bidirectional=True)

        self.h0 = torch.zeros(2,1,128)
        self.inputs = nn.Parameter(torch.Tensor(len(structure),1, 64))
        nn.init.orthogonal_(self.inputs)
        self.inputs.requires_grad=False

        if wn_flag:
            self.linear_list = [weight_norm(nn.Linear(256, structure[i], bias=False)) for i in range(len(structure))]
        else:
            self.linear_list = [nn.Linear(256, structure[i], bias=False,) for i
                                in range(len(structure))]

        self.mh_fc = torch.nn.ModuleList(self.linear_list)

    def forward(self, k_masks):
        if self.bn1.weight.is_cuda:
            self.inputs = self.inputs.cuda()
            self.h0 = self.h0.cuda()
        outputs, hn = self.Bi_GRU(self.inputs, self.h0)
        outputs = [F.relu(self.bn1(outputs[i,:])) for i in  range(len(self.structure))]

        outputs = [self.mh_fc[i](outputs[i]) for i in range(len(self.mh_fc))]

        ori_masks = []
        for i in range(len(outputs)):
            # g = sample_gumbel(outputs[i].size())
            # # print(g.size())
            # if outputs[i].is_cuda:
            #     g = g.cuda()
            # current_out = torch.exp(outputs[i])
            current_out = torch.sigmoid(outputs[i])
            # print(c_mask)
            if self.training:
                # print(current_out)
                _, index = torch.sort(current_out, descending=True)

                c_mask = k_masks[i].gather(0, index.squeeze().argsort())

                # if current_out.size(1) == 16:
                #     s = 0.02
                # elif current_out.size(1) == 32:
                #     s = 0.01
                # elif current_out.size(1) == 64:
                #     s = 0.001
                soft_r = torchsort.soft_rank(current_out.cpu(), regularization_strength=0.005)
                # print(current_out)
                # print(soft_r)
                # soft_r = c_mask.size(0) - soft_r
                soft_mask = soft_indexing(c_mask, soft_r.squeeze().cuda()-1.0)
                # print(soft_mask)
                c_mask = soft_mask.gather(0, index.squeeze().argsort())
            else:
                _, index = torch.sort(current_out, descending=True)
                c_mask = k_masks[i].gather(0, index.squeeze().argsort())

                soft_r = torchsort.soft_rank(current_out.cpu(), regularization_strength=1e-5)

                soft_mask = soft_indexing(c_mask, soft_r.squeeze().cuda()-1.0, hard=True)

                c_mask = soft_mask.gather(0, index.squeeze().argsort())
                # print(c_mask)
            # print(c_mask)
            ori_masks.append(c_mask)
        # out = torch.cat(outputs, dim=1)

        return ori_masks

def soft_indexing(x, index, hard=False):
    # soft_x = torch.zeros(x.size())
    x_size = x.size(0)
    # if x.is_cuda:
    #     soft_x = x.cuda()
    # print(x.size())
    # print(index.size())
    soft_list = []
    # print(index)
    # print(x)
    for i in range(x.size(0)):

        x_range = torch.arange(x_size)
        i_lt = torch.LongTensor([i])
        if x.is_cuda:
            x_range = x_range.cuda()
            i_lt = i_lt.cuda()

        c_idx = torch.index_select(index, 0, i_lt)
        num = torch.exp(-(x_range-c_idx).pow(2))

        den = num.sum().detach()
        # print(num/den)
        c_v = ((num/den)*x).sum()
        soft_list.append(c_v)
        # if i == 0:
        #     soft_x = c_v
        # else:
        #     soft_x = torch.cat([soft_x, c_v])
    soft_x = torch.stack(soft_list)

    if hard:
        out_hard = torch.zeros(soft_x.size())
        out_hard[soft_x >= 0.5] = 1
        out_hard[soft_x < 0.5] = 0
        if soft_x.is_cuda:
            out_hard = out_hard.cuda()
        soft_x = (soft_x - out_hard).detach() + soft_x
    # print(num)
    # print(den)
    # print(soft_list[0])
    # print(soft_x)
    return soft_x

class permutation_generator(nn.Module):
    def __init__(self, structure=None,):
        super(permutation_generator, self).__init__()
        self.structure = structure
        # torch.eye(self.structure[i])
        # torch.randn(self.structure[i], self.structure[i]).abs()
        params_list = [nn.Parameter(torch.randn(self.structure[i], self.structure[i]).abs()) for i in range(len(self.structure))]
        self.params = nn.ParameterList(params_list)

    def forward(self, k_masks):
        perm_mats = self.actual_permutation()
        # print(perm_mats[0].size())
        # print(k_masks[0].size())
        p_kmasks = [torch.matmul(perm_mats[i], k_masks[i]) for i in range(len(self.structure))]
        # print(p_kmasks[0].size())
        return p_kmasks

    def projection(self):
        for i in range(len(self.structure)):
            # c_perm

            c_perm = F.relu(self.params[i].data)
            c_perm = c_perm / c_perm.sum(0, keepdim=True).detach()
            c_perm = c_perm / c_perm.sum(1, keepdim=True).detach()
            self.params[i].data = c_perm

    def actual_permutation(self):
        self.actual_perms = []
        for i in range(len(self.structure)):
            if not self.training:
                c_perm = self.params[i]
                # c_perm = torch.round(c_perm)
                max_idx = torch.argmax(c_perm, 0, keepdim=True)
                one_hot = torch.FloatTensor(c_perm.shape)
                one_hot.zero_()
                if max_idx.is_cuda:
                    one_hot = one_hot.cuda()

                one_hot.scatter_(0, max_idx, 1)

                c_perm = one_hot
            else:
                c_perm = self.params[i]

            self.actual_perms.append(c_perm)
        return self.actual_perms

    def regularization(self):
        losses = []
        for i in range(len(self.structure)):
            c_perm = self.params[i]
            c_loss = c_perm.abs().sum(0) - (c_perm.pow(2).sum(0)).sqrt()
            c_loss = c_loss.sum()
            r_loss = c_perm.abs().sum(1) - (c_perm.pow(2).sum(1)).sqrt()
            r_loss = r_loss.sum()

            losses.append(c_loss+r_loss)

        return torch.sum(torch.stack(losses))

class gumbel_matching(nn.Module):
    def __init__(self, structure=None,):
        super(gumbel_matching, self).__init__()
        self.structure = structure
        # torch.eye(self.structure[i])
        # torch.randn(self.structure[i], self.structure[i]).abs()
        params_list = [nn.Parameter(3*torch.eye(self.structure[i])) for i in range(len(self.structure))]
        self.params = nn.ParameterList(params_list)

    def forward(self, k_masks):
        perm_mats = self.actual_permutation()
        # print(perm_mats[0].size())
        # print(k_masks[0].size())
        p_kmasks = [torch.matmul(perm_mats[i], k_masks[i]) for i in range(len(self.structure))]
        # print(p_kmasks[0].size())
        return p_kmasks

    def actual_permutation(self):
        self.actual_perms = []
        for i in range(len(self.structure)):

            log_alpha = self.params[i]

            soft_perms_inf, log_alpha_w_noise = my_gumbel_sinkhorn(log_alpha.unsqueeze(0))
            if not self.training:
                # log_alpha_w_noise_flat = torch.transpose(log_alpha_w_noise, 0, 1)
                # n_numbers = log_alpha_w_noise.size(-1)
                # log_alpha_w_noise_flat = log_alpha_w_noise.view(-1, n_numbers, n_numbers)
                #
                # hard_perms_inf = my_matching(log_alpha_w_noise_flat)
                # perm = hard_perms_inf.float()
                # if log_alpha_w_noise.is_cuda:
                #     perm = perm.cuda()
                c_perm = self.params[i]
                # c_perm = torch.round(c_perm)
                max_idx = torch.argmax(c_perm, 0, keepdim=True)
                one_hot = torch.FloatTensor(c_perm.shape)
                one_hot.zero_()
                if max_idx.is_cuda:
                    one_hot = one_hot.cuda()

                one_hot.scatter_(0, max_idx, 1)

                perm = one_hot
            else:
                perm = soft_perms_inf

            self.actual_perms.append(perm.squeeze())

        return self.actual_perms


from typing import List
from abc import abstractmethod
from typing import List, Set, Mapping
from index.structure import TermOccurrence
import math
from enum import Enum

class IndexPreComputedVals:
    def __init__(self, index):
        self.index = index
        self.document_norm, self.doc_count = self.precompute_vals()

    def precompute_vals(self):
        """
        Inicializa os atributos por meio do indice (idx):
            doc_count: o numero de documentos que o indice possui
            document_norm: A norma por documento (cada termo é presentado pelo seu peso (tfxidf))
        """
        document_norm = {}
        doc_count = self.index.document_count
        for key, entry in self.index.dic_index.items():
            occ_list = self.index.get_occurrence_list(key)
            for occ in occ_list:
                # print(occ)
                tfxidf = (
                    VectorRankingModel.tf_idf(
                        self.index.document_count, occ.term_freq, len(occ_list)
                    )
                    ** 2
                )
                document_norm[occ.doc_id] = (
                    document_norm[occ.doc_id] + tfxidf
                    if occ.doc_id in document_norm
                    else tfxidf
                )
        for doc in document_norm.keys():
            document_norm[doc] = document_norm[doc] ** 0.5
        return document_norm, doc_count

class RankingModel:
    @abstractmethod
    def get_ordered_docs(
        self,
        query: Mapping[str, TermOccurrence],
        docs_occur_per_term: Mapping[str, List[TermOccurrence]],
    ) -> (List[int], Mapping[int, float]):
        raise NotImplementedError(
            "Voce deve criar uma subclasse e a mesma deve sobrepor este método"
        )

    def rank_document_ids(self, documents_weight):
        doc_ids = list(documents_weight.keys())
        doc_ids.sort(key=lambda x: -documents_weight[x])
        return doc_ids

class OPERATOR(Enum):
    AND = 1
    OR = 2

# Atividade 1
class BooleanRankingModel(RankingModel):
    def __init__(self, operator: OPERATOR):
        self.operator = operator

    def intersection_all(
        self, map_lst_occurrences: Mapping[str, List[TermOccurrence]]
    ) -> List[int]:
        print(f"map_occ: {map_lst_occurrences}")
        if not map_lst_occurrences:
            return []
        first_term = list(map_lst_occurrences)[0]
        first_list = map_lst_occurrences[first_term]
        list_id = []
        for term_occ in first_list:
            list_id.append(term_occ.doc_id)
        set_ids = set(list_id)
        for term, lst_occurrences in map_lst_occurrences.items():
            # print(lst_occurrences)
            occ_list = []
            for term_occ in lst_occurrences:
                occ_list.append(term_occ.doc_id)
            set_ids = set_ids.intersection(set(occ_list))
        print(f"interseção: {set_ids}")
        return list(set_ids)

    def union_all(
        self, map_lst_occurrences: Mapping[str, List[TermOccurrence]]
    ) -> List[int]:
        print(f"map_occ: {map_lst_occurrences}")
        if not map_lst_occurrences:
            return []
        first_term = list(map_lst_occurrences)[0]
        first_list = map_lst_occurrences[first_term]
        list_id = []
        for term_occ in first_list:
            list_id.append(term_occ.doc_id)
        set_ids = set(list_id)
        for term, lst_occurrences in map_lst_occurrences.items():
            occ_list = []
            for term_occ in lst_occurrences:
                occ_list.append(term_occ.doc_id)
            set_ids = set_ids.union(set(occ_list))
        print(f"união: {set_ids}")
        return list(set_ids)

    def get_ordered_docs(
        self,
        query: Mapping[str, TermOccurrence],
        map_lst_occurrences: Mapping[str, List[TermOccurrence]],
    ) -> (List[int], Mapping[int, float]):
        """Considere que map_lst_occurrences possui as ocorrencias apenas dos termos que existem na consulta"""
        if self.operator == OPERATOR.AND:
            return self.intersection_all(map_lst_occurrences), None
        else:
            return self.union_all(map_lst_occurrences), None

# Atividade 2
class VectorRankingModel(RankingModel):
    def __init__(self, idx_pre_comp_vals: IndexPreComputedVals):
        self.idx_pre_comp_vals = idx_pre_comp_vals

    @staticmethod
    def tf(freq_term: int) -> float:
        return 1 + math.log2(freq_term) if freq_term > 0 else 0.0

    @staticmethod
    def idf(doc_count: int, num_docs_with_term: int) -> float:
        return math.log2(doc_count / num_docs_with_term)

    @staticmethod
    def tf_idf(doc_count: int, freq_term: int, num_docs_with_term) -> float:
        tf = VectorRankingModel.tf(freq_term)
        idf = VectorRankingModel.idf(doc_count, num_docs_with_term)
        # print(f"TF:{tf} IDF:{idf} n_i: {num_docs_with_term} N: {doc_count}")
        return tf * idf

    def get_ordered_docs(
        self,
        query: Mapping[str, TermOccurrence],
        docs_occur_per_term: Mapping[str, List[TermOccurrence]],
    ) -> (List[int], Mapping[int, float]):
        documents_weight = {}

        for term, occ_list in docs_occur_per_term.items():
            if term not in query:
                continue
            wquery = self.tf_idf(
                self.idx_pre_comp_vals.doc_count, query[term].term_freq, len(occ_list)
            )
            for occ in occ_list:
                wdoc = self.tf_idf(
                    self.idx_pre_comp_vals.doc_count, occ.term_freq, len(occ_list)
                )
                documents_weight[occ.doc_id] = (
                    wdoc * wquery / self.idx_pre_comp_vals.document_norm[occ.doc_id]
                    if occ.doc_id not in documents_weight
                    else documents_weight[occ.doc_id]
                    + wdoc * wquery / self.idx_pre_comp_vals.document_norm[occ.doc_id]
                )
        # for key, value in documents_weight.items():
        #     documents_weight[key] = value / self.idx_pre_comp_vals.document_norm[key]
        return self.rank_document_ids(documents_weight), documents_weight


# --coding: utf8--

import os
import sys

PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

def path(*a):
    return os.path.join(PROJECT_ROOT, *a)

# This trick allows to import apps without that prefixes
sys.path.insert(0, path('apps'))
sys.path.insert(0, path('lib'))
sys.path.insert(1, path('.'))

TEST = 'test' in sys.argv

ALLOWED_HOSTS = ['rpe.io']

ADMINS = [
    ('Alex Morozov', 'inductor2000@mail.ru')
]

TIME_ZONE = 'Europe/Moscow'
LANGUAGE_CODE = 'ru-ru'
USE_I18N = True
USE_L10N = True
USE_TZ = True

MEDIA_URL = '/media/'
STATIC_URL = '/static/'

MEDIA_ROOT = path('../media')
STATIC_ROOT = path('../../static')

STATICFILES_DIRS = (
    path('static'),
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'rpenglish.urls'
WSGI_APPLICATION = 'rpenglish.wsgi.application'

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
    'djangobower',
    'hamlpy',
    'pipeline',
    'lib',
    'adminsortable',
    'scripts',
    'plays',
)

HAML_LOADERS = (
    ('django.template.loaders.cached.Loader', (
        'hamlpy.template.loaders.HamlPyFilesystemLoader',
        'hamlpy.template.loaders.HamlPyAppDirectoriesLoader',
    )),
)

COMMON_TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

TEMPLATE_LOADERS = HAML_LOADERS + COMMON_TEMPLATE_LOADERS
TEMPLATE_DIRS = (
    path('templates'),
)

from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP  # NOQA

TEMPLATE_CONTEXT_PROCESSORS = TCP + (
    'django.core.context_processors.request',
)

STATICFILES_FINDERS += (
    'djangobower.finders.BowerFinder',
)

BOWER_COMPONENTS_ROOT = path('static')
BOWER_INSTALLED_APPS = (
    'bootstrap#3.3.6',
)

PIPELINE_COMPILERS = (
    'lib.sass.SASSCCompiler',
    'pipeline.compilers.coffee.CoffeeScriptCompiler',
)

def sass_load_paths(*apps):
    """
    A helper to make cross-imports of scss files possible
    """
    return ' '.join('--include-path %s/static' % path(app)
                    for app in apps)

# The paths to scss directories with files which should have a possibility of
# importing each other.
PIPELINE_SASSC_ARGUMENTS = sass_load_paths('', )

PIPELINE_CSS_COMPRESSOR = None
PIPELINE_JS_COMPRESSOR = None
PIPELINE_DISABLE_WRAPPER = True

PIPELINE_CSS = {
    'base': {
        'source_filenames': [
            'bower_components/bootstrap/dist/css/bootstrap.css',
            'bower_components/bootstrap/dist/css/bootstrap-theme.css',
        ],
        'output_filename': 'css/base.css'
    }
}

STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'
STATICFILES_FINDERS += (
    'pipeline.finders.PipelineFinder',
)

# Параметры для удобного запуска ./manage.py shell_plus --notebook
IPYTHON_ARGUMENTS = [
    '--ext', 'django_extensions.management.notebook_extension',
]

NOTEBOOK_ARGUMENTS = [
    '--ip=0.0.0.0',
    '--no-browser',
]

STUDENT_COLORS = ['#ff0000', '#00ff00', '#0000ff', ]
PLAY_STEPS = ['review_source', 'direct_translation', 'reverse_translation',
              'role_play', ]


from modeltranslation.translator import TranslationOptions, register

from .models import FrontPage

@register(FrontPage)
class FrontPageTranslationOptions(TranslationOptions):
    fields = (
        "hero_header",
        "hero_text",
        "about_header",
        "about_text",
        "why_us_header",
        "why_us_text",
        "more_info_header",
        "more_info_text",
    )


import xlrd
import matplotlib.pyplot as plt

loc = "../excel/Covid_deaths.xls"

loc2 = "../excel/Covid_innlagt.xls"

wb = xlrd.open_workbook(loc)
sheet = wb.sheet_by_index(0)
sheet.cell_value(0, 0)

wb2 = xlrd.open_workbook(loc2)
sheet2 = wb2.sheet_by_index(0)
sheet2.cell_value(0, 0)

print(sheet.nrows)

days = []

def plotSettings(fig, ax1, ax2, ax1xlabel, ax1ylabel, ax2xlabel):
    fig.tight_layout()
    ax1.set_ylabel(ax1ylabel)
    ax1.set_xlabel(ax1xlabel)
    ax2.set_ylabel(ax2xlabel)
    ax1.yaxis.label.set_color('r')
    ax2.yaxis.label.set_color('b')
    plt.tight_layout()
    plt.show()

def getDødsfallNum(i, c):
    positiv = int(sheet.cell_value(i, c))
    return positiv

def getInnlagtNum(i, c):
    positiv = int(sheet2.cell_value(i, c))
    return positiv

def getDaysInnlagte():
    for i in range(315):
        if i < 1:
            print(i)
        else:
            days.append(i)

def getDaysDøde():
    for i in range(315):
        if i < 1:
            print(i)
        else:
            days.append(i)

def getInnlagte(column):
    innlagt = []
    for i in range(315):
        if i < 1:
            print(i)
        else:
            innlagt.append(getInnlagtNum(i, column))

    return innlagt

def getDødsfall(column):
    deaths = []
    for i in range(315):
        if i < 1:
            print(i)
        else:
            deaths.append(getDødsfallNum(i, column))

    return deaths

def plotting():
    fig, ax1 = plt.subplots()
    getDaysInnlagte()
    kuminnlagt = getInnlagte(3)

    kumdeaths = getDødsfall(2)

    ax1.plot(days, kuminnlagt, 'r-', markersize=0.1)

    ax2 = ax1.twinx()

    ax2.plot(days, kumdeaths, 'b-', markersize=0.1)

    # for i_x, i_y in zip(days,
    #                     kuminnlagt):  # hentet fra https://stackoverflow.com/questions/52408274/showing-points-coordinate-in-plot-in-python
    #     if i_x == 565:
    #         ax1.text(i_x, i_y, '({}, {})'.format(i_x, i_y))
    #
    # for i_x, i_y in zip(days,
    #                     kumdeaths):  # hentet fra https://stackoverflow.com/questions/52408274/showing-points-coordinate-in-plot-in-python
    #     if i_x == 565:
    #         ax2.text(i_x, i_y, '({}, {})'.format(i_x, i_y))

    plotSettings(fig, ax1, ax2, 'Døgn (21.02.2020-31.12.2020)', 'Innlagte', 'Døde')

    #plt.xlabel("Døgn (21.02.2020 - 07.09.2021)")
    #plt.ylabel("Kumulativ innlagte (rød) vs døde (blå)")

    #plt.show()

if __name__ == "__main__":
    plotting()


import datetime
import dataclasses
import warnings
from collections import OrderedDict
from typing import Optional, List, Iterator

from huawei_lte_api.ApiGroup import ApiGroup
from huawei_lte_api.Session import GetResponseType, SetResponseType
from huawei_lte_api.enums.sms import BoxTypeEnum, TextModeEnum, SaveModeEnum, SendTypeEnum, PriorityEnum, TypeEnum, StatusEnum, SortTypeEnum
from huawei_lte_api.Tools import Tools

@dataclasses.dataclass
class Message:
    index: int  # Index in API
    status: StatusEnum  # Status of SMS
    phone: str  # Phone number of sender
    content: str  # Text content of SMS
    date_time: datetime.datetime  # Datetime of SMS send/receive
    sca: Optional[str]  # Message center number in INTL format eg. +420603052000
    save_type: SaveModeEnum  # How to save received SMS in device
    priority: PriorityEnum  # What priority this SMS have
    type: TypeEnum  # Type of SMS
    text_mode: TextModeEnum = TextModeEnum.SEVEN_BIT  # Type of encoding of SMS

    @classmethod
    def from_dict(cls, data: dict) -> 'Message':
        date_time = data.get('Date')
        return Message(
            index=int(data.get('Index', 0)),
            status=StatusEnum(int(data.get('Smstat', 0))),
            phone=data.get('Phone', ''),
            content=data.get('Content', ''),
            date_time=Tools.string_to_datetime(date_time) if date_time else datetime.datetime.now(),
            sca=data.get('Sca'),
            save_type=SaveModeEnum(int(data.get('SaveType', 0))),
            priority=PriorityEnum(int(data.get('Priority', 0))),
            type=TypeEnum(int(data.get('SmsType', 0))),
        )

    def to_dict(self) -> dict:
        return {
            'Index': str(self.index),
            'Smstat': str(self.status.value),
            'Phone': self.phone,
            'Content': self.content,
            'Date': Tools.datetime_to_string(self.date_time),
            'Sca': self.sca,
            'SaveType': str(self.save_type.value),
            'Priority': str(self.priority.value),
            'SmsType': str(self.type.value)
        }

class Sms(ApiGroup):
    def get_cbsnewslist(self) -> GetResponseType:
        return self._session.get('sms/get-cbsnewslist')

    def sms_count(self) -> GetResponseType:
        return self._session.get('sms/sms-count')

    def splitinfo_sms(self) -> GetResponseType:
        return self._session.get('sms/splitinfo-sms')

    def sms_feature_switch(self) -> GetResponseType:
        return self._session.get('sms/sms-feature-switch')

    def send_status(self) -> GetResponseType:
        return self._session.get('sms/send-status')

    def get_sms_list(self,
                     page: int = 1,
                     box_type: BoxTypeEnum = BoxTypeEnum.LOCAL_INBOX,
                     read_count: int = 20,
                     sort_type: SortTypeEnum = SortTypeEnum.DATE,
                     ascending: bool = False,
                     unread_preferred: bool = False
                     ) -> GetResponseType:

        if isinstance(sort_type, int):
            warnings.warn(
                "get_sms_list: Passing int into sort_type is deprecated and will be removed in next minor version! Please use enums.sms.SortTypeEnum instead!.",
                DeprecationWarning
            )
            sort_type = SortTypeEnum(sort_type)

        # Note: at least the B525s-23a is order sensitive
        return Tools.enforce_list_response(self._session.post_get('sms/sms-list', OrderedDict((
            ('PageIndex', page),
            ('ReadCount', read_count),
            ('BoxType', box_type.value),
            ('SortType', sort_type.value),
            ('Ascending', 1 if ascending else 0),
            ('UnreadPreferred', 1 if unread_preferred else 0),
        ))), 'Message', 'Messages')

    def delete_sms(self, sms_id: int) -> SetResponseType:
        """
        Delete single SMS by its ID
        :param sms_id: Id of SMS you wish to delete
        :return: dict
        """
        return self._session.post_set('sms/delete-sms', {'Index': sms_id})

    def backup_sim(self, from_date: datetime.datetime, is_move: bool = False) -> SetResponseType:
        return self._session.post_set('sms/backup-sim', OrderedDict((
            ('IsMove', int(is_move)),
            ('Date', Tools.datetime_to_string(from_date))
        )))

    def set_read(self, sms_id: int) -> SetResponseType:
        return self._session.post_set('sms/set-read', {
            'Index': sms_id
        })

    def save_sms(self,
                 phone_numbers: List[str],
                 message: str,
                 sms_index: int = -1,
                 sca: Optional[str] = None,
                 text_mode: TextModeEnum = TextModeEnum.SEVEN_BIT,
                 from_date: Optional[datetime.datetime] = None,
                 ) -> SetResponseType:
        """

        :param phone_numbers:
        :param message:
        :param sms_index:
        :param sca: (Optional) Message center number in INTL format eg. +420603052000
        :param text_mode:
        :param from_date:
        :return:
        """

        if from_date is None:
            from_date = datetime.datetime.utcnow()

        return self._session.post_set('sms/save-sms', OrderedDict((
            ('Index', sms_index),
            ('Phones', {'Phone': phone_numbers}),
            ('Sca', sca),
            ('Content', message),
            ('Length', len(message)),
            ('Reserved', text_mode.value),
            ('Date', Tools.datetime_to_string(from_date))
        )))

    def send_sms(self,
                 phone_numbers: List[str],
                 message: str,
                 sms_index: int = -1,
                 sca: Optional[str] = None,
                 text_mode: TextModeEnum = TextModeEnum.SEVEN_BIT,
                 from_date: Optional[datetime.datetime] = None,
                 ) -> SetResponseType:
        """

        :param phone_numbers:
        :param message:
        :param sms_index:
        :param sca: (Optional) Message center number in INTL format eg. +420603052000
        :param text_mode:
        :param from_date:
        :return:
        """
        if from_date is None:
            from_date = datetime.datetime.utcnow()
        return self._session.post_set('sms/send-sms', OrderedDict((
            ('Index', sms_index),
            ('Phones', {'Phone': phone_numbers}),
            ('Sca', sca),
            ('Content', message),
            ('Length', len(message)),
            ('Reserved', text_mode.value),
            ('Date', Tools.datetime_to_string(from_date))
        )))

    def cancel_send(self) -> SetResponseType:
        return self._session.post_set('sms/cancel-send', 1)

    def config(self) -> GetResponseType:
        return self._session.get('sms/config')

    def set_config(self,
                   sca: str,
                   save_mode: SaveModeEnum = SaveModeEnum.LOCAL,
                   validity: int = 10752,
                   use_s_report: bool = False,
                   send_type: SendTypeEnum = SendTypeEnum.SEND,
                   priority: PriorityEnum = PriorityEnum.NORMAL
                   ) -> SetResponseType:
        """
        Sets default SMS send config
        :param sca: Message center number in INTL format eg. +420603052000
        :param save_mode:
        :param validity: validity in seconds?
        :param use_s_report:
        :param send_type:
        :param priority:
        :return:
        """
        return self._session.post_set('sms/config', OrderedDict((
            ('SaveMode', save_mode.value),
            ('Validity', validity),
            ('Sca', sca),
            ('UseSReport', use_s_report),
            ('SendType', send_type.value),
            ('Priority', priority.value)
        )))

    def sms_count_contact(self) -> GetResponseType:
        return self._session.get('sms/sms-count-contact')

    def sms_list_contact(self,
                         pageindex: int = 1,
                         readcount: int = 20,
                         ) -> GetResponseType:
        return self._session.post_get('sms/sms-list-contact', {
            'pageindex': pageindex,
            'readcount': readcount,
        })

    def get_sms_list_pdu(self,
                         page: int = 1,
                         box_type: BoxTypeEnum = BoxTypeEnum.LOCAL_INBOX,
                         read_count: int = 20,
                         ) -> GetResponseType:
        """
        Return SMS in PDU format
        :param page: page number
        :param box_type: box type
        :param read_count: items per page
        :return:
        """
        return self._session.post_get('sms/sms-list-pdu', {
            'PageIndex': page,
            'ReadCount': read_count,
            'BoxType': box_type.value,
        })

    def split_sms(self) -> GetResponseType:
        """
        Endpoint found by reverse engineering B310s-22 firmware, unknown usage
        :return:
        """
        return self._session.get('sms/split-sms')

    def send_sms_pdu(self,
                     pdu: str,
                     length: int,
                     sms_index: int = -1,
                     sca: Optional[str] = None,
                     validity: int = 10752,
                     status_report: bool = False,
                     save_mode: SaveModeEnum = SaveModeEnum.LOCAL,
                     send_type: SendTypeEnum = SendTypeEnum.SEND
                     ) -> SetResponseType:
        """
        Sends PDU SMS, this is not implemented on my router so not tested
        :param pdu: PDU to send e.g. 001100098121436587F900000B05E8329BFD06
        :param length: !TODO Length of PDU not an actual len() but some magic calculation I will not research right now
        :param sms_index: Index of sms in router default -1
        :param sca: # Message center number in INTL format e.g. +420603052000
        :param validity: validity in seconds?
        :param status_report: Require status report for sms (received or not)
        :param save_mode: SaveModeEnum
        :param send_type: SendTypeEnum
        :return:
        """

        return self._session.post_set('sms/send-sms-pdu', {
            'Index': sms_index,
            'PDU': pdu,
            'Length': length,
            'SaveMode': save_mode.value,
            'Validity': validity,  # validity in seconds?
            'Sca': sca,  # Message center number in INTL format eg. +420603052000
            'UseSReport': 1 if status_report else 0,  # Report SMS received
            'SendType': send_type.value
        })

    def recover_sms(self) -> GetResponseType:
        """
        Endpoint found by reverse engineering B310s-22 firmware, unknown usage
        :return:
        """
        return self._session.get('sms/recover-sms')

    def copy_sms(self) -> GetResponseType:
        """
        Endpoint found by reverse engineering B310s-22 firmware, unknown usage
        :return:
        """
        return self._session.get('sms/copy-sms')

    def move_sms(self) -> GetResponseType:
        """
        Endpoint found by reverse engineering B310s-22 firmware, unknown usage
        :return:
        """
        return self._session.get('sms/move-sms')

    def get_messages(self,
                     page: int = 1,
                     box_type: BoxTypeEnum = BoxTypeEnum.LOCAL_INBOX,
                     read_count: Optional[int] = None,
                     sort_type: SortTypeEnum = SortTypeEnum.DATE,
                     ascending: bool = False,
                     unread_preferred: bool = False
                     ) -> Iterator[Message]:

        # No read count, return all, API does not provide a way to return all so we need to do it our self
        if read_count is None:
            read_count = 20  # Read by chunks of 20
            page = 1  # Start page has to be always 1

        while True:
            now = datetime.datetime.now()
            sms_list_tmp = self.get_sms_list(page, box_type, read_count, sort_type, ascending, unread_preferred)
            if int(sms_list_tmp.get('Count', 0)) == 0:
                break

            # get messages
            for message_raw in sms_list_tmp.get('Messages', {}).get('Message', []):
                message = Message.from_dict(message_raw)

                # Check if message is possibly multipart,
                # if it is ignore it if is younger than 60 seconds
                # This way we provide the router with enough time to receive all possible parts and do correct rebuild
                if message.type == TypeEnum.MULTIPART and message.date_time + datetime.timedelta(seconds=10) > now:
                    continue

                yield message

            page += 1


from __future__ import annotations

import types
import typing
from imaplib import IMAP4
from imaplib import IMAP4_SSL

from ._config import Configuration
from ._console import console
from ._types import MailBoxesType

class Client:
    """An encapsulation of an IMAP Client.  This client is underpinned by
    either a IMAP4 client if port 143 is provided otherwise it utilises an
    IMAP4_SSL Client.

    :param host: The imap server host.
    :param port: The imap server port.
    """

    def __init__(self, config: Configuration) -> None:
        self.config = config
        self._delegate = self.initialise_client()

    def initialise_client(self) -> typing.Union[IMAP4, IMAP4_SSL]:
        """Initialise the underlying wrapped client."""
        client_cls = IMAP4_SSL if self.config.ssl else IMAP4
        try:
            client = client_cls(**self.config.client_args)
            client.login(self.config.user, self.config.password)
            return client
        except ConnectionError:
            console.print_exception()
            raise
        except IMAP4.error:
            console.print_exception()
            raise

    @property
    def total_mailboxes(self) -> int:
        """Retrieve the total number of mail boxes in the server."""
        return 10

    @property
    def total_mails(self) -> int:
        """Retrieve the total number of emails in all mailboxes."""
        return 1337

    def retrieve_mailboxes(self, directory: str = '""', pattern: str = "*") -> MailBoxesType:
        """Retrieves all the mailboxes available in the server.

        :param directory: The directory to recurse, top-level by default.
        :param pattern: Pattern to apply to names, matches anything by default.
        """
        return self._delegate.list()

    def quota(self, root: str) -> typing.Tuple[str, typing.List[typing.Any]]:
        """Retrieve the roots resource usage and limits."""
        return self._delegate.getquota(root)

    def close(self) -> None:
        """Close the underlying imap client."""
        self._delegate.close()

    def __enter__(self) -> Client:
        return self

    def __exit__(
        self,
        exc_type: typing.Optional[typing.Type[BaseException]] = None,
        exc_val: typing.Optional[BaseException] = None,
        exc_tb: typing.Optional[types.TracebackType] = None,
    ) -> None:
        """Allow the client to be used as a context manager itself."""
        self._delegate.__exit__(exc_type, exc_val, exc_tb)


#  [파이썬 S/W 문제해결 구현] 4일차 - 병합 정렬 (제출용) D3

def merge_sort(lst):
    if len(lst) <= 1:
        return lst

    mid = len(lst) // 2
    left = lst[:mid]
    right = lst[mid:]

    nleft = merge_sort(left)
    nright = merge_sort(right)
    return merge(nleft, nright)

def merge(nleft, nright):
    global cnt
    i, j = 0, 0
    nlst = []

    if nleft[-1] > nright[-1]: #정답 찾기
        cnt += 1

    while i < len(nleft) and j < len(nright):
        if nleft[i] < nright[j]:
            nlst.append(nleft[i])
            i += 1
        else:
            nlst.append(nright[j])
            j += 1
    while i < len(nleft):
        nlst.append(nleft[i])
        i += 1
    while j < len(nright):
        nlst.append(nright[j])
        j += 1
    return nlst

T = int(input())

for tc in range(1, T + 1):
    N = int(input())
    lst = list(map(int, input().split()))
    cnt = 0

    ans = (merge_sort(lst))[N // 2]

    print(f'#{tc} {ans} {cnt}')


import os
import unittest
import unittest.mock
import app
import database
import tempfile

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

import models

class APITestCase(unittest.TestCase):
    class DatabaseMock:
        pass

    def setUp(self):
        self.engine = create_engine('sqlite:///:memory:')
        self.session = scoped_session(sessionmaker(autocommit=False,
                                                   autoflush=False,
                                                   bind=self.engine))
        database.Base.query = self.session.query_property()
        database.Base.metadata.create_all(bind=self.engine)

        self.db_fd, app.app.config['DATABASE'] = tempfile.mkstemp()
        app.app.config['TESTING'] = True
        self.app = app.app.test_client()
        with app.app.app_context():
            database.init_db()

        board = models.Board(
            status='OPEN'
        )
        task1 = models.Task(
            status=False,
            text="TEST TEXT",
            board_id=1
        )
        task2 = models.Task(
            status=True,
            text="TEST TEXT",
            board_id=1
        )
        self.session.add(board)
        self.session.add(task1)
        self.session.add(task2)
        self.session.commit()

    def tearDown(self):
        self.session.remove()
        os.close(self.db_fd)
        os.unlink(app.app.config['DATABASE'])

    def test_get_boards(self):
        rv = self.app.get('/todo/api/v1.0/board')
        self.assertEqual(rv.status_code, 200)
        self.assertNotEqual(len(rv.json), 0)

    def test_get_tasks(self):
        rv = self.app.get('/todo/api/v1.0/tasks')
        self.assertEqual(len(rv.json), 2)
        self.assertEqual(rv.status_code, 200)

    def test_get_tasks_with_status(self):
        rv = self.app.get('todo/api/v1.0/tasks?status=False')
        data = rv.json
        self.assertEqual(data[0]['status'], False)
        self.assertEqual(rv.status_code, 200)

    def test_get_tasks_with_board_id(self):
        rv = self.app.get('/todo/api/v1.0/tasks?board=1')
        data = rv.json
        self.assertEqual(data[0]['board_id'], 1)
        self.assertEqual(rv.status_code, 200)

    def test_get_tasks_with_board_id_error_1(self):
        rv = self.app.get('/todo/api/v1.0/tasks?board=99999999')
        self.assertEqual(rv.status_code, 400)

    def test_get_tasks_with_board_id_error_2(self):
        rv = self.app.get('/todo/api/v1.0/tasks?board=1.2')
        data = rv.json
        self.assertEqual(rv.status_code, 500)
        self.assertEqual(data['error'], 'board must be integer')

    def test_get_tasks_with_query_error(self):
        rv = self.app.get('/todo/api/v1.0/tasks?accord=999')
        self.assertEqual(rv.status_code, 400)

    def test_get_tasks_with_status_error(self):
        rv = self.app.get('/todo/api/v1.0/tasks?status=1')
        self.assertEqual(rv.status_code, 400)

    @unittest.mock.patch('database.db_session.commit', DatabaseMock)
    def test_create_task(self):
        rv = self.app.post('/todo/api/v1.0/tasks', json={"text": "Create test task", "board_id": "1"})
        self.assertEqual(rv.status_code, 201)

    def test_create_task_error_empty_json(self):
        rv = self.app.post('/todo/api/v1.0/tasks', json={})
        self.assertEqual(rv.status_code, 400)

    def test_create_task_error_json(self):
        rv = self.app.post('/todo/api/v1.0/tasks', json={"text_1": "Create new task", "board_id": "2"})
        self.assertEqual(rv.status_code, 400)

    def test_create_task_error_board_id(self):
        rv = self.app.post('/todo/api/v1.0/tasks', json={"text": "Create 2 new task", "board_id": '999999'})
        self.assertEqual(rv.status_code, 500)

    def test_get_tasks_with_id(self):
        rv = self.app.get('/todo/api/v1.0/tasks/1')
        self.assertEqual(rv.status_code, 200)

    def test_get_tasks_with_error_id(self):
        rv = self.app.get('/todo/api/v1.0/tasks/99999')
        self.assertEqual(rv.status_code, 404)

    def test_update_task(self):
        task = models.Task.query.filter_by(id=1).first()
        status = task.status
        self.assertFalse(status)
        rv = self.app.put('/todo/api/v1.0/tasks/1', json={"status": "true"})
        task2 = models.Task.query.filter_by(id=1).first()
        new_status = task2.status
        self.assertTrue(new_status)
        self.assertEqual(rv.status_code, 204)

    def test_update_task_empty_json(self):
        rv = self.app.put('/todo/api/v1.0/tasks/1', json={})
        self.assertEqual(rv.status_code, 400)

    def test_update_task_error_json(self):
        rv = self.app.put('/todo/api/v1.0/tasks/1', json={"status": "TRUE1"})
        self.assertEqual(rv.status_code, 400)

    @unittest.mock.patch('database.db_session.commit', DatabaseMock)
    def test_delete_task(self):
        task = models.Task(
            text='TEST',
            board_id=1
        )
        self.session.add(task)
        self.session.commit()
        id_task = task.id
        rv = self.app.delete(f'/todo/api/v1.0/tasks/{id_task}')
        self.assertEqual(rv.status_code, 204)

    def test_delete_task_error(self):
        rv = self.app.delete(f'/todo/api/v1.0/tasks/99999999')
        self.assertEqual(rv.status_code, 404)

if __name__ == '__main__':
    unittest.main()


# Напишите программу, которая найдёт произведение пар чисел списка.
# Парой считаем первый и последний элемент, второй и предпоследний и т.д.
# *Пример:*
# - [2, 3, 4, 5, 6] =>[12,15,16]      ([2*6, 3*5, 4*4]);
# - [2, 3, 5, 6] => [12,15]   ( [2*6, 3*5])

import random

def create_list(nums_amount, min, max):
    list = []
    for i in range(0, nums_amount):
        list.append(random.randint(min, max))
    return list

def sum_of_corresponding_elements(list):
    sums_list = []

    if len(list)%2 ==0:
        length = int((len(list)/2))
    else:
        length = int((len(list)/2)+0.5)

    for i in range(0, length):
        sums_list.append(list[i]+list[len(list)-1-i])

    return sums_list

new_list = create_list(7, 0, 10)
print(new_list)
print(sum_of_corresponding_elements(new_list))


import arcpy
from arcpy import env
from arcpy.sa import *
from utils import *

__all__ = ['inundation_extents']

def inundation_extents(ElevationRaster, list_thresholds=[0,5,10,15], out_raster_root_path=None, out_polygon_root_path=None, decimal_places=3):
    """ Creates a set of inundation extents based on elevation thresholds and exports them as polygons and/or rasters.

    Inputs:
        ElevationRaster L raster
        list_thresholds [optional] : list
        out_raster_tool_path [optional] : str
        out_polygon_root_path [optional] L str
        decimal_places [optional] : int

    Returns:
        None

    """

    multiplier = 10**decimal_places
    ElevationRasterInt = Int(ElevationRaster * multiplier)

    for i, th in enumerate(list_thresholds):

    #     if i==0:
    #         outRaster=set_null_above(ElevationRasterInt,th*multiplier)
    #         if out_raster_root_path is not None:
    #             outRaster.save(f"{out_raster_root_path}_below_{str(th).replace('.','p')}")
    #         if out_polygon_root_path is not None:
    #             out_polygon_features = f"{out_polygon_root_path}_below_{str(th).replace('.','p')}"
    #             arcpy.conversion.RasterToPolygon(outRaster, out_polygon_features)

        if i<len(list_thresholds)-1:
            low_th = th
            high_th = list_thresholds[i+1]
            outRaster = set_null_between(ElevationRasterInt, low_th*multiplier, high_th*multiplier)
            if out_raster_root_path is not None:
                outRaster.save(f"{out_raster_root_path}_from_{str(low_th).replace('.','p')}_to_{str(high_th).replace('.','p')}")
            if out_polygon_root_path is not None:
                out_polygon_features = f"{out_polygon_root_path}_from_{str(low_th).replace('.','p')}_to_{str(high_th).replace('.','p')}"
                arcpy.conversion.RasterToPolygon(outRaster, out_polygon_features)


#!/usr/bin/env python
# coding: utf-8

import warnings
warnings.filterwarnings('ignore')

# Qiskit
from qiskit.algorithms import NumPyMinimumEigensolver
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit_optimization import QuadraticProgram

# Dwaves
import dimod
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite

import numpy as np
import pandas as pd
from sympy import *
import re
import os

from qiskit.algorithms.optimizers import COBYLA

################### ########
#Different distributions data generator functions

def create_dir(path, log=False):
    if not os.path.exists(path):
        if log:
            print('The directory', path, 'does not exist and will be created')
        os.makedirs(path)
    else:
        if log:
            print('The directory', path, ' already exists')

#################################### SOLVER

def numpy_for_qubo(qubo, p=None):                      # Classical solver for QUBO
  """
  numpy_for_qubo solves the given QUBO using Numpy library functions
  :param
  qubo: CSG problem instance reduced to the form of qubo.

  return:
  result: An array of binary digits which denotes the solutionn of the input qubo problem
  """
  exact_mes = NumPyMinimumEigensolver()
  exact = MinimumEigenOptimizer(exact_mes)  # using the exact classical numpy minimum eigen solver
  result = exact.solve(qubo)
  return result

def solve_QUBO(linear, quadratic, algo, p=1):
  """
  solve_QUBO is ahigher order function to solve QUBO using the given algo parameter function
  :param
  linear: dictionary of linear coefficient terms in the QUBO formulation of the CSG problem.
  quadratic: dictionary of quadratic coefficient terms in the QUBO formulation of the CSG problem.
  algo: a callback function for qaoa_for_qubo or numpy_for_qubo

  return:
  result: An array of binary digits which denotes the solutionn of the input qubo problem

  """
  keys = list(linear.keys())
  keys.sort(key=natural_keys)
  qubo = QuadraticProgram()
  for key in keys:
    qubo.binary_var(key)                                                             # initialize the binary variables
  qubo.minimize(linear=linear, quadratic=quadratic)                                  # initialize the QUBO maximization problem instance
  op, offset = qubo.to_ising()
  qp=QuadraticProgram()
  qp.from_ising(op, offset, linear=True)
  result = algo(qubo, p)
  return result

###############################################

def natural_keys(text):
  """
  alist.sort(key=natural_keys) sorts in human order
  http://nedbatchelder.com/blog/200712/human_sorting.ht
  For example: Built-in function ['x_8','x_10','x_1'].sort() will sort as ['x_1', 'x_10', 'x_8']
  But using natural_keys as callback function for sort() will sort as ['x_1','x_8','x_10']
  param:
  text: a list of strings ending with numerical characters

  return:
  sorted list in a human way
  """
  return [ atoi(c) for c in re.split(r'(\d+)', text) ]

def atoi(text):
  """
  Function returns the corresponding value of a numerical string as integer datatype
  param:
  text: string conntaining only numerical charcaters

  return:
  integer value corresponding to the input text
  """
  return int(text) if text.isdigit() else text

def exact_solver(linear, quadratic, offset = 0.0):
    """
    Solve Ising hamiltonian or qubo problem instance using dimod API.
    dimod is a shared API for samplers.It provides:
    - classes for quadratic models—such as the binary quadratic model (BQM) class that contains Ising and QUBO models used by samplers such as the D-Wave system—and higher-order (non-quadratic) models.
    - reference examples of samplers and composed samplers.
    - abstract base classes for constructing new samplers and composed samplers.

    :params
    linear: dictionary of linear coefficient terms in the QUBO formulation of the CSG problem.
    quadratic: dictionary of quadratic coefficient terms in the QUBO formulation of the CSG problem.
    offset: Constant energy offset associated with the Binary Quadratic Model.

    :return
    sample_set: Samples and any other data returned by dimod samplers.
    """
    vartype = dimod.BINARY

    bqm = dimod.BinaryQuadraticModel(linear, quadratic, offset, vartype)
    sampler = dimod.ExactSolver()
    sample_set = sampler.sample(bqm)
    return sample_set

def dwave_solver(linear, quadratic, offset = 0.0, runs=1000):
    """
    Solve Ising hamiltonian or qubo problem instance using dimod API for using dwave system.

    :params
    linear: dictionary of linear coefficient terms in the QUBO formulation of the CSG problem.
    quadratic: dictionary of quadratic coefficient terms in the QUBO formulation of the CSG problem.
    runs: Number of repeated executions

    :return
    sample_set: Samples and any other data returned by dimod samplers.
    """

    vartype = dimod.BINARY

    bqm = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype)
    sampler = EmbeddingComposite(DWaveSampler())
    sample_set = sampler.sample(bqm, num_reads=runs)
    return sample_set

def extract_best_result(df):
    """
    A function to fetch the binary string with least energy of the input hamiltonian operator

    :params
    df:

    :return
    x: an array of binary digits specifies the solution of the input problem instance
    fval: value of the operator corresponding to the binary digits in x
    """

    row_min = df[df.energy == df.energy.min()]

    cols = []
    for col in df.columns:
        if 'x_' in col:
            cols.append(col)

    x = []

    for col in cols:
        x.append(row_min.iloc[0][col])

    fval = row_min.energy.iloc[0]
    return x, fval

def from_bin_to_var(x, dictionary):
    """
    function to convert binary string to coalition structure

    :params
    x: an array of binary digits (specifies the solution of the input problem instance)
    dictionary: dictionary with coalitions as keys and coalition values as values (CSG problem instance)

    :return
    solution: list of lists. coalition structure.
    """
    solution = []
    for i in range(len(x)):
        if x[i] == 1:
            print(list(dictionary.keys())[i])
            solution.append(list(dictionary.keys())[i])
    return solution

def create_QUBO(linear_dict, quadratic_dict):
    """
    create a QUBO problem instance using the linear and quadratic coefficients.

    :params
    linear: dictionary of linear coefficient terms in the QUBO formulation of the CSG problem.
    quadratic: dictionary of quadratic coefficient terms in the QUBO formulation of the CSG problem.

    :return
    Object of QuadraticProgram class corresponding to the input linear and quadratic coefficients.
    """
    qubo = QuadraticProgram()

    keys = list(linear_dict.keys())
    keys.sort(key=natural_keys)

    for key in keys:
        qubo.binary_var(key)

    qubo.minimize(linear=linear_dict, quadratic=quadratic_dict)
    return qubo

def from_columns_to_string(df):

    cols = []
    for col in df.columns:
        if 'x_' in col:
            cols.append(col)

    df['x'] = 'x'
    for index, row in df.iterrows():
        x = ''
        for col in cols:
            x = x + str(row[col])
        df.loc[index, 'x'] = x
    return df[['x', 'num_occurrences', 'energy']]

def get_ordered_solution(dictionary):
    """
    Reordering the (key,value) pairs in the dictionary to fetch only the values in order.
    param:
    dictionary: input dictionary.

    return:
    solution: list of values after reordering the dictionary elements.
    """
    sortedDict = dict(sorted(dictionary.items(), key=lambda x: x[0].lower()))
    solution = []
    for k, v in sortedDict.items():
        solution.append(v)

    return solution

def results_from_dwave(sample_set, exact=False):
    """
    Fetch the details of the output_ from D-Wave system (Quantum Annealing).

    :params
    sample_set: Samples and any other data returned by dimod samplers.

    :return
    solution: a list of binary values corresponding to the solution provided by the output_ of D-Wave device.
    fval: The function value (operator value) of the input hamiltonian corresponding to the solution.
    prob: Probability of the solution.
    rank: rank of the solution out of all possible binary arrays.
    time: time taken by the D-Wave device to compute the solution.
    """
    df = sample_set.to_pandas_dataframe()
    row_min = df[df.energy == df.energy.min()]

    cols = []
    for col in df.columns:
        if 'x_' in col:
            cols.append(col)

    cols.sort(key=natural_keys)

    solution = []

    for col in cols:
        solution.append(row_min.iloc[0][col])

    fval = row_min.energy.iloc[0]

    if not exact:
        occ_min_fval = row_min.num_occurrences.to_list()[0]
        occurences = df.num_occurrences.to_list()

        occurences = sorted(occurences, reverse=True)

        time = sample_set.info['timing']['qpu_sampling_time']/1000

        rank = occurences.index(occ_min_fval)+1
        prob = occ_min_fval / sum(df.num_occurrences)
    else:
        rank = 1
        prob = 1
        time = 1

    return solution, fval, prob, rank, time


import os
import pandas as pd
import numpy as np
from backend.utils.check_uploaded_files import open_file

def write_tables(params, name, annot_file, r, p, row2bin, bin2label, axis=0):
    """
    Filters, extends and saves annot_file as .json for DataTables JS library +
    writes 2nd half of _var.js. axis=1 corresponds to rows, axis=0 to columns
    """

    # --------------------------------------------------------------------------
    # FILTER, EXTEND ANNOT FILE
    # --------------------------------------------------------------------------

    # filter annotation file and R matrix by the GEs used in the network
    if axis == 1:
        annot = annot_file.loc[r.index]
    else:
        annot = annot_file.loc[r.columns]

    # drop Bin columns we don't need it anymore
    annot.drop('Bin', axis=1, inplace=True)

    # add number of correlated features column to annot file
    corr_num = np.sum(r != 0, axis=axis)
    annot.insert(3, '#corr', corr_num)

    # loop through annot files and add the as separate columns
    #   - name of correlated features,
    #   - r-val of correlated features,
    #   - p-val of correlated features,
    #   - name of bin in network

    corr_name = []
    r_vals = []
    p_vals = []
    corr_bin = []
    if axis == 0:
        r = r.T
        p = p.T

    for row in r.index:
        # names of correlated features
        non_zero = r.loc[row][r.loc[row] != 0]
        non_zero_names = non_zero.index.values.ravel()
        # r-vals of correlated features
        non_zero_r_vals = np.array(map("{0:.3f}".format, non_zero.values.ravel()))
        # p-vals of correlated features
        non_zero_p = p.loc[row][r.loc[row] != 0]
        non_zero_p_vals = np.array(map("{0:.7f}".format, non_zero_p.values.ravel()))

        # sort correlated features alphabetically
        if len(non_zero_names) > 1:
            ind_sort = np.argsort(non_zero_names)
            non_zero_names = non_zero_names[ind_sort]
            non_zero_r_vals = non_zero_r_vals[ind_sort]
            non_zero_p_vals = non_zero_p_vals[ind_sort]

        # merge values intro one string
        corr_name.append('__|__'.join(non_zero_names))
        r_vals.append('__|__'.join(non_zero_r_vals))
        p_vals.append('__|__'.join(non_zero_p_vals))

        # bin name of row
        corr_bin.append(bin2label[row2bin[row]])

    annot.insert(0, 'Name', annot.index.values.ravel())
    annot.insert(0, 'CorrMapperPval', p_vals)
    annot.insert(0, 'CorrMapperRval', r_vals)
    annot.insert(0, 'CorrMapperCorrName', corr_name)
    annot.insert(0, 'CorrMapperBin', corr_bin)

    # --------------------------------------------------------------------------
    # WRITE MODIFIED ANNOT FILE AS JSON
    # --------------------------------------------------------------------------

    json_str = annot.to_json(None, orient='records')
    # make it legible by breaking line and adding tabulation
    n1 = '    '
    n2 = n1 * 2
    json_str = json_str.replace('","','",\n' + n2 + '"')
    json_str = json_str.replace('},{','},\n' + n2 + '{')
    # add prefix and suffix so Data-tables accepts it
    json_str = '{\n' + n1 + '"data":\n' + n2 + json_str + '\n}'

    # save results
    if axis == 1:
        table = '_row-table.json'
        table_var = 'var table1_cols'
    else:
        table = '_column-table.json'
        table_var = 'var table2_cols'

    file_name = file_name = name + table
    out_file = os.path.join(params['vis_genomic_folder'], file_name)
    f = open(out_file, 'w')
    f.write(json_str)
    f.close()

    # --------------------------------------------------------------------------
    # WRITE SECOND HALF OF VARS.JS
    # --------------------------------------------------------------------------

    file_name = name + '_vars.js'
    out_file = os.path.join(params['vis_genomic_folder'], file_name)
    f = open(out_file, 'a')
    f.write(table_var + ' = ' + str(list(annot.columns[4:])) + ';\n')
    f.close()


# coding: UTF-8

class FruitOperate:
    """对水果集合的操作"""
    def __init__(self, fruit_list=None):
        if fruit_list is not None:
            self.fruit_dict = self.__get_fruit_dict(fruit_list)
        else:
            self.fruit_dict = {}    # 存放水果信息的列表

    @staticmethod
    def __get_fruit_dict(fruit_list):
        """把传进来的水果信息转换成字典格式"""
        fruit_dict = {}
        for fruit in fruit_list:
            fruit_dict[fruit.name] = fruit
        return fruit_dict

    def judge_fruit_exist(self, name):
        """判断水果在不在库中"""
        if name in self.fruit_dict:
            return True
        else:
            return False

    def query_all_fruit(self):
        """查询全部"""
        info_list = ["共查询到{}条记录".format(len(self.fruit_dict))]
        for fruit in self.fruit_dict.values():
            info_list.append(fruit.name + " 价格:" + str(fruit.price) + "  数量:" + str(fruit.amount))
        return info_list

    def query_single_fruit(self, fruit_name: str):
        """根据水果名查询水果信息"""
        info_list = []
        if fruit_name in self.fruit_dict:
            fruit = self.fruit_dict[fruit_name]
            info_list.append(fruit.name + " 价格:" + str(fruit.price) + "  数量:" + str(fruit.amount))
        else:
            info_list.append("库存中没有{}".format(fruit_name))
        return info_list

    def add_fruit(self, fruit):
        """增加一种水果"""
        if fruit.name in self.fruit_dict:
            return False
        self.fruit_dict[fruit.name] = fruit
        return True

    def modify_fruit(self, name: str, price=None, amount=None):
        """修改水果信息"""
        if name in self.fruit_dict:
            if price is not None and price != "":
                self.fruit_dict[name].price = price
            if amount is not None and amount != "":
                self.fruit_dict[name].amount = amount
            return True
        else:
            return False

    def remove_fruit(self, name):
        """删除指定名字的水果"""
        if name in self.fruit_dict:
            self.fruit_dict.pop(name)
            return True
        else:
            return False


import tkinter as tk
from tkinter import messagebox
from typing import List, Optional

class TicTacToe:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Tic Tac Toe")
        self.player_turn = 'X'

        # Initialize buttons
        self.buttons: List[List[Optional[tk.Button]]] = [[None for _ in range(3)] for _ in range(3)]

        for i in range(3):
            for j in range(3):
                self.buttons[i][j] = tk.Button(self.root, width=10, height=5,
                                               command=lambda row=i, col=j: self.click(row, col),
                                               bg='white', fg='black')
                self.buttons[i][j].grid(row=i, column=j)

        self.reset_button = tk.Button(self.root, text="Reset", command=self.reset_game)
        self.reset_button.grid(row=3, columnspan=3)

    def click(self, i, j):
        if self.buttons[i][j]["text"] == "":
            self.buttons[i][j]["text"] = self.player_turn
            if self.player_turn == 'X':
                self.buttons[i][j]["fg"] = 'red'
            else:
                self.buttons[i][j]["fg"] = 'blue'
            self.buttons[i][j]["state"] = 'disabled'
            if self.check_winner(self.player_turn):
                messagebox.showinfo("Game Over", "{} Wins!".format(self.player_turn))
                self.reset_game()
                return
            elif self.player_turn == 'X':
                self.player_turn = 'O'
            else:
                self.player_turn = 'X'

    def check_winner(self, player):
        for i in range(3):
            row_win = all(self.buttons[i][j]['text'] == player for j in range(3))
            col_win = all(self.buttons[j][i]['text'] == player for j in range(3))
            if row_win or col_win:
                return True

        diagonal1_win = all(self.buttons[i][i]['text'] == player for i in range(3))
        diagonal2_win = all(self.buttons[i][2 - i]['text'] == player for i in range(3))

        if diagonal1_win or diagonal2_win:
            return True

        return False

    def reset_game(self):
        for i in range(3):
            for j in range(3):
                self.buttons[i][j]["text"] = ""
                self.buttons[i][j]["state"] = "normal"
                self.buttons[i][j]["fg"] = "black"
        self.player_turn = 'X'

    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    game = TicTacToe()
    game.run()


import torch
import torch.nn as nn
import torch.nn.functional as F
from Pointnet.models.pointnet2_utils import PointNetSetAbstraction,PointNetFeaturePropagation
import numpy as np

class pointSem(nn.Module):
    def __init__(self):
        super(pointSem, self).__init__()
        self.sa = PointNetSetAbstraction(1024, 0.1, 32, 9, [32, 32, 64], False)
        self.sa2 = PointNetSetAbstraction(256, 0.2, 32, 64 + 3, [64, 64, 128], False)
        self.sa3 = PointNetSetAbstraction(64, 0.4, 32, 128 + 3, [128, 128, 256], False)
        self.sa4 = PointNetSetAbstraction(16, 0.8, 32, 256 + 3, [256, 256, 512], False)
        self.fp4 = PointNetFeaturePropagation(768, [256, 256])
        self.fp3 = PointNetFeaturePropagation(384, [256, 256])
        self.fp2 = PointNetFeaturePropagation(320, [256, 128])
        self.fp1 = PointNetFeaturePropagation(128, [128, 128, 128])
        self.conv1 = nn.Conv1d(128, 128, 1)
        self.bn1 = nn.BatchNorm1d(128)
        self.drop1 = nn.Dropout(0.5)
        self.conv = nn.Conv1d(128,16, 1)
        #self.fcx = nn.Linear(1280,512)
        #self.adaptive = nn.AdaptiveAvgPool1d(512)

    def sortit(self,xyz,points):
        print(points.shape, " ", xyz.shape, " ", type(points))
        new_xyz = np.zeros((1,points.shape[2],3))
        new_points = np.zeros((1,points.shape[2],points.shape[1]))
        xyz = xyz.permute(0,2,1).cpu().detach().numpy()
        points = points.permute(0,2,1).cpu().detach().numpy()
        for i,x in enumerate(xyz):
            print(points.shape, " ", x.shape, " ", type(x))
            temp = points[i][np.argsort(x[:,0])].reshape((1,points[1],points[2]))
            new_points = np.append(new_points,temp,axis=0)
            temp = xyz[i][np.argsort(x[:,0])].reshape((1,xyz[1],3))
            new_xyz = np.append(new_xyz,temp,axis=0)
        xyz = torch.tensor(new_xyz).float()
        points = torch.tensor(new_points).float()

        return xyz[1:],permute(0,2,1), points[1:].permute(0,2,1)

    def forward(self, xyz):
        l0_points = xyz
        l0_xyz = xyz[:,:3,:]
        print(l0_points.shape, ' ', l0_xyz.shape)

        l1_xyz, l1_points = self.sa(l0_xyz, l0_points)
        #l1_xyz, l1_points = self.sortit(l1_xyz,l1_points)
        l2_xyz, l2_points = self.sa2(l1_xyz, l1_points)
        #l2_xyz, l2_points = self.sortit(l2_xyz,l2_points)
        l3_xyz, l3_points = self.sa3(l2_xyz, l2_points)
        #l3_xyz, l3_points = self.sortit(l3_xyz,l3_points)
        l4_xyz, l4_points = self.sa4(l3_xyz, l3_points)
        #l4_xyz, l4_points = self.sortit(l4_xyz,l4_points)

        l3_points = self.fp4(l3_xyz, l4_xyz, l3_points, l4_points)
        l2_points = self.fp3(l2_xyz, l3_xyz, l2_points, l3_points)
        l1_points = self.fp2(l1_xyz, l2_xyz, l1_points, l2_points)
        l0_points = self.fp1(l0_xyz, l1_xyz, None, l1_points)

        x = self.drop1(F.relu(self.bn1(self.conv1(l0_points))))
        x = self.conv(x)
        #x = self.fcx(x)
        #x = self.adaptive(x)
        print("hi")
        print(x.shape)
        x = F.log_softmax(x, dim=1)
        x = x.permute(0, 2, 1).squeeze()
        print(x.shape)
        return x.reshape(-1,16*1280) #l3_points.permute(0,2,1)

class get_loss(nn.Module):
    def __init__(self):
        super(get_loss, self).__init__()
    def forward(self, pred, target, trans_feat, weight):
        total_loss = F.nll_loss(pred, target, weight=weight)

        return total_loss

if __name__ == '__main__':
    import  torch
    model = get_model(13)
    xyz = torch.rand(6, 9, 2048)
    (model(xyz))


# works on HC04 IC Chip - Hex inverters

import RPi.GPIO as GPIO
from time import sleep

ON = GPIO.HIGH
OFF = GPIO.LOW

GPIO.setmode(GPIO.BCM)
pin_list = [1,3,5,9,11,13]

def setup():
    for pin in pin_list:
        GPIO.setup(pin, GPIO.OUT)

def turnon(delay):
    for pin in pin_list:
        GPIO.output(pin, ON)
        print("pin " + str(pin) + " is on!")
        sleep(delay)

def turnoff(delay):
    for pin in pin_list:
        GPIO.output(pin, OFF)
        print("pin " + str(pin) + " is off!!")
        sleep(delay)

def main():
    setup()
    try:
        while(True):
            turnon(0.7)
            turnoff(0.7)
    except KeyboardInterrupt:
        GPIO.cleanup()

main()


import sys

# 230605

input = sys.stdin.readline

answer = []

for _ in range(int(input())):
    answer.append(tuple(map(int, input().split())))

answer.sort(key=lambda tp: (tp[0], tp[1]))
for tp in answer:
    print(tp[0], tp[1])


from typing import Tuple
from turtle import Turtle, RawTurtle

def draw_pixel(turtle: Turtle | RawTurtle, pixel: Tuple[int, int], color="black"):
    turtle.penup()
    turtle.goto(pixel)
    turtle.color(color)
    turtle.pendown()
    turtle.dot(5)
    return turtle


class GameStats():
    """Armazena os dados estatísticos da Invasção Alienígena"""

    def __init__(self, ai_settings):
        """Inicializa dos dados estatístivos."""
        self.ai_settings = ai_settings
        self.reset_stats()
        # Inicializa a Invasão Alienígena como ativa
        self.game_active = False

        # A pontuação máxima jamais devera ser reiniciada
        self.high_score = 0

    def reset_stats(self):
        """Inicializa os dados estatísticos que podem mudar durante o jogo."""
        self.ships_left = self.ai_settings.ship_limit
        self.score = 0
        self.level = 0


"""Documentazione ufficiale Flask>> https://flask.palletsprojects.com/en/2.2.x/quickstart/"""
from flask import Flask, request

app = Flask(__name__)

#DECORETOR: prende in input la funzione somma, esegue codice prima e dopo essa. il valore di ritorno è un'altra funzione
@app.route('/', methods=['GET'])
def somma():
    try:
        a = int(request.args.get('a'))
        b = int(request.args.get('b'))
        c = a + b
        return str(c)
    except:
        return "Errore!!"
    """return "
Faccio la somma
"""

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

# RICHIESTA HTTP = http://localhost:5000/?a=2&b=7      --> 9            è andata a buon fine la richiesta
# RICHIESTA HTTP = http://localhost:5000/?a=2&b=fhbsd  --> Errore!!     non è andata a buon fine la richiesta


import collections
from dis import disco
N, M, V = map(int, input().split())

graph = collections.defaultdict(list)

for _ in range(M):
    N1, N2 = map(int, input().split())
    graph[N1].append(N2)
    graph[N2].append(N1)

for _ in graph.values():
    _.sort()

def DFS(v, discovered=[]):
    discovered.append(v)
    for w in graph[v]:
        if w not in discovered:
            discovered = DFS(w, discovered)
    return discovered

def BFS(start_v):
    discovered = [start_v]
    queue = [start_v]
    while queue:
        v = queue.pop(0)
        for w in graph[v]:
            if w not in discovered:
                discovered.append(w)
                queue.append(w)
    return discovered

print(*DFS(V))
print(*BFS(V))


import smtplib

def mail(subject):
    # creates SMTP session
    s = smtplib.SMTP('smtp.gmail.com', 587)

    # start TLS for security
    s.starttls()

    # Authentication
    s.login("automailsforme@gmail.com", "automailsforme123")

    # message to be sent
    message = subject

    # sending the mail
    s.sendmail("automailsforme@gmail.com", "tinto.t.kurian@gmail.com", message)

    # terminating the session
    s.quit()

def main():
    mail("This is an automated mail")

if __name__ == '__main__':
    main()


from selenium import webdriver
from pages.quotes_page import QuotesPage

firefox = webdriver.Firefox(executable_path = 'C:\\Users\\Owais Mohammad\\PythonProjects\\geckodriver.exe')
firefox.get('http://quotes.toscrape.com/search.aspx')
page = QuotesPage(firefox)

author = page.ask_for_author()
page.select_author(author_name=author)

tags = page.get_available_tags()
tag = page.ask_for_tag(tags)

page.select_tag(tag_name=tag)

page.search_button.click()

print(page.quotes)


'''
2021.08.31. Fire! (불!)
https://www.acmicpc.net/problem/4179
'''
from sys import stdin
from collections import deque

stdin = open("../input.txt", "r")

dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

r, c = map(int, stdin.readline().rstrip().split())
board = [list(map(str, stdin.readline().rstrip())) for _ in range(r)]
dist = [[-1] * c for _ in range(r)]
fire = [[-1] * c for _ in range(r)]
dist_q, fire_q = deque(), deque()

for i in range(r):
    for j in range(c):
        if board[i][j] == 'J':
            dist_q.append([i, j])
            dist[i][j] = 0
        if board[i][j] == 'F':
            fire_q.append([i, j])
            fire[i][j] = 0

while fire_q:
    cur_x, cur_y = fire_q.popleft()
    for dir in range(4):
        nx, ny = cur_x + dx[dir], cur_y + dy[dir]
        if 0 <= nx < r and 0 <= ny < c:
            if board[nx][ny] == '.' and fire[nx][ny] == -1:
                fire_q.append([nx, ny])
                fire[nx][ny] = fire[cur_x][cur_y] + 1

while dist_q:
    cur_x, cur_y = dist_q.popleft()
    for dir in range(4):
        nx, ny = cur_x + dx[dir], cur_y + dy[dir]
        if not (0 <= nx < r and 0 <= ny < c):
            print(dist[cur_x][cur_y] + 1)
            exit(0)
        if dist[nx][ny] >= 0 or board[nx][ny] == '#':
            continue
        if fire[nx][ny] != -1 and fire[nx][ny] <= dist[cur_x][cur_y] + 1:
            continue
        dist_q.append([nx, ny])
        dist[nx][ny] = dist[cur_x][cur_y] + 1
print("IMPOSSIBLE")