from collections import namedtuple

"""
The following tuples are defined to help store all types of expressions.
For example, the Reference_constant tuple is defined to address the single_assignment of type (reference := constant). So it
contains three elements: reference, constant and the line number in the alg file. More examples are listed below:

- Reference_if_expression: contains reference, if_expression which is of type If_Expression and finally the line number
- FunctionCall: includes a name of the function, expression which contains all parameter expressions (see the function_call rule)
  and finally the line number
- ElseIf: contains a condition (which is an expression rule), expression to be visited when the condition is true and
  finally the line number

"""

Reference_constant = namedtuple('Reference_constant', ['reference', 'constant', 'line'])
Reference_Reference = namedtuple('Reference_Reference', ['reference1', 'reference2', 'line'])
#MinMax_Expressions = namedtuple('MinMax_Expressions', ['references', 'types', 'vals'])
Reference_if_expression = namedtuple('Reference_if_expression', ['reference', 'if_expression', 'line'])
BinaryOperation = namedtuple('BinaryOperation', ['expression1', 'operation', 'expression2', 'line'])
Reference_binary_operation = namedtuple('Reference_binary_operation', ['reference', 'binaryOperation', 'line'])
VarTypeCausality = namedtuple('VarTypeCausality', ['type', 'causality', 'line'])
ExpressionVariable = namedtuple('ExpressionVariable', ['name', 'line'])
ElseIf = namedtuple ('ElseIf', ['condition', 'expression', 'line'])
FunctionCall = namedtuple('FunctionCall', ['name', 'expression', 'line'])
UnaryOperation = namedtuple('UnaryOperation', ['operation', 'expression', 'line'])
Reference_function_call = namedtuple('Reference_function_call', ['reference', 'functionCall', 'line'])

class If_Expression:

    """
    Class If_Expression represents the if_expression rule, it contains a number of properties to store all elements of the
    if_expression. These properties include:

    - conditions: stores the expression which act as a condition after the "if" keyword (see the if_expression rule)
    - elseIf: contains all the elseif_expression expressions
    - expression: includes the expression which is visited when the condition is true
    - elseExpr: contains the expression which is visited when the condition is false

    """

    def __init__(self):
        self.conditions = {}
        self.elseIf = {}
        self.expression = {}
        self.elseExpr = {}
        self.condCounter = 0
        self.elseIfCounter = 0
        self.expressionCounter = 0
        self.elseCounter = 0

    def addCondition (self, condition):
        self.condCounter += 1
        cond = 'condition' + str(self.condCounter)
        self.conditions[cond] = condition

    def addElseIF(self, condition, expression):
        self.elseIfCounter += 1
        elseIfKey = 'elseIf' + str(self.elseIfCounter)
        elseIfVal = ElseIf(condition, expression, condition[2])
        self.elseIf[elseIfKey] = elseIfVal

    def addExpression (self, expression):
        self.expressionCounter += 1
        expr = 'expression' + str(self.expressionCounter)
        self.expression[expr] = expression

    def addElseExpression (self, expression):
        self.elseCounter += 1
        expr = 'elseExpr' + str(self.elseCounter)
        self.elseExpr[expr] = expression

    def getConditions (self):
        return self.conditions

    def getElseIfs (self):
        return self.elseIf

    def getExpressions (self):
        return self.expression

    def getElseExpr (self):
        return self.elseExpr

    def toString (self):
        ifString = []
        str1 = 'if'
        ifString.append(str1)
        for x in self.conditions.keys():
            #ifString += ' ' + self.conditions[x][1]
            str1 = self.conditions[x][1]
            ifString.append(str1)
        str1 = 'then'
        ifString.append(str1)
        for x in self.expression.keys():
            str1 = self.expression[x][1]
            ifString.append(str1)
        if len(self.elseIf) > 0:
            str1 = 'elseif'
            ifString.append(str1)
            for x in self.elseIf.keys():
                str1 = self.elseIf[x].condition
                ifString.append(str1)
            for x in self.elseIf.keys():
                str1 = self.elseIf[x].expression
                ifString.append(str1)
        if len(self.elseExpr) > 0:
            str1 = 'else'
            ifString.append(str1)
            for x in self.elseExpr.keys():
                #print (self.elseExpr[x][1].expression1[1])#, self.elseExpr[x][1].operation, self.elseExpr[x][1].expression2[1])
                str1 = "exp1 " + str(self.elseExpr[x][1].expression1[1]) + " operation " + str(self.elseExpr[x][1].operation) + " exp2 " + str(self.elseExpr[x][1].expression2[1])
                ifString.append(str1)
        return ifString

class Function:

    """
    Class Function represents the function_declaration rule, it contains a number of properties to store all local variables
    and expressions of the function_declaration. These properties include:

    - declaredLocalVars: stores the local declared variables
    - expressionsVariables: a list of all references contained in expressions of the function
    - reference_to_constant: includes all Reference_constant expressions which are contained in the function
    - reference_to_if_expression: contains all Reference_if_expression expressions
    - binaryOperations: stores all Reference_binary_operation expressions
    - and others, all hold proper names that explain the purpose

    """
    def __init__(self):
        self.declaredLocalVars = {}
        self.expressionsVariables = []
        self.reference_to_constant = {}
        self.reference_to_if_expression = {}
        self.reference_to_reference = {}
        self.reference_to_functionCall = {}
        #self.single_assignment = {}
        self.binaryOperations = {}
        self.method = False
        self.function = False
        self.refToConstCounter = 0
        self.refToBinaryOperCounter = 0
        self.refToRefCounter = 0
        self.refToIfExprCounter = 0
        self.refToFunctionCallCounter = 0

    def setName (self, name):
        self.name = name

    def setFunctionMethod(self, methodFunction):
        if methodFunction == 'function':
            self.function = True
        else:
            self.method = True

    def addDeclaredLocalVars (self, varCausality, nameAndType, line):
        #varCausality = node[i].children[j].children[0].value
        varTypeCaus = VarTypeCausality(nameAndType[1], varCausality, line)
        if len(nameAndType[0]) == 1:
            self.declaredLocalVars[nameAndType[0][0]] = varTypeCaus
        else:
            for i in range(len(nameAndType[0])):
                self.declaredLocalVars[nameAndType[0][i]] = varTypeCaus

    def addReference_to_constant (self, refConstant):
        self.refToConstCounter += 1
        statement = 'refToConst' + str(self.refToConstCounter)
        exprVar= ExpressionVariable (refConstant.reference, refConstant.line)
        #print (" adding from Reference_to_constant  " + exprVar.name)
        self.expressionsVariables.append(exprVar)
        self.reference_to_constant[statement] = refConstant

    def addReference_to_binaryOperation(self, refToBinaryOperation):
        self.refToBinaryOperCounter += 1
        statement = 'refToBinaryOperation' + str(self.refToBinaryOperCounter)
        #binaryOperation = BinaryOperation(expression1, operation, expression2)
        exprVar= ExpressionVariable (refToBinaryOperation.reference, refToBinaryOperation.line)

        self.expressionsVariables.append(exprVar)
        self.expressionsVariables += self.__retrieveVars_binaryOperation(refToBinaryOperation.binaryOperation)

        self.binaryOperations[statement] = refToBinaryOperation

    def addReference_to_reference(self, refToRef):
        self.refToRefCounter += 1
        statement = 'refToRef' + str(self.refToRefCounter)
        exprVar1= ExpressionVariable (refToRef.reference1, refToRef.line)
        self.expressionsVariables.append(exprVar1)
        exprVar2= ExpressionVariable (refToRef.reference2, refToRef.line)
        self.expressionsVariables.append(exprVar2)
        self.reference_to_reference[statement] = refToRef

    def addReference_to_ifExpression (self, refToIfExpression):
        self.refToIfExprCounter += 1
        statement = 'refToIfExpr' + str(self.refToIfExprCounter)
        exprVar= ExpressionVariable (refToIfExpression.reference, refToIfExpression.line)
        self.expressionsVariables.append(exprVar)
        self.expressionsVariables += self.__retrieveIfExprVars(refToIfExpression.if_expression)

        self.reference_to_if_expression[statement] = refToIfExpression

    def addReference_to_functionCall (self, refToFunctionCall):
        self.refToFunctionCallCounter += 1
        statement = 'refToIfExpr' + str(self.refToFunctionCallCounter)
        exprVar= ExpressionVariable (refToFunctionCall.reference, refToFunctionCall.line)
        self.expressionsVariables.append(exprVar)

        self.expressionsVariables += self.__retrieveVars_functionCall(refToFunctionCall.functionCall)
        self.reference_to_functionCall[statement] = refToFunctionCall

    def addExpressionVar (self, exprvar):
        self.expressionsVariables.append(exprvar)

    def __retrieveIfExprVars (self, ifExpression):

        varList = []
        condtionsList = ifExpression.getConditions()
        for key in condtionsList.keys():
            varList += self.__retrieveVars_expression(condtionsList[key])

        expressionsList = ifExpression.getExpressions()
        for key in expressionsList.keys():
            varList += self.__retrieveVars_expression(expressionsList[key])

        elseifList = ifExpression.getElseIfs()
        for key in elseifList.keys():
            varList += self.__retrieveVars_expression(elseifList[key].condition)
            varList += self.__retrieveVars_expression(elseifList[key].expression)

        elseExpressions = ifExpression.getElseExpr()
        for key in elseExpressions.keys():
            varList += self.__retrieveVars_expression(elseExpressions[key])

        return varList

    def __retrieveVars_expression(self, expression):
        varList = []
        #print(expression)
        if expression[0] == 'reference':
            exprVar= ExpressionVariable (expression[1], expression[2])
            varList.append(exprVar)
        elif expression[0] == 'binary_operation':
            varList += self.__retrieveVars_binaryOperation(expression[1])
        elif expression[0] == 'if_expression':
            varList += self.__retrieveIfExprVars(expression[1])
        elif expression[0] == 'function_call':
            varList += self.__retrieveVars_functionCall(expression[1])
        elif expression[0] == 'unary_operation':
            if expression[1] == 'function_call':
                varList += self.__retrieveVars_functionCall(expression[2])
            elif expression[1] == 'reference':
                exprVar= ExpressionVariable (expression[2], expression[3])
                varList.append(exprVar)
            elif expression[1] == 'binary_operation':

                varList += self.__retrieveVars_binaryOperation(expression[2])
            elif expression[1] == 'if_expression':
                varList += self.__retrieveVars_functionCall(expression[2])

        return varList

    def __retrieveVars_functionCall(self, functionCall):
        varList= []
        exprsList = functionCall.expression
        for i in range(len(exprsList)):
            varList += self.__retrieveVars_expression(exprsList[i])

        return varList

    def __retrieveVars_binaryOperation (self, binaryOperation):
        varsList = []

        expr1 = binaryOperation.expression1
        expr2 = binaryOperation.expression2

        if expr1[0] == "reference":
            exprVar= ExpressionVariable (expr1[1], binaryOperation.line)
            varsList.append(exprVar)
        elif expr1[0] == "binary_operation":
            varsList += self.__retrieveVars_binaryOperation(expr1[1])

        if expr2[0] == "reference":
            exprVar= ExpressionVariable (expr2[1], binaryOperation.line)
            varsList.append(exprVar)
        elif expr2[0] == "binary_operation":
            varsList += self.__retrieveVars_binaryOperation(expr2[1])

        return varsList

    def getExpressionsVariables (self):
        return self.expressionsVariables

    def getLocalVariables (self):
        return self.declaredLocalVars

    def getReference_to_constant (self):
        return self.reference_to_constant

    def getReference_to_if_expression (self):
        return self.reference_to_if_expression

    def getReference_to_reference (self):
        return self.reference_to_reference

    def getBinary_operations (self):
        return self.binaryOperations

    def getReference_to_functionCall (self):
        return self.reference_to_functionCall

    def display (self):
        print(self.name)
        for x in self.reference_to_constant.keys():
            print(x, " ref = ",  self.reference_to_constant[x].reference, " constant = ", self.reference_to_constant[x].constant)
        for x in self.reference_to_reference.keys():
            print(x, " ref1 = ", self.reference_to_reference[x].reference1, " ref2 = ", self.reference_to_reference[x].reference2)
        for x in self.binaryOperations.keys():
            print(x, " ref = ", self.binaryOperations[x].reference, " exp1 = ", self.binaryOperations[x].binaryOperation.expression1, " operation ", self.binaryOperations[x].binaryOperation.operation, " exp2 = ", self.binaryOperations[x].binaryOperation.expression2)
        for x in self.reference_to_if_expression.keys():
            print(x)
            print ("...", " ref = ", self.reference_to_if_expression[x].reference)
            #print ("......", self.reference_to_if_expression[x].if_expression.toString())
            for i in range(len(self.reference_to_if_expression[x].if_expression.toString())):
                print(self.reference_to_if_expression[x].if_expression.toString()[i])


import time
from random import randint

from sqlalchemy.orm import Session

from . import models, schemas

def get_user(db: Session, user_id: int):
    return db.query(models.User).filter(models.User.id == user_id).first()

def get_user_by_email(db: Session, email: str):
    return db.query(models.User).filter(models.User.email == email).first()

def get_users(db: Session, skip: int = 0, limit: int = 100):
    return db.query(models.User).offset(skip).limit(limit).all()

def get_user_by_phonenumber(db: Session, phonenumber: str):
    return db.query(models.User).filter(models.User.phonenumber == phonenumber).first()

def create_user(db: Session, user:schemas.UserCreate):
    token = hash(user.email + user.phonenumber + str(time.time()) + str(randint(0,1000000)))
    db_user = models.User(email=user.email, phonenumber=user.phonenumber, name=user.name, token=token)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

def get_contacts(db: Session, user_id: int, skip: int = 0, limit: int = 100):
    return db.query(models.Contact).filter(models.Contact.owner_id == user_id).offset(skip).limit(limit).all()

def create_user_contact(db: Session, contact: schemas.ContactCreate, user_id: int):
    db_contact = models.Contact(**contact.dict(), owner_id=user_id)
    db.add(db_contact)
    db.commit()
    db.refresh(db_contact)
    return db_contact

def contact_check(db: Session, user_id: int, contact_mail: str, contact_phonenumber: str):
    db_contact = db.query(models.Contact).filter(models.Contact.owner_id == user_id).filter(models.Contact.email == contact_mail).filter(models.Contact.phonenumber == contact_phonenumber).first()
    if db_contact is not None:
        return True
    else:
        return False

def update_user_email(db: Session, user_id: int, mail: str):
    db_user = db.query(models.User).filter(models.User.id == user_id).first()
    if db_user is None:
        return None
    db_user.email = mail
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

def update_user_phonenumber(db: Session, user_id: int, phone_number: str):
    db_user = db.query(models.User).filter(models.User.id == user_id).first()
    if db_user is None:
        return None
    db_user.phonenumber = phone_number
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

def delete_user(db: Session, user_id: int):
    db_user = db.query(models.User).filter(models.User.id == user_id).first()
    skip = 0
    limit = 100
    try:
        db_contacts = db.query(models.Contact).filter(models.Contact.owner_id == user_id).offset(skip).limit(limit).all()
        for db_contact in db_contacts:
            db.delete(db_contact)
        db.delete(db_user)
        db.commit()
        return True
    except:
        return False

def update_contact_email(db: Session, user_id: int, email: str, mail: str):
    db_contact = db.query(models.Contact).filter(models.Contact.owner_id == user_id and models.Contact.email == email).first()
    db_contact.email = mail
    db.add(db_contact)
    db.commit()
    db.refresh(db_contact)
    return db_contact

def update_contact_phonenumber(db: Session, user_id: int, phonenumber: str, newphonenumber: str):
    db_contact = db.query(models.Contact).filter(models.Contact.owner_id == user_id and models.Contact.phonenumber == phonenumber).first()
    db_contact.phonenumber = newphonenumber
    db.add(db_contact)
    db.commit()
    db.refresh(db_contact)
    return db_contact

def delete_contact(db: Session, user_id: int, contact_param: str):
    db_contact = db.query(models.Contact).filter(models.Contact.owner_id == user_id
                                                 and (models.Contact.phonenumber == contact_param
                                                      or models.Contact.email == contact_param)).first()
    if db_contact is None:
        return False
    print(db_contact.email)
    try:
        db.delete(db_contact)
        db.commit()
        return True
    except:
        return False

def update_user_premium_status(db: Session, user_id: int):
    try:
        db_user = db.query(models.User).filter(models.User.id == user_id).first()
        if db_user is None:
            return False
        db_user.premium = True
        db.add(db_user)
        db.commit()
        db.refresh(db_user)
        return True
    except Exception as e:
        print(e)


import unittest
from typing import List

class Solution:
    def sumPrefixScores(self, words: List[str]) -> List[int]:
        # get prefix map
        prefix_map = {}
        for word in words:
            prefix = ""
            for c in word:
                prefix += c
                if prefix in prefix_map:
                    prefix_map[prefix] += 1
                else:
                    prefix_map[prefix] = 1

        ans = []
        for word in words:
            score = 0
            prefix = ""
            for c in word:
                prefix += c
                score += prefix_map[prefix]
            ans.append(score)
        return ans

class Test(unittest.TestCase):
    def test(self):
        cases = [
            [["abc", "ab", "bc", "b"], [5, 4, 3, 2]],
            [["abcd"], [4]],
        ]
        for ci, co in cases:
            result = Solution().sumPrefixScores(ci)
            assert result == co, (ci, co, result)

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

6183. Sum of Prefix Scores of Strings.py


from dataclasses import dataclass
from itertools import chain, repeat
from pprint import pformat
from string import Template
from textwrap import dedent
from typing import (
    AbstractSet,
    Iterable,
    Iterator,
    MutableMapping,
    MutableSequence,
    Optional,
    Sequence,
    Tuple,
)
from uuid import uuid4

from pynvim import Nvim
from pynvim.api import Buffer, Window
from pynvim.api.common import NvimError
from pynvim_pp.api import (
    buf_get_extmarks,
    buf_get_lines,
    buf_set_text,
    create_ns,
    cur_win,
    win_get_buf,
    win_get_cursor,
    win_set_cursor,
)
from pynvim_pp.lib import decode, encode, write
from pynvim_pp.logging import log
from std2.types import never

from ..consts import DEBUG
from ..lang import LANG
from ..shared.runtime import Metric
from ..shared.trans import trans_adjusted
from ..shared.types import (
    UTF8,
    UTF16,
    Completion,
    Context,
    ContextualEdit,
    Edit,
    Mark,
    NvimPos,
    RangeEdit,
    SnippetEdit,
)
from ..snippets.parse import ParsedEdit, parse
from ..snippets.parsers.types import ParseError
from .mark import mark
from .rt_types import Stack
from .state import State

NS = uuid4()

@dataclass(frozen=True)
class EditInstruction:
    primary: bool
    begin: NvimPos
    end: NvimPos
    cursor_yoffset: int
    cursor_xpos: int
    new_lines: Sequence[str]

@dataclass(frozen=True)
class _Lines:
    lines: Sequence[str]
    b_lines8: Sequence[bytes]
    b_lines16: Sequence[bytes]
    len8: Sequence[int]

def _lines(lines: Sequence[str]) -> _Lines:
    b_lines8 = tuple(map(encode, lines))
    return _Lines(
        lines=lines,
        b_lines8=b_lines8,
        b_lines16=tuple(encode(line, encoding=UTF16) for line in lines),
        len8=tuple(len(line) for line in b_lines8),
    )

def _rows_to_fetch(ctx: Context, edit: Edit, *edits: Edit) -> Tuple[int, int]:
    row, _ = ctx.position

    def cont() -> Iterator[int]:
        for e in chain((edit,), edits):
            if isinstance(e, ContextualEdit):
                lo = row - (len(e.old_prefix.split(ctx.linefeed)) - 1)
                hi = row + (len(e.old_suffix.split(ctx.linefeed)) - 1)
                yield from (lo, hi)

            elif isinstance(e, RangeEdit):
                (lo, _), (hi, _) = e.begin, e.end
                yield from (lo, hi)

            elif isinstance(e, Edit):
                yield row

            else:
                never(e)

    line_nums = tuple(cont())
    return min(line_nums), max(line_nums) + 1

def _contextual_edit_trans(
    ctx: Context, lines: _Lines, edit: ContextualEdit
) -> EditInstruction:
    row, col = ctx.position
    old_prefix_lines = edit.old_prefix.split(ctx.linefeed)
    old_suffix_lines = edit.old_suffix.split(ctx.linefeed)

    r1 = row - (len(old_prefix_lines) - 1)
    r2 = row + (len(old_suffix_lines) - 1)

    c1 = (
        lines.len8[r1] - len(encode(old_prefix_lines[0]))
        if len(old_prefix_lines) > 1
        else col - len(encode(old_prefix_lines[0]))
    )
    c2 = (
        len(encode(old_suffix_lines[-1]))
        if len(old_prefix_lines) > 1
        else col + len(encode(old_suffix_lines[0]))
    )

    begin = r1, c1
    end = r2, c2

    new_lines = edit.new_text.split(ctx.linefeed)
    new_prefix_lines = edit.new_prefix.split(ctx.linefeed)
    cursor_yoffset = -len(old_prefix_lines) + len(new_prefix_lines)
    cursor_xpos = (
        len(encode(new_prefix_lines[-1]))
        if len(new_prefix_lines) > 1
        else len(encode(ctx.line_before))
        - len(encode(old_prefix_lines[-1]))
        + len(encode(new_prefix_lines[0]))
    )

    inst = EditInstruction(
        primary=True,
        begin=begin,
        end=end,
        cursor_yoffset=cursor_yoffset,
        cursor_xpos=cursor_xpos,
        new_lines=new_lines,
    )
    return inst

def _edit_trans(
    unifying_chars: AbstractSet[str],
    ctx: Context,
    lines: _Lines,
    edit: Edit,
) -> EditInstruction:

    adjusted = trans_adjusted(unifying_chars, ctx=ctx, edit=edit)
    inst = _contextual_edit_trans(ctx, lines=lines, edit=adjusted)
    return inst

def _range_edit_trans(
    unifying_chars: AbstractSet[str],
    ctx: Context,
    primary: bool,
    lines: _Lines,
    edit: RangeEdit,
) -> EditInstruction:
    new_lines = edit.new_text.split(ctx.linefeed)

    if (
        primary
        and not isinstance(edit, ParsedEdit)
        and len(new_lines) <= 1
        and edit.begin == edit.end
    ):
        return _edit_trans(unifying_chars, ctx=ctx, lines=lines, edit=edit)

    else:
        (r1, ec1), (r2, ec2) = sorted((edit.begin, edit.end))

        if edit.encoding == UTF16:
            c1 = len(encode(decode(lines.b_lines16[r1][: ec1 * 2], encoding=UTF16)))
            c2 = len(encode(decode(lines.b_lines16[r2][: ec2 * 2], encoding=UTF16)))
        elif edit.encoding == UTF8:
            c1 = len(lines.b_lines8[r1][:ec1])
            c2 = len(lines.b_lines8[r2][:ec2])
        else:
            raise ValueError(f"Unknown encoding -- {edit.encoding}")

        begin = r1, c1
        end = r2, c2

        lines_before = (
            edit.new_prefix.split(ctx.linefeed)
            if isinstance(edit, ParsedEdit)
            else new_lines
        )
        cursor_yoffset = (r2 - r1) + (len(lines_before) - 1)
        cursor_xpos = (
            (
                len(encode(lines_before[-1]))
                if len(lines_before) > 1
                else len(lines.b_lines8[r2][:c1]) + len(encode(lines_before[0]))
            )
            if primary
            else -1
        )

        inst = EditInstruction(
            primary=primary,
            begin=begin,
            end=end,
            cursor_yoffset=cursor_yoffset,
            cursor_xpos=cursor_xpos,
            new_lines=new_lines,
        )
        return inst

def _instructions(
    ctx: Context,
    unifying_chars: AbstractSet[str],
    lines: _Lines,
    primary: Edit,
    secondary: Sequence[RangeEdit],
) -> Iterator[EditInstruction]:
    if isinstance(primary, RangeEdit):
        inst = _range_edit_trans(
            unifying_chars,
            ctx=ctx,
            primary=True,
            lines=lines,
            edit=primary,
        )
        yield inst

    elif isinstance(primary, ContextualEdit):
        inst = _contextual_edit_trans(ctx, lines=lines, edit=primary)
        yield inst

    elif isinstance(primary, Edit):
        inst = _edit_trans(unifying_chars, ctx=ctx, lines=lines, edit=primary)
        yield inst

    else:
        never(primary)

    for edit in secondary:
        yield _range_edit_trans(
            unifying_chars,
            ctx=ctx,
            primary=False,
            lines=lines,
            edit=edit,
        )

def _consolidate(
    instruction: EditInstruction, *instructions: EditInstruction
) -> Sequence[EditInstruction]:
    edits = sorted(chain((instruction,), instructions), key=lambda i: (i.begin, i.end))
    pivot = 0, 0
    stack: MutableSequence[EditInstruction] = []

    for edit in edits:
        if edit.begin >= pivot:
            stack.append(edit)
            pivot = edit.end

        elif edit.primary:
            while stack:
                conflicting = stack.pop()
                if conflicting.end <= edit.begin:
                    break
            stack.append(edit)
            pivot = edit.end

        else:
            pass

    return stack

def _shift(instructions: Iterable[EditInstruction]) -> Iterator[EditInstruction]:
    row_shift = 0
    col_shift: MutableMapping[int, int] = {}

    for inst in instructions:
        (r1, c1), (r2, c2) = inst.begin, inst.end
        yield EditInstruction(
            primary=inst.primary,
            begin=(r1 + row_shift, c1 + col_shift.get(r1, 0)),
            end=(r2 + row_shift, c2 + col_shift.get(r2, 0)),
            cursor_yoffset=inst.cursor_yoffset,
            cursor_xpos=inst.cursor_xpos,
            new_lines=inst.new_lines,
        )
        row_shift += (r2 - r1) + len(inst.new_lines) - 1
        f_length = len(encode(inst.new_lines[-1])) if inst.new_lines else 0
        col_shift[r2] = -(c2 - c1) + f_length if r1 == r2 else -c2 + f_length

def apply(nvim: Nvim, buf: Buffer, instructions: Iterable[EditInstruction]) -> None:
    for inst in _shift(instructions):
        try:
            buf_set_text(
                nvim, buf=buf, begin=inst.begin, end=inst.end, text=inst.new_lines
            )
        except NvimError as e:
            tpl = """
            ${e}
            ${inst}
            """
            msg = Template(dedent(tpl)).substitute(e=e, inst=inst)
            log.warn(f"%s", msg)

def _cursor(cursor: NvimPos, instructions: Iterable[EditInstruction]) -> NvimPos:
    row, _ = cursor
    col = -1

    for inst in instructions:
        row += inst.cursor_yoffset
        col = inst.cursor_xpos
        if inst.primary:
            break

    assert col != -1
    return row, col

def _parse(stack: Stack, state: State, comp: Completion) -> Tuple[Edit, Sequence[Mark]]:
    if isinstance(comp.primary_edit, SnippetEdit):
        visual = ""
        return parse(
            stack.settings.match.unifying_chars,
            context=state.context,
            snippet=comp.primary_edit,
            visual=visual,
        )
    else:
        return comp.primary_edit, ()

def _restore(nvim: Nvim, win: Window, buf: Buffer, pos: NvimPos) -> Tuple[str, int]:
    row, _ = pos
    ns = create_ns(nvim, ns=NS)
    marks = tuple(buf_get_extmarks(nvim, buf=buf, id=ns))
    if len(marks) != 2:
        return "", 0
    else:
        m1, m2 = marks
        after, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        cur_row, cur_col = win_get_cursor(nvim, win=win)

        (_, lo), (_, hi) = m1.end, m2.begin

        binserted = encode(after)[lo:hi]
        inserted = decode(binserted)

        if inserted and cur_row == row and lo <= cur_col <= hi:
            movement = cur_col - lo
        else:
            movement = len(binserted)

        if inserted:
            buf_set_text(nvim, buf=buf, begin=m1.end, end=m2.begin, text=("",))

        return inserted, movement

def edit(
    nvim: Nvim, stack: Stack, state: State, metric: Metric, synthetic: bool
) -> Optional[Tuple[int, int]]:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    if buf.number != state.context.buf_id:
        log.warn("%s", "stale buffer")
        return None
    else:
        nvim.options["undolevels"] = nvim.options["undolevels"]

        if synthetic:
            inserted, movement = "", 0
        else:
            inserted, movement = _restore(
                nvim, win=win, buf=buf, pos=state.context.position
            )

        try:
            primary, marks = _parse(stack, state=state, comp=metric.comp)
        except ParseError as e:
            primary, marks = metric.comp.primary_edit, ()
            write(nvim, LANG("failed to parse snippet"))
            log.info("%s", e)

        lo, hi = _rows_to_fetch(
            state.context,
            primary,
            *metric.comp.secondary_edits,
        )
        if lo < 0 or hi > state.context.line_count + 1:
            log.warn("%s", pformat(("OUT OF BOUNDS", (lo, hi), metric)))
            return None
        else:
            limited_lines = buf_get_lines(nvim, buf=buf, lo=lo, hi=hi)
            lines = [*chain(repeat("", times=lo), limited_lines)]
            view = _lines(lines)

            instructions = _consolidate(
                *_instructions(
                    state.context,
                    unifying_chars=stack.settings.match.unifying_chars,
                    lines=view,
                    primary=primary,
                    secondary=metric.comp.secondary_edits,
                )
            )
            n_row, p_col = _cursor(
                state.context.position,
                instructions=instructions,
            )
            n_col = p_col + movement

            if not synthetic:
                stack.idb.inserted(metric.instance.bytes, sort_by=metric.comp.sort_by)

            apply(nvim, buf=buf, instructions=instructions)
            if inserted:
                try:
                    buf_set_text(
                        nvim,
                        buf=buf,
                        begin=(n_row, p_col),
                        end=(n_row, p_col),
                        text=(inserted,),
                    )
                except NvimError as e:
                    log.warn("%s", e)

            try:
                win_set_cursor(nvim, win=win, row=n_row, col=n_col)
            except NvimError as e:
                log.warn("%s", e)

            if marks:
                mark(nvim, settings=stack.settings, buf=buf, marks=marks)

            if DEBUG:
                log.debug(
                    "%s",
                    pformat(
                        (
                            (metric.comp.primary_edit, *metric.comp.secondary_edits),
                            instructions,
                        )
                    ),
                )
            return n_row, n_col


import base64
import gzip
import io
from pathlib import Path

import pandas as pd

from mpu.excel_formats import (STOCK_COLUMNS_FORMAT,
                               STOCK_WITH_NEW_PRICE_COLUMNS_FORMAT)
from mpu.utils.pyopenxl_utils import EXCEL_ENGINE, format_excel_df

def get_stock_file_path(folder_path: Path, csv: bool = False) -> Path:
    """Constructs the stock file path from a folder path"""
    if csv:
        return folder_path / "stock.csv"
    else:
        return folder_path / "stock.xlsx"

def convert_base64_gzipped_string_to_dataframe(b64_zipped_string: str) -> pd.DataFrame:
    """Converts a base64 gzipped strings (or bytes) into a pandas dataframe"""
    decoded_string = base64.b64decode(b64_zipped_string)
    csv_string = gzip.decompress(decoded_string)

    return pd.read_csv(io.BytesIO(csv_string), sep=";")

def save_stock_df_as_excel_formatted_file(
    df: pd.DataFrame, file_path: Path, new_price: bool = False
) -> None:
    cols_format = (
        STOCK_WITH_NEW_PRICE_COLUMNS_FORMAT if new_price else STOCK_COLUMNS_FORMAT
    )

    with pd.ExcelWriter(path=str(file_path), engine=EXCEL_ENGINE) as writer:
        df.to_excel(excel_writer=writer, index=False, engine=EXCEL_ENGINE)

        format_excel_df(df=df, writer=writer, format_config=cols_format)


from django.contrib import admin

from .models import Category, Product, ProductReview

class ProductAdmin(admin.ModelAdmin):
    list_display=('title', 'slug', 'category', 'parent', 'is_featured', 'price', 'num_available', 'num_visits')
    list_filter=('category', 'is_featured', 'num_visits')
    prepopulated_fields={'slug': ('title', 'quantity', 'unit')}

admin.site.register(Category)
admin.site.register(Product, ProductAdmin)
admin.site.register(ProductReview)


import os
from pathlib import Path
import shutil
import asyncio
import time
from pkg_resources import resource_filename
import pytest

KIVY_STALL_TIMEOUT = 90

UI_CONF = '\n'.join([
    '[main]',
    'config_filename = {vidhub_conf}',
    '[osc]',
    'enable = no',
    '',
])

IS_CI = os.environ.get('CI') == 'true'

TMPFILE_DEST = Path.home() / 'pytest-tmpdir'
if not TMPFILE_DEST.exists():
    TMPFILE_DEST.mkdir()

async def wait_clock_frames(n, sleep_time=1 / 60.):
    from kivy.clock import Clock
    frames_start = Clock.frames
    while Clock.frames < frames_start + n:
        await asyncio.sleep(sleep_time)

def get_kv_logfile():
    from kivy.logger import Logger, FileHandler
    for h in Logger.handlers:
        if not isinstance(h, FileHandler):
            continue
        return Path(h.filename)

@pytest.fixture
async def kivy_app(tmpdir, monkeypatch):
    vidhub_conf = Path(tmpdir) / 'vidhubcontrol.json'
    assert not vidhub_conf.exists()
    ui_conf = Path(tmpdir) / 'vidhubcontrol-ui.ini'
    assert not ui_conf.exists()
    ui_conf.write_text(UI_CONF.format(vidhub_conf=vidhub_conf))
    print(f'vidhub_conf={vidhub_conf}')
    print(f'ui_conf={ui_conf}')

    monkeypatch.setenv('VIDHUBCONTROL_USE_KIVY', '1')
    monkeypatch.setenv('KIVY_UNITTEST', '1')
    monkeypatch.setattr('vidhubcontrol.discovery.ZEROCONF_AVAILABLE', False)

    from vidhubcontrol.kivyui import main as kivy_main

    kv_logfile = get_kv_logfile()

    KV_FILE = Path(resource_filename(kivy_main.__name__, 'vidhubcontrol.kv'))

    class AppOverride(kivy_main.VidhubControlApp):
        def __init__(self, **kwargs):
            kwargs['kv_file'] = str(KV_FILE)
            super().__init__(**kwargs)
            self._startup_ready = asyncio.Event()
            self._app_ready = asyncio.Event()

        def get_application_config(self):
            return str(ui_conf)

        async def start_async(self):
            """Use this method to start the app in tests
            """
            self._run_task = asyncio.ensure_future(self.async_run())
            await self.wait_for_widget_init()
            await self._app_ready.wait()

        async def stop_async(self):
            """Use this method to stop the app in tests
            """
            self.stop()
            await self._run_task

        def on_start(self, *args, **kwargs):
            super().on_start(*args, **kwargs)
            self._startup_ready.set()

        async def async_start(self):
            """Override of base class method to initialize config, interfaces, etc
            """
            await super().async_start()
            self._app_ready.set()

        async def wait_for_widget_init(self, root=None):
            await self._startup_ready.wait()
            if root is None:
                root = self.root
            def check_init():
                for w in root.walk():
                    if w.parent is None:
                        return False
                    if 'app' in w.properties() and w.app is None:
                        return False
                return True
            while not check_init():
                await asyncio.sleep(.01)

    app = AppOverride()
    await app.start_async()
    await wait_clock_frames(5)
    assert Path(app.vidhub_config.filename) == vidhub_conf
    assert not len(app.vidhub_config.vidhubs)
    assert not len(app.vidhub_config.smartviews)
    assert not len(app.vidhub_config.smartscopes)

    try:
        yield app
        await app.stop_async()
    finally:
        if IS_CI:
            tmpsrc = Path(tmpdir).parent
            tmpdst = TMPFILE_DEST / tmpsrc.name

            def copy_ignore_fn(src, names):
                src = Path(src)
                ignored = set()
                for name in names:
                    if (src / name).is_symlink():
                        ignored.add(name)
                return ignored

            shutil.copytree(tmpsrc, tmpdst, ignore=copy_ignore_fn)
            shutil.copy2(kv_logfile, tmpdst)

@pytest.fixture
def KvEventWaiter():
    class KvEventWaiter_(object):
        def __init__(self):
            self._loop = asyncio.get_event_loop()
            self.queue = asyncio.Queue()
            self._lock = asyncio.Lock()
        def bind(self, obj, *events):
            kwargs = {e:self.kivy_callback for e in events}
            obj.bind(**kwargs)
        def unbind(self, obj, *events):
            kwargs = {e:self.kivy_callback for e in events}
            obj.unbind(**kwargs)
        def empty(self):
            return self.queue.empty()
        async def assert_empty(self):
            await asyncio.sleep(0)
            if self.empty():
                return True
            async with self._lock:
                items = []
                while not self.empty():
                    item = await self.queue.get()
                    self.queue.task_done()
                    items.append(item)
            raise Exception(f'{self} not empty. Queue items: {items}')
        async def clear(self):
            await asyncio.sleep(0)
            async with self._lock:
                while not self.empty():
                    _ = await self.queue.get()
                    self.queue.task_done()
        async def wait(self, timeout=5):
            r = await asyncio.wait_for(self.queue.get(), timeout)
            self.queue.task_done()
            return r
        async def bind_and_wait(self, obj, timeout=5, *events):
            self.bind(obj, *events)
            return await self.wait(timeout)
        def kivy_callback(self, *args, **kwargs):
            async def put(item):
                if self._lock.locked():
                    return
                async with self._lock:
                    await self.queue.put(item)
            asyncio.ensure_future(put((args, kwargs)))

    return KvEventWaiter_


import os

from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy

# set the db folder and name relative to the application root folder
project_dir = os.path.dirname(os.path.abspath(__file__))
database_file = f"sqlite:///{os.path.join(project_dir,'bookdatabase.db')}"
print(f"database located at:{database_file}")

app = Flask(__name__)

# bind the app and the db location
app.config["SQLALCHEMY_DATABASE_URI"] = database_file

# initialize the connction to the database and keep this in db variable
db=SQLAlchemy(app)

# class Book, will create a table in db

class Book(db.Model):
    title = db.Column(db.String(80), unique=True, nullable=False, primary_key=True)

    # default representer for the Book class. This will allow to use 'print(book)' and
    # receive a meaningful output.
    def __repr__(self):
        return "<Title: {}".format(self.title)

# to initiate the database use the foolowing
# >python
# >>>from app import db
# >>>db.create_all()
# >>>exit()

# main route of the applicaiton
# by default, flask accepts GET request for all routes
# adding 'methods=["GET", "POST"]' to the route decorator will solve 'Method not allowed'
# error after submitting the form
@app.route("/", methods=["GET", "POST"])
def home():
    if request.form:
        try:
            book = Book(title=request.form.get("title"))
            db.session.add(book)
            db.session.commit()
        except Exception as e:
            print("Failed to add book")
            print(e)

    books = Book.query.all()
    return render_template("index.html", books=books)

@app.route("/update", methods=["POST"])
def update():
    try:
        newtitle = request.form.get("newtitle")
        oldtitle = request.form.get("oldtitle")
        book = Book.query.filter_by(title=oldtitle).first()
        book.title = newtitle
        db.session.commit()
    except Exception as e:
        print("Failed to update book title")
        print(e)
    return redirect("/")

@app.route("/delete", methods=["POST"])
def delete():
    try:
        title = request.form.get("title")
        book = Book.query.filter_by(title=title).first()
        db.session.delete(book)
        db.session.commit()
    except Exception as e:
        print("Failed to delete book")
        print(e)

    return redirect("/")

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


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#%load_ext google.colab.data_table

import pandas as pd
import random
from datetime import datetime, timedelta
from functools import wraps

first_names = [
    "Maria Carmen",
    "Maria",
    "Carmen",
    "Josefa",
    "Isabel",
    "Ana Maria",
    "Maria Dolores",
    "Maria Pilar",
    "Maria Teresa",
    "Ana",
    "Laura",
    "Francisca",
    "Antonia",
    "Dolores",
    "Maria Angeles",
    "Cristina",
    "Marta",
    "Maria Jose",
    "Maria Isabel",
    "Pilar",
    "Maria Luisa",
    "Lucia",
    "Concepcion",
    "Elena",
    "Mercedes",
    "Manuela",
    "Rosa Maria",
    "Raquel",
    "Sara",
    "Maria Jesus",
    "Paula",
    "Juana",
    "Teresa",
    "Rosario",
    "Encarnacion",
    "Beatriz",
    "Rosa",
    "Nuria",
    "Silvia",
    "Montserrat",
    "Julia",
    "Patricia",
    "Irene",
    "Monica",
    "Andrea",
    "Rocio",
    "Angela",
    "Maria Mar",
    "Margarita",
    "Sonia",
    "Sandra",
    "Susana",
    "Alicia",
    "Yolanda",
    "Alba",
    "Maria Josefa",
    "Marina",
    "Natalia",
    "Maria Rosario",
    "Inmaculada",
    "Angeles",
    "Esther",
    "Maria Mercedes",
    "Ana Isabel",
    "Eva",
    "Veronica",
    "Amparo",
    "Noelia",
    "Maria Rosa",
    "Maria Victoria",
    "Maria Concepcion",
    "Carolina",
    "Claudia",
    "Eva Maria",
    "Catalina",
    "Consuelo",
    "Victoria",
    "Lorena",
    "Ana Belen",
    "Maria Antonia",
    "Maria Elena",
    "Miriam",
    "Emilia",
    "Nerea",
    "Luisa",
    "Ines",
    "Maria Nieves",
    "Gloria",
    "Lidia",
    "Carla",
    "Aurora",
    "Esperanza",
    "Josefina",
    "Sofia",
    "Milagros",
    "Olga",
    "Celia",
    "Maria Soledad",
    "Purificacion",
]

store_names = [
    "Situwala",
    "Yakkha",
    "Gnawale",
    "Buhyo",
    "Kutal",
    "Bindukar",
    "Upeti",
    "Mana",
    "Badhyo",
    "Barme",
    "Dhnaju",
    "Kami",
    "Baidhaya",
    "Ma",
    "Ghimere",
    "Sangami",
    "Ghotane",
    "Kewat",
    "Singtan",
    "Chitrakr",
    "Khwaonjoo",
    "Manjhi",
]

city_names = [
    "Távora",
    "Cataguases",
    "Médici",
    "Bressane",
    "Onça",
    "Brígida",
    "Parati",
    "Mônica",
    "Pantano",
    "Anastácio",
    "Ostras",
    "Jequitibá",
]

# Decorate (@) data generating functions to randomly return certain values (decorating = adding to an existing function)
def randomly_return(frequency, value):
    # frequency = 0..1, 0 is return never, 1 is return always
    # value: what to return
    def inner_function(fn):
        @wraps(fn)
        def wrapper():
            return fn() if random.random() > frequency else value
        return wrapper
    return inner_function

@randomly_return(frequency = 0.002, value=np.datetime64('nat'))
def get_datetime_string(min_year=1980, max_year=datetime.now().year):
    # generate a datetime in format yyyy-mm-dd hh:mm:ss.000000
    start = datetime(min_year, 1, 1, 0, 0, 0)
    years = max_year - min_year + 1
    end = start + timedelta(days=365 * years)
    return start + (end - start) * random.random()

@randomly_return(frequency = 0.003, value=".")
def get_total_amount():
    return round(random.random() * 500, 2)

# Distributed evenly, not realistic.
@randomly_return(frequency = 0.01, value=np.nan)
def get_number_of_products():
    return random.randint(0, 200)

@randomly_return(frequency = 0.07, value="")
def get_cashier():
    return random.choice(first_names)

@randomly_return(frequency = 0.02, value=None)
def get_store_name():
    return random.choice(store_names)

@randomly_return(frequency = 0.07, value="Missing")
def get_city():
    return random.choice(city_names)

@randomly_return(frequency = 0.5, value="NA")
def get_discount_card():
    return random.random() > 0.5

@randomly_return(frequency = 0.006, value=-1)
def get_time_spent():
    return random.randint(30, 600)

def get_random_data(fn, n):
    return [fn() for _ in range(n)]

num_rows = 20_000

data = {
    "datetime": get_random_data(get_datetime_string, num_rows),
    "total_amount": get_random_data(get_total_amount, num_rows),
    "number_of_products": get_random_data(get_number_of_products, num_rows),
    "cashier": get_random_data(get_cashier, num_rows),
    "store": get_random_data(get_store_name, num_rows),
    "city": get_random_data(get_city, num_rows),
    "discount_card_used": get_random_data(get_discount_card, num_rows),
    "time_spent": get_random_data(get_time_spent, num_rows)
}

df = pd.DataFrame(data=data)

## Changing different kind of null values to a default null value
## defaults are: None, NAN (np.nan), NAT (np.nat)

# Three ways of doing this

# 1. Using .loc
# df.loc[df["total_amount"] == ".", "total_amount"] = np.nan  # replacing "." with "NaN"
# print(df.head(20))

# 2. Simple replace .replace(old,new)
# df["total_amount"].replace(".", np.nan, inplace=True)
# print(df.head(20))

# 3. Complex replace
# Simple replace doesn't work when there are None values (empty cells), instead use a dictionary replace:
# .replace({old:new})
np.sort(df["cashier"].unique()) # inplace argument doesn't work in this case
print(df["cashier"].tail(20))

df["cashier"] = df["cashier"].replace({"": None , np.nan: None})  # inplace argument doesn't work in this case
print(df["cashier"].tail(20))

print(df["cashier"].value_counts(dropna=False))
print(df.loc[df["cashier"].isna()]) # Selects all None values

# Coverting values from different columns to standard null values (in this case: None )
print(df["city"].unique())
df["city"].replace("Missing", None, inplace=True)
print(df["city"].unique())

df["discount_card_used"].unique()
df["discount_card_used"].replace("NA", False, inplace=True)  # Think about what value you replace 'NA' with (False, True)
print(df["discount_card_used"].value_counts())


#!/usr/bin/env python3

from wearebeautiful.scale import scale_mesh
import click

@click.command()
@click.option('--cleanup', default=False, help='Clean the mesh before scaling')
@click.option('--invert/--no-invert', default=False, help='Flip the normals on the STL file')
@click.argument("len", nargs=1, type=float)
@click.argument("in_file", nargs=1)
@click.argument("out_file", nargs=1)
def scale(invert, len, in_file, out_file):
    scale_mesh(invert, len, in_file, out_file)

def usage(command):
    with click.Context(command) as ctx:
        click.echo(command.get_help(ctx))

if __name__ == "__main__":
    print("scale_mesh.py running, making STL files. <3\n")
    scale()
    sys.exit(0)


import torch

class Args():
    def __init__(self):
        self.max_length = 128
        self.lr = 1e-5
        self.num_epochs = 5
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.batch_size = 8
        self.model_name = "ai-forever/ruRoberta-large"
        self.random_state = 101
        self.num_classes = 29


"""A setuptools based setup module."""
from os import path
from setuptools import setup, find_packages
from io import open

here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='Immunitor',
    version='0.0.1',
    description='Immunitor',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/cunyap/immunitor',
    author='Andreas P. Cuny',
    author_email='andreas.cuny@bsse.ethz.ch',
    classifiers=[
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
    ],
    keywords='Immunitor',
    packages=find_packages(),
    install_requires=['Flask',
                      'Flask-WTF',
                      "click",
                      "itsdangerous",
                      "Jinja2",
                      "MarkupSafe",
                      "python-dotenv",
                      "Werkzeug",
                      "WTForms",
                      "Flask-QRcode",
                      "pgeocode",
                      "plotly",
                      "pandas",
                      "pybis",
                      "flask_recaptcha",
                      "waitress"],
    extras_require={
        'dev': ['check-manifest'],
        'test': ['coverage'],
        'env': ['python-dotenv']
    },
    entry_points={
        'console_scripts': [
            'run=wsgi:__main__',
        ],
    },
    project_urls={
        'Bug Reports': 'https://github.com/cunyap/codevscovid19_app/issues',
        'Source': 'https://github.com/cunyap/codevscovid19_app',
    },
)


import re
import os
import socket
import time
import struct
import dpkt
import dpkt.dns
from threading import Thread, Event

from tiny_test_fw import DUT
import ttfw_idf

# g_run_server = True
# g_done = False
stop_mdns_server = Event()
esp_answered = Event()

def get_dns_query_for_esp(esp_host):
    dns = dpkt.dns.DNS(b'\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01')
    dns.qd[0].name = esp_host + u'.local'
    print("Created query for esp host: {} ".format(dns.__repr__()))
    return dns.pack()

def get_dns_answer_to_mdns(tester_host):
    dns = dpkt.dns.DNS(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
    dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA
    dns.rcode = dpkt.dns.DNS_RCODE_NOERR
    arr = dpkt.dns.DNS.RR()
    arr.cls = dpkt.dns.DNS_IN
    arr.type = dpkt.dns.DNS_A
    arr.name = tester_host
    arr.ip = socket.inet_aton('127.0.0.1')
    dns. an.append(arr)
    print("Created answer to mdns query: {} ".format(dns.__repr__()))
    return dns.pack()

def get_dns_answer_to_mdns_lwip(tester_host, id):
    dns = dpkt.dns.DNS(b"\x5e\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x0a\x64\x61\x76\x69\x64"
                       b"\x2d\x63\x6f\x6d\x70\x05\x6c\x6f\x63\x61\x6c\x00\x00\x01\x00\x01\xc0\x0c"
                       b"\x00\x01\x00\x01\x00\x00\x00\x0a\x00\x04\xc0\xa8\x0a\x6c")
    dns.qd[0].name = tester_host
    dns.an[0].name = tester_host
    dns.an[0].ip = socket.inet_aton('127.0.0.1')
    dns.an[0].rdata = socket.inet_aton('127.0.0.1')
    dns.id = id
    print("Created answer to mdns (lwip) query: {} ".format(dns.__repr__()))
    return dns.pack()

def mdns_server(esp_host):
    global esp_answered
    UDP_IP = "0.0.0.0"
    UDP_PORT = 5353
    MCAST_GRP = '224.0.0.251'
    TESTER_NAME = u'tinytester.local'
    TESTER_NAME_LWIP = u'tinytester-lwip.local'
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    sock.bind((UDP_IP,UDP_PORT))
    mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.settimeout(30)
    while not stop_mdns_server.is_set():
        try:
            if not esp_answered.is_set():
                sock.sendto(get_dns_query_for_esp(esp_host), (MCAST_GRP,UDP_PORT))
                time.sleep(0.2)
            data, addr = sock.recvfrom(1024)
            dns = dpkt.dns.DNS(data)
            if len(dns.qd) > 0 and dns.qd[0].type == dpkt.dns.DNS_A:
                if dns.qd[0].name == TESTER_NAME:
                    print("Received query: {} ".format(dns.__repr__()))
                    sock.sendto(get_dns_answer_to_mdns(TESTER_NAME), (MCAST_GRP,UDP_PORT))
                elif dns.qd[0].name == TESTER_NAME_LWIP:
                    print("Received query: {} ".format(dns.__repr__()))
                    sock.sendto(get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id), addr)
            if len(dns.an) > 0 and dns.an[0].type == dpkt.dns.DNS_A:
                if dns.an[0].name == esp_host + u'.local':
                    print("Received answer to esp32-mdns query: {}".format(dns.__repr__()))
                    esp_answered.set()
        except socket.timeout:
            break
        except dpkt.UnpackError:
            continue

@ttfw_idf.idf_example_test(env_tag="Example_WIFI")
def test_examples_protocol_mdns(env, extra_data):
    global stop_mdns_server
    """
    steps: |
      1. join AP + init mdns example
      2. get the dut host name (and IP address)
      3. check the mdns name is accessible
      4. check DUT output if mdns advertized host is resolved
    """
    dut1 = env.get_dut("mdns-test", "examples/protocols/mdns", dut_class=ttfw_idf.ESP32DUT)
    # check and log bin size
    binary_file = os.path.join(dut1.app.binary_path, "mdns-test.bin")
    bin_size = os.path.getsize(binary_file)
    ttfw_idf.log_performance("mdns-test_bin_size", "{}KB".format(bin_size // 1024))
    ttfw_idf.check_performance("mdns-test_bin_size", bin_size // 1024, dut1.TARGET)
    # 1. start mdns application
    dut1.start_app()
    # 2. get the dut host name (and IP address)
    specific_host = dut1.expect(re.compile(r"mdns hostname set to: \[([^\]]+)\]"), timeout=30)
    specific_host = str(specific_host[0])
    thread1 = Thread(target=mdns_server, args=(specific_host,))
    thread1.start()
    try:
        dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
    except DUT.ExpectTimeout:
        stop_mdns_server.set()
        thread1.join()
        raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
    try:
        # 3. check the mdns name is accessible
        if not esp_answered.wait(timeout=30):
            raise ValueError('Test has failed: did not receive mdns answer within timeout')
        # 4. check DUT output if mdns advertized host is resolved
        dut1.expect(re.compile(r"mdns-test: Query A: tinytester.local resolved to: 127.0.0.1"), timeout=30)
        dut1.expect(re.compile(r"mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1"), timeout=30)
        dut1.expect(re.compile(r"mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1"), timeout=30)
    finally:
        stop_mdns_server.set()
        thread1.join()

if __name__ == '__main__':
    test_examples_protocol_mdns()


"""Altair charts definitions"""
import altair as alt
import pandas as pd

def create_balance_chart(balance_df: pd.DataFrame) -> alt.Chart:
    """
    Creates an interactive chart of absolute balance in time.

    Args:
        balance_df: Balance DataFrame including `date` and `balance` columns.

    Returns:
        Altair chart.
    """
    line = (
        alt.Chart(balance_df)
        .mark_line()
        .encode(
            alt.X("date:T", title=None, axis=alt.Axis(format="%b %y", labelAngle=-70)),
            alt.Y("balance:Q", title="balance [SEK]"),
        )
    )

    selection_nearest = alt.selection_single(
        fields=["date"],
        nearest=True,
        on="mouseover",
        empty="none",
    )

    tooltips = (
        alt.Chart(balance_df)
        .mark_rule(color="white")
        .encode(
            x="date:T",
            opacity=alt.condition(selection_nearest, alt.value(0.5), alt.value(0)),
            tooltip=[
                alt.Tooltip("date:T", format="%d %b %Y"),
                alt.Tooltip("balance:Q", format=",.2f"),
            ],
        )
        .add_selection(selection_nearest)
    )

    points = line.mark_point().encode(
        opacity=alt.condition(selection_nearest, alt.value(1), alt.value(0))
    )

    return (line + tooltips + points).interactive()

def create_expenses_incomes_chart(expenses_incomes_df: pd.DataFrame) -> alt.Chart:
    """
    Creates a bar chart of monthly aggregated incomes and expenses.

    Args:
        expenses_incomes_df: DataFrame including `date`, `type` and `amount` columns.

    Returns:
        Altair chart.
    """
    bars = (
        alt.Chart(expenses_incomes_df)
        .mark_bar()
        .encode(
            x=alt.X("type:N", title="", sort="descending"),
            y=alt.Y("amount:Q", title="amount [SEK]"),
            color=alt.Color(
                "type:N",
                sort="descending",
                scale=alt.Scale(range=["mediumseagreen", "indianred"]),
            ),
            column="yearmonth(date):T",
        )
        .configure_legend(
            orient="top",
            title=None,
        )
        .configure_header(title=None)
        .configure_facet(spacing=5)
    )

    return bars


import os
import wx

import gimelstudio.constants as const

class NodeGraphDropTarget(wx.DropTarget):
    def __init__(self, window, *args, **kwargs):
        super(NodeGraphDropTarget, self).__init__(*args, **kwargs)
        self._window = window
        self._composite = wx.DataObjectComposite()
        self._textDropData = wx.TextDataObject()
        self._fileDropData = wx.FileDataObject()
        self._composite.Add(self._textDropData)
        self._composite.Add(self._fileDropData)
        self.SetDataObject(self._composite)

    def OnDrop(self, x, y):
        return True

    def OnData(self, x, y, result):
        self.GetData()
        formatType, formatId = self.GetReceivedFormatAndId()
        if formatType in (wx.DF_TEXT, wx.DF_UNICODETEXT):
            return self.OnTextDrop()
        elif formatType == wx.DF_FILENAME:
            return self.OnFileDrop()

    def GetReceivedFormatAndId(self):
        _format = self._composite.GetReceivedFormat()
        formatType = _format.GetType()
        try:
            formatId = _format.GetId()  # May throw exception on unknown formats
        except Exception:
            formatId = None
        return formatType, formatId

    def OnTextDrop(self):
        try:
            self._window.AddNode(self._textDropData.GetText(), nodeid=None,
                                 pos=(0, 0), location="CURSOR")
            self._window.UpdateNodegraph()
        except Exception as error:
            self.ShowError(error)
        return wx.DragCopy

    def OnFileDrop(self):
        for filename in self._fileDropData.GetFilenames():
            try:
                filetype = os.path.splitext(filename)[1]

                if filetype.lower() in const.SUPPORTED_FT_SAVE_LIST:
                    if os.path.exists(filename) is True:
                        # Create Image node with path
                        node = self._window.AddNode("corenode_image", pos=(0, 0),
                                                    nodeid=None, location="CURSOR")
                        node.NodeEditProp(idname="file_path",
                                          value=filename, render=False)
                        node.ToggleExpand()
                        node.NodeDndEventHook()
                        self._window.UpdateNodegraph()

                    else:
                        self.ShowError()

                else:
                    dlg = wx.MessageDialog(None,
                                           _("That file type isn't currently supported!"),
                                           _("Cannot Open File!"), style=wx.ICON_EXCLAMATION)
                    dlg.ShowModal()
                    return False

            except Exception as error:
                self.ShowError(error)

        return wx.DragCopy

    def ShowError(self, error=""):
        dlg = wx.MessageDialog(None, "\n {}!".format(str(error)),
                               _("Error!"), style=wx.ICON_ERROR)
        dlg.ShowModal()
        return False


import os
import typing as tp

import cv2
import numpy as np
import scipy.ndimage
import time
import tqdm
from PIL import Image

KERNELS = [
    np.array(
        [
            [-1, 2, -1],
            [-1, 2, -1],
            [-1, 2, -1],
        ]
    ),
    np.array(
        [
            [2, -1, -1],
            [-1, 2, -1],
            [-1, -1, 2],
        ]
    ),
    np.array(
        [
            [-1, -1, -1],
            [2, 2, 2],
            [-1, -1, -1],
        ]
    ),
    np.array(
        [
            [-1, -1, 2],
            [-1, 2, -1],
            [2, -1, -1],
        ]
    ),
]

SOURCE_DIR = "/home/andresokol/data/compressed"
MASK_ROOT = "/home/andresokol/data/masks_v2"
ORIENTATION_ROOT = "/home/andresokol/data/orientation_v2"

def get_direction_weights(image: np.ndarray, kernel: np.ndarray) -> np.ndarray:
    channel = cv2.filter2D(image, -1, kernel).astype(float)
    # channel = cv2.boxFilter(channel, -1, (3, 3))
    channel = scipy.ndimage.maximum_filter(channel, size=5)
    return channel

# def directed_sobel(image: np.ndarray, axis: int) -> np.ndarray:
#     channel = scipy.ndimage.sobel(image, axis=axis)
#     channel = np.abs(channel - 128) * 2
#     # channel = scipy.ndimage.maximum_filter(channel, size=3)
#     return channel

# def image_gradient(img: np.ndarray) -> np.ndarray:
#     hor_grad = (img[1:, :] - img[:-1, :])[:, :-1]
#     ver_grad = (img[:, 1:] - img[:, :-1])[:-1:, :]
#     magnitude = np.sqrt(hor_grad ** 2 + ver_grad ** 2)
#     return magnitude

def read_original(img_dir: str, img_name: str) -> np.ndarray:
    image = cv2.imread(f"{SOURCE_DIR}/{img_dir}/{img_name}.jpg")
    image = cv2.resize(image, (512, 512))
    return image

def read_mask(img_dir: str, img_name: str) -> np.ndarray:
    image = cv2.imread(f"{MASK_ROOT}/{img_dir}/{img_name}.png")
    image = cv2.resize(image, (512, 512))
    return image

def adjust_gamma(image, gamma=1.0):
    # build a lookup table mapping the pixel values [0, 255] to
    # their adjusted gamma values
    invGamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** invGamma) * 255
        for i in np.arange(0, 256)]).astype("uint8")
    # apply gamma correction using the lookup table
    return cv2.LUT(image, table)

def extract_structure_data(original: np.ndarray) -> np.ndarray:
    image = np.copy(original)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
#     direction_weights = np.dstack(
#         (
#             get_direction_weights(image, KERNELS[0]),
#             np.maximum(
#                 get_direction_weights(image, KERNELS[1]),
#                 get_direction_weights(image, KERNELS[3]),
#             ),
#             get_direction_weights(image, KERNELS[2]),
#         )
#     )
#     directions = np.argmax(direction_weights, axis=2)

#     blue_channel = directions * 127
#     red_channel = 255 - blue_channel

    axis_0 = scipy.ndimage.convolve1d(image.astype(float), [-1, 1, 0], axis=0)
    axis_0 = np.abs(axis_0)

    axis_1 = scipy.ndimage.convolve1d(image.astype(float), [-1, 1, 0], axis=1)
    axis_1 = np.abs(axis_1)

    composite = np.dstack([
        axis_1,
        np.zeros_like(axis_0),
        axis_0,
    ])

    composite = adjust_gamma(composite.astype('uint8'), gamma=4)

#     image = cv2.merge(
#         (
#             red_channel.astype("uint8"),
#             np.zeros(shape=red_channel.shape, dtype="uint8"),
#             blue_channel.astype("uint8"),
#         )
#     )

    # image = cv2.boxFilter(image, -1, (16, 16))

    # downsampled = cv2.resize(image, (64, 64))

    return composite

def apply_threshold(image: np.ndarray, threshold: float) -> np.ndarray:
    normalized = image.astype(float) / 255.0
    return (normalized > threshold).astype(int) * 255

def process(image: np.ndarray, mask: np.ndarray) -> np.ndarray:
    image = extract_structure_data(image)

    hair_mask, _, _ = cv2.split(mask)
    # hair_mask = cv2.resize(hair_mask, image.shape[:2])
    hair_mask = apply_threshold(hair_mask, 0.4)

    image = np.dstack((image, hair_mask.astype("uint8")))

    return image

def apply_on_original(bg: np.ndarray, image: np.ndarray) -> np.ndarray:
    bg_pil = Image.fromarray(bg).convert("RGBA")
    image_pil = Image.fromarray(image)
    composite = Image.alpha_composite(bg_pil, image_pil)
    return np.asarray(composite)  # type: ignore

def image_paths() -> tp.List[tp.Tuple[str, str]]:
    paths = []
    for dirname in os.listdir(SOURCE_DIR):
        for filename in os.listdir(f"{SOURCE_DIR}/{dirname}"):
            if not os.path.exists(f"{MASK_ROOT}/{dirname}/{filename[:-len('.jpg')]}.png"):
                continue
            if filename.endswith(".jpg"):
                paths.append((dirname, filename[:-len(".jpg")]))
    print(f"Found {len(paths)} images")
    return paths

def main():
    # img_dir, img_name = "01000", "01000"
    for img_dir, img_name in tqdm.tqdm(image_paths()):
        target_dir = f"{ORIENTATION_ROOT}/{img_dir}"
        if not os.path.exists(target_dir):
            os.mkdir(target_dir)

        if os.path.exists(f"{target_dir}/{img_name}.png"):
            continue

        original = read_original(img_dir, img_name)
        mask = read_mask(img_dir, img_name)

        image = process(original, mask)

        structure_overlayed = apply_on_original(original, image)
        cv2.imwrite(
            f"{target_dir}/{img_name}.png",
            structure_overlayed,
        )

    # cv2.imshow("w", structure_overlayed)
    # while cv2.waitKey(5) & 0xFF != 27:
    #     time.sleep(0.5)

if __name__ == "__main__":
    main()


import os
from datetime import timedelta, timezone

import discord
from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

utc = timezone.utc
jst = timezone(timedelta(hours=9), "Asia/Tokyo")

guild_id = int(os.environ["GUILD_ID"])

vc_log_channel = int(os.environ["VC_LOG_CHANNEL"])

class Logger(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener(name="on_voice_state_update")
    async def vc_log(
        self,
        member: discord.Member,
        before: discord.VoiceState,
        after: discord.VoiceState,
    ):
        if member.guild.id == guild_id and (before.channel != after.channel):
            channel = self.bot.get_channel(vc_log_channel)
            now = discord.utils.utcnow().astimezone(jst)
            if before.channel is None:
                message = f"{now:%m/%d %H:%M:%S} : {member.name}(ID: {member.id}) が {after.channel.mention} に参加しました。"
                await channel.send(message)
                return
            elif after.channel is None:
                message = f"{now:%m/%d %H:%M:%S} : {member.name}(ID: {member.id}) が {before.channel.mention} から退出しました。"
                await channel.send(message)
                return
            else:
                message = f"{now:%m/%d %H:%M:%S} : {member.name}(ID: {member.id}) が {before.channel.mention} から {after.channel.mention} に移動しました。"
                await channel.send(message)
                return

def setup(bot):
    return bot.add_cog(Logger(bot))


import numpy as np
from scipy import signal
from skimage.util import pad
from skimage.measure import compare_ssim
from timeit import default_timer as timer

def compute_nrmse(im1, im2):
    """
    Compute the Normalized Mean Square Error.

    A min-max normalized mean square error value and array are computed from
    two input images (i.e. patterns). This implementation ignores the order of
    im1 and im2 in the normalization. We normalize to scale values between 0
    and 1, and then subtract both the global value and the array from 1 so
    that higher values indicate a greater degree of similarity (i.e. less
    error) between the two images.

    Args:
        im1 (ndarray): 2d array
        im2 (ndarray): 2d array, same size/shape/type as im1
    Returns:
        nrmse (tuple): nrmse value and array of nrsme values
    Raises:
        Exception: description
    """
    print("Computing NRMSE...")
    start = timer()

    im1_max = np.nanmax(im1)
    im2_max = np.nanmax(im2)
    im1_min = np.nanmin(im1)
    im2_min = np.nanmin(im2)
    both_max = max(im1_max, im2_max)
    both_min = min(im1_min, im2_min)

    # Compute global index NRMSE value
    mse = np.mean(np.square(im1 - im2))
    min_max_nrmse = np.sqrt(mse) / (both_max - both_min)
    # Compute NRSE array
    square_error = np.square(im1 - im2)
    min_max_nrmse_arr = np.sqrt(square_error) / (both_max - both_min)
    # Reverse scale so 1 is 'good', 0 is 'bad'
    nrmse_flip = round(1 - min_max_nrmse, 3)
    nrmse_arr_flip = 1 - min_max_nrmse_arr

    nrmse_results = (nrmse_flip, nrmse_arr_flip)

    print("Complete. " + str((timer() - start))[0:4] + " s")

    return nrmse_results

def compute_ssim(im1, im2):
    """
    Compute Structural Similarity Index of two single band images.

    The human visual system is well adapted to extracting structural
    information from a scene. Structural information refers to how
    objects are arranged in a scene independent of background
    intensity and contrast (Wang et al., 2004). "We define
    structural information in an image as those attributes that
    represent the structure of objects in the scene, independent of
    the average luminance and contrast. Since luminance and contrast
    can vary across a scene, we use the local luminance and contrast
    for our definition. Luminance, contrast, and structure
    comparisons make up SSIM. Brightness in the SSIM map indicates
    the magnitude of the local SSIM index (squared for visibility).

     Wang, Z., Bovik, A. C., Sheikh, H. R., & Simoncelli, E. P.
     (2004). Image quality assessment: From error visibility to
     structural similarity. IEEE Transactions on Image Processing,
     13, 600-612.
     https://ece.uwaterloo.ca/~z70wang/publications/ssim.pdf,
     DOI:10.1109/TIP.2003.819861

    Args:
        im1 (ndarray): 2d array for similarity
        im2 (ndarray): 2d array, same size/shape as im1
    Returns:
        ssim (tuple): mean value and array of SSIM values
    Raises:
        Exception: description
    """

    start = timer()
    print("Computing SSIM...")
    mean_ssim_val, ssim_arr = compare_ssim(im1, im2,
                                           sigma=1.5,
                                           gaussian_weights=True,
                                           use_sample_covariance=False,
                                           full=True)

    mean_ssim_val_scaled = (mean_ssim_val + 1) / 2
    ssim_arr_scaled = (ssim_arr + 1) / 2
    ssim = (mean_ssim_val_scaled, ssim_arr_scaled)

    print("Complete. " + str((timer() - start))[0:4] + " s")

    return ssim

def cw_ssim(im1, im2, width):
    """
    Compute a complex wavelet implementation of SSIM (CW-SSIM).

    CW-SSIM insensitive to translation, scaling and rotation of
    images. A value of +1 indicates perfect similarity and a value of
    -1 indicates lack of similarity.

    Args:
        im1 (ndarray): 2d array for similarity
        im2 (ndarray): 2d array, same size/shape as im1
        width (int): wavelet width for convolution (default: 30)
    Returns:
        ssim (tuple): mean value and array of CW-SSIM values
    Raises:
        Exception: description
    """
    start = timer()
    print("Computing Complex Wavelet SSIM...")

    # Define a width for the wavelet convolution
    widths = np.arange(1, width+1)

    # Unwrap image arrays to 1 dimensional arrays
    sig1 = np.ravel(im1)
    sig2 = np.ravel(im2)

    # Perform a continuous wavelet transform (cwt) on each array
    # Use Ricker (a.k.a. Mexican Hat a.k.a. Marr) wavelet
    # Ricker is neg. normalized 2nd derivative of a Gaussian
    cwtmatr1 = signal.cwt(sig1, signal.ricker, widths)
    cwtmatr2 = signal.cwt(sig2, signal.ricker, widths)

    # Compute the first term:
    # Compute product of the absolute values of the cwts
    c1c2 = np.multiply(abs(cwtmatr1), abs(cwtmatr2))
    # Compute squares of absolute values of the cwt for each image
    c1_2 = np.square(abs(cwtmatr1))
    c2_2 = np.square(abs(cwtmatr2))
    num_ssim_1 = 2 * np.sum(c1c2, axis=0) + 0.01
    den_ssim_1 = np.sum(c1_2, axis=0) + np.sum(c2_2, axis=0) + 0.01
    # Compute the second term:
    """
    Compute consistency of phase changes between the arrays.
    Structural info of local features is concentrated in the relative
    phase patterns of the wavelet coefficients (i.e. a consistent
    phase shift of all coefficients does not change the structure of
    the local image feature. First compute the product of the cwt of
    the first image and the complex conjugate of the cwt of the second image:
    """
    c1c2_conj = np.multiply(cwtmatr1, np.conjugate(cwtmatr2))
    num_ssim_2 = 2 * np.abs(np.sum(c1c2_conj, axis=0)) + 0.01
    den_ssim_2 = 2 * np.sum(np.abs(c1c2_conj), axis=0) + 0.01

    # Compute Index and Mean
    cw_ssim_map = (num_ssim_1 / den_ssim_1) * (num_ssim_2 / den_ssim_2)
    cw_ssim_map = cw_ssim_map.reshape(im1.shape[0],
                                      im1.shape[1])
    cw_ssim_index = round(np.average(cw_ssim_map), 3)

    print("Complete. " + str((timer() - start))[0:4] + " s")

    return (cw_ssim_index + 1) / 2, (cw_ssim_map + 1) / 2

def convolve(image, kernel):
    """ Perform Convolution on Image with a given kernel.

    Parameters
    ----------
    image : ndarray
        Image.  Any dimensionality.
    kernel : ndarray
        Kernel to convolve over image.

    Returns
    -------
    output : ndarray
        Convolved Image.
    """

    # grab the spatial dimensions of the image, along with
    # the spatial dimensions of the kernel
    (iH, iW) = image.shape[:2]
    (kH, kW) = kernel.shape[:2]

    # allocate memory for the output image, taking care to
    # "pad_size" the borders of the input image so the spatial
    # size (i.e., width and height) are not reduced

    pad_size = int((kW - 1) / 2)
    image = pad(image, pad_size, mode='edge')
    output = np.zeros((iH, iW), dtype="float32")

    # loop over the input image, "sliding" the kernel across
    # each (x, y)-coordinate from left-to-right and top to
    # bottom

    for y in np.arange(pad_size, iH + pad_size):
        for x in np.arange(pad_size, iW + pad_size):
            # extract the ROI of the image by extracting the
            # *center* region of the current (x, y)-coordinates
            # dimensions

            roi = image[y - pad_size:y + pad_size + 1, x - pad_size:x
                        + pad_size + 1]

            # perform the actual convolution by taking the
            # element-wise product between the ROI and
            # the kernel, then summing the matrix

            k = (roi * kernel).sum()

            # store the convolved value in the output (x,y)
            # coordinate of the output image
            output[y - pad_size, x - pad_size] = k
    return output

def compute_gms(im1, im2):
    """ Compute the Gradient Magnitude Similarity (GMS) and
    Deviation Index (GMSD) of two images.

    A GMSD of 1 indicates perfect similarity. A GMSD of 0 is the
    lower bound for poor similarity.
    Xue, W., Zhang, L., Mou, X., & Bovik, A. C. (2014).
    Gradient magnitude similarity deviation: A highly efficient perceptual
    image quality index.
    IEEE Transactions on Image Processing, 23(2), 668–695.
    http://doi.org/10.1109/TIP.2013.2293423

    Args:
        im1 (ndarray): 2d array for similarity
        im2 (ndarray): 2d array, same size/shape as im1
    Returns:
        gms_index (float): The GMSD metric.
    gms_map (ndarray) GMS Array.
    """

    print("Computing Gradient Magnitude Similarity...")
    start = timer()
    # Construct Prewitt kernels with values from literature
    h_x = [0.33, 0, -0.33, 0.33, 0, -0.33, 0.33, 0, -0.33]
    h_x = np.array(h_x).reshape(3, 3)
    h_y = np.flipud(np.rot90(h_x))

    # Create gradient magnitude images for each image with Prewitt kernels
    # Reference (im1)
    ref_conv_hx = convolve(im1, h_x)
    ref_conv_hy = convolve(im1, h_y)
    ref_grad_mag = np.sqrt((ref_conv_hx ** 2) + (ref_conv_hy ** 2))

    # 'Distorted' (im2)
    dst_conv_hx = convolve(im2, h_x)
    dst_conv_hy = convolve(im2, h_y)
    dst_grad_mag = np.sqrt((dst_conv_hx ** 2) + (dst_conv_hy ** 2))

    c = 0.0026  # Constant provided by literature

    gms_map = (2 * ref_grad_mag * dst_grad_mag + c) / (ref_grad_mag ** 2 + dst_grad_mag ** 2 + c)
    gms_index = np.sqrt(np.sum((gms_map - gms_map.mean()) ** 2) / gms_map.size)

    end = timer()
    print("...Complete. Elapsed Seconds: " + str((end - start))[0:4])

    return 1 - round(gms_index, 3), gms_map

def compute_all_iqa(im1, im2):
    """
    Compute all similarity metrics and maps and return a dictionary.

    Calls all simliarity metrics (IQA) on an image pair. Current metrics: MSE,
    SSIM, CW-SSIM, and GMS).
    Args:
        im1 (ndarray): 2d array for similarity
        im2 (ndarray): 2d array, same size/shape as im1
    Returns:
        sim (dict): dictionary that stores results with the following
        structure: results{
                    [*metric*: float,
                    *metric*_arr: array]}
    Raises:
        None.
    """
    sim = dict()
    sim['nrmse'], sim['nrmse_arr'] = compute_nrmse(im1, im2)
    sim['ssim'], sim['ssim_arr'] = compute_ssim(im1, im2)
    sim['cwssim'], sim['cwssim_arr'] = cw_ssim(im1, im2, 10)
    sim['gms'], sim['gms_arr'] = compute_gms(im1, im2)
    # sim['fsim_value'], sim['pc_max_map'] = compute_fsim(im1, im2)
    return sim


import cv2
import numpy as np

# Comment: CV2 is based on static image analysis.
#   But videos are just a collection of several static images. So it works pretty similar with video or image

# Using grayscale takes away different colors (3, being RGB) and +1 being Alpha (opacity)
#   it requires less processing using just grayscale

# img = cv2.imread('wristwatch.jpeg', cv2.IMREAD_GRAYSCALE)
img = cv2.imread('wristwatch.jpeg', cv2.IMREAD_COLOR)

cv2.line(img, (0,0), (150,150), (255,255,255), 15) #xy0 , xy1 , color BGR, linewidth
cv2.rectangle(img, (15,25), (200,150), (0,0,0), 10)
cv2.circle(img, (100,63), 55, (0,0,255), 10) # center, radius, color, linewidth = -1 => fill

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'OpenCV Tutorial', (0,130), font, 1, (200,200,130), 2, cv2.LINE_AA)
# IMREAD_COLOR = 1
# IMREAD_UNCHANGED = -1
# IMREAD_GRAYSCALE = 0

### Plotting with OpenCV
cv2.imshow('image', img)
cv2.waitKey(0) # any key closes the window
cv2.destroyAllWindows()

# cv2.imwrite('filename.png', img) # Saves the image


"""
Lhs functions are inspired by
https://github.com/clicumu/pyDOE2/blob/
master/pyDOE2/doe_lhs.py
"""
import numpy as np
from sklearn.utils import check_random_state
from scipy import spatial
from ..space import Space, Categorical
from .base import InitialPointGenerator

def _random_permute_matrix(h, random_state=None):
    rng = check_random_state(random_state)
    h_rand_perm = np.zeros_like(h)
    samples, n = h.shape
    for j in range(n):
        order = rng.permutation(range(samples))
        h_rand_perm[:, j] = h[order, j]
    return h_rand_perm

class Lhs(InitialPointGenerator):
    """Latin hypercube sampling

    Parameters
    ----------
    lhs_type : str, default='classic'
        - 'classic' - a small random number is added
        - 'centered' - points are set uniformly in each interval

    criterion : str or None, default='maximin'
        When set to None, the LHS is not optimized

        - 'correlation' : optimized LHS by minimizing the correlation
        - 'maximin' : optimized LHS by maximizing the minimal pdist
        - 'ratio' : optimized LHS by minimizing the ratio
          `max(pdist) / min(pdist)`

    iterations : int
        Defines the number of iterations for optimizing LHS
    """
    def __init__(self, lhs_type="classic", criterion="maximin",
                 iterations=1000):
        self.lhs_type = lhs_type
        self.criterion = criterion
        self.iterations = iterations

    def generate(self, dimensions, n_samples, random_state=None):
        """Creates latin hypercube samples.

        Parameters
        ----------
        dimensions : list, shape (n_dims,)
            List of search space dimensions.
            Each search dimension can be defined either as

            - a `(lower_bound, upper_bound)` tuple (for `Real` or `Integer`
              dimensions),
            - a `(lower_bound, upper_bound, "prior")` tuple (for `Real`
              dimensions),
            - as a list of categories (for `Categorical` dimensions), or
            - an instance of a `Dimension` object (`Real`, `Integer` or
              `Categorical`).

        n_samples : int
            The order of the LHS sequence. Defines the number of samples.
        random_state : int, RandomState instance, or None (default)
            Set random state to something other than None for reproducible
            results.

        Returns
        -------
        np.array, shape=(n_dim, n_samples)
            LHS set
        """
        rng = check_random_state(random_state)
        space = Space(dimensions)
        transformer = space.get_transformer()
        n_dim = space.n_dims
        space.set_transformer("normalize")
        if self.criterion is None or n_samples == 1:
            h = self._lhs_normalized(n_dim, n_samples, rng)
            h = space.inverse_transform(h)
            space.set_transformer(transformer)
            return h
        else:
            h_opt = self._lhs_normalized(n_dim, n_samples, rng)
            h_opt = space.inverse_transform(h_opt)
            if self.criterion == "correlation":
                mincorr = np.inf
                for i in range(self.iterations):
                    # Generate a random LHS
                    h = self._lhs_normalized(n_dim, n_samples, rng)
                    r = np.corrcoef(np.array(h).T)
                    if len(np.abs(r[r != 1])) > 0 and \
                            np.max(np.abs(r[r != 1])) < mincorr:
                        mincorr = np.max(np.abs(r - np.eye(r.shape[0])))
                        h_opt = h.copy()
                        h_opt = space.inverse_transform(h_opt)
            elif self.criterion == "maximin":
                maxdist = 0
                # Maximize the minimum distance between points
                for i in range(self.iterations):
                    h = self._lhs_normalized(n_dim, n_samples, rng)
                    d = spatial.distance.pdist(np.array(h), 'euclidean')
                    if maxdist < np.min(d):
                        maxdist = np.min(d)
                        h_opt = h.copy()
                        h_opt = space.inverse_transform(h_opt)
            elif self.criterion == "ratio":
                minratio = np.inf

                # Maximize the minimum distance between points
                for i in range(self.iterations):
                    h = self._lhs_normalized(n_dim, n_samples, rng)
                    p = spatial.distance.pdist(np.array(h), 'euclidean')
                    if np.min(p) == 0:
                        ratio = np.max(p) / 1e-8
                    else:
                        ratio = np.max(p) / np.min(p)
                    if minratio > ratio:
                        minratio = ratio
                        h_opt = h.copy()
                        h_opt = space.inverse_transform(h_opt)
            else:
                raise ValueError("Wrong criterion."
                                 "Got {}".format(self.criterion))
            space.set_transformer(transformer)
            return h_opt

    def _lhs_normalized(self, n_dim, n_samples, random_state):
        rng = check_random_state(random_state)
        x = np.linspace(0, 1, n_samples + 1)
        u = rng.rand(n_samples, n_dim)
        h = np.zeros_like(u)
        if self.lhs_type == "centered":
            for j in range(n_dim):
                h[:, j] = np.diff(x) / 2.0 + x[:n_samples]
        elif self.lhs_type == "classic":
            for j in range(n_dim):
                h[:, j] = u[:, j] * np.diff(x) + x[:n_samples]
        else:
            raise ValueError("Wrong lhs_type. Got ".format(self.lhs_type))
        return _random_permute_matrix(h, random_state=rng)


from ANNarchy import *
import pylab as plt
from scipy import signal, stats
from model_neuronmodels import params, rng, Izhikevich2007RS, Izhikevich2007FS
from extras import lognormalPDF, get_log_normal_fit, set_size

### create 1000 neurons of each neurontype
corE = Population(1000, neuron=Izhikevich2007RS, name='CorE')
corI = Population(1000, neuron=Izhikevich2007FS, name='CorI')

### create spiketimearray input with one spike
spike_times = [
  [10] for i in range(1)
]
inputPop = SpikeSourceArray(spike_times=spike_times)

### direct this spike to both populations
inputPopcorE = Projection(
    pre    = inputPop,
    post   = corE,
    target = 'ampa',
    name = 'inputPopcorE'
).connect_all_to_all(weights = params['weightDist'](rng))#weights have specific log normal dist to obtain PSP dist

inputPopcorI = Projection(
    pre    = inputPop,
    post   = corI,
    target = 'ampa',
    name = 'inputPopcorI'
).connect_all_to_all(weights = params['weightDist'](rng))#weights have specific log normal dist to obtain PSP dist

"""
### Define weights so that the PSP distribution looks like the target PSP population (see extras.lognormalPDF)

#how new mu, sigma were obtained:
#inputPopcorE --> weights * 0.5
test=0.3*rng.lognormal(-0.7,0.93,10000)
shape,loc,scale = stats.lognorm.fit(test)
sigma=shape
mu=np.log(scale)
print(mu,sigma)
quit()
#inputPopcorE --> weights * 0.3-0.4
... both about mu=1.5"""

### compile
compile()

### compare weight distribution with target EPSP distribution
plt.figure()
x=np.arange(0.01,7.5,0.01)
plt.hist(np.array(inputPopcorE.w).flatten(), 100, density=True, align='mid', label='weights')
plt.plot(x, lognormalPDF(x), label='EPSPs Song et al. (2005)')
plt.xlim(0,10)
plt.legend()
plt.savefig('../results/get_weightDist/get_weightDist_weightsE_dist.svg')

### record membranepotential of both neurons
mon_v_corE = Monitor(corE, 'v')
mon_v_corI = Monitor(corI, 'v')

### simulate 100 ms
simulate(100)

### plot membrane potentials
v_corE = mon_v_corE.get('v')
v_corI = mon_v_corI.get('v')

### get peak values from membrane potentials
maxPosE=np.zeros(1000)*np.nan
maxPosI=np.zeros(1000)*np.nan
maxValE=np.zeros(1000)*np.nan
maxValI=np.zeros(1000)*np.nan
for idx in range(1000):
    if len(signal.argrelmax(v_corE[:,idx])[0])>0:
        maxPosE[idx]=signal.argrelmax(v_corE[:,idx])[0][0]
        maxValE[idx]=v_corE[int(maxPosE[idx]),idx]
    if len(signal.argrelmax(v_corI[:,idx])[0])>0:
        maxPosI[idx]=signal.argrelmax(v_corI[:,idx])[0][0]
        maxValI[idx]=v_corI[int(maxPosI[idx]),idx]

plt.figure()
plt.subplot(211)
plt.plot(v_corE[:,0],color='C0')
plt.plot(v_corE[:,1],color='C1')
plt.plot(v_corE[:,999],color='C2')
plt.axvline(maxPosE[0],color='C0')
plt.axvline(maxPosE[1],color='C1')
plt.axvline(maxPosE[999],color='C2')
plt.axhline(maxValE[0],color='C0')
plt.axhline(maxValE[1],color='C1')
plt.axhline(maxValE[999],color='C2')
plt.subplot(212)
plt.plot(v_corI[:,0],color='C0')
plt.plot(v_corI[:,1],color='C1')
plt.plot(v_corI[:,999],color='C2')
plt.axvline(maxPosI[0],color='C0')
plt.axvline(maxPosI[1],color='C1')
plt.axvline(maxPosI[999],color='C2')
plt.axhline(maxValI[0],color='C0')
plt.axhline(maxValI[1],color='C1')
plt.axhline(maxValI[999],color='C2')
plt.savefig('../results/get_weightDist/get_weightDist_PSPexamples.svg')

### calculate PSP distribution from membrane potentials

## difference between resting potential and peaks below 0
PSPsE=maxValE[maxValE<0]-params['RS_v_r']
PSPsI=maxValI[maxValE<0]-params['FS_v_r']

plt.figure()
plt.subplot(211)
plt.hist(PSPsE[PSPsE<=10], 100, density=True, align='mid', label='EPSPs in CorE')
plt.plot(x,lognormalPDF(x), label='EPSPs Song et al. (2005)')
plt.xlim(0,10)
plt.legend()
plt.subplot(212)
plt.hist(PSPsI[PSPsI<=10], 100, density=True, align='mid', label='EPSPs in CorI')
plt.plot(x,lognormalPDF(x), label='EPSPs Song et al. (2005)')
plt.xlim(0,10)
plt.legend()
plt.savefig('../results/get_weightDist/get_weightDist_PSP_dist.svg')

### COMPARISON COMBINED PSP DISTRIBUTION SIMULATION (E+I) VS EXPERIMENTAL

## COMBINE PSP DISTRIBUTIONS OF E AND I
PSP_dist = np.concatenate([PSPsE, PSPsI])

### OBTAIN FITTED LOG NORMAL DISTRIBUTION
fit = get_log_normal_fit(PSP_dist)

## PLOT
plt.figure()
plt.hist(PSP_dist[PSP_dist<=10], 100, density=True, align='mid', color='grey', alpha=0.5)
plt.plot(x,lognormalPDF(x), label='Song et al. (2005)', color='k')
plt.plot(x, lognormalPDF(x, mu=fit[0], sigma=fit[1], shift=fit[2]), label='Model', color='red', ls='dashed')
plt.legend(fontsize=8)
set_size(5.93/2.54,2.44/2.54)
plt.savefig('../results/get_weightDist/get_weightDist_combined_PSP_dist.svg')


from __future__ import annotations

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship

from .. import database

class Organization(database.Base):
    __tablename__ = "organization"

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    slug = Column(String, nullable=False)
    external_slug = Column(String)

    items = relationship("Item")
    users = relationship("User")
    sentry_installations = relationship("SentryInstallation")

    def __init__(self, name: str, slug: str, external_slug: str) -> None:
        self.name = name
        self.slug = slug
        self.external_slug = external_slug

    def __repr__(self) -> str:
        return f"<Organization #{self.id}: {self.slug}>"


import requests

def download(url):
    print("开始下载：",url)
    response=requests.get(url,verify=False)
    print("下载完成")
    filename=url.split(r"/")[-1]
    with open(filename,mode='wb') as file_obj:
        file_obj.write(response.content)

if __name__ == '__main__':
    url_list=[r"https://i.tuiimg.net/006/2522/2.jpg",
              r"https://i.tuiimg.net/006/2522/3.jpg",
              r"https://i.tuiimg.net/006/2522/4.jpg"]
    for item in url_list:
        download(item)


import scrapy

class Test(scrapy.Spider):
    name = 'xxx'
    start_urls = ['https://github.com/shiyanlou?tab=repositories']

    def parse(self, r):
        for i in r.xpath('//li[contains(@class, "col-12")]'):
            yield {
                'name': i.css('a::text').extract_first().strip(),
                'update_time': i.xpath('.//relative-time/@datetime').extract_first()
            }
        url = r.xpath('//div[@class="pagination"]/a')[-1].css('::attr(href)').extract_first()
        if r.xpath('//div[@class="pagination"]/a')[-1].css('::text').extract_first() == 'Next':
            yield r.follow(url, callback=self.parse)


# Cow Beauty Pageant
# Gold 5, BFS, DFS

from collections import deque
import sys
input = sys.stdin.readline
M = 5931
sys.setrecursionlimit(M)

def dfs(x,y):
    grid[x][y] = k
    for nx,ny in ((x+1,y),(x-1,y),(x,y+1),(x,y-1)):
        if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] == 'X':
            dfs(nx,ny)

def bfs(i,j):
    q = deque([(i,j)])
    visit = [[-2]*m for _ in range(n)]
    visit[i][j] += 1
    while q:
        x,y = q.popleft()
        if grid[i][j]*grid[x][y] < 0:
            return visit[x][y]
        for nx,ny in ((x+1,y),(x-1,y),(x,y+1),(x,y-1)):
            if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] != grid[i][j] and visit[nx][ny] == -2:
                q.append((nx,ny))
                visit[nx][ny] = visit[x][y]+1
    return M

n,m = map(int,input().split())
grid = [list(input()) for _ in range(n)]

k = -1
for i in range(n):
    for j in range(m):
        if grid[i][j] == 'X':
            dfs(i,j)
            k = 1
        elif grid[i][j] == '.':
            grid[i][j] = 0

result = M
for i in range(n):
    for j in range(m):
        if grid[i][j] != 0:
            result = min(result,bfs(i,j))
print(result)


import os
from functools import cached_property

from pandas import read_csv

from app import DATA_DIRPATH

GTZAN_DIRPATH = os.path.join(DATA_DIRPATH, "gtzan")
GENRES_DIRPATH = os.path.join(GTZAN_DIRPATH, "genres_original")

class AudioFile:

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

        self.genre = audio_filepath.split("/")[-2]
        self.audio_filename = audio_filepath.split("/")[-1]

        self.genre_dirpath = os.path.join(GENRES_DIRPATH, self.genre)

class GenreDataset:

    #def __init__(self, gtzan_dirpath=GTZAN_DIRPATH):
    #    self.gtzan_dirpath = gtzan_dirpath
    #    self.genres_dirpath = os.path.join(self.gtzan_dirpath, "genres_original")

    @cached_property
    def genres(self):
        return sorted([genre for genre in os.listdir(GENRES_DIRPATH) if genre not in [".DS_Store"]])

    #@cached_property
    #def audio_filepaths(self):
    #    filepaths = []
    #    for genre in self.genres:
    #        genre_dirpath = os.path.join(GENRES_DIRPATH, genre)
    #        audio_filenames = sorted([fname for fname in os.listdir(genre_dirpath) if fname.endswith(".wav")])
    #        #print(genre, len(audio_filenames))
    #        for audio_filename in audio_filenames:
    #            audio_filepath = os.path.join(genre_dirpath, audio_filename)
    #            filepaths.append(audio_filepath)
    #    return filepaths

    @cached_property
    def audio_files(self):
        files = []
        for genre in self.genres:
            genre_dirpath = os.path.join(GENRES_DIRPATH, genre)
            audio_filenames = sorted([fname for fname in os.listdir(genre_dirpath) if fname.endswith(".wav")])
            #print(genre, len(audio_filenames))

            for audio_filename in audio_filenames:
                audio_filepath = os.path.join(genre_dirpath, audio_filename)
                files.append(AudioFile(audio_filepath))

        return files

    def features_csv_filepath(self, track_length, n_mfcc):
        features_dirpath = os.path.join(GTZAN_DIRPATH, f"features_{track_length}s")
        os.makedirs(features_dirpath, exist_ok=True)
        return os.path.join(features_dirpath, f"mfcc_{n_mfcc}_features.csv")

    def read_features_csv(self, track_length, n_mfcc):
        csv_filepath = self.features_csv_filepath(track_length, n_mfcc)
        return read_csv(csv_filepath)


import requests
import json
import pandas as pd

def OrientQuery(query,database):

    url = "http://localhost:2480/command/CustomerE2E/sql"

    payload = json.dumps({
        "command": "select * from COLUMN"
    })
    headers = {
        'Authorization': 'Basic cm9vdDpyb290',
        'Content-Type': 'application/json',
        'Cookie': 'OSESSIONID=OS1647213389295-1231421075967031879'
    }

    response = requests.request("POST", url, headers=headers, data=payload)
    #data = json.loads(response.text)
    #df = pd.json_normalize(data['result'])

    return (response.text)


from typing import List

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:

        def find(ix, i, j, readed):
            readed.append((i, j))
            if ix == len(word):
                return True
            if board[i][j] != word[ix]:
                return False
            rslt = []
            candi = [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]
            for nxt_i, nxt_j in candi:
                if nxt_i < 0 or nxt_i >= len(board) or nxt_j < 0 or nxt_j >= len(board[0]) or (nxt_i, nxt_j) in readed:
                    continue
                r = find(ix+1, nxt_i, nxt_j)
                print(i, j, r, nxt_i, nxt_j)
                rslt.append(r)
            print(i, j, rslt)
            if sum(rslt) == 0:
                return False
            return True

        for i in range(len(board)):
            for j in range(len(board[0])):
                readed = []
                print('*************************')
                if find(0, i, j):
                    return True
        return False

s = Solution()
board = [["A","B","C","E"],
         ["S","F","C","S"],
         ["A","D","E","E"]]
word = "ABFS"
print(s.exist(board, word))