import torch
from distributed_auto_differentiation.utils import dprint

def power_iteration_BC(B, C, rank=3, numiterations=1, device='cuda', tol=1e-3, compute_sigma=True):
    """This function is the main workhorse of rank-dAD. The original function was
            written by Sergey Plis in numpy, then translated into pytorch by Bradley Baker,
            and then modified by Sergey Plis and Bradley Baker.

        Args:
            B - The initial left matrix for the power-iteration based factorization
            C - the initial right matrix for the power-iteration based factorization
        Kwargs:
            rank - the maximum effective rank to use
            numiterations - the number of power iterations to perform
            device - the device where tensors will remain
            tol - a float tolerance used for removing "insignificant" eigenvectors
        Returns:
            The "rank" top left and right eigenvectors
    """
    #dprint(rank, tol, compute_sigma, B.shape, C.shape)
    [cm, cn] = C.shape
    if cm > cn:
        CC = torch.mm(C.T, C)
        BCC = torch.mm(B, CC)
    else:
        BCT = torch.mm(B, C.T)
        BCC = torch.mm(BCT, BCT.T)
    #dprint(BCT.shape, BCC.shape)
    #dprint(CC.shape, BCC.shape, C.shape, B.shape, BCC.shape)
    #dprint(torch.linalg.matrix_rank(BCC))

    def zero_result():
        sigma = torch.tensor(0.0, device=device)
        b_k = torch.zeros(B.shape[0], device=device)
        c_k = torch.zeros(C.shape[0], device=device)
        return {"b": b_k, "c": c_k, "sigma": sigma, "v": b_k}

    def eigenvalue(B, v):
        Bv = torch.mv(B.T, v)
        return torch.sqrt(Bv.dot(torch.mv(CC, Bv)))

    def eigenvalue2(B, v):
        Bv = torch.mv(torch.mm(C, B.T), v)
        return torch.sqrt(Bv.T.dot(Bv))

    def past_values(computed_eigs):
        bb = torch.stack([x['b'] for x in computed_eigs], 0)
        vv = torch.stack([x['v'] for x in computed_eigs], 0)
        return bb, vv

    def iterations(computed_eigs=[], is_sigma=1):
        if not is_sigma: return zero_result()
        # start with one of the columns
        b_k = torch.rand(B.shape[0], device=device)
        if computed_eigs:
            bb, vv = past_values(computed_eigs)
        for _ in range(numiterations):
            adjuster = torch.tensor(0.0, device=device)
            if computed_eigs:
                adjuster = torch.mv(vv.T, torch.mv(bb, b_k))
            # calculate the matrix-by-vector product (BC'CB' - adjusting_matrix)b
            if cm > cn:
                b_k1 = torch.mv(BCC, torch.mv(B.T, b_k)) - adjuster
            else:
                b_k1 = torch.mv(BCC, b_k) - adjuster
            # calculate the norm of b
            b_k1_norm = torch.norm(b_k1)
            # re normalize the vector
            b_k = b_k1 / b_k1_norm
        if compute_sigma:
            if cm > cn:
                sigma = eigenvalue(B, b_k)
            else:
                sigma = eigenvalue2(B, b_k)
            if torch.isnan(sigma): return zero_result()
        else:
            sigma = 1
        if cm > cn:
            c_k = torch.mv(C, torch.mv(B.T, b_k)) / sigma
        else:
            c_k = torch.mv(BCT.T, b_k) / sigma
        if len(computed_eigs) > 1 and torch.norm(b_k - computed_eigs[-1]['b']) / torch.norm(
                computed_eigs[-1]['b']) < tol:
            r = zero_result()
            computed_eigs[-1]['b'] = r['b']
            computed_eigs[-1]['c'] = r['c']
            computed_eigs[-1]['sigma'] = r['sigma']
            return zero_result()
        return {"b": b_k, "c": c_k, "sigma": sigma, "v": sigma * sigma * b_k}

    eigs = [{"sigma": torch.tensor(1.0, device=device)}]
    for i in range(rank):
        eigs += [iterations(computed_eigs=eigs[1:], is_sigma=eigs[-1]["sigma"])]
        if eigs[-1]["sigma"] == 0.0:
            break
    eigs = eigs[1:-1]
    return (
        torch.stack([x["sigma"] * x["b"] for x in eigs], 1),
        torch.stack([x["c"] for x in eigs], 1))


"""
const $ = new Env("统计东哥历史红包");
统计东哥历史红包
"""

import requests
import sys
import re
import time
import os

def gettimestamp():
    return str(int(time.time() * 1000))

def printf(text):
    print(text)
    sys.stdout.flush()

def getinfo(ck):
    isNext = True
    page = 1
    sum = 0
    usedsum = 0
    count = 0
    while isNext:
        url = "https://wq.jd.com/user/info/QueryUserRedEnvelopesV2?type=2&orgFlag=JD_PinGou_New&page=%s&cashRedType=1&redBalanceFlag=0&channel=3&_=%s&sceneval=2&g_login_type=1&g_ty=ls" % (
            page, gettimestamp())
        headers = {
            'accept': '*/*',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9',
            'dnt': '1',
            'referer': 'https://wqs.jd.com/',
            'sec-fetch-dest': 'script',
            'sec-fetch-mode': 'no-cors',
            'sec-fetch-site': 'same-site',
            'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
            'cookie': ck
        }
        r = requests.get(url, headers=headers).json()
        # print(r)
        if r['data']['unUseRedInfo']['redList'] == None:
            print('累计红包总数', count, '累计红包总额 %.2f' % sum, '已使用红包总额 %.2f' % usedsum)
            isNext = False
        else:
            page += 1
            count = r['data']['unUseRedInfo']['count']
            for i in r['data']['unUseRedInfo']['redList']:
                sum += float(i['discount'])
                usedsum += (float(i['discount']) - float(i['balance']))

if __name__ == '__main__':
    try:
        printf("--------[212796668]群管理贡献--------")
        cks = os.environ["JD_COOKIE"].split("&")
    except:
        f = open("/jd/config/config.sh", "r", encoding='utf-8')
        cks = re.findall(r'Cookie[0-9]*="(pt_key=.*?;pt_pin=.*?;)"', f.read())
        f.close()
    for ck in cks:
        ptpin = re.findall(r"pt_pin=(.*?);", ck)[0]
        printf("--------开始京东账号" + ptpin + "--------")
        try:
            getinfo(ck)
        except:
            print("发生异常错误")


#MAP and REDUCE are very effective ways to handle data structure. Here are
#Some examples.

#   1. I have an array of Temperature in Degree F. I want to convert them to
#   Degree C. Use map to convert the temperature unit.

DegreeF = [-40, 0,0,20,30,40, 50, 60, 70, 80, 90, 100, 110, 120, 320]

def convert_F_to_C(T):
    '''
    Conversion formula:
    (C-0)/100-0 = (F-32)/(212-32)
    --> C= (F-32)*100/180
    --> C = (F-32)*5/9
    '''
    return round((T-32)*5/9,2) #round in two decimal places

#Note in python 3, you need to pass the map in list to convert it to list
#Note, even though convert_F_to_C method has argument T, in map we pass the
#argument as a parameter of map method.
#Here: map(convert_F_to_C,DegreeF)==> map(function, argument of function)
DegreeC= list(map(convert_F_to_C,DegreeF))

for i in range(len(DegreeF)):
    print (DegreeF[i],"F =  ", DegreeC[i],"C")

# 2. Similar example: given I have an array x, create another array that is
# x^3-2x+2

import random
arr = [random.randint(0,10) for _ in range (10)]
print ("Original array: \n",arr)

new_arr = list(map(lambda x: x**3 -2*x +2, arr))

#Here lambda expression is short form of function
"""
def func(x):
    return x**3 -2*x +2
"""

print("Original array mapped to a function: \n",new_arr)

# 3. Find sum of all elements of an array using reduce
arr = [random.randint(-3,3) for _ in range (10)]
print ("Original array: \n",arr)

from functools import reduce #In general you need to import this library to use reduce

sum_of_all = reduce(lambda x, y :x+y, arr)
print ("sum_of_all: ", sum_of_all)

#Equivalent function for lambda expression:
def func(x,y):
    return x+y

sum_of_all_1 = reduce(func, arr)

print ("sum_of_all_1: ", sum_of_all_1)

# 4. Use reduce to find max value in an array

def myMax(x,y):
    if x>y:
        return x
    else:
        return y
maxValue  = reduce (myMax,arr)

print ("Original array: \n",arr)
print ("Max value of array: ",maxValue)


from fbs_runtime.application_context import ApplicationContext

import sys
import os
import logging

from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtCore import Qt, QThread, pyqtSignal, pyqtSlot

from PIL import Image
from fysom import FysomError

from ayab.ayab_gui import Ui_MainWindow
from ayab.plugins.ayab_plugin import AyabPluginControl
from ayab.plugins.ayab_plugin.firmware_flash import FirmwareFlash
from ayab.ayab_about import Ui_AboutForm

# Temporal serial imports.
import serial
import serial.tools.list_ports

# from playsound import playsound

logging.basicConfig(filename='ayab_log.txt',
                    level=logging.DEBUG,
                    format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s',
                    datefmt='%y-%m-%d %H:%M:%S')
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
console.setFormatter(
    logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s'))
logging.getLogger().addHandler(console)

# Fix PyQt5 for HiDPI screens
if hasattr(Qt, 'AA_EnableHighDpiScaling'):
    QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
    QtWidgets.QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
# Remove Help Button
if hasattr(Qt, 'AA_DisableWindowContextHelpButton'):
    QtWidgets.QApplication.setAttribute(Qt.AA_DisableWindowContextHelpButton,
                                        True)

class GuiMain(QMainWindow):
    """GuiMain is the main object that handles the instance of AYAB's GUI from ayab_gui.UiForm .

    GuiMain inherits from QMainWindow and instanciates a window with the form components form ayab_gui.UiForm.
    """

    signalUpdateProgress = pyqtSignal(int, int, int)
    signalUpdateColor = pyqtSignal('QString')
    signalUpdateStatus = pyqtSignal(int, int, 'QString', int)
    signalUpdateNotification = pyqtSignal('QString')
    signalDisplayPopUp = pyqtSignal('QString', 'QString')
    signalUpdateNeedles = pyqtSignal(int, int)
    signalUpdateAlignment = pyqtSignal('QString')
    signalDisplayBlockingPopUp = pyqtSignal('QString', 'QString')
    signalPlaysound = pyqtSignal('QString')
    signalUpdateButtonKnitEnabled = pyqtSignal(bool)
    signalUpdateWidgetKnitcontrolEnabled = pyqtSignal(bool)

    def __init__(self, app_context):
        super(GuiMain, self).__init__(None)

        self.app_context = app_context

        self.image_file_route = None

        self.pil_image = None
        self.start_needle = 80
        self.stop_needle = 119
        self.imageAlignment = "center"
        self.var_progress = 0
        self.zoomlevel = 3

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.enabled_plugin = AyabPluginControl()
        self.enabled_plugin.setup_ui(self)
        self.showMaximized()
        self.setupBehaviour()

        self.ui.label_notifications.setText("")
        self.ui.label_current_row.setText("")
        self.ui.label_current_color.setText("")

    def update_progress(self, row, total=0, repeats=0):
        '''Updates the Progress Bar.'''
        #Store to local variable
        self.var_progress = row
        self.refresh_scene()

        # Update label
        if total != 0:
            text = "Row {0}/{1}".format(row, total)
            if repeats != 0:
                text += " ({0} repeats completed)".format(repeats)
        else:
            text = ""
        self.ui.label_current_row.setText(text)

        options_ui = self.enabled_plugin.options_ui
        options_ui.label_progress.setText("{0}/{1}".format(row, total))

    def update_color(self, color):
        '''Updates the current color.'''
        text = ""
        if color != "":
            text += "Color "
        self.ui.label_current_color.setText(text + color)

    def updateStatus(self, hall_l, hall_r, carriage_type, carriage_position):
        options_ui = self.enabled_plugin.options_ui
        options_ui.progress_hall_l.setValue(hall_l)
        options_ui.label_hall_l.setText(str(hall_l))
        options_ui.progress_hall_r.setValue(hall_r)
        options_ui.label_hall_r.setText(str(hall_r))
        options_ui.slider_position.setValue(carriage_position)
        options_ui.label_carriage.setText(carriage_type)

    def update_file_selected_text_field(self, route):
        '''Sets self.image_file_route and ui.filename_lineedit to route.'''
        self.ui.filename_lineedit.setText(route)
        self.image_file_route = route

    def slotUpdateNotification(self, text):
        '''Updates the Notification field'''
        logging.info("Notification: " + text)
        self.ui.label_notifications.setText(text)

    def slotUpdateNeedles(self, start_needle, stop_needle):
        '''Updates the position of the start/stop needle visualisation'''
        self.start_needle = start_needle
        self.stop_needle = stop_needle
        self.refresh_scene()

    def slotUpdateAlignment(self, alignment):
        '''Updates the alignment of the image between start/stop needle'''
        self.imageAlignment = alignment
        self.refresh_scene()

    def slotUpdateWidgetKnitcontrolEnabled(self, enabled):
        self.ui.widget_knitcontrol.setEnabled(enabled)

    def slotUpdateButtonKnitEnabled(self, enabled):
        self.ui.knit_button.setEnabled(enabled)

    def wheelEvent(self, event):
        '''Using mouse wheel events to zoom the pattern view'''
        if self.pil_image is not None:
            # angleDelta.y is 120 or -120 when scrolling
            zoom = event.angleDelta().y() / 120

            self.zoomlevel = self.zoomlevel + zoom
            if self.zoomlevel <= 1:
                self.zoomlevel = 1
            elif self.zoomlevel >= 5:
                self.zoomlevel = 5
            self.refresh_scene()

    def start_knitting_process(self):
        # Disable everything which should not be touched
        # during knitting
        self.ui.menuTools.setEnabled(False)
        self.ui.widget_imgload.setEnabled(False)
        self.ui.menuImage_Actions.setEnabled(False)
        self.ui.widget_optionsdock.setEnabled(False)
        self.ui.knit_button.setEnabled(False)
        self.ui.cancel_button.setEnabled(True)

        self.gt = GenericThread(self.enabled_plugin.knit, parent_window=self)
        self.gt.start()

    def cancel_knitting_process(self):
        self.enabled_plugin.cancel()

    def resetUI(self):
        # (Re-)enable UI elements
        self.ui.menuTools.setEnabled(True)
        self.ui.widget_imgload.setEnabled(True)
        self.ui.menuImage_Actions.setEnabled(True)
        self.ui.widget_optionsdock.setEnabled(True)
        self.ui.knit_button.setEnabled(False)
        self.ui.cancel_button.setEnabled(False)

    def setupBehaviour(self):
        # Connecting UI elements.
        self.ui.load_file_button.clicked.connect(self.file_select_dialog)
        self.ui.knit_button.clicked.connect(self.start_knitting_process)
        self.ui.cancel_button.clicked.connect(self.cancel_knitting_process)
        self.ui.actionLoad_AYAB_Firmware.triggered.connect(self.generate_firmware_ui)
        self.ui.image_pattern_view.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
        # Connecting Signals.
        self.signalUpdateProgress.connect(self.update_progress)
        self.signalUpdateColor.connect(self.update_color)
        self.signalUpdateStatus.connect(self.updateStatus)
        self.signalUpdateNotification.connect(self.slotUpdateNotification)
        self.signalDisplayPopUp.connect(self.display_blocking_pop_up)
        self.signalUpdateNeedles.connect(self.slotUpdateNeedles)
        self.signalUpdateAlignment.connect(self.slotUpdateAlignment)
        self.signalPlaysound.connect(self.slotPlaysound)
        self.signalUpdateWidgetKnitcontrolEnabled.connect(self.slotUpdateWidgetKnitcontrolEnabled)
        self.signalUpdateButtonKnitEnabled.connect(self.slotUpdateButtonKnitEnabled)

        # This blocks the other thread until signal is done
        self.signalDisplayBlockingPopUp.connect(self.display_blocking_pop_up)

        self.ui.actionQuit.triggered.connect(QtCore.QCoreApplication.instance().quit)
        self.ui.actionAbout.triggered.connect(self.open_about_ui)
        self.ui.actionMirror.triggered.connect(self.mirror_image)
        self.ui.actionInvert.triggered.connect(self.invert_image)
        self.ui.actionRepeat.triggered.connect(self.repeat_image)
        self.ui.actionRotate_Left.triggered.connect(self.rotate_left)
        self.ui.actionRotate_Right.triggered.connect(self.rotate_right)
        self.ui.actionVertical_Flip.triggered.connect(self.flip_image)

    def load_image_from_string(self, image_str):
        '''Loads an image into self.ui.image_pattern_view using a temporary QGraphicsScene'''

        # TODO Check for maximum width before loading the image
        self.pil_image = Image.open(image_str)

        self.pil_image = self.pil_image.convert("RGBA")

        self.refresh_scene()
        self.statusBar().showMessage(image_str)
        # Enable plugin elements after first load of image
        self.ui.widget_optionsdock.setEnabled(True)
        self.ui.menuImage_Actions.setEnabled(True)
        # Tell loaded plugin elements about changed parameters
        width, height = self.pil_image.size
        self.enabled_plugin.slotSetImageDimensions(width,
                                                   height)

    def refresh_scene(self):
        '''Updates the current scene '''
        width, height = self.pil_image.size

        data = self.pil_image.convert("RGBA").tobytes("raw", "RGBA")
        qim = QtGui.QImage(data,
                           self.pil_image.size[0],
                           self.pil_image.size[1],
                           QtGui.QImage.Format_ARGB32)
        pixmap = QtGui.QPixmap.fromImage(qim)

        self.set_dimensions_on_gui(pixmap.width(), pixmap.height())

        qscene = QtWidgets.QGraphicsScene()

        # TODO move to generic configuration
        machine_width = 200
        bar_height = 5.0

        # add pattern and move accordingly to alignment
        pattern = qscene.addPixmap(pixmap)
        if self.imageAlignment == 'left':
            pattern.setPos(
                (self.start_needle - 100),
                0)
        elif self.imageAlignment == 'center':
            pattern.setPos(
                -(pixmap.width()/2.0)+((self.start_needle+self.stop_needle)/2) - 100,
                0)
        elif self.imageAlignment == 'right':
            pattern.setPos(
                (self.stop_needle - 100 - pixmap.width()),
                0)
        else:
            logging.warning("invalid alignment")

        # Draw "machine"
        rect_orange = QtWidgets.QGraphicsRectItem(
            -(machine_width/2.0),
            -bar_height,
            (machine_width/2.0),
            bar_height)
        rect_orange.setBrush(QtGui.QBrush(QtGui.QColor("orange")))
        rect_green = QtWidgets.QGraphicsRectItem(
            0.0,
            -bar_height,
            (machine_width/2.0),
            bar_height)
        rect_green.setBrush(QtGui.QBrush(QtGui.QColor("green")))

        qscene.addItem(rect_orange)
        qscene.addItem(rect_green)

        # Draw limiting lines (start/stop needle)
        limit_bar_width = 0.5

        qscene.addItem(
            QtWidgets.QGraphicsRectItem(self.start_needle - 101,
                                        -bar_height,
                                        limit_bar_width,
                                        pixmap.height() + 2*bar_height))
        qscene.addItem(
            QtWidgets.QGraphicsRectItem(self.stop_needle - 100,
                                        -bar_height,
                                        limit_bar_width,
                                        pixmap.height() + 2*bar_height))

        # Draw knitting progress
        qscene.addItem(
            QtWidgets.QGraphicsRectItem(-(machine_width/2.0),
                                        pixmap.height() - self.var_progress,
                                        machine_width,
                                        limit_bar_width))

        qv = self.ui.image_pattern_view
        qv.resetTransform()
        qv.scale(self.zoomlevel, self.zoomlevel)
        qv.setScene(qscene)

    def set_dimensions_on_gui(self, width, height):
        text = "{} - {}".format(width, height)
        self.ui.label_notifications.setText("Image Dimensions: " + text)

    def display_blocking_pop_up(self, message="", message_type="info"):
        logging.debug("MessageBox {}: '{}'".format(message_type, message))
        box_function = {
            "error": QtWidgets.QMessageBox.critical,
            "info": QtWidgets.QMessageBox.information,
            "question": QtWidgets.QMessageBox.question,
            "warning": QtWidgets.QMessageBox.warning
        }
        message_box_function = box_function.get(message_type)

        ret = message_box_function(
            self,
            "AYAB",
            message,
            QtWidgets.QMessageBox.Ok,
            QtWidgets.QMessageBox.Ok)
        if ret == QtWidgets.QMessageBox.Ok:
            return True

    def conf_button_function(self):
        self.enabled_plugin.configure(self)

    def file_select_dialog(self):
        filenameValue = self.ui.filename_lineedit.text()
        if filenameValue == '':
            filePath = self.app_context.get_resource("patterns")
        else:
            filePath = ''
        file_selected_route, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open file", filePath, 'Images (*.png *.PNG *.jpg *.JPG *.jpeg *.JPEG *.bmp *.BMP *.gif *.GIF *.tiff *.TIFF *.tif *.TIF)')
        if file_selected_route:
            self.update_file_selected_text_field(file_selected_route)
            self.load_image_from_string(str(file_selected_route))

    def generate_firmware_ui(self):
        self.__flash_ui = FirmwareFlash(self)
        self.__flash_ui.show()

    def open_about_ui(self):
        __version__ = "package_version"
        filename_version = self.app_context.get_resource("ayab/package_version")
        with open(filename_version) as version_file:
            __version__ = version_file.read().strip()

        self.__AboutForm = QtWidgets.QFrame()
        self.__about_ui = Ui_AboutForm()
        self.__about_ui.setupUi(self.__AboutForm)
        self.__about_ui.label_3.setText("Version " + __version__)
        self.__AboutForm.show()

    def invert_image(self):
        '''Public invert current Image function.'''
        self.apply_image_transform("invert")

    def repeat_image(self):
        '''Public repeat current Image function.'''
        v = QtWidgets.QInputDialog.getInt(
            self,
            "Repeat",
            "Vertical",
            value=1,
            min=1
        )
        h = QtWidgets.QInputDialog.getInt(
            self,
            "Repeat",
            "Horizontal",
            value=1,
            min=1
        )
        self.apply_image_transform("repeat", v[0], h[0])

    def mirror_image(self):
        '''Public mirror current Image function.'''
        self.apply_image_transform("mirror")

    def flip_image(self):
        '''Public mirror current Image function.'''
        self.apply_image_transform("flip")

    def rotate_left(self):
        '''Public rotate left current Image function.'''
        self.apply_image_transform("rotate", 90.0)

    def rotate_right(self):
        '''Public rotate right current Image function.'''
        self.apply_image_transform("rotate", -90.0)

    def apply_image_transform(self, transform_type, *args):
        '''Executes an image transform specified by key and args.

        Calls a function from transform_dict, forwarding args and the image,
        and replaces the QtImage on scene.
        '''
        transform_dict = {
            'invert': self.__invert_image,
            'repeat': self.__repeat_image,
            'mirror': self.__mirror_image,
            'flip': self.__flip_image,
            'rotate': self.__rotate_image,
        }
        transform = transform_dict.get(transform_type)
        image = self.pil_image
        if not image:
            return
        # Executes the transform function
        try:
            image = transform(image, args)
        except:
            logging.error("Error on executing transform")

        # Update the view
        self.pil_image = image

        # Disable Knit Controls
        self.ui.widget_knitcontrol.setEnabled(False)

        # Update maximum values
        width, height = self.pil_image.size
        self.enabled_plugin.slotSetImageDimensions(width,
                                                   height)
        # Draw canvas
        self.refresh_scene()

    def __rotate_image(self, image, args):
        if not args:
            logging.debug("image not altered on __rotate_image.")
            return image
        logging.debug("rotating image")
        rotated_image = image.rotate(args[0], expand=1)
        return rotated_image

    def __invert_image(self, image, args):
        import PIL.ImageOps

        if image.mode == 'RGBA':
            r, g, b, a = image.split()
            rgb_image = Image.merge('RGB', (r, g, b))
            inverted_image = PIL.ImageOps.invert(rgb_image)
        else:
            inverted_image = PIL.ImageOps.invert(image)

        return inverted_image

    def __mirror_image(self, image, args):
        import PIL.ImageOps
        mirrored_image = PIL.ImageOps.mirror(image)
        return mirrored_image

    def __flip_image(self, image, args):
        import PIL.ImageOps
        flipped_image = PIL.ImageOps.flip(image)
        return flipped_image

    def __repeat_image(self, image, args):
        """
        Repeat image.
        Repeat pHorizontal times horizontally, pVertical times vertically
        Sturla Lange 2017-12-30
        """
        old_h = image.size[1]
        old_w = image.size[0]
        new_h = old_h*args[0] # pVertical
        new_w = old_w*args[1] # pHorizontal
        new_im = Image.new('RGB', (new_w,new_h))
        for h in range(0,new_h,old_h):
          for w in range(0,new_w,old_w):
            new_im.paste(image, (w,h))
        return new_im

    def getSerialPorts(self):
        """
        Returns a list of all USB Serial Ports
        """
        return list(serial.tools.list_ports.grep("USB"))

    def slotPlaysound(self, event):
        return
        #if event == "start":
        #    playsound(self.app_context.get_resource("assets/start.wav"))
        #if event == "nextline":
        #    playsound(self.app_context.get_resource("assets/nextline.wav"))
        #if event == "finished":
        #    playsound(self.app_context.get_resource("assets/finish.wav"))

class GenericThread(QThread):
    '''A generic thread wrapper for functions on threads.'''

    def __init__(self, function, *args, **kwargs):
        QtCore.QThread.__init__(self)
        self.function = function
        self.args = args
        self.kwargs = kwargs

    def __del__(self):
        #self.join()
        self.wait()

    def run(self):
        try:
            self.function(*self.args, **self.kwargs)
        except FysomError as fe:
            logging.error(fe)
        return

def run(app_context):
    translator = QtCore.QTranslator()
    ## Loading ayab_gui main translator.
    translator.load(QtCore.QLocale.system(), "ayab_gui", ".", app_context.get_resource("ayab/translations"), ".qm")
    app = QtWidgets.QApplication(sys.argv)
    app.installTranslator(translator)
    window = GuiMain(app_context)
    window.show()
    sys.exit(app.exec_())


from Birds.models import Finch
from django.views.generic import TemplateView
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.template import loader

from django.views import generic
from django.views.generic.edit import CreateView, UpdateView
from .models import Finch

#domain/
def index(request):
	return render(request, 'Birds/index.html')

#domain/all_unclaimed_males/
class Unc_MaleView(generic.ListView):
	template_name = 'Birds/all_unclaimed_males.html'
	model = Finch
	context_object_name= 'all_birds'
	def get_queryset(self):
		return Finch.objects.all()

def detail(request, pk, **kwargs):
	def get_context_data(self, **kwargs):
		return {"bird": self.get_object()}
	return HttpResponseRedirect(reverse('Birds:birdinfo', kwargs={'pk': birds.pk}))

# #domain/all_unclaimed_males/<BirdID>
# class DetailsView(generic.DetailView):
# 	model = Finch
# 	template_name = 'Birds/details.html'
# 	def get_context_data(self, **kwargs):
# 		return {"bird": self.get_object(),}

class FinchCreate(CreateView):
	model = Finch
	fields = ['BirdID','Location','Procedure','Experimenter','Notes']

class FinchUpdate(UpdateView):
	model = Finch
	fields = ['BirdID','Location','Procedure','Experimenter','Notes']

# def birddetails(request, **kwargs):
# 	if request.method == 'GET':
# 		return render(request, 'Birds/details.html')
# 	if request.method == 'POST':
# 		form = Finch(request.POST)
# 		if form.is_valid():
# 			obj = Finch()
# 			obj.Location = form.cleaned_data['Location']
# 			obj.save()
# 			return HttpResponseRedirect('/')

def search(request):
    if 'q' in request.GET and request.GET['q']:
        q = request.GET['q']
        birds = Finch.objects.filter(BirdID__icontains=q)
        return render(request, 'Birds/search_result.html',
                      {'birds': birds, 'query': q})
    else:
        return HttpResponse('Please submit a query!')


from pycountry import countries

from webapp.services.import_services.models import LocationUpdate, BusinessUpdate, EvseUpdate, ConnectorUpdate, RegularHoursUpdate, \
    ExceptionalPeriodUpdate, ImageUpdate
from webapp.services.import_services.ocpi.ocpi_validators import LocationInput, EvseInput, ConnectorInput, BusinessDetailsInput, ImageInput

class OcpiMapper:

    def map_location(self, location_input: LocationInput, source: str) -> LocationUpdate:
        location_update = LocationUpdate(
            uid=location_input.id,
            source=source,
            name=location_input.name,
            address=location_input.address,
            postal_code=location_input.postal_code,
            city=location_input.city,
            state=location_input.state,
            country=countries.get(alpha_3=location_input.country).alpha_2,
            lat=location_input.coordinates.latitude,
            lon=location_input.coordinates.longitude,
            directions=location_input.directions,
            parking_type=location_input.parking_type,
            time_zone=location_input.time_zone,
            last_updated=location_input.last_updated,
            evses=[],
        )
        for evse_input in location_input.evses:
            location_update.evses.append(self.map_evse(evse_input))

        for business_type in ('operator', 'suboperator', 'owner'):
            if not getattr(location_input, business_type):
                continue

            setattr(location_update, business_type, self.map_business(business_input=getattr(location_input, business_type)))

        if location_input.opening_times:
            location_update.twentyfourseven = location_input.opening_times.twentyfourseven
            if location_input.opening_times.regular_hours:
                location_update.regular_hours = []
                for regular_hour_input in location_input.opening_times.regular_hours:
                    location_update.regular_hours.append(RegularHoursUpdate(**regular_hour_input.to_dict()))

            if location_input.opening_times.exceptional_openings:
                location_update.exceptional_openings = []
                for exceptional_opening_input in location_input.opening_times.exceptional_openings:
                    location_update.exceptional_openings.append(ExceptionalPeriodUpdate(**exceptional_opening_input.to_dict()))

            if location_input.opening_times.exceptional_closings:
                location_update.exceptional_closings = []
                for exceptional_closings_input in location_input.opening_times.exceptional_closings:
                    location_update.exceptional_closings.append(ExceptionalPeriodUpdate(**exceptional_closings_input.to_dict()))

        return location_update

    def map_evse(self, evse_input: EvseInput) -> EvseUpdate:
        evse_update = EvseUpdate(
            uid=evse_input.evse_id,
            status=evse_input.status,
            floor_level=evse_input.floor_level,
            physical_reference=evse_input.physical_reference,
            last_updated=evse_input.last_updated,
            capabilities=evse_input.capabilities,
            parking_restrictions=evse_input.parking_restrictions,
            # TODO: directions
            connectors=[],
        )

        if evse_input.coordinates:
            evse_update.lat = evse_input.coordinates.latitude
            evse_update.lon = evse_input.coordinates.longitude

        for connector_input in evse_input.connectors:
            evse_update.connectors.append(self.map_connector(connector_input))

        return evse_update

    @staticmethod
    def map_connector(connector_input: ConnectorInput) -> ConnectorUpdate:
        connector_update = ConnectorUpdate(
            uid=connector_input.id,
            standard=connector_input.standard,
            format=connector_input.format,
            power_type=connector_input.power_type,
            max_voltage=connector_input.max_voltage,
            max_amperage=connector_input.max_amperage,
            max_electric_power=connector_input.max_electric_power,
            last_updated=connector_input.last_updated,
            terms_and_conditions=connector_input.terms_and_conditions,
        )

        return connector_update

    def map_business(self, business_input: BusinessDetailsInput) -> BusinessUpdate:
        business_update = BusinessUpdate(
            name=business_input.name,
            website=business_input.website,
        )
        if business_input.logo:
            business_update.logo = self.map_image(business_input.logo)

        return business_update

    @staticmethod
    def map_image(image_input: ImageInput) -> ImageUpdate:
        image_update = ImageUpdate(
            external_url=image_input.url,
            width=image_input.width,
            category=image_input.category,
            type=image_input.type,
            height=image_input.height,
        )
        return image_update


import os
import PySimpleGUI as sg

sg.theme('DarkAmber')

close_window_action = "Ja!"
print("Vilka snälla kollegor jag har")
file_selector_column = [
    [
        sg.Text("File Browser"),
        sg.In(size=(25,1), enable_events=True, key="-FOLDER-"),
        sg.FolderBrowse(),
    ],
    [
        sg.Listbox(
            values=[],enable_events=True, size=(40,20), key = "-FILE LIST-"
        )
    ]
]

layout = [
    [file_selector_column],
    [sg.Text("Hej! Ska vi bygga ett grafiskt gränssnitt på SUP:en?")],
    [sg.Button(close_window_action)]
]

# Create the window
window = sg.Window("Demo", layout, margins=(200, 50))

# Event loop
while True:
    event, values = window.read()
#     if event == "-FOLDER-":
#         folder = values["-FOLDER-"]
#         try:
#             file_list = os.listdir(folder)
#         except:
#             file_list = []
#         filenames = [
#             f
#             for f in file_list
#             if os.path.isfile(os.path.join(folder, f))
#             and f.lower().endswith((".pdf"))
#         ]

#     elif event == "-FILE LIST-":
#         try:
#             filename = os.path.join(
#                 values["-FOLDER-"], values["-FILE LIST-"][0]
#             )
#             window["-TOUT-"].update(filename)
#             window["-IMAGE-"].update(filename=filename)

#         except:
#             pass

    if event in (close_window_action, sg.WIN_CLOSED):
        break

window.close()


from setuptools import setup

with open("README.md", "r") as fh:
    long_description = fh.read()

setup(
    name='django-bazaar-of-wonders',
    author='https://github.com/Bazaar-Trader',
    version='0.1.40',

    description='Bazaar of Wonders is a Django-based web application that aggregates card details and pricing statistics for trading card games, namely, Magic: The Gathering.',
    long_description=long_description,
    long_description_content_type="text/markdown",

    url="https://github.com/Bazaar-Trader/Bazaar_Of_Wonders",
    packages=['bazaar_of_wonders','main','bazaar_of_wonders_server_scripts','bazaar_of_wonders_db'],
    include_package_data=True,
    install_requires=['django','django-tinymce4-lite','django-materializecss-form','PyYAML','bs4','django-environ','apscheduler'],
    python_requires='>=3.8',
    classifiers=[
        "Programming Language :: Python :: 3",
        "Operating System :: OS Independent",
    ],

    entry_points =
    { 'console_scripts':
        [
            'bazaar_start = bazaar_of_wonders_server_scripts.run:main',
        ]
    },

)


from selenium import webdriver # http://pythonclub.com.br/selenium-parte-1.html
from selenium.webdriver.common.keys import Keys # https://stackoverflow.com/questions/1629053/typing-enter-return-key-in-selenium
from selenium.webdriver.common.by import By # https://selenium-python.readthedocs.io/waits.html#explicit-waits
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time # https://www.tutorialspoint.com/python/time_sleep

def scrape(author_name):

    # Iniciando o Selenium e indo até a página
    wd = webdriver.Firefox(executable_path = "./geckodriver.exe") # https://stackoverflow.com/questions/40208051/selenium-using-python-geckodriver-executable-needs-to-be-in-path
    wd.get("https://scholar.google.com.br/")

    # Pesquisando pelo nome do autor
    WebDriverWait(wd, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#gs_hdr_tsi")))
    search_box = wd.find_element_by_css_selector("#gs_hdr_tsi")
    search_box.send_keys(author_name)
    search_box.send_keys(Keys.ENTER)

    # Clicando no primeiro perfil
    WebDriverWait(wd, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".gs_r")))

    try:
        profile = wd.find_element_by_css_selector(".gs_rt2 b")
        profile.click()
    except:
        wd.quit()
        print("Autor não encontrado.")
        return None

    # Clicando no mostrar mais até que não dê mais
    page, new_page = "", wd.page_source
    while page != new_page:
        time.sleep(0.5)
        page = new_page
        mostrar_mais = wd.find_element_by_css_selector("#gsc_bpf_more .gs_wr")
        mostrar_mais.click()
        new_page = wd.page_source

    # Coletando os títulos e autores
    title = []
    authors = []
    we = wd.find_elements_by_css_selector(".gsc_a_at")
    for i in we:
        title.append(i.text)
    we = wd.find_elements_by_css_selector(".gsc_a_at+ .gs_gray")
    for i in we:
        authors.append(list(filter(lambda x: x != "...", i.text.split(", ")))) # https://www.geeksforgeeks.org/python-ways-to-remove-particular-list-element/

    # Finalizando o Selenium e arrumando o output
    wd.quit()
    output = []
    for i in range(len(title)):
        output.append({"title": title[i], "authors": authors[i]})

    return output


import itertools
import os.path

import torch

from data import *
from models import *
from sklearn.metrics import confusion_matrix
from tqdm import tqdm

device = torch.device('cuda' if torch.cuda.is_available() else "cpu")
print(f'Using {device}')

generator = torch.Generator()
generator.manual_seed(5757)

def train_model(m, c, o, train_l, val_l, epochs=10):
    losses = []
    v_losses = []
    for e in range(epochs):
        m.train()
        running = 0.0
        for inputs, labels in tqdm(train_l):
            inputs, labels = inputs.to(device), labels.to(device)
            o.zero_grad()
            out = m(inputs)
            loss = c(out, labels)
            loss.backward()
            o.step()
            running += loss.item()
        # Get average loss per batch
        e_loss = running / len(train_l)
        losses.append(e_loss)
        print()
        print(f'Epoch {e + 1}/{epochs}, Loss: {e_loss}')

        m.eval()
        running_v = 0.0
        with torch.no_grad():
            for i, l in tqdm(val_l):
                i, l = i.to(device), l.to(device)
                out = m(i)
                running_v += c(out, l).item()
        e_v_loss = running_v / len(val_l)
        v_losses.append(e_v_loss)
        print(f'Epoch {e + 1}/{epochs}, Validation Loss: {e_v_loss}')

    print('Done training!')
    return losses, v_losses

def plot_results(m, loader, title):
    m.eval()
    all_preds = []
    all_labels = []
    hard_labels_list = ['A', 'E', 'I', 'J', 'N', 'M', 'S', 'T']
    hard_preds = []
    hard_labels = []
    label_to_idx = {label: idx for idx, label in enumerate(loader.dataset.dataset.classes)}
    hard_label_indices = {label_to_idx[label] for label in hard_labels_list if label in label_to_idx}
    with torch.no_grad():
        correct = 0
        total = 0
        for images, labels in tqdm(loader):
            images, labels = images.to(device), labels.to(device)
            out = m(images)
            _, pred = torch.max(out.data, 1)
            total += labels.size(0)
            correct += (pred == labels).sum().item()
            all_preds.extend(pred.view(-1).cpu().numpy())
            all_labels.extend(labels.view(-1).cpu().numpy())

            for p, l in zip(pred.view(-1).cpu().numpy(), labels.view(-1).cpu().numpy()):
                if l in hard_label_indices:
                    if p in hard_label_indices:
                        hard_labels.append(l)
                        hard_preds.append(p)

        acc = 100 * correct / total
        print(f'Accuracy: {acc}')
    plot_cm(all_labels, all_preds, loader.dataset.dataset.classes, 'General', title)
    plot_cm(hard_labels, hard_preds, hard_labels_list, 'Hard', title, hard=True)

def plot_cm(true, pred, classes, title, m_title, hard=False):
    cm = confusion_matrix(true, pred)
    if not hard:
        plt.figure(figsize=(21, 21))
    else:
        plt.figure(figsize=(7, 7))
    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
    plt.title(f'{title} Confusion Matrix, {m_title} Data')
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    # Normalize the confusion matrix
    cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, "{:0.4f}".format(cm[i, j]),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
    plt.show()

def plot_loss(t_losses, v_losses):
    plt.figure(figsize=(10, 6))
    plt.plot(t_losses, label='Training Loss')
    plt.plot(v_losses, label='Validation Loss')
    plt.title('Training Loss Over Epochs')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()
    plt.tight_layout()
    plt.savefig('./trainlosses.png')

def main(train_p=False, results=False):
    data = fetch_data()

    # Split dataset
    train_size = int(0.7 * len(data))
    val_size = int(.15 * len(data))
    test_size = len(data) - (train_size + val_size)
    train, val, test = random_split(data, [train_size, val_size, test_size], generator=generator)

    # Data Loaders
    batch_size = 32
    train_loader = DataLoader(train, batch_size=batch_size, shuffle=True)
    val_loader = DataLoader(val, batch_size=batch_size)
    test_loader = DataLoader(test, batch_size=batch_size)

    model = ASLCNN(len(data.classes)).to(device)

    if train_p or not os.path.isfile('./data/asl_classifier_state_dict.pth'):
        crit = nn.CrossEntropyLoss()
        optimizer = optim.Adam(model.parameters(), lr=.003)

        print('start training')
        losses, v_losses = train_model(model, crit, optimizer, train_loader, val_loader)

        # Saving Model State Dictionary
        state_dict_path = 'data/asl_classifier_state_dict.pth'
        torch.save(model.state_dict(), state_dict_path)
        print(f"State dictionary saved to {state_dict_path}")

        plot_loss(losses, v_losses)

    if results:
        model.load_state_dict(torch.load('data/asl_classifier_state_dict.pth'))
        model.eval()
        plot_results(model, train_loader, 'Train')
        # plot_results(model, val_loader, 'Validation')
        plot_results(model, test_loader, 'Test')

if __name__ == '__main__':
    # main()
    # main(train_p=True, results=True)
    main(results=True)


import logging
import os
import subprocess
from datetime import date
from flask import Flask,render_template,request
from logging.handlers import RotatingFileHandler

app=Flask(__name__)

@app.route('/')
def main_page():
    # will display main game page
    year = date.today().year
    return render_template('index.html', year=year)

@app.route('/api')
def api_docs():
    # serves api documentation page
    return render_template('api_doc.html')

@app.route('/get_winner', methods = ['GET', 'POST'])
def winner_request():
    # getting the winner api endpoint
    if request.method == 'GET' and 'board' in request.args:
        return exec_ai(request.args["board"], 'o', '-w')
    elif request.method == 'POST' and "board" in request.form:
        return exec_ai(request.form["board"], 'o', '-w')
    return render_template("data_error.html")

@app.route('/get_move', methods = ['GET', 'POST'])
def move_request():
    # getting next move api endpoint
    if (request.method == 'GET' and 'board' in request.args
            and 'player' in request.args):
        return exec_ai(request.args["board"], request.args["player"], "-m")
    elif (request.method == 'POST' and "board" in request.form
            and "player" in request.form):
        return exec_ai(request.form["board"], request.form["player"], "-m")
    return render_template("data_error.html")

def exec_ai(board_data, player, flag):
    abspath_cwd = os.path.dirname(os.path.abspath(__file__))
    script_path = os.path.join(abspath_cwd, 'backend_ai/./TTAI')
    return subprocess.check_output([script_path, board_data, player, flag])

if __name__ == "__main__":
    abspath_cwd = os.path.dirname(os.path.abspath(__file__))
    file_handler = RotatingFileHandler(os.path.join(abspath_cwd, '../tictac_error.log'),
        maxBytes=1024 * 1024 * 100, backupCount=20)
    file_handler.setLevel(logging.INFO)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    file_handler.setFormatter(formatter)
    app.logger.addHandler(file_handler)
    app.run(debug=True)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" Audio solving module. """

import os
import random
import shutil
import tempfile

from asyncio import TimeoutError, CancelledError
from aiohttp.client_exceptions import ClientError

from nonocaptcha import util
from nonocaptcha.speech import Amazon, Azure, Sphinx, DeepSpeech, AzureSpeech
from nonocaptcha.base import Base
from nonocaptcha.exceptions import DownloadError, ReloadError, TryAgain

class SolveAudio(Base):
    def __init__(self, page, loop, proxy, proxy_auth, proc_id):
        self.page = page
        self.loop = loop
        self.proxy = proxy
        self.proxy_auth = proxy_auth
        self.proc_id = proc_id

    async def solve_by_audio(self):
        """Go through procedures to solve audio"""
        await self.get_frames()
        for _ in range(10):
            try:
                answer = await self.loop.create_task(self.get_audio_response())
            except DownloadError:
                raise
            except ReloadError:
                raise
            else:
                if not answer:
                    continue
            await self.type_audio_response(answer)
            await self.click_verify()
            try:
                result = await self.check_detection(self.animation_timeout)
            except TryAgain:
                continue
            else:
                return result
        else:
            return {"status": "retries_exceeded"}

    async def get_audio_response(self):
        """Download audio data then send to speech-to-text API for answer"""
        try:
            audio_url = await self.image_frame.evaluate(
                'jQuery("#audio-source").attr("src")')
            if not isinstance(audio_url, str):
                raise DownloadError(f"Audio url is not valid, expected `str`"
                                    "instead received {type(audio_url)}")
        except CancelledError:
            raise DownloadError("Audio url not found, aborting")

        self.log("Downloading audio file")
        try:
            audio_data = await self.loop.create_task(
                util.get_page(
                    audio_url,
                    proxy=self.proxy,
                    proxy_auth=self.proxy_auth,
                    binary=True,
                    timeout=self.page_load_timeout))
        except ClientError as e:
            self.log(f"Error `{e}` occured during audio download, retrying")
        else:
            answer = None
            service = self.speech_service.lower()
            if service in [
                "azure",
                "pocketsphinx",
                "deepspeech",
                "azurespeech"
            ]:
                if service == "azurespeech":
                    speech = AzureSpeech()
                elif service == "azure":
                    speech = Azure()
                elif service == "pocketsphinx":
                    speech = Sphinx()
                else:
                    speech = DeepSpeech()
                tmpd = tempfile.mkdtemp()
                tmpf = os.path.join(tmpd, "audio.mp3")
                await util.save_file(tmpf, data=audio_data, binary=True)
                answer = await self.loop.create_task(speech.get_text(tmpf))
                shutil.rmtree(tmpd)
            else:
                speech = Amazon()
                answer = await self.loop.create_task(
                    speech.get_text(audio_data))
            if answer:
                self.log(f'Received answer "{answer}"')
                return answer

            self.log("No answer, reloading")
            await self.click_reload_button()
            func = (
                f'"{audio_url}" !== '
                f'jQuery(".rc-audiochallenge-tdownload-link").attr("href")')
            try:
                await self.image_frame.waitForFunction(
                    func, timeout=self.animation_timeout)
            except TimeoutError:
                raise ReloadError("Download link never updated")

    async def type_audio_response(self, answer):
        self.log("Typing audio response")
        response_input = await self.image_frame.J("#audio-response")
        length = random.uniform(70, 130)
        await self.loop.create_task(
            response_input.type(text=answer, delay=length))

    async def click_verify(self):
        self.log("Clicking verify")
        verify_button = await self.image_frame.J("#recaptcha-verify-button"
                                                 )
        await self.click_button(verify_button)


import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import click
from datetime import date, datetime
import os

HEADERS={
    'Referrer-Policy':'origin-when-cross-origin',
    'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.61 Safari/537.36"
}

@click.command()
def main():
    click.echo("This is the Grab Scraper 🐳🐳🐳")
    click.echo('Enter the URL below. It should be similar to https://food.grab.com/my/en/restaurant/burger-king-plaza-low-yat-delivery/1-CYUVMB3DUEABUE')
    url = click.prompt('URL',type=str)
    click.echo('Running the Scraper')
    scrape(url)

def dt_now():
    return datetime.now().strftime('%d-%m-%y-%H-%M')

def scrape(url):

    req = requests.get(url,headers = HEADERS)
    if req.status_code != 200:
        raise ConnectionError('Unable to access URL')
    soup = BeautifulSoup(req.text, 'html.parser')
    click.secho("Webpage Accessed",fg='cyan')

    menu_div = soup.find('div',class_=re.compile('menuContentWrapper*'))# 4 is the index of the container
    categories = menu_div.find_all('div',class_=re.compile('category*'))

    click.secho("Categories Identified",fg='cyan')

    df = []
    for cat in categories:
        category_name = cat.find('h2',class_=re.compile('categoryName'))
        if category_name: # Some weird interaction which creates duplicatess
            category_name =category_name.text
        else:
            continue
        menu_items = cat.find_all('div',class_=re.compile("menuItemWrapper*"))
        for item in menu_items:

            item_name = item.find('h3').text
            item_desc = item.find('h6',class_=re.compile('itemDescription*'))
            item_desc = item_desc.text if item_desc else ""

            item_price = float(item.find('h6',class_=re.compile('discountedPrice*')).text)

            dis_div = item.find('div',class_=re.compile('ant-row itemDiscount*'))
            if dis_div:
                print(f'Discounted Price found for {item_name}')

            info = {
                'name':item_name,
                'category': category_name,
                'price': item_price,
                'description': item_desc,
            }

            df.append(info)

    df = pd.DataFrame.from_dict(df)
    restaurant_name = url.split('/')[-2]
    df = df.drop_duplicates()
    if not os.path.isdir('output'):
        os.mkdir('output')
    df.to_csv(f'output/{restaurant_name}_{dt_now()}.csv',index=False)
    click.secho("Data Saved",fg='cyan')

if __name__ == "__main__":
    main()


import pytest
from decorator import name, greeting_decorator, nickname, farewell_decorator

def test_name_decorator():
    actual = name('bob')
    expected = 'Hello there, bob'
    assert actual == expected

def test_nicknname_farewell():
    actual = nickname('Tim')
    expected = 'Well, Tim, It\'s been real. Take care!'
    assert actual == expected


from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from models import *
from pyramid.session import SignedCookieSessionFactory
from pyramid.security import Allow, Deny, Authenticated, Everyone

my_session_factory = SignedCookieSessionFactory('itsasecrert')

class RootFactory(object):
    def __init__(self, request):
        self.__acl__ = [
            (Allow, Everyone, 'view'),
            (Allow, Authenticated, 'add')
        ]

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    Base.metadata.create_all()

    authn_policy = AuthTktAuthenticationPolicy('sosecret', hashalg='sha512')
    authz_policy = ACLAuthorizationPolicy()

    config = Configurator(settings=settings, session_factory=my_session_factory, root_factory=RootFactory)
    config.set_authentication_policy(authn_policy)
    config.set_authorization_policy(authz_policy)
    config.include('pyramid_chameleon')
    config.include('pyramid_jinja2')
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('home','/')
    config.add_route('view_blog', '/index')
    config.add_route('register', '/register')
    config.add_route('view_my', '/my')
    config.add_route('blog_article', '/post/{id}')
    config.add_route('blog_create','/post')
    config.add_route('login','/login')
    config.add_route('logout','/logout')
    config.add_route('about','/about')
    config.scan()
    return config.make_wsgi_app()


import logging

from django.conf import settings
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

from avanan.slack.models import SQSQueue

logger = logging.getLogger(__name__)

def get_slack_webclient():
    return WebClient(token=settings.SLACK_USER_TOKEN)

def produce_sqs(message):
    queue_instance, created = SQSQueue.get_default_queue()
    queue = queue_instance.get_aws_queue()
    response = queue.send_message(MessageBody=message)
    return response

def delete_message(timestamp, channel):
    try:
        client = get_slack_webclient()
        response = client.chat_delete(
            channel=channel,
            ts=timestamp)
        logger.info(response)
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]
        return e.response['error']


from sentence_transformers.losses import CosineSimilarityLoss

from setfit import SetFitModel, SetFitTrainer
from setup_utils import seed_everything, MODEL_SEED

def do_setfit(args, train_ds, val_ds, config_dict=None):
    if len(set(train_ds['labels'])) != 2:
        metric = 'f1'
    else:
        metric = 'ap'
    if not config_dict:
        config_dict = {'batch_size':16,
                       'model_seed':MODEL_SEED,
                       'metric': metric,
                       'num_iterations':20,
                       'num_epochs':1}
        seed_everything(MODEL_SEED)
        model = SetFitModel.from_pretrained("sentence-transformers/{}".format(args.st_model))
    else:
        seed_everything(config_dict['model_seed'])
        model = SetFitModel.from_pretrained("sentence-transformers/{}".format(config_dict['st_model']))

    trainer = SetFitTrainer(
    model=model,
    train_dataset=train_ds,
    eval_dataset=val_ds,
    loss_class=CosineSimilarityLoss,
    metric=config_dict['metric'], #was f1
    batch_size=config_dict['batch_size'],
    seed=config_dict['model_seed'],
    num_iterations=config_dict['num_iterations'], # The number of text pairs to generate for contrastive learning
    num_epochs=config_dict['num_epochs'], # The number of epochs to use for constrastive learning
    column_mapping={"text": "text", "labels": "label"} # Map dataset columns to text/label expected by trainer
    )

    trainer.train()
    return trainer

def predict_with_setfit(X, y, sbert_trainer):
    print('predicting with setfit')
    clf = sbert_trainer.model
    y_logit = clf.predict_proba(X)
    if len(y_logit.shape) == 2:
        y_logit = y_logit[:, 1]
    y_pred = clf.predict(X)
    predictions = (y_logit, y_pred, y)

    return predictions


#!/usr/bin/env python3
# Based on https://python101.readthedocs.io/pl/latest/pygame/pong/#
import pygame
from typing import Type
import skfuzzy as fuzz
import skfuzzy.control as fuzzcontrol

FPS = 30

class Board:
    def __init__(self, width: int, height: int):
        self.surface = pygame.display.set_mode((width, height), 0, 32)
        pygame.display.set_caption("AIFundamentals - PongGame")

    def draw(self, *args):
        background = (0, 0, 0)
        self.surface.fill(background)
        for drawable in args:
            drawable.draw_on(self.surface)

        pygame.display.update()

class Drawable:
    def __init__(self, x: int, y: int, width: int, height: int, color=(255, 255, 255)):
        self.width = width
        self.height = height
        self.color = color
        self.surface = pygame.Surface(
            [width, height], pygame.SRCALPHA, 32
        ).convert_alpha()
        self.rect = self.surface.get_rect(x=x, y=y)

    def draw_on(self, surface):
        surface.blit(self.surface, self.rect)

class Ball(Drawable):
    def __init__(
        self, x: int, y: int, radius: int = 20, color=(255, 10, 0), speed: int = 3,
    ):
        super(Ball, self).__init__(x, y, radius, radius, color)
        pygame.draw.ellipse(self.surface, self.color, [0, 0, self.width, self.height])
        self.x_speed = speed
        self.y_speed = speed
        self.start_speed = speed
        self.start_x = x
        self.start_y = y
        self.start_color = color
        self.last_collision = 0

    def bounce_y(self):
        self.y_speed *= -1

    def bounce_x(self):
        self.x_speed *= -1

    def bounce_y_power(self):
        self.color = (
            self.color[0],
            self.color[1] + 10 if self.color[1] < 255 else self.color[1],
            self.color[2],
        )
        pygame.draw.ellipse(self.surface, self.color, [0, 0, self.width, self.height])
        self.x_speed *= 1.1
        self.y_speed *= 1.1
        self.bounce_y()

    def reset(self):
        self.rect.x = self.start_x
        self.rect.y = self.start_y
        self.x_speed = self.start_speed
        self.y_speed = self.start_speed
        self.color = self.start_color
        self.bounce_y()

    def move(self, board: Board, *args):
        self.rect.x += round(self.x_speed)
        self.rect.y += round(self.y_speed)

        if self.rect.x < 0 or self.rect.x > (
            board.surface.get_width() - self.rect.width
        ):
            self.bounce_x()

        if self.rect.y < 0 or self.rect.y > (
            board.surface.get_height() - self.rect.height
        ):
            self.reset()

        timestamp = pygame.time.get_ticks()
        if timestamp - self.last_collision < FPS * 4:
            return

        for racket in args:
            if self.rect.colliderect(racket.rect):
                self.last_collision = pygame.time.get_ticks()
                if (self.rect.right < racket.rect.left + racket.rect.width // 4) or (
                    self.rect.left > racket.rect.right - racket.rect.width // 4
                ):
                    self.bounce_y_power()
                else:
                    self.bounce_y()

class Racket(Drawable):
    def __init__(
        self,
        x: int,
        y: int,
        width: int = 80,
        height: int = 20,
        color=(255, 255, 255),
        max_speed: int = 10,
    ):
        super(Racket, self).__init__(x, y, width, height, color)
        self.max_speed = max_speed
        self.surface.fill(color)

    def move(self, x: int, board: Board):
        delta = x - self.rect.x
        delta = self.max_speed if delta > self.max_speed else delta
        delta = -self.max_speed if delta < -self.max_speed else delta
        delta = 0 if (self.rect.x + delta) < 0 else delta
        delta = (
            0
            if (self.rect.x + self.width + delta) > board.surface.get_width()
            else delta
        )

        # print("X: " +str(self.rect.x))
        # print(delta)

        self.rect.x += delta

class Player:
    def __init__(self, racket: Racket, ball: Ball, board: Board) -> None:
        self.ball = ball
        self.racket = racket
        self.board = board

    def move(self, x: int):
        self.ball.rect.centery
        self.racket.move(x, self.board)

    def move_manual(self, x: int):
        """
        Do nothing, control is defined in derived classes
        """
        pass

    def act(self, x_diff: int, y_diff: int):
        """
        Do nothing, control is defined in derived classes
        """
        pass

class PongGame:
    def __init__(
        self, width: int, height: int, player1: Type[Player], player2: Type[Player]
    ):
        pygame.init()
        self.board = Board(width, height)
        self.fps_clock = pygame.time.Clock()
        self.ball = Ball(width // 2, height // 2)

        self.opponent_paddle = Racket(x=width // 2, y=0)
        self.oponent = player1(self.opponent_paddle, self.ball, self.board)

        self.player_paddle = Racket(x=width // 2, y=height - 20)
        self.player = player2(self.player_paddle, self.ball, self.board)

    def run(self):
        while not self.handle_events():
            self.ball.move(self.board, self.player_paddle, self.opponent_paddle)
            self.board.draw(
                self.ball, self.player_paddle, self.opponent_paddle,
            )
            self.oponent.act(
                self.oponent.racket.rect.centerx - self.ball.rect.centerx,
                self.oponent.racket.rect.centery - self.ball.rect.centery,
            )
            self.player.act(
                self.player.racket.rect.centerx - self.ball.rect.centerx,
                self.player.racket.rect.centery - self.ball.rect.centery,
            )
            self.fps_clock.tick(FPS)

    def handle_events(self):
        for event in pygame.event.get():
            if (event.type == pygame.QUIT) or (
                event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE
            ):
                pygame.quit()
                return True
        keys = pygame.key.get_pressed()
        if keys[pygame.constants.K_LEFT]:
            self.player.move_manual(0)
        elif keys[pygame.constants.K_RIGHT]:
            self.player.move_manual(self.board.surface.get_width())
        return False

class NaiveOponent(Player):
    def __init__(self, racket: Racket, ball: Ball, board: Board):
        super(NaiveOponent, self).__init__(racket, ball, board)

    def act(self, x_diff: int, y_diff: int):
        x_cent = self.ball.rect.centerx
        self.move(x_cent)

class HumanPlayer(Player):
    def __init__(self, racket: Racket, ball: Ball, board: Board):
        super(HumanPlayer, self).__init__(racket, ball, board)

    def move_manual(self, x: int):
        # print(self.ball.rect.centery)
        self.move(x)

# ----------------------------------
# DO NOT MODIFY CODE ABOVE THIS LINE
# ----------------------------------

class FuzzyPlayer(Player):
    def __init__(self, racket: Racket, ball: Ball, board: Board):
        super(FuzzyPlayer, self).__init__(racket, ball, board)

        # self.fuzzy_controler(1,1)
        # self.fuzzy_controler()
        # x_dist = fuzz.control.Antecedent...
        # y_dist = fuzz.control.Antecedent...
        # speed = fuzz.control.Consequent...
        # racket_controller = fuzz.control.ControlSystem...

    def act(self, x_diff: int, y_diff: int):
        velocity = self.make_decision(x_diff, y_diff)
        self.move(self.racket.rect.x + velocity)

    def fuzzy_controler(self,x,y):
        import numpy as np
        # x_distance = fuzzcontrol.Antecedent((abs(self.racket.rect.centerx-self.ball.rect.centerx),1), 'x_distance')
        # y_distance = fuzzcontrol.Antecedent((abs(self.racket.rect.centery-self.ball.rect.centery),1), 'y_distance')
        # movement = fuzzcontrol.Consequent(np.arange(0, 1, 1), 'movement')
        # print("x:"+ str(self.racket.rect.centerx - self.ball.rect.centerx))
        # print("y:" + str(self.racket.rect.centery - self.ball.rect.centery))
        x = self.racket.rect.centerx - self.ball.rect.centerx
        y = self.racket.rect.centery - self.ball.rect.centery
        # if x==0:
        #     x+=1
        x_distance = fuzzcontrol.Antecedent(np.arange(-800, 801, 1), 'x_distance')
        y_distance = fuzzcontrol.Antecedent(np.arange(1, 401, 1), 'y_distance')
        movement = fuzzcontrol.Consequent(np.arange(-10,11, 1), 'movement')

        # x_distance = fuzzcontrol.Antecedent(np.arange(0, 801, 1), 'x_distance')
        # y_distance = fuzzcontrol.Antecedent(np.arange(0, 401, 1), 'y_distance')
        # movement = fuzzcontrol.Consequent(np.arange(-400, 401, 1), 'movement')

        # Auto-membership function population
        #prawdopodobnie ręcznie wypadało by to zrobić
        x_distance['poor'] = fuzz.trapmf(x_distance.universe, [-800,-800,-100  , 0])
        x_distance['average'] = fuzz.trapmf(x_distance.universe, [-200,-100, 100 , 200])
        x_distance['good'] = fuzz.trapmf(x_distance.universe, [0,100, 800 , 800])
        # x_distance.automf(3)
        x_distance.view()

        # x_distance.view()
        y_distance['poor'] = fuzz.trapmf(y_distance.universe, [0,100,200,200])
        # y_distance['average'] = fuzz.trapmf(y_distance.universe, [100,180,220,300])
        y_distance['average'] = fuzz.trimf(y_distance.universe, [190,200,210])
        y_distance['good'] = fuzz.trapmf(y_distance.universe, [200,200,300,400])
        # y_distance.view()
        # y_distance.automf(3)
        # y_distance.view()

        # Custom membership functions can be built interactively with a familiar,
        # Pythonic API
        # movement['right'] = fuzz.trimf(movement.universe, [-10,-5,0])
        # movement['stay'] = fuzz.trimf(movement.universe, [-1,0,1])
        # movement['left'] = fuzz.trimf(movement.universe, [0,5,10])

        # movement.view()
        movement['right'] = fuzz.trapmf(movement.universe, [-10,-10, -5 , 0])
        movement['stay'] = fuzz.trapmf(movement.universe, [-1, -1, 1, 1])
        movement['left'] = fuzz.trapmf(movement.universe, [0,5, 10, 10])

        #na razie max mamy 3.47 jakimś cudem

        # movement.view()
        # movement['left'] = fuzz.trapmf(movement.universe, [-400, -400, -200, -100])
        # movement['stay'] = fuzz.trapmf(movement.universe, [-100, -50, 50, 100])
        # movement['right'] = fuzz.trapmf(movement.universe, [100, 200, 400, 400])

        # # movement.view()
        # You can see how these look with .view()
        # x_distance['average'].view()
        # y_distance['average'].view()
        # movement.view()

        # Create the rules
        rule1_1 = fuzzcontrol.Rule(x_distance['poor'] & y_distance['poor'], movement['left'])
        rule1_2 = fuzzcontrol.Rule(x_distance['poor'] & y_distance['average'], movement['left'])
        rule1_3 = fuzzcontrol.Rule(x_distance['poor'] & y_distance['good'], movement['left'])
        rule2_1 = fuzzcontrol.Rule(x_distance['average'], movement['stay'])
        rule2_2 = fuzzcontrol.Rule(x_distance['average'], movement['stay'])
        rule2_3 = fuzzcontrol.Rule(x_distance['average'], movement['stay'])
        rule3_1 = fuzzcontrol.Rule(x_distance['good'] & y_distance['poor'], movement['right'])
        rule3_2 = fuzzcontrol.Rule(x_distance['good'] & y_distance['average'], movement['right'])
        rule3_3 = fuzzcontrol.Rule(x_distance['good'] & y_distance['good'], movement['right'])

        # rule1 = fuzzcontrol.Rule(x_distance['good'], movement['right'])
        # rule2 = fuzzcontrol.Rule(x_distance['average'], movement['stay'])
        # rule3 = fuzzcontrol.Rule(x_distance['poor'], movement['left'])

        # rule1.view()

        # Create the control system
        tipping_ctrl = fuzzcontrol.ControlSystem([rule1_1,rule1_2,rule1_3,rule2_1,rule2_2,rule2_3, rule3_1,rule3_2, rule3_3])
        # tipping_ctrl = fuzzcontrol.ControlSystem([rule1,rule2,rule3])

        # Create a tipping simulation
        tipping = fuzzcontrol.ControlSystemSimulation(tipping_ctrl)

        # Pass inputs to the ControlSystem using Antecedent labels with Pythonic API
        # Note: if you like passing many inputs all at once, use .inputs(dict_of_data)
        tipping.input['x_distance'] = x
        tipping.input['y_distance'] = y

        # tipping.input['y_distance'] = y
        # Crunch the numbers
        tipping.compute()
        # print(tipping.output)
        # movement.view(sim=tipping)

        # print(tipping.output['movement'])
        return tipping.output['movement']*3

    def make_decision(self, x_diff: int, y_diff: int):
        # racket_controller.compute()
        # ...

        res = self.fuzzy_controler(self.racket.rect.centerx,self.racket.rect.centery)
        # print(res)

        #czyli mamy przedział -10- 0 i 0 10
        return res

if __name__ == "__main__":
    # game = PongGame(800, 400, NaiveOponent, HumanPlayer)

    #sprawdzić rozmiary w input itp ponieważ  zawsze ujemene wychodzi a dystans powyżej 750 nie spadł nigdy

    game = PongGame(800, 400, NaiveOponent, FuzzyPlayer)
    game.run()


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 20 21:14:04 2018

@author: Paris
"""

import numpy as np
import matplotlib.pyplot as plt
from pyDOE import lhs
from scipy.interpolate import griddata

from models_tf import DarcyNet2D

np.random.seed(1234)

if __name__ == "__main__":

    dataset = np.load('./test.npz')
    X = dataset['coo']
    K = dataset['k']
    U = dataset['u']

    idx = 11
    X_star = X
    k_star = K[idx:idx+1,:].T
    u_star = U[idx:idx+1,:].T

    N_u = 100
    N_k = 250
    N = u_star.shape[0]

    # Specify input domain bounds
    lb, ub = X.min(0), X.max(0)

    # Training data
    idx_k = np.random.choice(N, N_k)
    X_k = X[idx_k,:]
    Y_k = k_star[idx_k,:]

    idx_u = np.random.choice(N, N_u)
    X_u = X[idx_u,:]
    Y_u = u_star[idx_u,:]

    X_f = X_star
    Y_f = np.zeros((N, 1))

    # Create model
    layers_u = [2,50,50,50,1]
    layers_k = [2,50,50,50,1]
    model = DarcyNet2D(X_k, Y_k, X_u, Y_u, X_f, Y_f,
                      layers_k, layers_u, lb, ub)

    # Train
    model.train()

    # Predict at test points
    k_pred = model.predict_k(X_star)
    u_pred = model.predict_u(X_star)

    # Relative L2 error
    error_k = np.linalg.norm(k_star - k_pred, 2)/np.linalg.norm(k_star, 2)
    error_u = np.linalg.norm(u_star - u_pred, 2)/np.linalg.norm(u_star, 2)

    # Plot
    nn = 200
    x = np.linspace(lb[0], ub[0], nn)
    y = np.linspace(lb[1], ub[1], nn)
    XX, YY = np.meshgrid(x,y)

    K_plot = griddata(X_star, k_pred.flatten(), (XX, YY), method='cubic')
    U_plot = griddata(X_star, u_pred.flatten(), (XX, YY), method='cubic')

    K_error = griddata(X_star, np.abs(k_star-k_pred).flatten(), (XX, YY), method='cubic')
    U_error = griddata(X_star, np.abs(u_star-u_pred).flatten(), (XX, YY), method='cubic')

    fig = plt.figure(1)
    plt.subplot(2,2,1)
    plt.pcolor(XX, YY, K_plot, cmap='viridis')
    plt.plot(X_k[:,0], X_k[:,1], 'ro', markersize = 1)
    plt.colorbar()
    plt.xlabel('$x_1$')
    plt.ylabel('$x_2$')
    plt.title('$k(x_1,x_2)$')

    plt.subplot(2,2,2)
    plt.pcolor(XX, YY, U_plot, cmap='viridis')
    plt.plot(X_u[:,0], X_u[:,1], 'ro', markersize = 1)
    plt.colorbar()
    plt.xlabel('$x_1$')
    plt.ylabel('$x_2$')
    plt.title('$u(x_1,x_2)$')

    plt.subplot(2,2,3)
    plt.pcolor(XX, YY, K_error, cmap='viridis')
    plt.colorbar()
    plt.xlabel('$x_1$')
    plt.ylabel('$x_2$')
    plt.title('Absolute error')

    plt.subplot(2,2,4)
    plt.pcolor(XX, YY, U_error, cmap='viridis')
    plt.colorbar()
    plt.xlabel('$x_1$')
    plt.ylabel('$x_2$')
    plt.title('Absolute error')


from typing import Optional

from db.models.user import User
from sqlalchemy import (
    select,
)
from app.crud.base import CRUDBase
from app.schemas.user import (
    UserFiltersSchema,
    UserOrderingSchema,
    UserOrderingAsc,
    UserOrderingDesc,
    UserOrderingRoleAsc,
    UserOrderingRoleDesc,
)
from sqlalchemy import (
    String,
    cast,
    or_,
    select,
)
from db.models.user import Role

class UserCRUD(CRUDBase):

    def get_user_by_login(
        self,
        login: str,
    ) -> Optional[User]:
        query = self.db.execute(select(User).filter(User.login == login))
        self.db.commit()
        user = query.scalars().first()
        return user

    def get_user_by_id(
        self,
        user_id: int,
    ) -> Optional[User]:
        query = self.db.execute(select(User).filter(User.id == user_id))
        self.db.commit()
        user = query.scalars().first()
        return user

    def get_users(
        self,
        search: Optional[str] = None,
        filters: Optional[UserFiltersSchema] = None,
        ordering: Optional[UserOrderingSchema] = None,
    ):
        query = select(self.model)
        # Только активные пользователи
        query = query.filter(self.model.is_active == True)
        if search:
            query = query.filter(
                or_(
                    cast(self.model.id, String).ilike(f'%{search}%'),
                    self.model.full_name.ilike(f'%{search}%'),
                    self.model.email.ilike(f'%{search}%'),
                    self.model.phone_number.ilike(f'%{search}%'),
                    self.model.city.ilike(f'%{search}%'),
                    self.model.address.ilike(f'%{search}%'),
                    self.model.zip_code.ilike(f'%{search}%'),
                    self.model.role.has(Role.title.ilike(f'%{search}%')),
                )
            )
        if filters:
            for key, value in filters:
                if key not in filters.__fields_set__:
                    continue
                else:
                    if key == 'role_title':
                        query = query.filter(self.model.role.has(Role.title.ilike(f'%{value}%')))
                    elif type(value) == str:
                        query = query.filter(getattr(self.model, key).ilike(f'%{value}%'))
                    elif type(value) == list:
                        query = query.filter(getattr(self.model, key).in_(value))

        if ordering:
            ordering_param = ordering.ordering
            if ordering_param in UserOrderingAsc:
                query = query.order_by(getattr(self.model, ordering_param.name).asc())
            elif ordering_param in UserOrderingDesc:
                query = query.order_by(getattr(self.model, ordering_param.name).desc())
            elif ordering_param in UserOrderingRoleAsc:
                query = (
                    query.join(self.model.role)
                    .order_by(getattr(Role, ordering_param.name).asc())
                )
            elif ordering_param in UserOrderingRoleDesc:
                query = (
                    query.join(self.model.role)
                    .order_by(getattr(Role, ordering_param.name).desc())
                )
        else:
            query = query.order_by(self.model.created_at.desc())

        users = self.db.execute(query).scalars().all()

        return users


import os
import matplotlib.pyplot as plt
from wordcloud import WordCloud, STOPWORDS
from PIL import Image
import requests
import copy
import traceback
# import paddle
# paddle.enable_static
import jieba
# jieba.enable_paddle()

from nonebot import on_command, CommandSession, scheduler, get_bot, MessageSegment

from utils import deco, fileio

resource_path = 'resources/wordcloud'

enabled_group_list = [1014696092, 723979982, 709216479, 1087846478, 1056873681, 659667024]

@scheduler.scheduled_job(
    'cron',
    day_of_week='*',
    hour='23',
    minute='0',
    second='0'
)
# @scheduler.scheduled_job(
#     'interval',
#     minutes=5
# )
async def _():
    bot = get_bot()

    # ensure filepath
    os.system(f'mkdir -p {os.path.join(resource_path, "chat_history")}')
    os.system(f'mkdir -p {os.path.join(resource_path, "group_wordcloud")}')

    # 分词
    stopwords = set()
    t = requests.get('https://raw.githubusercontent.com/hoochanlon/cn_stopwords/main/baidu_stopwords.txt').text.split()
    # t = open(os.path.join(resource_path, 'stopwords.txt'), 'r').readlines()
    content = [line.strip() for line in t]
    stopwords.update(content)

    for group_id in enabled_group_list:
        file_path = os.path.join(resource_path, f'chat_history/{group_id}.txt')
        group_word_cloud = '\n草，这不是啥也没聊吗'
        if os.path.exists(file_path):
            text = await fileio.read_txt(file_path)
            if text.strip():
                try:
                    jbc = list(jieba.cut(text))
                    # jbc = list(jieba.cut(text, use_paddle=True))
                    stopwords_group = copy.deepcopy(stopwords)
                    stopwords_group.update(jbc)

                    wc = WordCloud(background_color="white",# 设置背景颜色
                        max_words=2000, # 词云显示的最大词数
                        height=400, # 图片高度
                        width=800, # 图片宽度
                        max_font_size=50, #最大字体
                        stopwords=stopwords_group, # 设置停用词
                        font_path=os.path.join(resource_path, 'msyh.ttc'), # 兼容中文字体，不然中文会显示乱码
                        )
                    # 生成词云
                    wc.generate(text)
                    # 生成的词云图像保存到本地
                    img_path = os.path.join(resource_path, f'group_wordcloud/{group_id}.png')
                    wc.to_file(img_path)
                    # 发送图片
                    img_path_send = f'file://{os.getcwd()}/{img_path}'
                    group_word_cloud = MessageSegment.image(img_path_send)
                except Exception as e:
                    msg = f'catch exception: generate wordcloud\ne: {e}\ntraceback:\n{traceback.print_exc()}'
                    await bot.send_group_msg(group_id=1014696092, message=msg)
            await fileio.clear_file(file_path)
        send_content = '[测试版]你群今日群聊词云已生成，请查收\n{}'.format(group_word_cloud)
        await bot.send_group_msg(group_id=group_id, message=send_content)

@on_command('gather_group_msg', patterns='.*', only_to_me=False)
@deco.only_these_group(enabled_group_list)
async def gather_group_msg(session: CommandSession):
    msg_text = session.current_arg_text + '\n'
    await fileio.addline(os.path.join(resource_path, f'chat_history/{session.ctx.get("group_id")}.txt'), msg_text)

if __name__ == '__main__':
    with open('test.txt', 'r') as f:
        text = f.read()

    # 分词
    stopwords = set()
    # t = requests.get('https://raw.githubusercontent.com/hoochanlon/cn_stopwords/main/baidu_stopwords.txt').text.split()
    t = open(os.path.join(resource_path, 'stopwords.txt'), 'r').readlines()
    print(t)
    content = [line.strip() for line in t]
    stopwords.update(content)
    jbc = list(jieba.cut(text, use_paddle=True))
    print(jbc)
    stopwords.update(jbc)

    wc = WordCloud(background_color="white",# 设置背景颜色
        max_words=2000, # 词云显示的最大词数
        height=400, # 图片高度
        width=800, # 图片宽度
        max_font_size=50, #最大字体
        stopwords=stopwords, # 设置停用词
        font_path=os.path.join(resource_path, 'msyh.ttc'), # 兼容中文字体，不然中文会显示乱码
        )

    # 生成词云
    wc.generate(text)

    # 生成的词云图像保存到本地
    wc.to_file("test.png")

    # 显示图像
    plt.imshow(wc, interpolation='bilinear')
    # interpolation='bilinear' 表示插值方法为双线性插值
    plt.axis("off")# 关掉图像的坐标
    plt.show()


'''
ComboBox
=======

Based on Spinner
'''

__all__ = ('ComboBox', 'ComboBoxOption')

from kivy.properties import ListProperty, ObjectProperty, BooleanProperty
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.lang import Builder

Builder.load_string('''
<ComboBoxOption>:
    size_hint_y: None
    height: 44

<ComboBox>:
    background_normal: 'atlas://data/images/defaulttheme/spinner'
    background_down: 'atlas://data/images/defaulttheme/spinner_pressed'
    on_key:
        if self.items: x, y = zip(*self.items); self.text = y[x.index(args[1])]
''')

class ComboBoxOption(Button):
    pass

class ComboBox(Button):
    items = ListProperty()
    key = ObjectProperty()

    option_cls = ObjectProperty(ComboBoxOption)

    dropdown_cls = ObjectProperty(DropDown)

    is_open = BooleanProperty(False)

    def __init__(self, **kwargs):
        self._dropdown = None
        super(ComboBox, self).__init__(**kwargs)
        self.items_dict = dict(self.items)
        self.bind(
            on_release=self._toggle_dropdown,
            dropdown_cls=self._build_dropdown,
            option_cls=self._build_dropdown,
            items=self._update_dropdown,
            key=self._update_text)
        self._build_dropdown()
        self._update_text()

    def _update_text(self, *largs):
        try:
            self.text = self.items_dict[self.key]
        except KeyError:
            pass

    def _build_dropdown(self, *largs):
        if self._dropdown:
            self._dropdown.unbind(on_select=self._on_dropdown_select)
            self._dropdown.dismiss()
            self._dropdown = None
        self._dropdown = self.dropdown_cls()
        self._dropdown.bind(on_select=self._on_dropdown_select)
        self._update_dropdown()

    def _update_dropdown(self, *largs):
        dp = self._dropdown
        cls = self.option_cls
        dp.clear_widgets()
        for key, value in self.items:
            item = cls(text=value)
            # extra attribute
            item.key = key
            item.bind(on_release=lambda option: dp.select(option.key))
            dp.add_widget(item)

    def _toggle_dropdown(self, *largs):
        self.is_open = not self.is_open

    def _on_dropdown_select(self, instance, data, *largs):
        self.key = data
        self.is_open = False

    def on_is_open(self, instance, value):
        if value:
            self._dropdown.open(self)
        else:
            self._dropdown.dismiss()


import typing

from alembic.config import Config as AlembicConfig
from alembic.command import upgrade

from configman import ConfigMan

from toolbelt.cli import Command, Argument

if typing.TYPE_CHECKING:
    from .config import Config

class MigratorConfig(ConfigMan):
    revision: str = "head"
    sql_only: bool = False

class Migrator(object):
    def __init__(self, config: 'Config'):
        self._alembic_config = AlembicConfig()
        self._alembic_config.set_main_option("script_location", "{{cookiecutter.project_name}}/internal/alembic")
        self._alembic_config.set_main_option("sqlalchemy.url", config.database)

        self._revision = config.migrator.revision
        self._sql_only = config.migrator.sql_only

    def run(self):
        upgrade(self._alembic_config, self._revision, self._sql_only)

migrator_command = Command(command_class=Migrator, args=[
    Argument("migrator.revision", ["revision"], "revision to upgrade to"),
    Argument("migrator.sql_only", ["--sql"],
             "instead of applying migration, spit out SQL commands.", action="store_true")
])


import os
import progressbar
from glob import glob
import pickle
import numpy as np

from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics

import cv2
import mahotas as mt
from skimage import feature
from numpy.lib import stride_tricks

from settings import image_dir, label_dir, model_dir, cache_dir
from settings import scaler_fn, model_fn
from settings import palette_bgr, palette_rgb
from settings import oversample, random_state
from settings import classes, class_sep
from settings import h_neigh, h_ind, lbp_radius, lbp_points
from settings import test_size

from tools import onehot2int, int2onehot, load_pickle, dump2pickle

def test_model(X, y, model):
    pred = model.predict(X)
    precision = metrics.precision_score(
        y, pred, average='weighted', labels=np.unique(pred))
    recall = metrics.recall_score(
        y, pred, average='weighted', labels=np.unique(pred))
    f1 = metrics.f1_score(y, pred, average='weighted', labels=np.unique(pred))
    accuracy = metrics.accuracy_score(y, pred)

    print('--------------------------------')
    print('[RESULTS] Accuracy: %.2f' % accuracy)
    print('[RESULTS] Precision: %.2f' % precision)
    print('[RESULTS] Recall: %.2f' % recall)
    print('[RESULTS] F1: %.2f' % f1)
    print('--------------------------------')
    return

def train_model(X, y):
    print('[INFO] Training MLP model.')
    model = MLPClassifier(solver='lbfgs', alpha=1e-5, warm_start=True,
                          hidden_layer_sizes=(30), learning_rate='adaptive', early_stopping=True, max_iter=200, random_state=random_state)
    model.fit(X, y)

    print('[INFO] Model training complete.')
    print('[INFO] Training Accuracy: %.2f' % model.score(X, y))
    return model

def calc_haralick(roi):
    feature_vec = []

    texture_features = mt.features.haralick(roi)
    mean_ht = texture_features.mean(axis=0)

    [feature_vec.append(i) for i in mean_ht[0:9]]
    return np.array(feature_vec)

def harlick_features(img, h_neigh):

    print('[INFO] Computing haralick features.')
    size = h_neigh
    shape = (img.shape[0] - size + 1, img.shape[1] - size + 1, size, size)
    strides = 2 * img.strides
    patches = stride_tricks.as_strided(img, shape=shape, strides=strides)
    patches = patches.reshape(-1, size, size)

    bar = progressbar.ProgressBar(maxval=img.size,
                                  widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])

    bar.start()

    h_features = []

    for i, p in enumerate(patches):
        bar.update(i+1)
        h_features.append(calc_haralick(p))

    return np.array(h_features)

def create_binary_pattern(img, p, r):

    print('[INFO] Computing local binary pattern features.')
    lbp = feature.local_binary_pattern(img, p, r)
    return (lbp-np.min(lbp))/(np.max(lbp)-np.min(lbp))

def create_features(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    feature_img = np.zeros((img.shape[0], img.shape[1], 4))
    feature_img[:, :, :3] = img

    hsv = np.zeros((img.shape[0], img.shape[1], 3))
    hsv[:, :, :3] = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    hsv = hsv[h_ind:-h_ind, h_ind:-h_ind]

    feature_img[:, :, 3] = create_binary_pattern(
        img_gray, lbp_points, lbp_radius)
    feature_img = feature_img[h_ind:-h_ind, h_ind:-h_ind]
    features = feature_img.reshape(
        feature_img.shape[0]*feature_img.shape[1], feature_img.shape[2])
    hsv = hsv.reshape(
        feature_img.shape[0]*feature_img.shape[1], 3)

    features = np.hstack((hsv, features))

    h_features = harlick_features(img_gray, h_neigh)

    features = np.hstack((features, h_features))

    return features

def create_dataset(image_dict, label_dict):
    print('[INFO] Creating training dataset on %d image(s).' %
          len(image_dict.keys()))

    X = []
    y = []

    for fn in image_dict.keys():
        img = image_dict[fn]
        label = label_dict[fn]

        cached_fn = os.path.join(cache_dir, fn.split(
            os.path.sep)[-1].split('.')[0]+".pkl")
        if os.path.isfile(cached_fn):
            features = load_pickle(cached_fn)
        else:
            features = create_features(img)
            dump2pickle(features, cached_fn)

        label = label[h_ind:-h_ind, h_ind:-h_ind]
        labels = label.reshape(label.shape[0]*label.shape[1], -1)
        X.append(features)
        y.append(labels)
    X = np.array(X)
    X = X.reshape(X.shape[0]*X.shape[1], -1)

    y = np.array(y)
    y = (y > 0) * 1
    y = y.astype(dtype=np.uint8)
    y = y.reshape(y.shape[0]*y.shape[1], -1)

    # delete ambigous samples
    indices = np.where(y.sum(axis=1) != 1)
    y = np.delete(y, indices, axis=0)
    X = np.delete(X, indices, axis=0)

    # unused
    def add_background_label(y):
        expanded = np.c_[y, np.zeros(y.shape[0])].astype(np.uint8)
        bg_label = np.zeros(len(classes)+1, dtype=np.uint8)
        bg_label[-1] = 1
        expanded[np.where(~expanded.any(axis=1))] = bg_label
        return expanded

    y_int = onehot2int(y)

    from collections import Counter
    print("Original dataset shape {}".format(Counter(y_int)))
    if oversample:
        from imblearn.over_sampling import RandomOverSampler
        ros = RandomOverSampler(random_state=random_state)
        X, y_int = ros.fit_resample(X, y_int)
        print("Resampled dataset shape {}".format(Counter(y_int)))
        y = int2onehot(y_int)

    scaler = MinMaxScaler()
    scaler.fit(X)
    X = scaler.transform(X)

    dump2pickle(scaler, os.path.join(model_dir, scaler_fn))

    return X, y

def read_data(image_dir, label_dir):

    print('[INFO] Reading image data.')

    filelist = glob(os.path.join(image_dir, '*.jpg'))
    image_dict = dict()
    label_dict = dict()

    for fn in filelist:
        image_dict[fn] = cv2.imread(fn, cv2.IMREAD_COLOR)
        label_fn = os.path.join(label_dir, fn.split(
            os.path.sep)[-1].split('.')[0]+".png")
        label_map = cv2.imread(label_fn, cv2.IMREAD_COLOR)
        label_layers = []
        if not os.path.isfile(label_fn):
            raise ValueError(
                "Label file {} does not exist".format(label_fn))
        for i in classes:
            indices = np.where(label_map == palette_bgr[i])[:2]
            ones = np.zeros((label_map.shape[0], label_map.shape[1]), np.uint8)
            ones[indices] = 1
            label_layers.append(ones)
        label_dict[fn] = np.stack([layer
                                   for layer in label_layers], axis=-1)
    return image_dict, label_dict

if __name__ == "__main__":
    cache_dir = os.path.join(cache_dir, "store")

    image_dict, label_dict = read_data(image_dir, label_dir)
    a = label_dict['data\\images\\pots_block_2_27.jpg']
    X, y = create_dataset(image_dict, label_dict)
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=test_size, random_state=random_state)
    print('[INFO] Feature vector size:', X_train.shape)
    model = train_model(X_train, y_train)
    test_model(X_test, y_test, model)
    dump2pickle(model, os.path.join(model_dir, model_fn))


from jit_code_generator import *
from collections import defaultdict

class AstVisitor:
    def __init__(self):
        #self.output = open(filename, 'w')
        self.code_generator = CodeGenerator()
        #list of dicts
        self.env = [defaultdict(lambda:None)]

    def enter_scope(self, env):
        self.env.append(env)

    def exit_scope(self):
        self.env.pop()

    def visit_fun(self, fun_node):
        if fun_node.subtype == "say":
            sentences = [param.accept(self) for param in fun_node.params]
            if len(sentences) == 1:
                return "print %s\n" % sentences[0]

            lst = self.code_generator.generate_list(sentences)
            prtstr = "'\\n'.join(%s)" % lst
            code = self.code_generator.generate_print(prtstr)
            #self.output.write(code + '\n')

        elif fun_node.subtype == "createNode":
            #self.output.write("Node()")
            code = "Node()"
        elif fun_node.subtype == "listen":
            code = "raw_input()"
        elif fun_node.subtype == "push":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "%s.push()\n" % params_str
        elif fun_node.subtype == "pull":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "pull(%s)\n" % params_str.replace('\n', '').replace('start', 'node')
        elif fun_node.subtype == "save":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "%s.save()\n" % params_str
        elif fun_node.subtype == "get":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "node_get(%s)\n" % params_str
        elif fun_node.subtype == "import":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "import(%s)\n" % params_str
        elif fun_node.subtype == "search":
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "search(%s)\n" % params_str
        else:
            visited_params = map(lambda node : node.accept(self), fun_node.params)
            params_str = ', '.join(visited_params)
            code = "%s(%s)\n" % (fun_node.subtype, ', '.join(visited_params))

        return code

    def visit_binop(self, binop_node):
        op = binop_node.op
        if (binop_node.right.type == "articleop"):
            lhs  = op = ""
        else:
            lhs = binop_node.left.accept(self).strip()

        rhs = binop_node.right.accept(self).strip()
        ls = lhs.split('.')
        if ls and ls[-1] == "body" and rhs.startswith("import("):
            return "%s.add_body(%s)\n" % (ls[0], rhs[7:-1])

        if binop_node.op == "=":
            self.env[-1][lhs] = rhs

        code = self.code_generator.generate_binaryOp(lhs, op, rhs)
        return code

    def visit_articleop(self, articleop_node):
        if not articleop_node: return

        lhs = articleop_node.left.accept(self).strip()
        rhs = articleop_node.right.accept(self).strip()
        #if articleop_node.op == "=":
        #    self.env[-1][lhs] = rhs

        code = self.code_generator.generate_articleOp(lhs, articleop_node.op, rhs, articleop_node.assign_to, articleop_node.list_of_things)

        return code

    def visit_str(self, str_node):
        return str_node.value

    def visit_list(self, list_node):
        return list_node.value

    def visit_num(self, str_node):
        return str(str_node)

    def visit_id(self, id_node):
        name = id_node.name
        current_env = self.env[-1]
        val = current_env[name]
        return name

    def visit_vardecl(self, decl_node):
        init_vals = defaultdict(lambda:None)
        init_vals['string'] =  ''
        init_vals['int'] = 0
        self.env[-1][decl_node.name] = None
        code = "%s = %s\n" % (decl_node.name, str(init_vals[decl_node.type]))
        return code

    def visit_forloop(self, for_node):
        itr = for_node.itr.accept(self)
        span = for_node.span.accept(self)
        body = map(lambda n : n.accept(self), for_node.body)
        code = self.code_generator.generate_forloop(itr, span, body)
        return code

    def visit_ifblock(self, if_node):
        ifc = if_node.if_clause.accept(self).strip()
        thc = map(lambda n : n.accept(self), if_node.then_clause)
        elc = map(lambda n : n.accept(self), if_node.else_clause)
        code = self.code_generator.generate_ifblock(ifc, thc, elc)
        return code

    def visit_astfundecl(self, fundecl_node):
        varlist = map(lambda n : n.accept(self).strip(), fundecl_node.varlist)
        fun_body = map(lambda n : n.accept(self), fundecl_node.stmtlist)
        code = self.code_generator.generate_fundecl(fundecl_node.name, varlist, fun_body)
        return code


"""
URL mappings for the user API.
"""
from django.urls import path

from modules.users import views

app_name = 'auth'

urlpatterns = [
    path('register/', views.CreateUserView.as_view(), name='register'),
    path('login/', views.CreateTokenView.as_view(), name='login'),
    path('logout/', views.LogoutUserView.as_view(), name='logout'),
    path('me/', views.ManageUserView.as_view(), name='me'),
]