import json
import logging
import tornado.gen

from tornado_http_auth import BasicAuthMixin
from pywakeonlan.wakeonlan import send_magic_packet
from server.base import BaseHandler

class DialogFlowHandler(BasicAuthMixin, BaseHandler):
    lastComputer = {}

    def initialize(self, credentials):
        self.credentials = credentials

    def check_xsrf_cookie(self):
        """
        Disable check since DialogFlow logs in via basic HTTP authentication
        """
        return True

    def prepare(self):
        self.get_authenticated_user(check_credentials_func=self.credentials.get, realm='Protected')

    def get(self):
        self.write("This is meant to be a webhook for DialogFlow")

    @tornado.gen.coroutine
    def get_wol_mac(self, userid, computer):
        laptop_mac, desktop_mac = yield self.get_macs(userid)

        if computer.strip().lower() == "laptop":
            return laptop_mac
        else:
            return desktop_mac

    @tornado.gen.coroutine
    def post(self):
        data = json.loads(self.request.body.decode('utf-8'))

        # Skip if already answered, e.g. saying "Hi!" will be fulfilled by "Small Talk"
        if 'fulfillmentText' in data['queryResult']:
            self.write(json.dumps({}))
            self.set_header("Content-type", "application/json")
            return

        # Make sure the user is logged in and provided a valid access token for a signed-up user
        if 'originalDetectIntentRequest' not in data or \
           'payload' not in data['originalDetectIntentRequest'] or \
           'user' not in data['originalDetectIntentRequest']['payload'] or \
           'accessToken' not in data['originalDetectIntentRequest']['payload']['user']:
            self.write(json.dumps({ "fulfillmentText": "You must be logged in." }))
            self.set_header("Content-type", "application/json")
            return

        userid = yield self.getUserIDFromToken(data['originalDetectIntentRequest']['payload']['user']['accessToken'])

        if not userid:
            logging.error("Invalid access token - userid: "+str(userid)+", data:"+str(data))
            self.write(json.dumps({ "fulfillmentText": "Invalid access token." }))
            self.set_header("Content-type", "application/json")
            return

        response = "Sorry, I'm not sure how to answer that."
        longResponse = None

        # Determine command/query and respond appropriately
        try:
            intent = data['queryResult']['intent']['displayName']
            params = data['queryResult']['parameters']

            if intent == "Computer Command":
                command = params['Command']
                computer = params['Computer']
                x = params['X']
                url = params['url']
                number = params['number']

                # Update last computer used
                if computer:
                    self.lastComputer[userid] = computer
                # If no computer specified, use last, if available
                elif userid in self.lastComputer:
                    computer = self.lastComputer[userid]

                # Only command we handle is the WOL packet
                if command == "power on":
                    if computer:
                        mac = yield self.get_wol_mac(userid, computer)

                        if mac:
                            send_magic_packet(mac, port=9)
                            response = "Woke your "+computer
                        else:
                            response = "Your "+computer+" is not set up for wake-on-LAN"
                    else:
                        response = "Please specify which computer you are asking about"
                else:
                    if userid in self.clients and computer in self.clients[userid]:
                        self.clients[userid][computer].write_message(json.dumps({
                            "command": { "command": command, "x": x, "url": url, "number": number }
                        }))
                        response, longResponse = yield self.clients[userid][computer].wait_response()

                        if not response:
                            response = "Command sent to "+computer
                    elif computer:
                        response = "Your "+computer+" is not currently online"
                    else:
                        response = "Please specify which computer you are asking about"

                    # TODO
                    # If this takes too long, then immediately respond "Command sent to laptop"
                    # and then do this: https://productforums.google.com/forum/#!topic/dialogflow/HeXqMLQs6ok;context-place=forum/dialogflow
                    # saving context and later returning response or something
            elif intent == "Computer Query":
                value = params['Value']
                x = params['X']
                computer = params['Computer']

                # Update last computer used
                if computer:
                    self.lastComputer[userid] = computer
                # If no computer specified, use last, if available
                elif userid in self.lastComputer:
                    computer = self.lastComputer[userid]

                # Only query we handle is the "where is my laptop/desktop"
                if value == "where":
                    if computer:
                        if userid in self.clients and computer in self.clients[userid]:
                            ip = self.clients[userid][computer].ip
                            response = "Unknown location for your "+computer

                            if ip:
                                if ip == self.serverIp:
                                    response = "Your "+computer+" is at home"
                                else:
                                    data = self.gi.record_by_addr(ip)

                                    if data and "city" in data and "region_name" in data and "country_name" in data:
                                        city = data["city"]
                                        region = data["region_name"]
                                        country = data["country_name"]
                                        response = "Your "+computer+" is in "+city+", "+region+", "+country+" ("+ip+")"
                        else:
                            response = "Could not find location of your "+computer
                    else:
                        response = "Please specify which computer you are asking about"
                else:
                    if userid in self.clients and computer in self.clients[userid]:
                        self.clients[userid][computer].write_message(json.dumps({
                            "query": { "value": value, "x": x }
                        }))
                        response, longResponse = yield self.clients[userid][computer].wait_response()

                        if not response:
                            response = "Your "+computer+" did not respond"
                    elif computer:
                        response = "Your "+computer+" is not currently online"
                    else:
                        response = "Please specify which computer you are asking about"
        except KeyError:
            pass

        #"source": string,
        #"payload": { },
        #"outputContexts": [ { object(Context) } ],
        #"followupEventInput": { object(EventInput) },
        #"fulfillmentMessages": [ { response } ],

        # If desired, display one thing and say another. This is useful for
        # example when the displayed text is a file name and you only want to
        # read the most relevant part of it.
        if longResponse:
            json_response = json.dumps({
                "fulfillmentMessages": [{
                    "platform": "ACTIONS_ON_GOOGLE",
                    "simpleResponses": {
                        "simpleResponses": [{
                            "textToSpeech": response,
                            "displayText": longResponse
                        }]
                    }
                }]})
        else:
            json_response = json.dumps({ "fulfillmentText": response })

        self.write(json_response)
        self.set_header("Content-type", "application/json")


DAY = 1

def part1(data):
    return sum(1 if j == "(" else -1 for j in data.strip())

def part2(data):
    curr = 0
    for i,c in enumerate(data.strip()):
        if c == "(":
            curr += 1
        else:
            curr -= 1
            if curr == -1:
                return i+1


#讓使用者輸入兩個數字 代表一個區間
a = int(input("Input a number: "))
b = int(input("Input another number: "))

# 找出符合 Self-Dividing Number的所有數
def SelfDividingNumber(left, right):
    res = []
    for n in range(left, right+1):
        if '0' in str(n):
            continue
        for i in str(n):
            if n % int(i) != 0:
                break
        else:
            res.append(n)
    return res
c = SelfDividingNumber(a, b)

#將差距最大的Self-Dividing Number 兩數印出
def gap(l):
    temp = 0
    for i in range(len(l)-1):
        dist = l[i+1] - l[i]
        if dist > temp:
            temp = dist
            res = [l[i], l[i+1]]
            continue
    return res
d = gap(c)
print(d)


# -*- coding: utf-8 -*-
from odoo.tests.common import TransactionCase
from odoo.addons.report_docx.report.report_docx import DataModelProxy
from odoo.tools import misc
import tempfile
import shutil

class test_ReportDocx(TransactionCase):

    def setUp(self):
        '''准备数据'''
        super(test_ReportDocx, self).setUp()
        self.ir_actions = self.env.ref('sell.report_sell_order_1')
        self.sell_order = self.env.ref('sell.sell_order_1')
        self.report_docx_sell = self.ir_actions._lookup_report('sell.order')

        self.ir_actions_pdf = self.env.ref('sell.report_sell_order_2')
        self.sell_order = self.env.ref('sell.sell_order_1')
        self.report_pdf_sell = self.ir_actions_pdf._lookup_report('sell.order')

    def test_lookup_report(self):
        '''测试docx报表模板'''
        self.report_docx_sell.create(self.cr, self.uid, self.sell_order.id, self.ir_actions, self.env.context)

    def test_lookup_report_pdf(self):
        '''测试docx报表模，输出类型为pdf'''
        self.ir_actions.write({'output_type':'pdf'})
        self.report_docx_sell.create(self.cr, self.uid,self.sell_order.id, self.ir_actions, self.env.context)

    def test_get_docx_data(self):
        model = self.report_docx_sell.get_docx_data(self.cr, self.uid, self.ir_actions.id, self.ir_actions, self.env.context)

    def test_save_file(self):
        doxc_file = self.report_docx_sell.create(self.cr, self.uid, self.sell_order.id, self.ir_actions, self.env.context)
        tempname = tempfile.mkdtemp()
        shutil.copy(misc.file_open('sell/template/sell.order.docx').name, tempname)
        self.report_docx_sell._save_file(tempname+"/sell.order.docx",doxc_file)

    def test_render_to_pdf(self):
        doxc_file = self.report_pdf_sell.create(self.cr, self.uid, self.sell_order.id, self.ir_actions_pdf,
                                                 self.env.context)

    def test_datamodelproxy(self):
        data=DataModelProxy([{"type":'selection'}])
        data.__getitem__(0)
        data = DataModelProxy([])
        data.__getattr__(0)

    def test_by_selection(self):
        data = DataModelProxy(self.env['home.page'])
        home = self.env['home.page']
        data._compute_by_selection(home._fields.get('menu_type'),"all_business")
        home = self.env['sell.order']
        data = DataModelProxy(home)
        data._compute_by_selection(home._fields.get('state'),"done")


def leiaInt(msg):
    """
    Validar se o valor é inteiro ou não
    :param msg: Valor a ser verificado
    :return:
    """
    val = False
    valor = 0

    while True:
        n = str(input(msg))
        if n.isnumeric() == True:
            valor = int(n)
            val = True
        else:
            print(f'\033[31mValor incorreto, digite uma valor númerico!\033[m')
        if val == True:
            break

    return valor

# Programa Principal
n = leiaInt('Digite um número: ')
print(f'Você digitou o número {n}')

Exercício Python #104 - Validando entrada de dados em Python.py


#
# @lc app=leetcode.cn id=209 lang=python3
#
# [209] 长度最小的子数组
#
# https://leetcode-cn.com/problems/minimum-size-subarray-sum/description/
#
# algorithms
# Medium (40.54%)
# Likes:    186
# Dislikes: 0
# Total Accepted:    25.7K
# Total Submissions: 62.6K
# Testcase Example:  '7\n[2,3,1,2,4,3]'
#
# 给定一个含有 n 个正整数的数组和一个正整数 s ，找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组，返回 0。
#
# 示例:
#
# 输入: s = 7, nums = [2,3,1,2,4,3]
# 输出: 2
# 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
#
#
# 进阶:
#
# 如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。
#
#

# @lc code=start
class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
        #滑窗法
        start = 0
        end = 0
        min_len = float("inf")
        res=0
        while end<len(nums):
            s-=nums[end]
            end+=1
            while s<=0:
                if end-start<min_len:
                    min_len=end-start
                    res=min_len
                s+=nums[start]
                start+=1

        return res

# @lc code=end

209.长度最小的子数组.py


scores = [60, 73, 81, 95, 34]
n = 5
i = 0
total = 0
while i < 5:
    total += scores[i]
    i += 1

avg = total / n

print('total ' + str(total))
print('average ' + str(avg))


import sys
import time
import traceback
import contextlib

import gevent.hub

# The maximum amount of time that the eventloop can be blocked
# without causing an error to be logged, in seconds.

MAX_BLOCKING_TIME = 0.1

# A global variable for tracking the time of the last greenlet switch.
# For server processes that use a single OS-level thread, a global works fine.
# You might like to use a threadlocal for complicated setups.

_last_switch_time = None

# A trace function that gets executed on every greenlet switch.
# It checks how much time has elapsed and logs an error if it was excessive.
# The Hub gets an exemption, because it's allowed to block on I/O.

def switch_time_tracer(what, origin, target):
    global _last_switch_time
    then = _last_switch_time
    now = _last_switch_time = time.time()
    if then is not None:
        blocking_time = now - then
        if origin is not gevent.hub.get_hub():
            if blocking_time > MAX_BLOCKING_TIME:
                msg = "Greenlet blocked the eventloop for %.4f seconds\n"
                msg = msg % (blocking_time,)
                print(sys.stderr, msg)
                traceback.print_stack()

# greenlet.settrace(switch_time_tracer)

@contextlib.contextmanager
def check_for_gevent_blocking():
    # Remember the time of last switch before entering the context.
    old_switch_time = _last_switch_time
    yield None
    # If the time of last switch has not changed when exiting the context,
    # then we obviously didn't yield back to the event loop.
    if old_switch_time is not None:
        if old_switch_time == _last_switch_time:
            raise RuntimeError("Code did not yield to gevent")


from types import SimpleNamespace

import torch
from torch import nn
import math

from src.vision.part3_training_utils import get_model_and_optimizer
from src.vision.part1_ppm import PPM
from src.vision.part5_pspnet import PSPNet

def test_get_model_and_optimizer_pspnet():
    """ """
    args = SimpleNamespace(
        **{
            "classes": 11,
            "zoom_factor": 8,
            "layers": 50,
            "ignore_label": 255,
            "arch": "PSPNet",
            "base_lr": 1e-3,
            "momentum": 0.99,
            "weight_decay": 1e-5,
            "pretrained": False,
            "use_ppm": True
        }
    )
    model, optimizer = get_model_and_optimizer(args)
    param_learning_rates = [group["lr"] for group in optimizer.param_groups]
    print(isinstance(model, PSPNet))
    print(isinstance(optimizer, torch.optim.Optimizer))
    print(len(optimizer.param_groups) > 1)
    print(args.base_lr in param_learning_rates)
    print(not all([param_learning_rates == 1e-3]))
    print(type(model))
    print(PSPNet)
    print(type(PSPNet))
    assert isinstance(model, PSPNet)
    assert isinstance(optimizer, torch.optim.Optimizer)

    assert len(optimizer.param_groups) > 1

    # some modules should be trained at this rate
    assert args.base_lr in param_learning_rates
    # should be separate rates
    assert not all([param_learning_rates == 1e-3])

def test_pspnet_output_shapes() -> None:
    """"""
    args = SimpleNamespace(
        **{
            "classes": 11,
            "zoom_factor": 8,
            "layers": 50,
            "ignore_label": 255,
        }
    )

    criterion = nn.CrossEntropyLoss(ignore_index=args.ignore_label)
    model = PSPNet(
        layers=args.layers,
        num_classes=args.classes,
        zoom_factor=args.zoom_factor,
        criterion=criterion,
        use_ppm=True,
        pretrained=False
    )

    # check whether PPM exists
    #print(isinstance(model.ppm, nn.Module))
    #print(isinstance(model.ppm, PPM))
    assert isinstance(model.ppm, nn.Module)
    assert isinstance(model.ppm, PPM)

    batch_size = 5
    H = 201
    W = 201
    x = torch.rand(batch_size,3,H,W).type(torch.float32)
    y = torch.ones(batch_size,H,W).type(torch.int64) * 255

    logits, yhat, main_loss, aux_loss = model(x, y)

    assert logits.shape == (batch_size, args.classes, H, W)

    # make sure that the output shape is correct
    assert yhat.shape == (batch_size, H, W)

    assert isinstance(logits, torch.Tensor)
    assert isinstance(yhat, torch.Tensor)
    assert isinstance(main_loss, torch.Tensor)
    assert isinstance(aux_loss, torch.Tensor)

    # check loss with all ground truth set to ignore index
    # assert torch.allclose(main_loss, torch.Tensor([0.]))
    # assert torch.allclose(aux_loss, torch.Tensor([0.]))

    # check the dilation settings

def test_check_output_shapes_testtime_pspnet():
    """When y is not provided to the model, losses should be None"""
    args = SimpleNamespace(
        **{
            "classes": 11,
            "zoom_factor": 8,
            "layers": 50,
            "ignore_label": 255,
        }
    )

    criterion = nn.CrossEntropyLoss(ignore_index=args.ignore_label)
    model = PSPNet(
        layers=args.layers,
        num_classes=args.classes,
        zoom_factor=args.zoom_factor,
        criterion=criterion,
        use_ppm=True,
        pretrained=False
    )

    batch_size = 5
    H = 201
    W = 201
    x = torch.rand(batch_size,3,H,W).type(torch.float32)
    y = torch.ones(batch_size,H,W).type(torch.int64) * 255

    logits, yhat, main_loss, aux_loss = model(x)

    assert logits.shape == (batch_size, args.classes, H, W)

    # make sure that the output shape is correct
    assert yhat.shape == (batch_size, H, W)

    assert isinstance(logits, torch.Tensor)
    assert isinstance(yhat, torch.Tensor)

    assert main_loss == None
    assert aux_loss == None

def test_pspnet_output_with_zoom_factor():
    args = SimpleNamespace(
        **{
            "classes": 11,
            "layers": 50,
            "ignore_label": 255,
        }
    )

    criterion = nn.CrossEntropyLoss(ignore_index=args.ignore_label)
    model = PSPNet(
        layers=args.layers,
        num_classes=args.classes,
        criterion=criterion,
        use_ppm=True,
        pretrained=False
    )
    batch_size = 5
    H = 201
    W = 201

    for zoom_factor in [1, 2, 4, 8]:
        model.zoom_factor = zoom_factor
        h_scaled = int(math.ceil(H/8 * zoom_factor))
        w_scaled = int(math.ceil(W/8 * zoom_factor))
        x = torch.rand(batch_size,3,H,W).type(torch.float32)
        y = torch.ones(batch_size,h_scaled,w_scaled).type(torch.int64) * 255

        logits, yhat, main_loss, aux_loss = model(x)

        assert logits.shape == (batch_size, args.classes, h_scaled, w_scaled)
        assert yhat.shape == (batch_size, h_scaled, w_scaled)


import tkinter as tk
import tkinter.messagebox

window = tk.Tk()
window.title("Welcome to edureka!")
# default size of table 'width x height'
window.geometry('350x200')

# create message box & yes-no question box
def clicked():
	tkinter.messagebox.showinfo('Message title', 'Message content')
	# question box will pop up after exiting the message box above!
	answer = tkinter.messagebox.askquestion('Quiz', 'Do you like Python?')
	if answer == 'yes':
		print("That's the right choice!")
	else:
		print('You better think twice.')

btn = tk.Button(window, text='Click here', command=clicked)
btn.grid(column=0, row=0)

window.mainloop()


from django.urls import path
from . import views

app_name = "dyslexia"
urlpatterns = [
    path("home", views.home, name="home"),
    path("features", views.features, name="features"),
    path("test", views.test, name="test"),
    path("practice", views.practice, name="practice"),
]


import os

from pathlib import Path

def process_input(input_path):
    grid = []
    with open(input_path, "r") as input_file:
        for line in input_file:
            grid.append(list(map(int, line.strip())))
    return grid

def find_visible_trees(grid):
    edge_nodes = 4 * (len(grid) - 1)

    internal_nodes = 0
    for idx in range(1, len(grid) - 1):
        for jdx in range(1, len(grid[0]) - 1):
            cur_tree = grid[idx][jdx]
            row, col = grid[idx], [item[jdx] for item in grid]

            lv = max(row[:jdx]) < cur_tree
            rv = max(row[jdx + 1 :]) < cur_tree
            tv = max(col[:idx]) < cur_tree
            bv = max(col[idx + 1 :]) < cur_tree

            if any([lv, rv, tv, bv]):
                internal_nodes += 1

    return edge_nodes + internal_nodes

def find_scenic_score(grid):
    cur_ss = 0
    for idx in range(1, len(grid) - 1):
        for jdx in range(1, len(grid[0]) - 1):
            cur_tree = grid[idx][jdx]
            row, col = grid[idx], [item[jdx] for item in grid]

            lss, rss, tss, bss = 0, 0, 0, 0

            for kdx in range(1, jdx + 1):
                lss += 1
                if row[jdx - kdx] >= cur_tree:
                    break

            for kdx in range(1, idx + 1):
                tss += 1
                if col[idx - kdx] >= cur_tree:
                    break

            for kdx in range(1, len(row) - jdx):
                rss += 1
                if row[jdx + kdx] >= cur_tree:
                    break

            for kdx in range(1, len(col) - idx):
                bss += 1
                if col[idx + kdx] >= cur_tree:
                    break

            cur_ss = max(cur_ss, lss * rss * tss * bss)

    return cur_ss

if __name__ == "__main__":
    input_path = os.path.join(Path(__file__).parent.absolute(), "input.txt")

    grid = process_input(input_path)
    print("1: ", find_visible_trees(grid))
    print("2: ", find_scenic_score(grid))


import collections
import json

from music21 import environment
from music21 import converter

from json_utils import NoteEncoder, note_decoder
from multi_score_signatures import MultiScoreSignatures
from notes_utils import should_skip

class ComposerSignatures:

    def __init__(self, path, composer=None):
        self.path = path
        scores = collections.defaultdict(list)
        with open(path) as f:
            lines = f.readlines()
            for line in lines:
                if should_skip(line):
                    continue
                try:
                    note_score = converter.parse(line.rstrip())
                    if composer is not None:
                        scores[composer].append(note_score)
                    else:
                        if note_score.metadata is not None and note_score.metadata.composer is not None:
                            scores[note_score.metadata.composer].append(note_score)
                        else:
                            scores['Unknown'].append(note_score)
                            print('Not found composer in metadata: ', line)
                    print('Parsed ', line)
                except Exception as ex:
                    print('Failed parsing for {} due to exception: {}'.format(line, ex))

        result = collections.defaultdict(list)
        for composer in scores:
            multi_score_signatures = MultiScoreSignatures().run(scores[composer])
            result[composer].append(multi_score_signatures)

        with open(path + ".json", "w") as outfile:
            json.dump(result, outfile, cls=NoteEncoder)
        with open(path + ".json") as json_file:
            data = json.load(json_file, object_hook=note_decoder)
            print(data)

e = environment.Environment()
e['autoDownload'] = 'allow'

ComposerSignatures('res/scores/n-grams/bach-control-set', 'Bach')


import time
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LassoLarsIC
from sklearn.pipeline import make_pipeline

start_time = time.time()
lasso_lars_ic = make_pipeline(
    StandardScaler(), LassoLarsIC(criterion="aic", normalize=False)
).fit(X_train1, y_train1)
fit_time = time.time() - start_time

def highlight_min(x):
    x_min = x.min()
    return ["font-weight: bold" if v == x_min else "" for v in x]

results.style.apply(highlight_min)

ax = results.plot()
ax.vlines(
    alpha_aic,
    results["AIC criterion"].min(),
    results["AIC criterion"].max(),
    label="alpha: AIC estimate",
    linestyles="--",
    color="tab:blue",
)
ax.vlines(
    alpha_bic,
    results["BIC criterion"].min(),
    results["BIC criterion"].max(),
    label="alpha: BIC estimate",
    linestyle="--",
    color="tab:orange",
)
ax.set_xlabel(r"$\alpha$")
ax.set_ylabel("criterion")
ax.set_xscale("log")
ax.legend()
_ = ax.set_title(
    f"Information-criterion for model selection (training time {fit_time:.2f}s)"
)


from html import escape
from typing import Optional, List
import html, time
import re

from telegram import Message, Chat, Update, Bot, User, CallbackQuery
from telegram import ParseMode, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.error import BadRequest
from telegram.ext import MessageHandler, Filters, CommandHandler, run_async, CallbackQueryHandler
from telegram.utils.helpers import mention_html

import eliana.modules.sql.welcome_sql as sql
import eliana.modules.sql.antispam_sql as gbansql
import eliana.modules.helper_funcs.cas_api as cas

from eliana.modules.sql.antispam_sql import is_user_gbanned
from eliana import dispatcher, OWNER_ID, LOGGER, MESSAGE_DUMP, sw
from eliana.modules.helper_funcs.chat_status import user_admin, is_user_ban_protected
from eliana.modules.helper_funcs.misc import build_keyboard, revert_buttons
from eliana.modules.helper_funcs.msg_types import get_welcome_type
from eliana.modules.helper_funcs.string_handling import markdown_parser, \
    escape_invalid_curly_brackets, extract_time, markdown_to_html
from eliana.modules.helper_funcs.msg_types import get_welcome_type
from eliana.modules.helper_funcs.extraction import extract_user
from eliana.modules.helper_funcs.filters import CustomFilters
from eliana.modules.disable import DisableAbleCommandHandler
from eliana.modules.log_channel import loggable
from eliana.modules.tr_engine.strings import tld

VALID_WELCOME_FORMATTERS = [
    'first', 'last', 'fullname', 'username', 'id', 'count', 'chatname',
    'mention'
]

ENUM_FUNC_MAP = {
    sql.Types.TEXT.value: dispatcher.bot.send_message,
    sql.Types.BUTTON_TEXT.value: dispatcher.bot.send_message,
    sql.Types.STICKER.value: dispatcher.bot.send_sticker,
    sql.Types.DOCUMENT.value: dispatcher.bot.send_document,
    sql.Types.PHOTO.value: dispatcher.bot.send_photo,
    sql.Types.AUDIO.value: dispatcher.bot.send_audio,
    sql.Types.VOICE.value: dispatcher.bot.send_voice,
    sql.Types.VIDEO.value: dispatcher.bot.send_video
}

# do not async
def send(update, message, keyboard, backup_message):
    chat = update.effective_chat
    cleanserv = sql.clean_service(chat.id)
    reply = update.message.message_id
    # Clean service welcome
    if cleanserv:
        try:
            dispatcher.bot.delete_message(chat.id, update.message.message_id)
        except BadRequest:
            pass
        reply = False
    try:
        msg = update.effective_message.reply_text(
            message,
            parse_mode=ParseMode.HTML,
            reply_markup=keyboard,
            reply_to_message_id=reply,
            disable_web_page_preview=True)
    except IndexError:
        msg = update.effective_message.reply_text(
            markdown_parser(backup_message + "\nNote: the current message was "
                            "invalid due to markdown issues. Could be "
                            "due to the user's name."),
            parse_mode=ParseMode.MARKDOWN,
            reply_to_message_id=reply)
    except KeyError:
        msg = update.effective_message.reply_text(
            markdown_parser(backup_message + "\nNote: the current message is "
                            "invalid due to an issue with some misplaced "
                            "curly brackets. Please update"),
            parse_mode=ParseMode.MARKDOWN,
            reply_to_message_id=reply)
    except BadRequest as excp:
        if excp.message == "Button_url_invalid":
            msg = update.effective_message.reply_text(
                markdown_parser(
                    backup_message +
                    "\nNote: the current message has an invalid url "
                    "in one of its buttons. Please update."),
                parse_mode=ParseMode.MARKDOWN,
                reply_to_message_id=reply)
        elif excp.message == "Unsupported url protocol":
            msg = update.effective_message.reply_text(
                markdown_parser(
                    backup_message +
                    "\nNote: the current message has buttons which "
                    "use url protocols that are unsupported by "
                    "telegram. Please update."),
                parse_mode=ParseMode.MARKDOWN,
                reply_to_message_id=reply)
        elif excp.message == "Wrong url host":
            msg = update.effective_message.reply_text(
                markdown_parser(
                    backup_message +
                    "\nNote: the current message has some bad urls. "
                    "Please update."),
                parse_mode=ParseMode.MARKDOWN,
                reply_to_message_id=reply)
            LOGGER.warning(message)
            LOGGER.warning(keyboard)
            LOGGER.exception("Could not parse! got invalid url host errors")
        else:
            try:
                msg = update.effective_message.reply_text(
                    markdown_parser(
                        backup_message +
                        "\nNote: An error occured when sending the "
                        "custom message. Please update."),
                    reply_to_message_id=reply,
                    parse_mode=ParseMode.MARKDOWN)
            except BadRequest:
                return ""
    return msg

@run_async
def new_member(bot: Bot, update: Update):
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    msg = update.effective_message # type: Optional[Message]
    chat_name = chat.title or chat.first or chat.username # type: Optional:[chat name]

    should_welc, cust_welcome, cust_content, welc_type = sql.get_welc_pref(
        chat.id)
    cust_welcome = markdown_to_html(cust_welcome)

    casPrefs = sql.get_cas_status(str(chat.id)) #check if enabled, obviously
    autoban = sql.get_cas_autoban(str(chat.id))
    defense = sql.getDefenseStatus(str(chat.id))
    if casPrefs and not autoban and cas.banchecker(user.id):
        bot.restrict_chat_member(chat.id, user.id,
                                         can_send_messages=False,
                                         can_send_media_messages=False,
                                         can_send_other_messages=False,
                                         can_add_web_page_previews=False)
        msg.reply_text("Warning! This user is CAS Banned. I have muted them to avoid spam. Ban is advised.")
        isUserGbanned = gbansql.is_user_gbanned(user.id)
        if not isUserGbanned:
            report = "CAS Banned user detected: {}".format(user.id)
            bot.send_message(MESSAGE_DUMP, report, html=True)
        if defense:
            bantime = int(time.time()) + 60
            chat.kick_member(new_mem.id, until_date=bantime)
    elif casPrefs and autoban and cas.banchecker(user.id):
        chat.kick_member(user.id)
        msg.reply_text("CAS banned user detected! User has been automatically banned!")
        isUserGbanned = gbansql.is_user_gbanned(user.id)
        if not isUserGbanned:
            report = "CAS Banned user detected: {}".format(user.id)
            bot.send_message(MESSAGE_DUMP, report, html=True)
    elif defense and (user.id not in SUDO_USERS + SUPPORT_USERS):
        bantime = int(time.time()) + 60
        chat.kick_member(user.id, until_date=bantime)
    elif should_welc:
        sent = None
        new_members = update.effective_message.new_chat_members
        for new_mem in new_members:
            # Give start information when add bot to group

            if is_user_gbanned(new_mem.id):
                return

            if sw != None:
                sw_ban = sw.get_ban(new_mem.id)
                if sw_ban:
                    return

            if new_mem.id == bot.id:
                bot.send_message(chat.id, tld(chat.id, 'welcome_added_to_grp'))
                bot.send_message(MESSAGE_DUMP, "I have been added to {} with ID:
{}
".format(chat.title, chat.id), parse_mode=ParseMode.HTML)

            else:
                if is_user_gbanned(new_mem.id):
                    return
                # If welcome message is media, send with appropriate function
                if welc_type != sql.Types.TEXT and welc_type != sql.Types.BUTTON_TEXT:
                    reply = update.message.message_id
                    cleanserv = sql.clean_service(chat.id)
                    # Clean service welcome
                    if cleanserv:
                        try:
                            dispatcher.bot.delete_message(
                                chat.id, update.message.message_id)
                        except BadRequest:
                            pass
                        reply = False
                    # Formatting text
                    first_name = new_mem.first_name or "PersonWithNoName"  # edge case of empty name - occurs for some bugs.
                    if new_mem.last_name:
                        fullname = "{} {}".format(first_name,
                                                  new_mem.last_name)
                    else:
                        fullname = first_name
                    count = chat.get_members_count()
                    mention = mention_html(new_mem.id, first_name)
                    if new_mem.username:
                        username = "@" + escape(new_mem.username)
                    else:
                        username = mention
                    formatted_text = cust_welcome.format(
                        first=escape(first_name),
                        last=escape(new_mem.last_name or first_name),
                        fullname=escape(fullname),
                        username=username,
                        mention=mention,
                        count=count,
                        chatname=escape(chat.title),
                        id=new_mem.id)
                    # Build keyboard
                    buttons = sql.get_welc_buttons(chat.id)
                    keyb = build_keyboard(buttons)
                    getsec, mutetime, custom_text = sql.welcome_security(
                        chat.id)

                    member = chat.get_member(new_mem.id)
                    # If user ban protected don't apply security on him
                    if is_user_ban_protected(chat, new_mem.id,
                                             chat.get_member(new_mem.id)):
                        pass
                    elif getsec:
                        # If mute time is turned on
                        if mutetime:
                            if mutetime[:1] == "0":
                                if member.can_send_messages is None or member.can_send_messages:
                                    try:
                                        bot.restrict_chat_member(
                                            chat.id,
                                            new_mem.id,
                                            can_send_messages=False)
                                        canrest = True
                                    except BadRequest:
                                        canrest = False
                                else:
                                    canrest = False

                            else:
                                mutetime = extract_time(
                                    update.effective_message, mutetime)

                                if member.can_send_messages is None or member.can_send_messages:
                                    try:
                                        bot.restrict_chat_member(
                                            chat.id,
                                            new_mem.id,
                                            until_date=mutetime,
                                            can_send_messages=False)
                                        canrest = True
                                    except BadRequest:
                                        canrest = False
                                else:
                                    canrest = False

                        # If security welcome is turned on
                        if canrest:
                            sql.add_to_userlist(chat.id, new_mem.id)
                            keyb.append([
                                InlineKeyboardButton(
                                    text=str(custom_text),
                                    callback_data="check_bot_({})".format(
                                        new_mem.id))
                            ])
                    keyboard = InlineKeyboardMarkup(keyb)
                    # Send message
                    ENUM_FUNC_MAP[welc_type](chat.id,
                                             cust_content,
                                             caption=formatted_text,
                                             reply_markup=keyboard,
                                             parse_mode="html",
                                             reply_to_message_id=reply)
                    return
                # else, move on
                first_name = new_mem.first_name or "PersonWithNoName"  # edge case of empty name - occurs for some bugs.

                if cust_welcome:
                    if new_mem.last_name:
                        fullname = "{} {}".format(first_name,
                                                  new_mem.last_name)
                    else:
                        fullname = first_name
                    count = chat.get_members_count()
                    mention = mention_html(new_mem.id, first_name)
                    if new_mem.username:
                        username = "@" + escape(new_mem.username)
                    else:
                        username = mention

                    valid_format = escape_invalid_curly_brackets(
                        cust_welcome, VALID_WELCOME_FORMATTERS)
                    res = valid_format.format(first=escape(first_name),
                                              last=escape(new_mem.last_name
                                                          or first_name),
                                              fullname=escape(fullname),
                                              username=username,
                                              mention=mention,
                                              count=count,
                                              chatname=escape(chat.title),
                                              id=new_mem.id)
                    buttons = sql.get_welc_buttons(chat.id)
                    keyb = build_keyboard(buttons)
                else:
                    res = sql.DEFAULT_WELCOME.format(first=first_name)
                    keyb = []

                getsec, mutetime, custom_text = sql.welcome_security(chat.id)
                member = chat.get_member(new_mem.id)
                # If user ban protected don't apply security on him
                if is_user_ban_protected(chat, new_mem.id,
                                         chat.get_member(new_mem.id)):
                    pass
                elif getsec:
                    if mutetime:
                        if mutetime[:1] == "0":

                            if member.can_send_messages is None or member.can_send_messages:
                                try:
                                    bot.restrict_chat_member(
                                        chat.id,
                                        new_mem.id,
                                        can_send_messages=False)
                                    canrest = True
                                except BadRequest:
                                    canrest = False
                            else:
                                canrest = False

                        else:
                            mutetime = extract_time(update.effective_message,
                                                    mutetime)

                            if member.can_send_messages is None or member.can_send_messages:
                                try:
                                    bot.restrict_chat_member(
                                        chat.id,
                                        new_mem.id,
                                        until_date=mutetime,
                                        can_send_messages=False)
                                    canrest = True
                                except BadRequest:
                                    canrest = False
                            else:
                                canrest = False

                    if canrest:
                        sql.add_to_userlist(chat.id, new_mem.id)
                        keyb.append([
                            InlineKeyboardButton(
                                text=str(custom_text),
                                callback_data="check_bot_({})".format(
                                    new_mem.id))
                        ])
                keyboard = InlineKeyboardMarkup(keyb)

                sent = send(update, res, keyboard,
                            sql.DEFAULT_WELCOME.format(
                                first=first_name))  # type: Optional[Message]

            prev_welc = sql.get_clean_pref(chat.id)
            if prev_welc:
                try:
                    bot.delete_message(chat.id, prev_welc)
                except BadRequest as excp:
                    pass

            if sent:
                sql.set_clean_welcome(chat.id, sent.message_id)

@run_async
def check_bot_button(bot: Bot, update: Update):
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    query = update.callback_query  # type: Optional[CallbackQuery]
    getalluser = sql.get_chat_userlist(chat.id)
    if user.id in getalluser:
        query.answer(text=tld(chat.id, 'welcome_mute_btn_unmuted'))
        # Unmute user
        bot.restrict_chat_member(chat.id,
                                 user.id,
                                 can_send_messages=True,
                                 can_send_media_messages=True,
                                 can_send_other_messages=True,
                                 can_add_web_page_previews=True)
        sql.rm_from_userlist(chat.id, user.id)
    else:
        try:
            query.answer(text=tld(chat.id, 'welcome_mute_btn_old_user'))
        except Exception:
            print("Nut")

@run_async
def left_member(bot: Bot, update: Update):
    chat = update.effective_chat  # type: Optional[Chat]
    should_goodbye, cust_goodbye, cust_content, goodbye_type = sql.get_gdbye_pref(
        chat.id)
    cust_goodbye = markdown_to_html(cust_goodbye)

    if should_goodbye:
        left_mem = update.effective_message.left_chat_member
        if left_mem:

            if is_user_gbanned(left_mem.id):
                return

            if sw != None:
                sw_ban = sw.get_ban(left_mem.id)
                if sw_ban:
                    return

            # Ignore bot being kicked
            if left_mem.id == bot.id:
                return

            # Give the owner a special goodbye
            if left_mem.id == OWNER_ID:
                update.effective_message.reply_text(
                    tld(chat.id, 'welcome_bot_owner_left'))
                return

            # if media goodbye, use appropriate function for it
            if goodbye_type != sql.Types.TEXT and goodbye_type != sql.Types.BUTTON_TEXT:
                reply = update.message.message_id
                cleanserv = sql.clean_service(chat.id)
                # Clean service welcome
                if cleanserv:
                    try:
                        dispatcher.bot.delete_message(
                            chat.id, update.message.message_id)
                    except BadRequest:
                        pass
                    reply = False
                # Formatting text
                first_name = left_mem.first_name or "PersonWithNoName"  # edge case of empty name - occurs for some bugs.
                if left_mem.last_name:
                    fullname = "{} {}".format(first_name, left_mem.last_name)
                else:
                    fullname = first_name
                count = chat.get_members_count()
                mention = mention_html(left_mem.id, first_name)
                if left_mem.username:
                    username = "@" + escape(left_mem.username)
                else:
                    username = mention

                formatted_text = cust_goodbye.format(
                    first=escape(first_name),
                    last=escape(left_mem.last_name or first_name),
                    fullname=escape(fullname),
                    username=username,
                    mention=mention,
                    count=count,
                    chatname=escape(chat.title),
                    id=left_mem.id)

                # Build keyboard
                buttons = sql.get_gdbye_buttons(chat.id)
                keyb = build_keyboard(buttons)
                keyboard = InlineKeyboardMarkup(keyb)

                # Send message
                ENUM_FUNC_MAP[goodbye_type](chat.id,
                                            cust_content,
                                            caption=formatted_text,
                                            reply_markup=keyboard,
                                            parse_mode="html",
                                            reply_to_message_id=reply)
                return

            first_name = left_mem.first_name or "PersonWithNoName"  # edge case of empty name - occurs for some bugs.
            if cust_goodbye:
                if left_mem.last_name:
                    fullname = "{} {}".format(first_name, left_mem.last_name)
                else:
                    fullname = first_name
                count = chat.get_members_count()
                mention = mention_html(left_mem.id, first_name)
                if left_mem.username:
                    username = "@" + escape(left_mem.username)
                else:
                    username = mention

                valid_format = escape_invalid_curly_brackets(
                    cust_goodbye, VALID_WELCOME_FORMATTERS)
                res = valid_format.format(first=escape(first_name),
                                          last=escape(left_mem.last_name
                                                      or first_name),
                                          fullname=escape(fullname),
                                          username=username,
                                          mention=mention,
                                          count=count,
                                          chatname=escape(chat.title),
                                          id=left_mem.id)
                buttons = sql.get_gdbye_buttons(chat.id)
                keyb = build_keyboard(buttons)

            else:
                res = sql.DEFAULT_GOODBYE
                keyb = []

            keyboard = InlineKeyboardMarkup(keyb)

            send(update, res, keyboard, sql.DEFAULT_GOODBYE)

@run_async
@user_admin
def security(bot: Bot, update: Update, args: List[str]) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    getcur, cur_value, cust_text = sql.welcome_security(chat.id)
    if len(args) >= 1:
        var = args[0].lower()
        if (var == "yes" or var == "y" or var == "on"):
            check = bot.getChatMember(chat.id, bot.id)
            if check.status == 'member' or check[
                    'can_restrict_members'] == False:
                text = tld(chat.id, 'welcome_mute_bot_cant_mute')
                update.effective_message.reply_text(text,
                                                    parse_mode="markdown")
                return ""
            sql.set_welcome_security(chat.id, True, str(cur_value), cust_text)
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_mute_enabled'))
        elif (var == "no" or var == "n" or var == "off"):
            sql.set_welcome_security(chat.id, False, str(cur_value), cust_text)
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_mute_disabled'))
        else:
            update.effective_message.reply_text(tld(chat.id,
                                                    'common_invalid_arg'),
                                                parse_mode=ParseMode.MARKDOWN)
    else:
        getcur, cur_value, cust_text = sql.welcome_security(chat.id)
        if getcur:
            getcur = "True"
        else:
            getcur = "False"
        if cur_value[:1] == "0":
            cur_value = "None"
        text = tld(chat.id, 'welcome_mute_curr_settings').format(
            getcur, cur_value, cust_text)
        update.effective_message.reply_text(text, parse_mode="markdown")

@run_async
@user_admin
def security_mute(bot: Bot, update: Update, args: List[str]) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    message = update.effective_message  # type: Optional[Message]
    getcur, cur_value, cust_text = sql.welcome_security(chat.id)
    if len(args) >= 1:
        var = args[0]
        if var[:1] == "0":
            mutetime = "0"
            sql.set_welcome_security(chat.id, getcur, "0", cust_text)
            text = tld(chat.id, 'welcome_mute_time_none')
        else:
            mutetime = extract_time(message, var)
            if mutetime == "":
                return
            sql.set_welcome_security(chat.id, getcur, str(var), cust_text)
            text = tld(chat.id, 'welcome_mute_time').format(var)
        update.effective_message.reply_text(text)
    else:
        if str(cur_value) == "0":
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_mute_time_settings_none'))
        else:
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_mute_time_settings').format(cur_value))

@run_async
@user_admin
def security_text(bot: Bot, update: Update, args: List[str]) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    getcur, cur_value, cust_text = sql.welcome_security(chat.id)
    if len(args) >= 1:
        text = " ".join(args)
        sql.set_welcome_security(chat.id, getcur, cur_value, text)
        text = tld(chat.id, 'welcome_mute_btn_text_changed').format(text)
        update.effective_message.reply_text(text, parse_mode="markdown")
    else:
        update.effective_message.reply_text(tld(
            chat.id, 'welcome_mute_btn_curr_text').format(cust_text),
                                            parse_mode="markdown")

@run_async
@user_admin
def security_text_reset(bot: Bot, update: Update):
    chat = update.effective_chat  # type: Optional[Chat]
    getcur, cur_value, cust_text = sql.welcome_security(chat.id)
    sql.set_welcome_security(chat.id, getcur, cur_value,
                             tld(chat.id, 'welcome_mute_btn_default_text'))
    update.effective_message.reply_text(tld(
        chat.id, 'welcome_mute_btn_text_reset').format(
            tld(chat.id, 'welcome_mute_btn_default_text')),
                                        parse_mode="markdown")

@run_async
@user_admin
def cleanservice(bot: Bot, update: Update, args: List[str]) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    if chat.type != chat.PRIVATE:
        if len(args) >= 1:
            var = args[0]
            if (var == "no" or var == "off"):
                sql.set_clean_service(chat.id, False)
                update.effective_message.reply_text(
                    tld(chat.id, 'welcome_clean_service_off'))
            elif (var == "yes" or var == "on"):
                sql.set_clean_service(chat.id, True)
                update.effective_message.reply_text(
                    tld(chat.id, 'welcome_clean_service_on'))
            else:
                update.effective_message.reply_text(
                    tld(chat.id, 'common_invalid_arg'),
                    parse_mode=ParseMode.MARKDOWN)
        else:
            update.effective_message.reply_text(tld(chat.id,
                                                    'common_invalid_arg'),
                                                parse_mode=ParseMode.MARKDOWN)
    else:
        curr = sql.clean_service(chat.id)
        if curr:
            update.effective_message.reply_text(tld(
                chat.id, 'welcome_clean_service_on'),
                                                parse_mode=ParseMode.MARKDOWN)
        else:
            update.effective_message.reply_text(tld(
                chat.id, 'welcome_clean_service_off'),
                                                parse_mode=ParseMode.MARKDOWN)

@run_async
@user_admin
def welcome(bot: Bot, update: Update, args: List[str]):
    chat = update.effective_chat  # type: Optional[Chat]
    # if no args, show current replies.
    if len(args) == 0 or args[0].lower() == "noformat":
        noformat = args and args[0].lower() == "noformat"
        pref, welcome_m, cust_content, welcome_type = sql.get_welc_pref(
            chat.id)
        prev_welc = sql.get_clean_pref(chat.id)
        if prev_welc:
            prev_welc = True
        else:
            prev_welc = False
        cleanserv = sql.clean_service(chat.id)
        getcur, cur_value, cust_text = sql.welcome_security(chat.id)
        if getcur:
            welcsec = "True "
        else:
            welcsec = "False "
        if cur_value[:1] == "0":
            welcsec += tld(chat.id, 'welcome_mute_time_short_none')
        else:
            welcsec += tld(chat.id,
                           'welcome_mute_time_short').format(cur_value)

        text = tld(chat.id,
                   'welcome_settings').format(pref, prev_welc, cleanserv,
                                              welcsec, cust_text)
        update.effective_message.reply_text(text,
                                            parse_mode=ParseMode.MARKDOWN)

        if welcome_type == sql.Types.BUTTON_TEXT or welcome_type == sql.Types.TEXT:
            buttons = sql.get_welc_buttons(chat.id)
            if noformat:
                welcome_m += revert_buttons(buttons)
                update.effective_message.reply_text(welcome_m)

            else:
                keyb = build_keyboard(buttons)
                keyboard = InlineKeyboardMarkup(keyb)

                send(update, welcome_m, keyboard, sql.DEFAULT_WELCOME)

        else:
            buttons = sql.get_welc_buttons(chat.id)
            if noformat:
                welcome_m += revert_buttons(buttons)
                ENUM_FUNC_MAP[welcome_type](chat.id,
                                            cust_content,
                                            caption=welcome_m)

            else:
                keyb = build_keyboard(buttons)
                keyboard = InlineKeyboardMarkup(keyb)
                ENUM_FUNC_MAP[welcome_type](chat.id,
                                            cust_content,
                                            caption=welcome_m,
                                            reply_markup=keyboard,
                                            parse_mode=ParseMode.HTML,
                                            disable_web_page_preview=True)

    elif len(args) >= 1:
        if args[0].lower() in ("on", "yes"):
            sql.set_welc_preference(str(chat.id), True)
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_greet_set_on'))

        elif args[0].lower() in ("off", "no"):
            sql.set_welc_preference(str(chat.id), False)
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_greet_set_off'))

        else:
            # idek what you're writing, say yes or no
            update.effective_message.reply_text(
                tld(chat.id, 'common_invalid_arg'))

@run_async
@user_admin
def goodbye(bot: Bot, update: Update, args: List[str]):
    chat = update.effective_chat  # type: Optional[Chat]

    if len(args) == 0 or args[0] == "noformat":
        noformat = args and args[0] == "noformat"
        pref, goodbye_m, cust_content, goodbye_type = sql.get_gdbye_pref(
            chat.id)
        if cust_content == None:
            cust_content = goodbye_m

        update.effective_message.reply_text(tld(
            chat.id, 'welcome_goodbye_settings').format(pref),
                                            parse_mode=ParseMode.MARKDOWN)

        if goodbye_type == sql.Types.BUTTON_TEXT:
            buttons = sql.get_gdbye_buttons(chat.id)
            if noformat:
                goodbye_m += revert_buttons(buttons)
                update.effective_message.reply_text(goodbye_m)

            else:
                keyb = build_keyboard(buttons)
                keyboard = InlineKeyboardMarkup(keyb)

                send(update, goodbye_m, keyboard, sql.DEFAULT_GOODBYE)

        else:
            buttons = sql.get_gdbye_buttons(chat.id)
            if noformat:
                goodbye_m += revert_buttons(buttons)
                ENUM_FUNC_MAP[goodbye_type](chat.id,
                                            cust_content,
                                            caption=goodbye_m)

            else:
                keyb = build_keyboard(buttons)
                keyboard = InlineKeyboardMarkup(keyb)
                ENUM_FUNC_MAP[goodbye_type](chat.id,
                                            cust_content,
                                            caption=goodbye_m,
                                            reply_markup=keyboard,
                                            parse_mode=ParseMode.HTML,
                                            disable_web_page_preview=True)

    elif len(args) >= 1:
        if args[0].lower() in ("on", "yes"):
            sql.set_gdbye_preference(str(chat.id), True)
            try:
                update.effective_message.reply_text(
                    tld(chat.id, 'welcome_goodbye_set_on'))
            except Exception:
                print("Nut")

        elif args[0].lower() in ("off", "no"):
            sql.set_gdbye_preference(str(chat.id), False)
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_goodbye_set_off'))

        else:
            # idek what you're writing, say yes or no
            update.effective_message.reply_text(tld(chat.id,
                                                    'common_invalid_arg'),
                                                parse_mode=ParseMode.MARKDOWN)

@run_async
@user_admin
@loggable
def set_welcome(bot: Bot, update: Update) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    msg = update.effective_message  # type: Optional[Message]

    # If user is not set text and not reply a message
    if not msg.reply_to_message:
        if len(msg.text.split()) == 1:
            msg.reply_text(tld(chat.id, 'welcome_set_welcome_no_text'),
                           parse_mode="markdown")
            return ""

    text, data_type, content, buttons = get_welcome_type(msg)

    if data_type is None:
        msg.reply_text(tld(chat.id, "welcome_set_welcome_no_datatype"))
        return ""

    sql.set_custom_welcome(chat.id, content, text, data_type, buttons)
    msg.reply_text(tld(chat.id, 'welcome_set_welcome_success'))

    return "{}:" \
           "\n#SET_WELCOME" \
           "\nAdmin: {}" \
           "\nSet the welcome message.".format(escape(chat.title),
                                               mention_html(user.id, user.first_name))

@run_async
@user_admin
@loggable
def reset_welcome(bot: Bot, update: Update) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    sql.set_custom_welcome(chat.id, None, sql.DEFAULT_WELCOME, sql.Types.TEXT)
    update.effective_message.reply_text(
        tld(chat.id, 'welcome_reset_welcome_success'))
    return "{}:" \
           "\n#RESET_WELCOME" \
           "\nAdmin: {}" \
           "\nReset the welcome message to default.".format(escape(chat.title),
                                                            mention_html(user.id, user.first_name))

@run_async
@user_admin
@loggable
def set_goodbye(bot: Bot, update: Update) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    msg = update.effective_message  # type: Optional[Message]
    text, data_type, content, buttons = get_welcome_type(msg)

    # If user is not set text and not reply a message
    if not msg.reply_to_message:
        if len(msg.text.split()) == 1:
            msg.reply_text(tld(chat.id, 'welcome_set_welcome_no_text'),
                           parse_mode="markdown")
            return ""

    if data_type is None:
        msg.reply_text(tld(chat.id, 'welcome_set_welcome_no_datatype'))
        return ""

    sql.set_custom_gdbye(chat.id, content, text, data_type, buttons)
    msg.reply_text(tld(chat.id, 'welcome_set_goodbye_success'))
    return "{}:" \
           "\n#SET_GOODBYE" \
           "\nAdmin: {}" \
           "\nSet the goodbye message.".format(escape(chat.title),
                                               mention_html(user.id, user.first_name))

@run_async
@user_admin
@loggable
def reset_goodbye(bot: Bot, update: Update) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    sql.set_custom_gdbye(chat.id, None, sql.DEFAULT_GOODBYE, sql.Types.TEXT)
    update.effective_message.reply_text(
        tld(chat.id, 'welcome_reset_goodbye_success'))
    return "{}:" \
           "\n#RESET_GOODBYE" \
           "\nAdmin: {}" \
           "\nReset the goodbye message.".format(escape(chat.title),
                                                 mention_html(user.id, user.first_name))

@run_async
@user_admin
@loggable
def clean_welcome(bot: Bot, update: Update, args: List[str]) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]

    if not args:
        clean_pref = sql.get_clean_pref(chat.id)
        if clean_pref:
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_clean_curr_on'))
        else:
            update.effective_message.reply_text(
                tld(chat.id, 'welcome_clean_curr_off'))
        return ""

    if args[0].lower() in ("on", "yes"):
        sql.set_clean_welcome(str(chat.id), True)
        update.effective_message.reply_text(
            tld(chat.id, 'welcome_clean_set_on'))
        return "{}:" \
               "\n#CLEAN_WELCOME" \
               "\nAdmin: {}" \
               "\nHas toggled clean welcomes to ON.".format(escape(chat.title),
                                                                         mention_html(user.id, user.first_name))
    elif args[0].lower() in ("off", "no"):
        sql.set_clean_welcome(str(chat.id), False)
        update.effective_message.reply_text(
            tld(chat.id, 'welcome_clean_set_off'))
        return "{}:" \
               "\n#CLEAN_WELCOME" \
               "\nAdmin: {}" \
               "\nHas toggled clean welcomes to OFF.".format(escape(chat.title),
                                                                                mention_html(user.id, user.first_name))
    else:
        # idek what you're writing, say yes or no
        update.effective_message.reply_text(
            "I understand 'on/yes' or 'off/no' only!")
        return ""

@run_async
@user_admin
def setcas(bot: Bot, update: Update):
    chat = update.effective_chat
    msg = update.effective_message
    split_msg = msg.text.split(' ')
    if len(split_msg)!= 2:
        msg.reply_text("Invalid arguments!")
        return
    param = split_msg[1]
    if param == "on" or param == "true":
        sql.set_cas_status(chat.id, True)
        msg.reply_text("Successfully updated configuration.")
        return
    elif param == "off" or param == "false":
        sql.set_cas_status(chat.id, False)
        msg.reply_text("Successfully updated configuration.")
        return
    else:
        msg.reply_text("Invalid status to set!") #on or off ffs
        return

@run_async
@user_admin
def setban(bot: Bot, update: Update):
    chat = update.effective_chat
    msg = update.effective_message
    split_msg = msg.text.split(' ')
    if len(split_msg)!= 2:
        msg.reply_text("Invalid arguments!")
        return
    param = split_msg[1]
    if param == "on" or param == "true":
        sql.set_cas_autoban(chat.id, True)
        msg.reply_text("Successfully updated configuration.")
        return
    elif param == "off" or param == "false":
        sql.set_cas_autoban(chat.id, False)
        msg.reply_text("Successfully updated configuration.")
        return
    else:
        msg.reply_text("Invalid autoban definition to set!") #on or off ffs
        return

@run_async
@user_admin
def get_current_setting(bot: Bot, update: Update):
    chat = update.effective_chat
    msg = update.effective_message
    stats = sql.get_cas_status(chat.id)
    autoban = sql.get_cas_autoban(chat.id)
    rtext = "CAS Preferences\n\nCAS Checking: {}\nAutoban: {}".format(stats, autoban)
    msg.reply_text(rtext, parse_mode=ParseMode.HTML)
    return

@run_async
def caschecker(bot: Bot, update: Update, args: List[str]):
    #/info logic
    msg = update.effective_message  # type: Optional[Message]
    user_id = extract_user(update.effective_message, args)
    if user_id and int(user_id) != 777000:
        user = bot.get_chat(user_id)
    elif user_id and int(user_id) == 777000:
        msg.reply_text("This is Telegram. Unless you manually entered this reserved account's ID, it is likely a broadcast from a linked channel.")
        return
    elif not msg.reply_to_message and not args:
        user = msg.from_user
    elif not msg.reply_to_message and (not args or (
            len(args) >= 1 and not args[0].startswith("@") and not args[0].isdigit() and not msg.parse_entities(
        [MessageEntity.TEXT_MENTION]))):
        msg.reply_text("I can't extract a user from this.")
        return
    else:
        return

    text = "CAS Check:" \
           "\nID: {}" \
           "\nFirst Name: {}".format(user.id, html.escape(user.first_name))
    if user.last_name:
        text += "\nLast Name: {}".format(html.escape(user.last_name))
    if user.username:
        text += "\nUsername: @{}".format(html.escape(user.username))
    text += "\n\nCAS Banned: "
    result = cas.banchecker(user.id)
    text += str(result)
    if result:
        parsing = cas.offenses(user.id)
        if parsing:
            text += "\nTotal of Offenses: "
            text += str(parsing)
        parsing = cas.timeadded(user.id)
        if parsing:
            parseArray=str(parsing).split(", ")
            text += "\nDay added: "
            text += str(parseArray[1])
            text += "\nTime added: "
            text += str(parseArray[0])
            text += "\n\nAll times are in UTC"
    update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)

#this sends direct request to combot server. Will return true if user is banned, false if
#id invalid or user not banned
@run_async
def casquery(bot: Bot, update: Update, args: List[str]):
    msg = update.effective_message  # type: Optional[Message]
    try:
        user_id = msg.text.split(' ')[1]
    except:
        msg.reply_text("There was a problem parsing the query.")
        return
    text = "Your query returned: "
    result = cas.banchecker(user_id)
    text += str(result)
    msg.reply_text(text)

@run_async
@user_admin
def setDefense(bot: Bot, update: Update, args: List[str]):
    chat = update.effective_chat
    msg = update.effective_message
    if len(args)!=1:
        stat = sql.getDefenseStatus(chat.id)
        text = "This group has the defense setting set to: {}\nUse On/off - yes/no to change settings.".format(stat)
        msg.reply_text(text, parse_mode=ParseMode.HTML)
        return
    param = args[0]
    if param == "on" or param == "true":
        sql.setDefenseStatus(chat.id, True)
        msg.reply_text("Defense mode has been turned on, this group is under attack. Every user that now joins will be auto kicked.")
        return
    elif param == "off" or param == "false":
        sql.setDefenseStatus(chat.id, False)
        msg.reply_text("Defense mode has been turned off, group is no longer under attack.")
        return
    else:
        msg.reply_text("Invalid status to set!") #on or off ffs
        return

def __migrate__(old_chat_id, new_chat_id):
    sql.migrate_chat(old_chat_id, new_chat_id)

__help__ = True

NEW_MEM_HANDLER = MessageHandler(Filters.status_update.new_chat_members,
                                 new_member)
LEFT_MEM_HANDLER = MessageHandler(Filters.status_update.left_chat_member,
                                  left_member)
WELC_PREF_HANDLER = CommandHandler("welcome",
                                   welcome,
                                   pass_args=True,
                                   filters=Filters.group)
GOODBYE_PREF_HANDLER = CommandHandler("goodbye",
                                      goodbye,
                                      pass_args=True,
                                      filters=Filters.group)
SET_WELCOME = CommandHandler("setwelcome", set_welcome, filters=Filters.group)
SET_GOODBYE = CommandHandler("setgoodbye", set_goodbye, filters=Filters.group)
RESET_WELCOME = CommandHandler("resetwelcome",
                               reset_welcome,
                               filters=Filters.group)
RESET_GOODBYE = CommandHandler("resetgoodbye",
                               reset_goodbye,
                               filters=Filters.group)
CLEAN_WELCOME = CommandHandler("cleanwelcome",
                               clean_welcome,
                               pass_args=True,
                               filters=Filters.group)
SECURITY_HANDLER = CommandHandler("welcomemute",
                                  security,
                                  pass_args=True,
                                  filters=Filters.group)
SECURITY_MUTE_HANDLER = CommandHandler("welcomemutetime",
                                       security_mute,
                                       pass_args=True,
                                       filters=Filters.group)
SECURITY_BUTTONTXT_HANDLER = CommandHandler("setmutetext",
                                            security_text,
                                            pass_args=True,
                                            filters=Filters.group)
SECURITY_BUTTONRESET_HANDLER = CommandHandler("resetmutetext",
                                              security_text_reset,
                                              filters=Filters.group)
CLEAN_SERVICE_HANDLER = CommandHandler("cleanservice",
                                       cleanservice,
                                       pass_args=True,
                                       filters=Filters.group)

SETCAS_HANDLER = CommandHandler("setcas", setcas, filters=Filters.group)
GETCAS_HANDLER = CommandHandler("getcas", get_current_setting, filters=Filters.group)
CASCHECK_HANDLER = CommandHandler("cascheck", caschecker, pass_args=True)
CASQUERY_HANDLER = CommandHandler("casquery", casquery, pass_args=True ,filters=CustomFilters.sudo_filter)
SETBAN_HANDLER = CommandHandler("setban", setban, filters=Filters.group)
DEFENSE_HANDLER = CommandHandler("defense", setDefense, pass_args=True)

help_callback_handler = CallbackQueryHandler(check_bot_button,
                                             pattern=r"check_bot_")

dispatcher.add_handler(NEW_MEM_HANDLER)
dispatcher.add_handler(LEFT_MEM_HANDLER)
dispatcher.add_handler(WELC_PREF_HANDLER)
dispatcher.add_handler(GOODBYE_PREF_HANDLER)
dispatcher.add_handler(SET_WELCOME)
dispatcher.add_handler(SET_GOODBYE)
dispatcher.add_handler(RESET_WELCOME)
dispatcher.add_handler(RESET_GOODBYE)
dispatcher.add_handler(CLEAN_WELCOME)
dispatcher.add_handler(SECURITY_HANDLER)
dispatcher.add_handler(SECURITY_MUTE_HANDLER)
dispatcher.add_handler(SECURITY_BUTTONTXT_HANDLER)
dispatcher.add_handler(SECURITY_BUTTONRESET_HANDLER)
dispatcher.add_handler(CLEAN_SERVICE_HANDLER)
dispatcher.add_handler(SETCAS_HANDLER)
dispatcher.add_handler(GETCAS_HANDLER)
dispatcher.add_handler(CASCHECK_HANDLER)
dispatcher.add_handler(CASQUERY_HANDLER)
dispatcher.add_handler(SETBAN_HANDLER)
dispatcher.add_handler(DEFENSE_HANDLER)

dispatcher.add_handler(help_callback_handler)


"""
" author : kaneshige
" created : 30.01.2022 21:40:04
"""

import sys
import itertools
from collections import deque

def main():
    n, m = map(int, readline().split())
    dp = [[[[0 for _ in range(m+1)]for _ in range(m+1)]for _ in range(m+1)] for _ in range(n + 1)]

    for i in range(m):
        dp[1][i][m][m] = 1
    #print(dp[0])

    for i in range(2, n + 1):
        for a in range(m+1):
            for b in range(m+1):
                for c in range(m+1):
                    for t in range(m):
                        ta = a
                        tb = b
                        tc = c
                        if c < t:
                            continue
                        elif b < t:
                            tc = t
                        elif a < t:
                            tb = t
                        else:
                            ta = t
                        dp[i][ta][tb][tc] += dp[i-1][a][b][c]
                        dp[i][ta][tb][tc] %= MOD

    ans = 0
    for a in range(m+1):
        for b in range(m+1):
            for c in range(m):
                ans += dp[n][a][b][c]
                ans %= MOD

    print(ans)

if __name__ == "__main__":
    "----------Constants------------"
    INF = (1 << 62) - 1
    #MOD = 10 ** 9 + 7
    MOD = 998244353
    # sys.setrecursionlimit(10**6)
    true_ceil = lambda x, y: (x + y - 1) // y
    "----------Input------------"
    readline = sys.stdin.readline
    "----------Run------------"
    main()


from Bot.bot_models.bot_key_local import TOKEN
from Bot.bot_models.states.state_provider import *
import Bot.bot_models.keyboards as kb
from Bot.bot_models.bot_helper import helper

day_timer = 86400

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def handle_command(message):  # Проверяем команды от пользователя
    provider = state_provider(bot)
    current_state = provider.get_state_for_user_id(user_id=message.from_user.id)
    new_state = default_state(bot, current_state.user)
    bot.send_message(message.from_user.id, "Привіт! Обери пункт меню щоб розпочати роботу",
                     reply_markup=kb.user_keyboard)
    provider.set_state(new_state)

@bot.callback_query_handler(lambda call: True)
def process_callback_button(call):
    bot.answer_callback_query(callback_query_id=call.id)
    provider = state_provider(bot)
    current_state = provider.get_state_for_user_id(call.from_user.id)
    new_state = current_state.handle_callable(call)
    provider.set_state(new_state)

@bot.message_handler(content_types=['text'])  # Проверяем текст от пользователя
def handle_text(message):
    chat_id = message.from_user.id
    provider = state_provider(bot)
    current_state = provider.get_state_for_user_id(chat_id)
    new_state = None

    if message.text == kb.menu["SUBSCRIBE"]:
        new_state = subscribe_menu_state(bot, current_state.user)
    elif message.text == kb.menu["EXCHANGE_RATE"]:
        new_state = show_exchange_rate_state(bot, current_state.user)
    elif message.text == kb.menu["CURRENCY_CONVERTER"]:
        new_state = currency_converter_state(bot, current_state.user)
    elif message.text == kb.menu["DEPOSIT_CALCULATOR"]:
        new_state = deposit_state(bot, current_state.user)
    else:
        new_state = current_state.handle_message(message)

    if new_state != None:
        helper.del_last_keyboard(current_state.user)
        provider.set_state(new_state)


import pygame;
import random;
import math;
BLACK = (0,0, 0)
WHITE = (255, 255,255)
BLUE = (50, 50, 255)
YELLOW = (255, 255, 0)
GREEN = (50, 255, 50)
pygame.init()

size = (640, 480)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("My window")
done = False;
clock = pygame.time.Clock()

d = 20

ballPosition = [d, d]
batStep = 15
Direction = [1, 1]

batPosition = [20, 200]
ballSpeed = 1

Direction[0] = random.randint(1,5)
Direction[1] = random.randint(1,5)
print("X: "+str(Direction[0]))
print("Y: "+str(Direction[1]))

while not done:

    #--Userinputandcontrols
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            done=True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:

                batPosition[1]=batPosition[1]-batStep
                if (batPosition[1] <= 0):
                    batPosition[1] = 0

            if event.key == pygame.K_DOWN:
                batPosition[1]=batPosition[1]+batStep
                if batPosition[1] >= 380:
                    batPosition[1] = 380

    screen.fill(BLACK)
            #--Drawhere

    #drawing
    pygame.draw.circle(screen,BLUE,(ballPosition[0],ballPosition[1]),15,0)
    pygame.draw.rect(screen,WHITE,(0, batPosition[1], 20,100)) #bat
    pygame.draw.rect(screen,WHITE,(620,0,640,480))
    #--flipdisplaytorevealnewpositionofobjects
    pygame.display.flip()
            #-Theclockticksover

    #ball movement

    ballPosition[0]=ballPosition[0]+Direction[0] #x movement of the ball
    ballPosition[1]=ballPosition[1]+Direction[1] #y movement of the ball

    #collision of the ball and the bat
    if (ballPosition[0] <= batPosition[0]+20) and ((ballPosition[1] > batPosition[1]-15) and (ballPosition[1] < batPosition[1]+100)):
        Direction[0] = (-1)*Direction[0]
        print("Hit the bat!")

    if (ballPosition[0] >= 605):  #Right wall
        #Direction[1] = (-1)*Direction[1]
        Direction[0] = (-1)*Direction[0]
        print("Hit the right wall")

    if (ballPosition[1] >= 465): #bottom wall
        Direction[1] = (-1)*Direction[1]
        print("Hit the bottom wall")

    if (ballPosition[1] <= 15): #top wall
        Direction[1] = (-1)*Direction[1]
        print("Hit the top wall")

    if (ballPosition[0] <= 15): #Left wall
        print("You lost!")
        done = True

    #moving the ball
    ballPosition[0] = ballPosition[0]+int((Direction[0]*ballSpeed)/2)
    ballPosition[1] = ballPosition[1]+int((Direction[1]*ballSpeed)/2)

    clock.tick(60)
#EndWhile-Endofgameloop
pygame.quit()


import base64
import json
import cv2

import sqlalchemy as sa
from sqlalchemy.sql import text

from starlette.applications import Starlette
from starlette.responses import JSONResponse, Response, StreamingResponse
from starlette.middleware.gzip import GZipMiddleware
from starlette.concurrency import run_in_threadpool

from frames import DB, LOG
from frames.hashing import ImageHash
from frames.misc import from_dataurl_to_cvimage, IMG_TYPES

from frames.db import (HASHES_T, showsql, RFT,
                       IMAGES_T, USER_T, UserImage,
                       Reference_Frame, Hashes, Images)

app = Starlette(debug=True)
app.add_middleware(GZipMiddleware, minimum_size=500)
# TODO Add auth middlewhere.

def api_response(message='', status='success', data=None, task=None, **kwargs):
    """Skeleton for the api response"""

    if data is None:
        data = []

    output = {"status": status,
              "data": data,
              "message": message
              }

    if status == 'success':
        status_code = 200
    else:
        status_code = 500

    return JSONResponse(output, status_code=status_code, background=task)

@app.on_event("startup")
async def startup():
    await DB.connect()

@app.on_event("shutdown")
async def shutdown():
    await DB.disconnect()

@app.route('/')
async def homepage(request):
    # Add some bootstrap page? See https://github.com/encode/starlette-example for ideas
    return JSONResponse({'hello': 'world'})

@app.route('/api/sql/dump/{name:str}')
async def dump_hashes_table(request):
    """Simple way to dump the tables to json."""
    name = request.path_params['name']

    if name == 'hashes':
        table = HASHES_T.select()

    elif name == 'userimage':
        # We skip the img key as this is the binary data.
        # We dont want to dump this info as they are huge.
        table = sa.select([col for col in USER_T.columns if col.key != 'img'])
    elif name == 'reference_frame':
        table = RFT.select()

    else:
        return api_response(status='error', message='Invalid table')

    async def gen():
        yield '{"status:"success", "message: "", data: ['
        async for row in DB.iterate(table):
            if row:
                yield json.dumps(dict(row))
                yield ','
        yield "]}"
    LOG.debug('dumping table %s to api' % name)
    return StreamingResponse(gen(), media_type="application/json")

@app.route('/api/query/')
async def test_check_if_show_in_db(request):
    """simple proxy for now later we will have our own db"""

    import http3
    q = request.query_params
    client = http3.AsyncClient()

    if q.get('q'):
        url = 'http://api.tvmaze.com/singlesearch/shows?q=%s' % q.get('q')
        result = await client.get(url)

        result = result.json()
        show_ids = result['externals']
        print(show_ids)

        res = await qq(show_ids['thetvdb'], q['season'])
        if isinstance(res, dict):
            return api_response(message=res['message'])
        elif isinstance(res, list):
            return api_response(data=res)
        else:
            return api_response(status='error')

async def qq(tvdbid, season):
    conf = 0.7 # should be a config option?
    # this should probably be changed as we should just remove enogh episodes.
    episode_statement = text("SELECT COUNT(DISTINCT episode) FROM frames.hashes "
                             "WHERE tvdbid = :tvdbid and season = :season").bindparams(tvdbid=tvdbid,
                                                                                season=season)
    # showsql(episode_statement)
    num_epiodes = await DB.fetch_one(episode_statement)
    num_epiodes = num_epiodes[0]
    req_eps = num_epiodes * conf
    LOG.debug('%s season %s got %s episodes' % (tvdbid, season, num_epiodes))

    if num_epiodes < 3: # Be a config option?
        return dict(message="To few episodes in the db")

    statement = text("SELECT hash FROM (SELECT * FROM frames.hashes "
                     "WHERE frames.hashes.tvdbid = :tvdbid "
                     "AND frames.hashes.season = :season "
                     "GROUP by hash, episode) as f "
                     "GROUP by hash "
                     "having count(hash) > :req_eps "
                     ).bindparams(tvdbid=tvdbid,
                                  season=season,
                                  req_eps=req_eps)

    # showsql(statement)

    result = []
    async for row in DB.iterate(statement):
        result.append(row.hash)

    return result

@app.route('/api/image/{hash:str}')
async def show_image(request):
    """Show a image to a user using the api."""
    img_hash = request.path_params['hash']
    q = USER_T.select().where(UserImage.hash == img_hash)
    result = await DB.fetch_all(q)

    if result is None:
        return api_response(status='error', message='No images match %s' % img_hash)

    if len(result) > 1:
        LOG.debug('We have more then one one image with this hash picking '
                  'the first one. You should check for duplicates')

    if request.query_params.get('base64', '') in ('true', True):
        # This should probably be a better method
        # to do this but it should be enough for now.
        bs = base64.b64encode(result[0].img)
        # All the images in the db should be stored as
        # png anyway, at least if they are upload using
        # the browser extension.
        img = 'data:image/png;base64,%s' % bs.decode("utf-8")
        return Response(img)

    return Response(result[0].img, media_type="image/png")

@app.route('/api/upload', methods=['POST'])
async def upload(request):
    """
    Upload command for the api.

    the form should contain.
    id, show, episode, season, file and type

    """

    # Lets start with some housekeeping first.
    five_mb = 5242880
    if int(request.headers["content-length"]) > five_mb:
        LOG.debug('File size to big')
        return api_response(status='error', message='The request was to large, try reduzing the image size.')

    form = await request.form()

    if form['file'].content_type not in IMG_TYPES:
        message = 'The file type was %s expected %s' % (form['file'].content_type, IMG_TYPES)
        LOG.debug(message)
        return api_response(status='error', message=message)

    if form.get('type', '') not in ('intro', 'outro'):
        message = 'Missing or invalid type, expected values was intro or outro'
        return api_response(status='error', message=message)

    file_ob = form.get('file')
    content = ''
    if file_ob is None:
        LOG.debug('The user forgot to add the damn file.')
        return api_response(status='error', message='Missing file')
    else:
        content = await file_ob.read()

    # Need to run this in the threadpool
    def tb():
        image = from_dataurl_to_cvimage(content)
        ih = ImageHash(cv2.img_hash.pHash(image))
        return ih

    ih = await run_in_threadpool(tb)
    ih_str = str(ih)

    # Images are stored in binary form.
    query = USER_T.insert().values(hash=ih_str,
                                   tvdbid=form['id'],
                                   img=content,
                                   season=int(form['season']),
                                   episode=int(form['episode']),
                                   show=form['show'],
                                   type=form['type'])
    await DB.execute(query)

    LOG.debug('Added %s %s %s with hash %s to the db', form['show'],
              form['season'], form['episode'], ih_str)

    return api_response(status='success')

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host='0.0.0.0', port=8000)


import pygame
from pygame.locals import *
import os
from Grid import Grid
from BarsContainer import BarsContainer
from pygame_widgets import Button

class AlgoVisual:
    def __init__(self, display):
        self.DISPLAY = display
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()
        pygame.font.init()
        self.surface = pygame.display.set_mode(self.DISPLAY)
        pygame.display.set_caption("AlgoVisual")
        self.font = pygame.font.SysFont("Copperplate-Light", 35)
        self.buttons = self.generateButtons()
        self.pathfinder = False
        self.sorter = False
        self.bgImg = pygame.image.load("bg.JPG")
        self.bgImg = pygame.transform.scale(self.bgImg, (self.DISPLAY[0],self.DISPLAY[1]))

    def generateButtons(self):
        button = []
        # Create Maze Button
        button.append(Button(
            self.surface, 700, 100, 200, 50, text='VISUALIZE',
            font=self.font,
            inactiveColour=(100,100,100),
            pressedColour=(140, 125, 140),
            textColour=(210,210,210),
            onRelease=self.pathFindingButtonOnClick
        ))

        button.append(Button(
            self.surface, 350, 575, 200, 50, text='VISUALIZE',
            font=self.font,
            inactiveColour=(100,100,100),
            pressedColour=(140, 125, 140),
            textColour=(210,210,210),
            onRelease=self.sortingButtonOnClick

        ))
        return button

    def pathFindingButtonOnClick(self):
        self.grid = Grid(self, 600, 75, 500, 500, 50)
        self.pathfinder = True

    def sortingButtonOnClick(self):
        self.container = BarsContainer(self, 350, 100, 800, 500,50)
        self.sorter = True

    def listen_events(self, events):
        for button in self.buttons:
            button.listen(events)

    def run(self):
        running = True
        clock = pygame.time.Clock()

        while running:
            events = pygame.event.get()
            for event in events:
                if event.type == QUIT:
                    running = False
                    break
                if event.type == pygame.KEYDOWN:
                    if event.key == K_ESCAPE:
                        running = False
                        break
                    if event.key == K_RETURN:
                        for bar in self.container.bars:
                            print("(",bar.x, bar.HEIGHT,")", end="" )
                        print()
                        print("-------------------------------------------")

            if self.sorter:
                self.container.listen_events(events)
            if self.pathfinder:
                self.grid.listen_events(events)
            if not self.sorter and not self.pathfinder:
                self.listen_events(events)

            self.surface.fill((180,210,230))

            self.draw()

            pygame.display.flip()

        pygame.quit()

    def draw(self):
        if self.sorter:
            self.container.draw()
        if self.pathfinder:
            self.grid.draw()
        if not self.sorter and not self.pathfinder:
            self.surface.blit(self.bgImg, (0,0))
            for button in self.buttons:
                button.draw()

if __name__ == "__main__":
    a = AlgoVisual((1200, 700))
    a.run()


# -*- coding: utf-8 -*-
from odoo import api, fields, models

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    #add sequene to numbered sequential to perant and sub products
    number = fields.Char('No')

    @api.multi
    @api.onchange('product_id')
    def product_id_change(self):
    	result = super(SaleOrderLine, self).product_id_change()
    	print (self.product_id,"<<<<<<<<<<<<<<<<<<<<<number = fields.Char('No')")
    	# if not self.order_line:
    	# 	self.number = 1
    	if self.product_id.product_accessories_ids:
    		print ("insssssssssssssssssss")
    		for accessory in self.product_id.product_accessories_ids:
    			print (accessory,">>>>>>>>><<<<<<<<<productssssss")

    	return result


from flask import request
from importlib_metadata import metadata
from sqlalchemy import Column, Integer, String, create_engine,Table,MetaData,ForeignKey

# Database Constant Variable
SQLITE = 'sqlite'

# Table Constant Variable
BOOKS = 'books'

class BooksDatabase:
    DB_ENGINE = {
        SQLITE: 'sqlite:///books'
    }

    db_engine = None

    def __init__(self,name='', author='', year='',book_type=''):
        engine_url = self.DB_ENGINE[SQLITE]

        self.db_engine = create_engine(engine_url)

        print(self.db_engine)

    def create_db_table(self):
        metadata = MetaData()
        books = Table(BOOKS, metadata,
                        Column('id', Integer, primary_key = True),
                        Column('name', String(50), index = True , nullable = False),
                        Column('author', String(50) , nullable = False),
                        Column('year', Integer() , nullable = False),
                        Column('book_type', Integer(), nullable = False),
                        Column('availability', String(50))

                        )
        try:
            metadata.create_all(self.db_engine)
            print("Table created")
        except Exception as e:
            print("error occured while table creation")
            print(e)

    def execute_query(self, query=''):
        if query == '' : return

        print (query)
        with self.db_engine.connect() as connection:
            try:
                connection.execute(query)
            except Exception as e:
                print(e)

    def addBook(self, name, author, year,book_type):
        query = f"INSERT INTO {BOOKS}(name, author,year,book_type, availability) VALUES ('{name}','{author}',{year},{book_type},'available')"
        self.execute_query(query)

    def removeBook(self, name):
            query = f"DELETE FROM {BOOKS} WHERE name = '{name}'"
            self.execute_query(query)

    def print_all_data(self, table = BOOKS):
        query = f"SELECT * FROM '{table}';"
        print(query)
        res = []
        with self.db_engine.connect() as connection:
            try:
                result = connection.execute(query)
            except Exception as e:
                print(e)
            else:
                for row in result:
                    res.append( row)
                result.close()
        # print("\n")
        return res

    def findBookStatus(self, name):
            query = f"SELECT availability FROM {BOOKS} WHERE name = '{name}'"
            print(query)
            res = []
            with self.db_engine.connect() as connection:
                try:
                    result = connection.execute(query)
                except Exception as e:
                    print(e)
                else:
                    for row in result:
                        res.append( row)
                    result.close()
            ress = res[0]
            ress = str(ress).strip('(').strip(')').strip(',')
            print (ress)
            return ress

    def updateBookStatus(self, name ,availability):
        query = f"UPDATE {BOOKS} SET availability = {availability} WHERE name = {name}"
        self.execute_query(query)


from testingSystem import TestingSystem

def get_next_arr(perv_arr: list) -> list:
    new_len = len(perv_arr) + 9
    next_arr = []
    for i in range(new_len):
        q = 0
        for j in range(10):
            if 0 <= (i - j) < len(perv_arr):
                q += perv_arr[i - j]
        next_arr.append(q)
    return next_arr

def find_tickets_count(n: int) -> int:
    n *= 2
    arr = [1] * 10
    result = 0

    for i in range(n // 2 - 1):
        arr = get_next_arr(arr)
    for r in arr:
        result += r ** 2

    return result

if __name__ == '__main__':
    test = TestingSystem(r'../files/A01_Счастливые_билеты-1801-057a77/1.Tickets')
    test.run_test(find_tickets_count)

2_Как выполнять домашние задания /senior/LuckySearchHalfNumber.py


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

# @Author  : classmate Lin.
# @Email   : 406728295@qq.com
# @File    : orders.py
# @Time    : 18-10-3 下午2:01

from flask_admin.contrib.sqla import ModelView

from app.admin.admin import current_user

def show_pay_status(v,c,m,p):
    if m.pay_status == 1:
        return '已支付'
    elif m.pay_status == 0:
        return '未支付'

    else:
        return '未知'

def show_order_status(v,c,m,p):
    if m.order_status == 1:
        return '已完成'
    elif m.order_status == 0:
        return '未完成'
    else:
        return '未知'

class OrdersView(ModelView):

    def is_accessible(self):
        return current_user.is_authenticated

    create_modal = True

    edit_modal = True

    can_export = True

    can_create = True

    can_edit = True

    can_set_page_size = True

    can_delete = True

    column_list = [
        'mch_order_id',
        'wx_order_id',
        'user_id',
        # 'lesson_id',
        'order_price',
        'pay_status',
        'order_status',
        'create_time',
        'update_time'
    ]

    column_labels = {
        'mch_order_id':'商户订单编号',
        'wx_order_id':'微信订单编号',
        'user_id':'用户编号',
        # 'lesson_id':'课程编号',
        'pay_status':'支付状态',
        'order_status':'订单状态',
        'order_price':'订单金额',
        'create_time':'创建时间',
        'update_time':'修改时间'
    }

    column_formatters = dict(
        order_price=lambda v, c, m, p: str(m.order_price/100)+' 元', #订单金额
        order_status=show_order_status,
        pay_status = show_pay_status
    )