import scrapy

class Dmoz(scrapy.Spider):
    name = "dmoz"
    # allowed_domain=["weibo.cn"]
    start_urls = ["http://www.liaoxuefeng.com"]

    def parse(self, response):
        print("开始执行parse方法")
        filename = response.body
        print(filename)

        with open('filename', 'w',encoding='utf-8') as f:
            f.write(str(response.body))


from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.uic import loadUi
import mysql.connector as mysql
import sys
from pyparsing import Word
import gui.ocr

class Notes(QFrame):
    def __init__(self):
        super().__init__()
        loadUi('gui\OCR_Notes.ui', self)
        self.setFixedSize(911, 436)
        self.con = self.createConnection()
        self.cursor = self.con.cursor()
        self.tablesize()
        self.show_notes()
        self.populateCombo()
        self.btnShow.clicked.connect(self.show_details)

    def show_notes(self):
        query = 'select note_id, content from notes'
        self.cursor.execute(query)
        self.dataset = self.cursor.fetchall()
        rowcount = len(self.dataset)
        self.table1.setRowCount(rowcount)
        rownum = 0
        for row in self.dataset:
            for column in range(len(row)):
                self.table1.setItem(rownum, column, QTableWidgetItem(str(row[column])))
            rownum = rownum + 1

    def show_details(self):
        self.note_id = self.cmb.currentText()
        query1 = 'select content from notes where note_id=%s'
        self.cursor.execute(query1, (int(self.note_id),))
        self.modelset = self.cursor.fetchone()
        self.txtShow.setText(self.modelset[0])

    def populateCombo(self):
        strsql = 'select note_id from notes'
        self.cursor.execute(strsql)
        self.dataset = self.cursor.fetchall()
        for data in self.dataset:
            self.cmb.addItem(str(data[0]))

    def createConnection(self):
        con = mysql.connect(host='localhost', database='ocr', user='root', password='')
        return con

    def showDialog(self,txt):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setWindowTitle('Message.')
        msg.setText(txt)
        msg.setStandardButtons(QMessageBox.Ok)
        msg.exec_()

    def tablesize(self):
        self.table1.setColumnWidth(0, 125)
        self.table1.setColumnWidth(1, 350)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    notes = Notes()
    notes.show()
    app.exec_()


# This is a scrapper module to get news from fake news and real news sites.
# Using BeautifulSoup as base library

import urllib3
from bs4 import BeautifulSoup

def getnpr():
    http = urllib3.PoolManager()
    quote_page = 'https://www.npr.org/tags/502124007/fake-news'
    r = http.request('GET', quote_page)
    # parse the html using beautiful soup and store in variable `soup`
    soup = BeautifulSoup(r.data, 'html.parser')
    # Take out the <div> of name and get its value
    news = soup.find_all('h2', attrs={'class': 'title'})
    news = news[0:10]
    text = []
    for link in news:
        r = http.request('GET', link.a.get('href'))
        soup = BeautifulSoup(r.data, 'html.parser')
        text.append(soup.find('div', attrs={'class': 'storytitle'}).text.strip() + ' ' +
        soup.find('div', attrs={'class': 'storytext'}).text.strip())
    return text

def getbbc():
    http = urllib3.PoolManager()
    quote_page = 'https://www.bbc.com/news/world'
    r = http.request('GET', quote_page)
    # parse the html using beautiful soup and store in variable `soup`
    soup = BeautifulSoup(r.data, 'html.parser')
    # Take out the <div> of name and get its value
    news = soup.find_all('article')
    news = news[0:10]
    text = []
    for link in news:
        new = link.header.div.h3.a.get('href')
        r = http.request('GET', 'https://www.bbc.com/'+new)
        soup = BeautifulSoup(r.data, 'html.parser')
        head = soup.find('h1', attrs={'class': 'story-body__h1'}).text.strip()
        body = soup.find('div', attrs={'class': 'story-body__inner'}).text.strip()
        text.append(head + ' ' +body)
    return text

# print(getbbc())


# -*- coding: utf-8 -*-

import re
import numpy as np
from datetime import datetime
from matplotlib import pyplot as plt

from .utils import rgb_dist, detect_consecutive_false, to_gray
from .utils import str_to_num_rank, num_to_str_rank
from .colors import BEIGE, GRAY, DGRAY, LGRAY, GREEN, BLACK
from .classifiers import LabelClassifier, CaptionJaClassifier, CaptionEnClassifier

class Graph:
    image = None
    def __init__(self, image):
        self.image = image

    def plot(self, show=True):
        if self.image is None: return
        plt.imshow(self.image)
        if show: plt.show()

    def get_num_grids(self):
        """
        Detect the number of gird lines
        """
        im = self.image
        if im is None or im.shape[0] < 1 or im.shape[1] < 1:
            return None

        thres_dist = 0.1
        thres_frac = 0.9
        mostly_gray = (rgb_dist(im, GRAY) < thres_dist)  | \
                      (rgb_dist(im, DGRAY) < thres_dist) | \
                      (rgb_dist(im, LGRAY) < thres_dist)

        frac = np.mean(mostly_gray, axis=1)
        gray_index = (frac > thres_frac).nonzero()[0]

        if len(gray_index) == 0: return 0
        return 1 + np.sum(np.diff(gray_index) > 1)

    def get_line_index(self):
        """
        Detect line position in the graph image

        Returns
          numpy array of the same length as the image's width
        """

        im = self.image
        if im is None or im.shape[0] < 1 or im.shape[1] < 1:
            return np.empty(0)

        # compute distance from green, black, gray and find the
        # cells that are closest to green
        dist_green = rgb_dist(im, GREEN)
        thres_dist = 0.35

        # change distance of cells for enough from green to 1
        # later, if colwise minimum is 1,
        # then the column is regarded as having no line
        dist_green[dist_green > thres_dist] = 1.0

        min_dist = np.min(dist_green, axis=0)
        has_line = np.where(min_dist < 1.0)[0]

        out = np.empty(im.shape[1])
        out[:] = np.nan
        for j in has_line:
            min_index = np.where(dist_green[:,j] == min_dist[j])[0]
            out[j] = np.mean(min_index)
            #out[j] = np.average(np.arange(im.shape[0]),\
            #                    weights=1.0-dist_green[:,j])

        return out

# this is shared by all instances of Yaxis
label_classifier = LabelClassifier()

class Yaxis:
    image = None
    nlabels = None

    def __init__(self, image):
        self.image = image
        self.classifier = label_classifier

    def plot(self, show=True):
        if self.image is None: return
        plt.imshow(self.image)
        if show: plt.show()

    def get_rank_range(self, positions):
        """
        Returns the min and max of y-axis labels

        Args
          positions: expected indices of labels.

        Returns
          tuple of strings such as (2k, 1d)
        """
        label_list = self.get_label_list(positions)
        ranks = ['' if l is None else self.classifier.predict(l) \
                 for l in label_list]
        #print(len(label_list))
        #print(ranks)

        # look for the max rank from the top
        max_rank = None
        i = 0
        while i < len(ranks):
            if ranks[i] == '':
                i += 1
                continue
            n = str_to_num_rank(ranks[i])
            if not np.isnan(n):
                max_rank = num_to_str_rank(n+i)
                break
            i += 1
        if max_rank is None: return ()

        # look for the min rank from the bottom
        min_rank = None
        i = 0
        while i < len(ranks):
            j = len(ranks)-i-1
            if ranks[j] == '':
                i += 1
                continue
            n = str_to_num_rank(ranks[j])
            if not np.isnan(n):
                min_rank = num_to_str_rank(n-i)
                break
            i += 1
        if min_rank is None: return ()

        return (min_rank, max_rank)

    def get_label_list(self, positions):
        """
        make Y-axis labal data

        Args
          positions: expected indices of labels.

        Returns
          list of (list of 2d-arrays) or None, where (i,j) element indicates
          the j-th letter of i-th label.
          (r, c) element of the 2d-array is the gray scale of cell (r,c)
        """
        image = self.image
        if image is None: return []
        if image.size == 0: return []

        thres_dist = 0.1
        thres_frac = 0.95

        def is_background(arr):
            dist = rgb_dist(arr, BEIGE)
            frac = np.mean(dist < thres_dist)
            return frac >= thres_frac

        # extract labels rows
        # start from position and expand the area up and down
        # until we hit background
        labels = []
        index_checked = [False] * image.shape[0]
        for p in positions:
            index_to_check = [p]
            i1 = image.shape[0]
            i2 = -1
            while len(index_to_check) > 0:
                i = index_to_check.pop()
                index_checked[i] = True

                flg = is_background(image[i])
                if not flg:
                    # new non-background is found so exand the area
                    i1 = min(i1, i)
                    i2 = max(i2, i)

                    if i-1 >= 0 and not index_checked[i-1]:
                        index_to_check.append(i-1)
                    if i+1 < image.shape[0] and not index_checked[i+1]:
                        index_to_check.append(i+1)
            if i1 <= i2:
                #print(i1, i2)
                labels.append(image[i1:(i2+1)])
            else:
                labels.append(None)

        # split labels into letters
        def split_to_letters(label):
            if label is None: return None
            dist = rgb_dist(label, BEIGE)
            frac = np.mean(dist < thres_dist, axis=0)
            is_background = (frac >= thres_frac)
            #start = np.where(np.logical_and(
            #    np.logical_not(is_background),
            #    np.append(True, is_background[0:-1])))[0]
            #end = np.where(np.logical_and(
            #    np.logical_not(is_background),
            #    np.append(is_background[1:], True)))[0] + 1
            start, end = detect_consecutive_false(is_background)
            return [label[:, a:b] for a,b in zip(start, end)]
        letters = [split_to_letters(label) for label in labels]

        # convert to gray scale
        for j in range(len(letters)):
            if letters[j] is None: continue
            for k in range(len(letters[j])):
                letters[j][k] = to_gray(letters[j][k], BEIGE, GRAY)

        return letters

    def extract_letters(self):
        """
        extract all sub images of letters

        Returns
          list of numpy arrays of shape (nrow, ncol)
          each element is the gray scale of the cell
        """
        image = self.image
        if image is None: return []
        if image.size == 0: return []

        thres_dist = 0.1
        thres_frac = 0.95

        dist = rgb_dist(image, BEIGE)
        is_beige = (dist < thres_dist)

        # identify rows of labels
        frac = np.mean(is_beige, axis=1)
        is_bg_row = (frac >= thres_frac)
        #row1 = np.where(np.logical_and(
        #    np.logical_not(is_bg_row),
        #    np.append(True, is_bg_row[0:-1])))[0]
        #row2 = np.where(np.logical_and(
        #    np.logical_not(is_bg_row),
        #        np.append(is_bg_row[1:], True)))[0] + 1
        row1, row2 = detect_consecutive_false(is_bg_row)

        def split_letters(i1, i2):
            frac = np.mean(is_beige[i1:i2], axis=0)
            is_bg_col = (frac >= thres_frac)
            #start = np.where(np.logical_and(
            #    np.logical_not(is_bg_col),
            #    np.append(True, is_bg_col[0:-1])))[0]
            #end = np.where(np.logical_and(
            #    np.logical_not(is_bg_col),
            #    np.append(is_bg_col[1:], True)))[0] + 1
            start, end = detect_consecutive_false(is_bg_col)
            return [image[i1:i2, a:b] for a,b in zip(start, end)]

        out = [split_letters(a,b) for a,b in zip(row1, row2)]
        # flatten
        out = sum(out, [])

        # convert to gray scale
        out = [to_gray(o, BEIGE, GRAY) for o in out]
        return out

# classifiers shared by all instances
caption_ja_classifier = CaptionJaClassifier()
caption_en_classifier = CaptionEnClassifier()

class Caption:
    image = None

    def __init__(self, image):
        self.image = image
        self.classifier_ja = caption_ja_classifier
        self.classifier_en = caption_en_classifier

    def plot(self, show=True):
        if self.image is None: return
        plt.imshow(self.image)
        if show: plt.show()

    def extract_letters(self):
        """
        extract all sub images of letters

        Returns
          list of numpy arrays of shape(nrow,ncol)
          each element is an image array.
          if asgray: each element is (nrow, ncol) shape
          otherwise: each element is (nrow, ncol, channel) shape
        """
        image = self.image
        if image is None: return []
        if image.size ==0: return []

        thres_dist = 0.3
        thres_frac = 1.0

        dist = rgb_dist(image, BEIGE)
        is_beige = (dist < thres_dist)

        # find rows that have non-background
        not_bg_row = (np.mean(is_beige, axis=1) < thres_frac)
        if not np.any(not_bg_row): return []  # all background
        # the first and last index of non-background
        index = not_bg_row.nonzero()[0]
        i1 = index[0]
        i2 = index[-1]

        # split into letters
        frac = np.mean(is_beige[i1:(i2+1)], axis=0)
        is_bg_col = (frac >= thres_frac)
        start, end = detect_consecutive_false(is_bg_col)

        out = [image[i1:(i2+1), a:b] for a,b in zip(start, end)]

        # to gray scale
        for i in range(len(out)):
            out[i] = to_gray(out[i], BEIGE, GRAY)

        return out

    def get_time_range(self):
        letter_array_list = self.extract_letters()

        # Try Japanese parser first
        title = self.classifier_ja.predict(letter_array_list)
        #print(title)
        r = re.findall(r'(\d{2}/\d{2}/\d{2})(\d{1,2}:\d{1,2}){0,1}', title)
        if len(r) >= 2:
            def to_datetime(s):
                if s[1] == '':
                    return datetime.strptime(s[0], '%y/%m/%d')
                else:
                    return datetime.strptime(s[0] + ' ' + s[1], '%y/%m/%d %H:%M')
            out = [to_datetime(s) for s in r]
            return tuple(out)

        # if Japanese parser does not work, try English parser
        title = self.classifier_en.predict(letter_array_list)
        #print(title)
        r = re.findall(r'([A-Z05][A-Za-z0-9]{2})(\d{1,2}).(\d{4})', title)
        if len(r) >= 2:
            def to_datetime(s):
                a,b,c = s
                #print(a, b, c)
                for key in self.classifier_en.conversions:
                    a = a.replace(key, self.classifier_en.conversions[key])
                #print(a, b, c)
                if not (a in ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \
                              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']):
                    return None
                return datetime.strptime(a + ' ' + b + ' ' + c, '%b %d %Y')
            out = [to_datetime(s) for s in r[0:2]]
            if out[0] is None or out[1] is None: return()
            return tuple(out)
        return ()


from rest_framework import serializers
from project.models import Project,FundApplyLog,\
    RefundApplyLog,InvoiceApplyLog,OperatorLog,ProjectInvestDataModel

class ProjectListSerializer(serializers.ModelSerializer):
    state_des = serializers.CharField(source='get_state_display', read_only=True)
    settleway_des = serializers.CharField(source='get_settleway_display', read_only=True)
    platformname = serializers.CharField(source='platform', read_only=True)
    profit = serializers.DecimalField(decimal_places=2,max_digits=10,read_only=True)
    topay_amount= serializers.DecimalField(decimal_places=2,max_digits=10,read_only=True)
    contact = serializers.CharField(source="contact.uname",read_only=True)
    audituser = serializers.CharField(source="audituser.uname",read_only=True)
    #apply_man = serializers.CharField(source="apply_man.uname",read_only=True)

    class Meta:
        model = Project
        fields = '__all__'
        read_only_fields = ('id','settleway_des','consume','state_des', 'time','profit','topay_amount')

class ProjectSerializer(serializers.ModelSerializer):
    #contact = serializers.CharField(source="contact.uname",read_only=True)

    class Meta:
        model = Project
        fields = '__all__'

class  FundApplyLogSerializer(serializers.ModelSerializer):
    #project = serializers.CharField(source="project.id",read_only=True)
    class Meta:
        model = FundApplyLog
        fields = '__all__'

class  FundApplyLogListSerializer(serializers.ModelSerializer):
    project = serializers.CharField(source="project.id",read_only=True)
    projectname = serializers.CharField(source="project.name",read_only=True)
    audit_man = serializers.CharField(source="audit_man.uname",read_only=True)
    apply_man = serializers.CharField(source="apply_man.uname",read_only=True)

    class Meta:
        model = FundApplyLog
        fields = '__all__'

class  RefundApplyLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = RefundApplyLog
        fields = '__all__'

class  RefundApplyLogListSerializer(serializers.ModelSerializer):
    project = serializers.CharField(source="project.id", read_only=True)
    projectname = serializers.CharField(source="project.name",read_only=True)
    audit_man = serializers.CharField(source="audit_man.uname",read_only=True)
    apply_man = serializers.CharField(source="apply_man.uname",read_only=True)

    class Meta:
        model = RefundApplyLog
        fields = '__all__'

class  InvoiceApplyLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = InvoiceApplyLog
        fields = '__all__'

class  InvoiceApplyLogListSerializer(serializers.ModelSerializer):
    project = serializers.CharField(source="project.id", read_only=True)
    projectname = serializers.CharField(source="project.name",read_only=True)
    audit_man = serializers.CharField(source="audit_man.uname",read_only=True)
    apply_man = serializers.CharField(source="apply_man.uname",read_only=True)

    class Meta:
        model = InvoiceApplyLog
        fields = '__all__'

class  OperatorLogSerializer(serializers.ModelSerializer):
    oman = serializers.CharField(source='oman.uname',read_only=True)
    otime = serializers.DateTimeField(format="%Y-%m-%d",read_only=True)

    class Meta:
        model = OperatorLog
        fields = '__all__'

class  ProjectInvestDataSerializer(serializers.ModelSerializer):
    projectname = serializers.CharField(source="project.name",read_only=True)
    audit_time = serializers.DateTimeField(format="%Y-%m-%d",read_only=True)
    audit_man = serializers.CharField(source="audit_man.uname",read_only=True)

    class Meta:
        model = ProjectInvestDataModel
        fields = '__all__'


import pandas as pd
import numpy as np
import streamlit as st
from scipy.spatial import distance

# Función para cargar el dataset
@st.cache_resource
def load_data():
    url = "https://raw.githubusercontent.com/pansolans/Similar/main/Colotto_api_septok_conlogos.xlsx"
    return pd.read_excel(url)
    st.cache_resource

def calculate_mahalanobis_distance(Datos_Ejercicio_4, name):
    regularization_factor = 1e-4
    cov_matrix = Datos_Ejercicio_4.drop(columns="Name").cov()
    regularized_cov_matrix = cov_matrix + np.eye(cov_matrix.shape[0]) * regularization_factor
    inv_cov = np.linalg.inv(regularized_cov_matrix)

    player_data_df = Datos_Ejercicio_4[Datos_Ejercicio_4["Name"] == name].drop(columns="Name")
    player_data = player_data_df.values[0]
    sim = Datos_Ejercicio_4.apply(lambda row: distance.mahalanobis(row.drop("Name").values, player_data, inv_cov), axis=1)
    return sim

def export_to_excel(df, file_name):
    df.to_excel(file_name, index=False)

def main():
    df = load_data()

    st.sidebar.header("Pampa Fútbol Analytics")
    st.sidebar.header("Filtros")

    cols_to_select = list(range(23,166))
    selected_vars = st.sidebar.multiselect("Seleccionar variables:", options=df.columns[cols_to_select].tolist())
    competition_ids = st.sidebar.multiselect("Seleccionar competitionId:", options=df["competitionId"].unique().tolist())
    season_ids = st.sidebar.multiselect("Seleccionar season:", options=df["season"].unique().tolist())
    pos_principales = st.sidebar.multiselect("Seleccionar Pos_principal:", options=df["Pos_principal"].unique().tolist())
    min_minutes, max_minutes = st.sidebar.slider("Seleccionar rango de minutesOnField:", int(df["minutesOnField"].min()), int(df["minutesOnField"].max()), (int(df["minutesOnField"].min()), int(df["minutesOnField"].max())))

    if not selected_vars or not competition_ids or not season_ids or not pos_principales:
        st.warning("Por favor, selecciona opciones en todos los filtros para continuar.")
        return

    filtered_df = df[
        (df["competitionId"].isin(competition_ids)) &
        (df["season"].isin(season_ids)) &
        (df["Pos_principal"].isin(pos_principales)) &
        (df["minutesOnField"] >= min_minutes) &
        (df["minutesOnField"] <= max_minutes)
    ]

    name = st.sidebar.selectbox("Seleccionar Jugador:", options=[None] + filtered_df["Jugador"].unique().tolist())
    if not name:
        st.warning("Por favor, selecciona un jugador para continuar.")
        return

    if st.sidebar.button("Búsqueda"):
        Datos_Ejercicio_4 = filtered_df[selected_vars]
        Datos_Ejercicio_4["Name"] = filtered_df["Jugador"]
        Datos_Ejercicio_4.fillna(0, inplace=True)

        sim = calculate_mahalanobis_distance(Datos_Ejercicio_4, name)

        sim = pd.DataFrame(sim, columns=["similitud"])
        sims95 = sim["similitud"].quantile(0.95)
        sim["similitud_2"] = 100 - (sim["similitud"] / sims95) * 100
        sim["Name"] = Datos_Ejercicio_4["Name"].values
        sim = sim[["Name", "similitud", "similitud_2"]]
        sim.columns = ["Name", "Dist_Euc_OP_Norm_mah", "Sim_Euc_OP_Norm_mah"]

        sim_sorted = sim.sort_values(by="Sim_Euc_OP_Norm_mah", ascending=False)
        sim_filtered = sim_sorted[["Name", "Sim_Euc_OP_Norm_mah"]]
        merged_df = pd.merge(sim_filtered, filtered_df[["Jugador", "Edad", "urlImagen.y", "equipoActual_nombre", "urlImagen.x", "competitionId", "minutesOnField"]], left_on="Name", right_on="Jugador", how="left")
        st.session_state.merged_df = merged_df
        st.session_state.displayed_df = None

    st.header("Jugadores Similares")

    min_age, max_age = st.slider("Minutos jugados:", int(df["minutesOnField"].min()), int(df["minutesOnField"].max()), (int(df["minutesOnField"].min()), int(df["minutesOnField"].max())))
    post_search_competition_ids = st.multiselect("Seleccionar competitionId para filtrar la tabla:", options=st.session_state.merged_df["competitionId"].unique().tolist())

    if st.session_state.merged_df is not None:
        filtered_by_age = st.session_state.merged_df[(st.session_state.merged_df["minutesOnField"] >= min_age) & (st.session_state.merged_df["minutesOnField"] <= max_age)]

        if post_search_competition_ids:
            filtered_by_age = filtered_by_age[filtered_by_age["competitionId"].isin(post_search_competition_ids)]

        st.session_state.displayed_df = filtered_by_age.head(20)  # Almacena solo los primeros 20 registros

        for index, row in st.session_state.displayed_df.iterrows():
            col1, col2, col3 = st.columns([1,3,1])
            if isinstance(row["urlImagen.y"], str):
                col1.image(row["urlImagen.y"], width=50)
            if isinstance(row["urlImagen.x"], str):
                col2.image(row["urlImagen.x"], caption=row["Name"], width=100)
            col3.markdown(f"Edad: {int(row['Edad'])}", unsafe_allow_html=True)
            col3.markdown(f"Equipo: {row['equipoActual_nombre']}", unsafe_allow_html=True)
            col3.markdown(f"Similitud: {row['Sim_Euc_OP_Norm_mah']:.2f}", unsafe_allow_html=True)
            col3.markdown(f"Minutos: {row['minutesOnField']}", unsafe_allow_html=True)

    # Botón para exportar a Excel
    if st.session_state.displayed_df is not None:
        if st.button('Exportar a Excel'):
            file_name = 'jugadores_similares.xlsx'  # Define el nombre del archivo aquí
            export_to_excel(st.session_state.displayed_df, file_name)
            st.success(f'Archivo exportado como {file_name}')

if __name__ == "__main__":
    main()


'''
write simple python code to scrape ads from website bazos.cz parse them and store its data in pandas dataframe
Here is a simple Python code to scrape ads from the website bazos.cz, parse the data, and store it in a Pandas DataFrame:
'''

import pandas as pd
import requests
from bs4 import BeautifulSoup

#url = 'https://www.bazos.cz/search.php?hledat=mazda+mx5&rubriky=www&hlokalita=&humkreis=25&cenaod=&cenado=&Submit=Hledat&kitx=ano'
#res = requests.get(url)
#soup = BeautifulSoup(res.text, 'html.parser')

read_from_web = 0

if (read_from_web):
    page = requests.get('https://www.bazos.cz/search.php?hledat=mazda+mx5&hlokalita=&humkreis=25&cenaod=10000&cenado=&order=1')
    # Create a BeautifulSoup object
    soup = BeautifulSoup(page.text, 'html.parser')
    # get the repo list
else:
    with open("ad.html") as fp:
        soup = BeautifulSoup(fp, 'html.parser')

ads = soup.find_all('div', {'class': 'inzeraty inzeratyflex'})

data = []
for ad in ads:
    title = ad.find('h2', {'class': 'nadpis'}).text
    price = ad.find('div', {'class': 'inzeratycena'}).text
    location = ad.find('div', {'class': 'inzeratylok'}).text
    data.append([title, price, location])
    #print(type(ad))
    #print(ad.text)
    #break

df = pd.DataFrame(data, columns=['Title', 'Price', 'Location', 'Text'])
#df = pd.DataFrame(data, columns=['Title', 'Price', 'Location'])

print(df)


import datetime
import uuid
import threading
from flet import (
    AlertDialog,
    AppBar,
    Column,
    Container,
    ElevatedButton,
    Icon,
    Page,
    PopupMenuButton,
    PopupMenuItem,
    UserControl,
    View,
    colors,
    Row,
    Text,
    TextField,
    TextButton,
    ButtonStyle,
    icons,
    padding,
    theme,
    IconButton,
    RoundedRectangleBorder
)

from add_patient_view import AddPatientView
from patients_list_view import PatientsListView
from data_simulator import Simulator
from users import Patient, PatientList

class PatientsView(UserControl):
    def __init__(self, app, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.app = app
        self.patients_list = PatientList()
        self.patients_list_view = PatientsListView(self)
        self.data_simulator=Simulator(self)
        self.build()
        threading.Thread(target=self.data_simulator.simulate).start()

    def build(self):
        self.layout =Container(
             Column([
                Row(
                    [
                     Text(value="Waiting Patients", style="headlineMedium",text_align="center"),
                     TextButton(
                                "Add new Patient",
                                icon=icons.ADD,
                                on_click=self.add_patient_dialog,
                                style=ButtonStyle(
                                    bgcolor=colors.BLUE_400,
                                    shape={"": RoundedRectangleBorder(radius=3)},
                                ),

                            )

                    ],
                ),
                Row(
                    [
                        TextField(
                            hint_text="Search all Patients",
                            autofocus=False,
                            content_padding=padding.only(left=10),
                            width=400,
                            height=40,
                            text_size=12,
                            border_color=colors.BLACK26,
                            focused_border_color=colors.BLUE_ACCENT,
                            suffix_icon=icons.SEARCH,

                        )
                    ]
                ),
                Row([Container(self.patients_list_view,height=600,width=800)]),
            ],
            expand=True,
        ),
        padding=padding.only(top=15, left=15),
        )

        return self.layout

    def add_patient_dialog(self, e):
        self.page.dialog = AddPatientView(self)
        self.page.dialog.open=True
        self.page.update()

    def add_patient(self, e):
        self.page.dialog.open=False
        self.page.update()
        name = self.page.dialog.content.controls[0].value
        age = self.page.dialog.content.controls[1].value
        address = self.page.dialog.content.controls[2].value
        location = self.page.dialog.content.controls[3].value
        complaint = self.page.dialog.content.controls[4].value
        Ctas = self.page.dialog.content.controls[5].value
        current_time = datetime.datetime.now()
        p=Patient(str(uuid.uuid4()),name,age,address,location,current_time,complaint,Ctas)
        self.patients_list.add_patient(p)
        self.patients_list_view.refresh()

    def refresh(self):
        self.patients_list_view.refresh()

    def cancel_add_patient(self, e):
        self.page.dialog.open=False
        self.page.update()


#!/usr/bin/env python
#
# Title: observer pattern implementation for App Engine
# Author: Domenico Pontari
# Email: fairsayan@gmail.com
# Website: http://it.linkedin.com/in/pontari/
#
# Rif about observer design pattern: http://it.wikipedia.org/wiki/Observer_pattern
# Basic idea: http://stackoverflow.com/questions/1904351/python-observer-pattern-examples-tips?answertab=votes#tab-top
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import Called

class Caller():
  def resume(self, event):
    logging.info ('Resumed caller...')

  def __init__(self):
    called = Called.Called()
    called.subscribe('resume', __name__, self)
    logging.info ('Running called object method...')
    called.run()


# -*- coding: utf-8 -*-
# from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from django.conf import settings

import hashlib

# TPL
from lxml import etree

from receive_message import BasicReceive, TextMsg, ImageMsg
from response_message import BasicResponse, Text
from how_old import handle_how_old
from tuling_robot import handle_tuling_robot

# Receive message type from wechat user.
REC_MESSAGE_TYPE_TEXT = u'text'
REC_MESSAGE_TYPE_IMAGE = u'image'
REC_MESSAGE_TYPE_VOICE = u'voice'
REC_MESSAGE_TYPE_VIDEO = u'video'
REC_MESSAGE_TYPE_SHORTVIDEO = u'shortvideo'
REC_MESSAGE_TYPE_LOCATION = u'location'
REC_MESSAGE_TYPE_LINK = u'link'
REC_MESSAGE_TYPE_EVENT = u'event'

# Event type from wechat user.
EVENT_SUBSCRIBE = u'subscribe'
EVENT_UNSUBSCRIBE = u'unsubscribe'
EVENT_SCAN = u'SCAN'
EVENT_LOCATION = u'LOCATION'
EVENT_CLICK = u'CLICK'
EVENT_VIEW = u'VIEW'

# Response message types to wechat user.
RESP_MESSAGE_TYPE_TEXT = u'text'
RESP_MESSAGE_TYPE_IMAGE = u'image'
RESP_MESSAGE_TYPE_VOICE = u'voice'
RESP_MESSAGE_TYPE_VIDEO = u'video'
RESP_MESSAGE_TYPE_MUSIC = u'music'
RESP_MESSAGE_TYPE_NEWS = u'news'
MESSAGE_TYPE = [u'text', u'image', u'voice', u'video', u'music', u'news']

# 订阅号或服务号的token
TOKEN = settings.WECHAT_TOKEN

@csrf_exempt
def wechat_varify(request):
    """Basic function used to conmunicate with wechat.

    GET means wechat server make connection with django server.
    POST means wechat user send message to wechat server and transfer to django server,
    And django server response message back to wechat server and transfer to wechat user.
    """
    if request.method == "GET":
        # Wechat server sent GET request to the URL to verify.
        return HttpResponse(WechatRequest.get_request(request), content_type="text/plain")
    elif request.method == "POST":
        # Wechat user POST the message to the URL with XML format.
        return HttpResponse(WechatRequest.post_request(request), content_type="application/xml")
    else:
        return None

class WechatRequest(object):

    """Implement the basic function for GET and POST.

    request is django.http.HttpRequest object.
    response is django.http.HttpResponse object.
    """

    @staticmethod
    def get_request(request):
        u"""Wechat server use http GET to make connect with django server.

        将token、timestamp、nonce三个参数进行字典序排序
        将三个参数字符串拼接成一个字符串进行sha1加密
        开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        """
        signature = request.GET.get("signature", None)
        timestamp = request.GET.get("timestamp", None)
        nonce = request.GET.get("nonce", None)
        echostr = request.GET.get("echostr", None)
        token = TOKEN

        tmp_list = [token, timestamp, nonce]
        tmp_list.sort()

        # Wechat office method
        sha1 = hashlib.sha1()
        map(sha1.update, tmp_list)
        hashcode = sha1.hexdigest()

        # My own method
        # tmp_str = '%s%s%s' % tuple(tmp_list)
        # hashcode = hashlib.sha1(tmp_str).hexdigest()

        if hashcode == signature:
            return echostr
        else:
            return None

    @staticmethod
    def post_request(request):
        """When get message or event from wechat user(wechat server), django server response something.

        This is just reply the message and event.
        Not django server use http to post message to wechat server(wechat user).
        """
        request_map = MessageUtil.parse_xml(request)
        receive_basic_object = BasicReceive(request_map)
        MsgType = receive_basic_object.MsgType
        ToUserName = receive_basic_object.ToUserName
        FromUserName = receive_basic_object.FromUserName

        # Response to different request message type.
        if MsgType == REC_MESSAGE_TYPE_TEXT:
            receive_text_object = TextMsg(request_map)
            receive_content = receive_text_object.Content
            response_content = handle_tuling_robot(receive_content, FromUserName)
            # If return nothing from tuling robot.
            if not response_content:
                response_content = u"只识别人话哦，别说鸟语!"
            response_text_object = Text(FromUserName, ToUserName, response_content)
            return response_text_object.response()
        elif MsgType == REC_MESSAGE_TYPE_IMAGE:
            receive_image_object = ImageMsg(request_map)
            PicUrl = receive_image_object.PicUrl
            response_content = handle_how_old(PicUrl)
            # If return nothing from how-old.net.
            if not response_content:
                response_content = u"只识别男女哦，不要发人妖!"
            response_image_object = Text(FromUserName, ToUserName, response_content)
            return response_image_object.response()
        elif MsgType == REC_MESSAGE_TYPE_VOICE:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_VIDEO:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_SHORTVIDEO:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_LOCATION:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_LINK:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_EVENT:
            return BasicResponse().response()
            Event = request_map.get(u'Event')
            if Event == EVENT_SUBSCRIBE:
                return BasicResponse().response()
            elif Event == EVENT_UNSUBSCRIBE:
                return BasicResponse().response()
            elif Event == EVENT_SCAN:
                return BasicResponse().response()
            elif Event == EVENT_LOCATION:
                return BasicResponse().response()
            elif Event == EVENT_CLICK:
                return BasicResponse().response()
            elif Event == EVENT_VIEW:
                return BasicResponse().response()
            else:
                return BasicResponse().response()
        else:
            return BasicResponse().response()

class MessageUtil(object):

    """Tools to transfer xml and string format messages.

    Wechat server POST the xml format message to django server,
    And django server need to POST xml format message to wechat server too.
    Define the message type, and get the message with xml format and parser it.
    """

    @staticmethod
    def parse_xml(request):
        """Parse receive message with xml format from wechat server."""
        str_xml = request.body.decode(u'utf-8')
        req_xml = etree.fromstring(str_xml)
        dict_xml = {}
        for node0 in req_xml:
            dict_tmp0 = {}
            for node1 in node0.getchildren():
                dict_tmp0[node1.tag] = node1.text
            if any(dict_tmp0):
                dict_xml[node0.tag] = dict_tmp0
            else:
                dict_xml[node0.tag] = node0.text
        return dict_xml


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

import csv
from io import StringIO
from string import Template
import requests
import json
from xml.etree import ElementTree

# get Brazilian states

filein = 'unidades-federativas.csv'

states = {}

with open(filein) as f:
    reader = csv.DictReader(f)
    for row in reader:
        states[row['Sigla']] = {
            'nome': row['Nome'],
            'ativo': False
            }

# get list of data catalogs

csv_url = 'https://github.com/dadosgovbr/catalogos-dados-brasil/raw/master/dados/catalogos.csv'

catalogs = []

r = requests.get(csv_url)

if r.status_code != 200:
    raise IOError('Cannot download data catalogs table from Github repository.')

reader = csv.DictReader(StringIO(r.text))

for row in reader:
    catalogs.append(row)

# check which states have catalogs

for catalog in catalogs:
    if catalog['UF'] in list(states.keys()):
        states[catalog['UF']]['ativo'] = True

# generate area activation script

filein = 'activate_areas.js'

with open(filein) as f:
    activate_script_template = Template(f.read())

habilitados_dict = {}

for state in list(states.keys()):
    if states[state]['ativo']:
        habilitados_dict[states[state]['nome']] = '1'

activate_areas_script = activate_script_template.substitute({'habilitados_dict': json.dumps(habilitados_dict)})

# generate map colors

filein = 'mapa.svg'

ns = {'svg': 'http://www.w3.org/2000/svg'}
ElementTree.register_namespace('', 'http://www.w3.org/2000/svg')

tree = ElementTree.parse(filein)

for a in tree.findall('svg:g[@id="Estados"]/svg:a', ns):
    state = a.get('data-target')[-2:]
    path = a.find('svg:path', ns)
    if states[state]['ativo']:
        xml_class = path.get('class').replace(' inactive','')
        xml_class += ' active'
        path.set('class', xml_class)

map_svg = ElementTree.tostring(tree.getroot()).decode()

# generate modals

filein = 'modal_template.html'

with open(filein) as f:
    modal_template = Template(f.read())

filein = 'catalog_template.html'

with open(filein) as f:
    catalog_template = Template(f.read())

modal_section = ''

for state in sorted(states.keys()):
    if states[state]['ativo']:
        modal_html = ''
        catalog_list = ''
        municipal_catalogs = {}

        for catalog in catalogs:
            if catalog['UF'] == state:
                catalog_type = ''
                if catalog['Solução'] == 'CKAN':
                    catalog_type = ''
                # add state catalogs
                if not catalog['Município']:
                    catalog_list += catalog_template.substitute({
                        'catalog_title': catalog['Título'],
                        'catalog_url': catalog['URL'],
                        'catalog_type': catalog_type,
                        })
                else:
                    catalogs_in_this_municipality = municipal_catalogs.setdefault(catalog['Município'], [])
                    catalogs_in_this_municipality.append(catalog)

        # add municipal catalogs
        for municipality, municipal_catalogs in list(municipal_catalogs.items()):
            municipality_html = '
{}
'.format(municipality)
            municipality_html += "
"
            for catalog in municipal_catalogs:
                catalog_type = ''
                if catalog['Solução'] == 'CKAN':
                    catalog_type = ''
                municipality_html += catalog_template.substitute({
                    'catalog_title': catalog['Título'],
                    'catalog_url': catalog['URL'],
                    'catalog_type': catalog_type,
                    })
            municipality_html += "
"
            catalog_list += municipality_html

        modal_html = modal_template.substitute({
            'state_abbr': state,
            'state_name': states[state]['nome'],
            'catalog_list': catalog_list
            })
        modal_section += modal_html

# national catalogs

catalog_list = ''
for catalog in catalogs:
    if not catalog['UF']:
        catalog_type = ''
        if catalog['Solução'] == 'CKAN':
            catalog_type = ''
        catalog_list += catalog_template.substitute({
            'catalog_title': catalog['Título'],
            'catalog_url': catalog['URL'],
            'catalog_type': catalog_type,
            })
modal_section += modal_template.substitute({
            'state_abbr': 'BR',
            'state_name': 'Nacionais',
            'catalog_list': catalog_list
            })

# generate page

filein = 'template-pagina.html'

with open(filein) as f:
    page_template = Template(f.read())

page_html = page_template.substitute({
    'activate_areas_script': activate_areas_script,
    'map_svg': map_svg,
    'modal_section': modal_section
    })

fileout = 'outras-iniciativas.html'

with open(fileout, 'w') as f:
    f.write(page_html)


import sys
import collections
import math

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

R, C, T = map(int, sys.stdin.readline().split(" "))

arr = []

# 배열값 입력하는 부분
for j in range(R):
    nums = list(map(int, sys.stdin.readline().split(" ")))
    arr.append(nums)

second = 0 # 확산시간 정의

# 개념 : 방향을 싱히좌우로 변할 수 있도록 만들고, i + 1 번째 값을 temp에 저장하고, i + 1 에 i 값을 넣기
# 오 : 1 왼 : 2 상 : 3 하 : 4

#  반시계방향으로 도는함수
def reverseTimeDir(dot):
    count = 0 # 도는 횟수
    global newArr, dust
    y, x = dot
    width = C # 가로길이
    height = y + 1 # 세로길이
    transY, transX = dot
    if(transX == C - 1):
        transY -= 1
        dir = 3
    else:
        transX += 1
        dir = 1
    temp = newArr[transY][transX]
    while(True):
        if(count == 2 * width + 2 * (height - 2) - 2):
            dust -= temp
            break

        # 모서리 부분 처리
        if(transX == C - 1 and transY == y): # 오른쪽에서 위쪽으로 방향바꾸는 구간
            dir = 3
        elif(transX == C - 1 and transY == 0): # 위쪽에서 왼쪽으로 방향을 바꾸는 구간
            dir = 2
        elif(transX == 0 and transY == 0): # 왼쪽에서 아래로 방향을 바꾸는 구간
            dir = 4
        elif(transX == 0 and transY == y): # 아래에서 오른쪽으로 방향을 바꾸는 구간
            dir = 1

        # 구간별 arr값 변경 진행
        if(dir == 1): # 오른쪽
            temp, newArr[transY][transX + 1] = newArr[transY][transX + 1], temp
            transX += 1
            if(count == 0):
                newArr[transY][transX - 1] = 0
        elif(dir == 2): # 왼쪽
            temp, newArr[transY][transX - 1] = newArr[transY][transX - 1], temp
            transX -= 1
            if(count == 0):
                newArr[transY][transX + 1] = 0
        elif(dir == 3): # 상
            temp, newArr[transY - 1][transX] = newArr[transY - 1][transX], temp
            transY -= 1
            if(count == 0):
                newArr[transY + 1][transX] = 0
        elif(dir == 4): # 하
            temp, newArr[transY + 1][transX] = newArr[transY + 1][transX], temp
            transY += 1
            if(count == 0):
                newArr[transY - 1][transX] = 0

        # 실행횟수 카운트
        count += 1

# 시계방향으로 도는 함수
def timeDir(dot):
    count = 0 # 도는 횟수
    global newArr, dust
    y, x = dot
    width = C # 가로길이
    height = R - y # 세로길이
    transY, transX = dot
    if(transX == R - 1):
        transY += 1
        dir = 4
    else:
        transX += 1
        dir = 1
    temp = newArr[transY][transX]
    while(True):
        if(count == 2 * width + 2 * (height - 2) - 2):
            dust -= temp
            break

        # 모서리 부분 처리
        if(transX == C - 1 and transY == y): # 오른쪽에서 아래로 방향바꾸는 구간
            dir = 4
        elif(transX == C - 1 and transY == R - 1): # 아래에서 왼쪽으로 방향바꾸는 구간
            dir = 2
        elif(transX == 0 and transY == R - 1): # 왼쪽에서 위로 방향바꾸는 구간
            dir = 3
        elif(transX == 0 and transY == y): # 위에서 오른쪽으로 방향 바꾸는 구간
            dir = 1

        # 구간별 arr값 변경 진행
        if(dir == 1): # 오른쪽
            temp, newArr[transY][transX + 1] = newArr[transY][transX + 1], temp
            transX += 1
            if(count == 0):
                newArr[transY][transX - 1] = 0
        elif(dir == 2): # 왼쪽
            temp, newArr[transY][transX - 1] = newArr[transY][transX - 1], temp
            transX -= 1
            if(count == 0):
                newArr[transY][transX + 1] = 0
        elif(dir == 3): # 상
            temp, newArr[transY - 1][transX] = newArr[transY - 1][transX], temp
            transY -= 1
            if(count == 0):
                newArr[transY + 1][transX] = 0
        elif(dir == 4): # 하
            temp, newArr[transY + 1][transX] = newArr[transY + 1][transX], temp
            transY += 1
            if(count == 0):
                newArr[transY - 1][transX] = 0

        # 실행횟수 카운트
        count += 1

def BFS(dots):
    global newArr
    q = collections.deque(dots)
    while q:
        count = 0
        y, x, dust = q.popleft()
        for i in range(4):
            newX = x + dx[i]
            newY = y + dy[i]
            if(newX >= 0 and newX < C and newY >= 0 and newY < R and arr[newY][newX] != -1):
                newArr[newY][newX] += dust // 5
                count += 1
        newArr[y][x] = dust - (dust // 5 * count) + newArr[y][x]
    for s in airDot:
        y, x = s[0], s[1]
        newArr[y][x] = -1

airDot = [] # 콩기청정기의 위치

dust = 0 # 미세먼지의 양

# 첫 먼지양 체크하기 (시간복잡도 때문에 처음 한번만 실행하고, 이후로는 먼지가 정화되는 수를 체크하여 빼는 형식으로 계산할 예정)
for s in arr:
    for k in s:
        if(k > 0):
            dust += k

while(second < T):
    if(second == 0):
        dots = [] # 미세먼지가 들어있는 좌표의 모음
        for j in range(R):
            for i in range(C):
                if(arr[j][i] == -1):
                    airDot.append((j,i))
                # 배열의 값이 -1인경우는 공기청정기, 0인경우는 미세먼지가 없는 경우이기에
                elif(arr[j][i] > 0):
                    dots.append((j, i, arr[j][i]))
    else:
        dots = [] # 미세먼지가 들어있는 좌표의 모음
        for j in range(R):
            for i in range(C):
                # 배열의 값이 -1인경우는 공기청정기, 0인경우는 미세먼지가 없는 경우이기에
                if(arr[j][i] > 0):
                    dots.append((j, i, arr[j][i]))

    newArr = []
    # 새로운 배열 생성 0으로 초기화된
    for s in arr:
        nums = []
        for i in range(C):
            nums.append(0)
        newArr.append(nums)

    BFS(dots)

    # 공기청정기 작동 실행
    reverseTimeDir(airDot[0])
    timeDir(airDot[1])
    second += 1

    # 바뀐 배열값을 원래배열에 저장
    for i in range(R):
        for j in range(C):
            arr[i][j] = newArr[i][j]

print(dust)

백준/Gold/17144. 미세먼지 안녕！/미세먼지 안녕！.py


# ensure to activate an environment that has detectron2 installed
import copy
import json
import math
import os
import torch
from collections import defaultdict
from tqdm import tqdm
import cv2
from sklearn.metrics import precision_recall_curve
from detectron2 import model_zoo
from detectron2.config import get_cfg
from detectron2.data import DatasetCatalog, MetadataCatalog
from detectron2.modeling import build_model
from detectron2.structures.boxes import BoxMode
from detectron2.checkpoint.detection_checkpoint import DetectionCheckpointer
from detectron2.engine import DefaultPredictor

from .json_utils import NumpyEncoder
from .stars_config import getEvalCfg

import time
import matplotlib.pyplot as plt
import numpy as np

class ClassWisePRCurve:
    """Accumulator Class for classwise PR Curve data
    """

    def __init__(self, classes_list):
        self.classes_list = classes_list
        self.pr_data = {}
        for c in self.classes_list:
            self.pr_data[c] = {"y_gt": [], "y_conf": []}
        plt.ion()
        min_x = 0
        max_x = 1
        self.figure, self.ax = plt.subplots()
        (self.lines,) = self.ax.plot([], [], ".", markersize=1)
        self.ax.set_autoscaley_on(True)
        self.ax.set_xlim(min_x, max_x)
        self.ax.set_xlabel("Recall")
        self.ax.set_ylabel("Precision")
        self.ax.grid()

        # self.annot = None
        # if(self.annot is not None):
        #     self.annot.remove()

        self.annot = self.ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))

    def addRawData(self, classname, y_gt, y_conf):
        """Accumulator for PR curve
        This data is the class wise results for each class formatted as a binary classifier

        Arguments:
            classname {str} -- Class name
            y_gt {list} -- list of the True prediction
            y_conf {list} -- list of the corresponding confidences for each prediction
        """
        self.pr_data[classname]["y_gt"] += y_gt
        self.pr_data[classname]["y_conf"] += y_conf

    def getPRCurveForClass(self, classname):
        """Get the PR Curve for a particular class

        Arguments:
            classname {str} -- Class name

        Returns:
            (3-tuple) -- array of precisions, recalls, and the threshold steps
        """
        # print(self.pr_data[classname]["y_gt"], self.pr_data[classname]["y_conf"])

        if(len(self.pr_data[classname]["y_gt"])>0):
            precision, recall, thresholds = precision_recall_curve(
                self.pr_data[classname]["y_gt"], self.pr_data[classname]["y_conf"]
            )
        else:
            precision, recall, thresholds = [], [], []
        return precision, recall, thresholds

    def getPRCurves(self):
        """Get PR Curves for all classes

        Returns:
            {dict} -- Dictional containg the precisions, recalls and threshold steps for each class
        """
        res = {}
        for c in self.classes_list:
            p, r, t = self.getPRCurveForClass(c)
            res[c] = {"precisions": p, "recalls": r, "threshold_steps": t}
        return res

    def updateAnnot(self, ind):
        th = round(100 * np.mean(np.take(self.data['threshold_steps'],ind['ind'])),2)
        x,y = self.lines.get_data()
        self.annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
        text = "Threshold: {}".format(th)
        self.annot.set_text(text)
        self.annot.get_bbox_patch().set_alpha(0.4)

    def hover(self, event):
        vis = self.annot.get_visible()
        if event.inaxes == self.ax:
            cont, ind = self.lines.contains(event)
            if cont:
                self.updateAnnot(ind)
                self.annot.set_visible(True)
                self.figure.canvas.draw_idle()
            else:
                if vis:
                    self.annot.set_visible(False)
                    self.figure.canvas.draw_idle()

    def plotCurve(self, data):
        xdata = data["recalls"]
        ydata = data["precisions"]
        self.lines.set_xdata(xdata)
        self.lines.set_ydata(ydata)
        self.ax.relim()
        self.ax.autoscale_view()
        self.figure.canvas.draw()

    def plotPRCurveForClass(self, classname, visualize=True):
        """Plot PR Curve for class

        Arguments:
            classname {str} -- Class name
            visualize {bool} -- True: View plot in pop-up
                                False: Save plot as image
        """
        p, r, t = self.getPRCurveForClass(classname)
        self.data = {"precisions": p, "recalls": r, "threshold_steps": t}

        self.annot.set_visible(False)
        if visualize:
            self.plotCurve(self.data)
            self.figure.canvas.mpl_connect("motion_notify_event", self.hover)
            # time.sleep(0.5)
            self.figure.canvas.flush_events()
        else:
            self.plotCurve(self.data)
            self.figure.canvas.flush_events()
            plt.savefig(f"PR_Curve_{classname}.png")

class ClassWiseStats:
    """Accumulator class for Precision and Recall Stats(at a single value of confidence)
    """

    def __init__(self, classes_list):
        self.classes_list = classes_list
        self.class_wise_scores = {
            classname: {"tp": 0, "fp": 0, "fn": 0} for classname in classes_list
        }

    def addStats(self, classname, tp, fp, fn):
        """Accumulate the counts of stats relevant for P,R Calculation

        Arguments:
            classname {str} -- name of the class
            tp {int} -- True Positive Count
            fp {int} -- False Positive Count
            fn {int} -- False Negative Count
        """
        self.class_wise_scores[classname]["tp"] += tp
        self.class_wise_scores[classname]["fp"] += fp
        self.class_wise_scores[classname]["fn"] += fn

    def getPrecision(self, classname):
        """Calculate Precision for the given class
            Precision = TP/(TP+FP)

        Arguments:
            classname {str} -- class name(must be present in classes list)

        Returns:
            precision -- the precision of the class
        """
        tp = self.class_wise_scores[classname]["tp"]
        fp = self.class_wise_scores[classname]["fp"]
        if (tp + fp) != 0:
            precision = tp / (tp + fp)
        else:
            precision = math.nan
        return precision

    def getRecall(self, classname):
        """Calculate Precision for the given class
            Recall = TP/(TP+FN)

        Arguments:
            classname {str} -- class name(must be present in classes list)

        Returns:
            recall -- the recall of the class
        """
        tp = self.class_wise_scores[classname]["tp"]
        fn = self.class_wise_scores[classname]["fn"]
        if (tp + fn) != 0:
            recall = tp / (tp + fn)
        else:
            recall = math.nan
        return recall

    def getAllStats(self):
        """Return the Precision and Recall for all classes as a dictionary
            Returned dictionary has classnames as keys and another dict as the value
            the second level dictionary has the values in the keys - `Precision` and `Recall`

        Returns:
            class_wise_pr{dict} -- Dictionary with class wise pr
        """
        class_wise_pr = {}
        for c in self.classes_list:
            class_wise_pr[c] = {
                "Precision": self.getPrecision(c),
                "Recall": self.getRecall(c),
            }
        return class_wise_pr

class StarsEvaluator:
    """Custom Evaluator for Object Detection models
    Written for Team S.T.A.R.S - CMU MRSD Capstone.
    `github/t27`
    """

    def __init__(
        self,
        model,
        classes_list,
        train_json=None,
        val_json=None,
        batch_size=8,
        confidence_thres=0.7,
        iou_thres=0.5,
        model_input_format="BGR",
        progress_bar=True,
        iterative_evaluation=False
    ):
        if not iterative_evaluation:
            self.train_dataset = self.get_data_dicts(train_json)
            self.test_dataset = self.get_data_dicts(val_json)
        else:
            self.train_dataset = None
            self.test_dataset = None
        self.model = model
        self.classes_list = classes_list
        self.batch_size = batch_size
        self.class_wise_stats = ClassWiseStats(self.classes_list)
        self.pr_curve_generator = ClassWisePRCurve(self.classes_list)
        self.confidence_thres = confidence_thres
        self.iou_thres = iou_thres
        self.model_input_format = model_input_format
        self.progress_bar = progress_bar

    def getStatsSummary(self):
        return (
            self.class_wise_stats.getAllStats(),
            self.pr_curve_generator.getPRCurves(),
        )

    def plotPRCurveForClass(self, classname):
        self.pr_curve_generator.plotPRCurveForClass(classname)

    def evaluateAndGetTestNumbers(self):
        return self.evaluateDataset(self.test_dataset)

    def getTrainNumbers(self):
        return self.evaluateDataset(self.train_dataset)

    def evaluateDatasetIterative(self, dataset):
        for ob in dataset:
            image_path = ob["file_name"]
            annotations = ob["annotations"]

            cv_image = cv2.imread(image_path)
            # our model is currently trained using the opencv representation(default detectron)
            if self.model_input_format == "RGB":
                cv_image = cv_image[:, :, ::-1]

            image = torch.as_tensor(cv_image.astype("float32").transpose(2, 0, 1))
            gt_boxes = []
            gt_classes = []
            for anno in annotations:
                gt_boxes.append(anno["bbox"])
                gt_classes.append(self.classes_list[anno["category_id"]])

            # This function evaluates an image adds the relevant stats to the Stats and PRCurve objects
            det_boxes, det_scores, det_classes = self.evaluateSingleImage(
                image, gt_boxes, gt_classes
            )
            yield det_boxes, det_scores, det_classes, gt_boxes, gt_classes, cv_image

        # return (
        #     self.class_wise_stats.getAllStats(),
        #     self.pr_curve_generator.getPRCurves(),
        # )

    def evaluateDataset(self, dataset):
        if self.progress_bar:
            dataset_it = tqdm(dataset)
        else:
            dataset_it = dataset
        for ob in dataset_it:
            image_path = ob["file_name"]
            annotations = ob["annotations"]

            image = cv2.imread(image_path)
            # our model is currently trained using the opencv representation(default detectron)
            if self.model_input_format == "RGB":
                image = image[:, :, ::-1]

            image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1))
            gt_boxes = []
            gt_classes = []
            for anno in annotations:
                gt_boxes.append(anno["bbox"])
                gt_classes.append(self.classes_list[anno["category_id"]])

            # This function evaluates an image adds the relevant stats to the Stats and PRCurve objects
            self.evaluateSingleImage(image, gt_boxes, gt_classes)

        return (
            self.class_wise_stats.getAllStats(),
            self.pr_curve_generator.getPRCurves(),
        )

        # TODO: add batch processing of the image

    def evaluateSingleImage(self, image, gt_boxes, gt_classes):
        """Evaluate a single image and get the numbers against GT

        Arguments:
            image {Tensor} -- torch Tensor of the image
            gt_boxes {list} -- List of GT boxes
            gt_classes {list} -- List of classes that correspond to the gt_boxes
        """

        # for each image, make a separate
        # read image
        # compare annotation
        det_boxes, det_scores, det_classes = self.getDetections(image)
        # print(det_classes)
        class_wise_preds = defaultdict(list)
        class_wise_gt = defaultdict(list)
        for idx, classnum in enumerate(det_classes):
            classname = self.classes_list[classnum[0]]
            class_wise_preds[classname].append((det_boxes[idx], det_scores[idx][0]))

        for idx, classval in enumerate(gt_classes):
            class_wise_gt[classval].append(gt_boxes[idx])

        for c in self.classes_list:
            tp, fp, fn, pr_curve_data = self.getConfusionMatrixForClass(
                class_wise_gt[c], class_wise_preds[c]
            )
            self.class_wise_stats.addStats(c, tp, fp, fn)
            self.pr_curve_generator.addRawData(
                c, pr_curve_data["y_gt"], pr_curve_data["y_conf"]
            )
        return det_boxes, det_scores, det_classes

    def getConfusionMatrixForClass(self, gt, preds):

        """Calculate True Positives, False Positives and False Negatives
        This method doesn't consider class, so ensure the class wise filtering
        is done before. Only pass GT and Preds of the same class to this method

        Arguments:
            gt {list} -- Array of GT boxes
            preds {list of 2-tuples} -- Array of predicted boxes and their confidence

        Returns:
            [3-tuple] -- TruePositiveCount,FalsePositiveCount,FalseNegativeCount
        """

        # TODO: ensure the preds are NMS'ed so that we dont have overlapping predictions of the same class
        gt_boxes = copy.deepcopy(gt)

        tp, fp = ([], [])

        y_gt = []
        y_confs = []
        # for representing this as a binary classification problem(for PR Curves),
        # tp - pred = 1, gt=1
        # fp - pred = 1, gt=0
        # fn - pred = 0, gt=1

        for pred_box, conf in preds:
            # find the GT box with the highest IOU, remove that box
            # need a minimum of this iou to be considered useful
            max_iou = self.iou_thres
            max_iou_idx = None
            for idx, gt_box in enumerate(gt_boxes):
                iou = self.getIOU(pred_box, gt_box)
                if iou > max_iou:
                    max_iou = iou
                    max_iou_idx = idx
            if max_iou_idx is not None:
                del gt_boxes[max_iou_idx]
                # since we found a succesful match, this is a true positive
                if conf > self.confidence_thres:
                    tp.append(pred_box)
                # for PR Curve
                y_gt.append(1)
                y_confs.append(conf)
            else:
                if conf > self.confidence_thres:
                    fp.append(pred_box)
                y_gt.append(0)
                y_confs.append(conf)

        for z in gt_boxes:
            y_gt.append(1)
            y_confs.append(0)  # zero confidence

        pr_curve_data = {"y_gt": y_gt, "y_conf": y_confs}

        tp_count = len(tp)
        # number of predictions that didn't match any gt box ar false positives
        fp_count = len(fp)

        # number of gt boxes that didnt match a pred box are false negatives
        fn_count = len(gt_boxes)

        return tp_count, fp_count, fn_count, pr_curve_data

    def getIOU(self, box1, box2):
        """Calculate Intersection over Union

        Arguments:
            box1 {list} -- list of [xmin ymin xmax ymax]
            box2 {list} -- list of [xmin ymin xmax ymax]
        """
        # Intersection
        i_xmin = max(box1[0], box2[0])
        i_ymin = max(box1[1], box2[1])
        i_xmax = min(box1[2], box2[2])
        i_ymax = min(box1[3], box2[3])
        if i_xmax > i_xmin and i_ymax > i_ymin:
            intersection = (i_xmax - i_xmin) * (i_ymax - i_ymin)
        else:
            intersection = 0
            return 0

        def boxarea(box):
            return (box[2] - box[0]) * (box[3] - box[1])

        union = boxarea(box1) + boxarea(box2) - intersection

        return intersection / union

    def getDetections(self, image):
        with torch.no_grad():
            c, h, w = image.shape
            inp = [{"image": image, "height": h, "width": w}]
            out = self.model(inp)[0]
            det_boxes = out["instances"].pred_boxes.tensor.to("cpu").numpy()
            det_scores = out["instances"].scores.to("cpu").unsqueeze(1).numpy()
            det_classes = out["instances"].pred_classes.to("cpu").unsqueeze(1).numpy()
            return det_boxes, det_scores, det_classes

    def get_data_dicts(self, json_file):
        data = json.load(open(json_file))

        for im in data:
            anno = im["annotations"]
            for an in anno:
                an["bbox_mode"] = BoxMode(an["bbox_mode"])
        return data

def prepareEvaluator(
    confidence_thres=0.7, iou_thres=0.5, chkpts_file="outputmodel_final.pth",iterative_evaluation=False
):
    classes_dict = {0: "vehicle", 1: "bike", 2: "pedestrian"}
    # # create cfg
    cfg = getEvalCfg()

    # pred = DefaultPredictor(cfg)

    model = build_model(cfg)  # building custom model, doesnt load chkpts automatically
    model.eval()
    DetectionCheckpointer(model).load(chkpts_file)

    if iterative_evaluation:
        evaluator = StarsEvaluator(
            model,
            list(classes_dict.values()),
            iou_thres=iou_thres,
            confidence_thres=confidence_thres,
            iterative_evaluation=True
        )
    else:
        evaluator = StarsEvaluator(
            model,
            list(classes_dict.values()),
            "stars_carla_train.json",
            "stars_carla_val.json",
            iou_thres=iou_thres,
            confidence_thres=confidence_thres,
        )

    return evaluator

def main():

    evaluator = prepareEvaluator(chkpts_file="final_training/output/model_final.pth")
    class_wise_results, pr_curves = evaluator.evaluateAndGetTestNumbers()
    json.dump(
        class_wise_results,
        open("class_wise_results.json", "w"),
        indent=2,
        cls=NumpyEncoder,
    )
    json.dump(
        pr_curves, open("pr_curves_raw_data.json", "w"), indent=2, cls=NumpyEncoder
    )
    ## Plot PR Curve

if __name__ == "__main__":
    main()

# Spec

# ---- for each image -------
# get gt boxes, and predicted boxes
#       put the gt boxes and predicted boxes in to class wise buckets
# for each class, conside confidence threshold as filter to calculate Positives
# use IOU threshold to identify true and false positives(decrement GT for every matched box), unmatched gt boxes are False negatives


from flask import Flask, render_template, request, url_for, redirect, flash
import tmdb_client
import datetime

app = Flask(__name__)
app.secret_key = b'2MSjdNsi7n@!N@#@$!@#sd'

@app.route("/")
def homepage():
    movie_lists = ["now_playing", "top_rated", "popular", "upcoming"]
    selected_list = request.args.get("list_type", "popular")
    if selected_list not in movie_lists:
        movies = tmdb_client.get_movies(8, list_name="popular")
        return render_template("homepage.html", movies=movies, selected_list="", movie_lists=movie_lists)
    else:
        movies = tmdb_client.get_movies(8, list_name=selected_list)
    return render_template("homepage.html", movies=movies, selected_list=selected_list, movie_lists=movie_lists)

@app.context_processor
def utility_processor():
    def tmdb_image_url(path, size):
        return tmdb_client.get_poster_url(path, size)
    return {"tmdb_image_url": tmdb_image_url}

@app.route("/movie/<movie_id>")
def movie_details(movie_id):
    details = tmdb_client.get_single_movie(movie_id)
    people = tmdb_client.get_single_movie_cast(movie_id)[:12]
    image_url = tmdb_client.get_poster_url(tmdb_client.get_single_image(movie_id), "w780")
    return render_template("movie_details.html", movie=details, people=people, image=image_url)

@app.route("/search")
def search():
    search_query = request.args.get("q", "")
    if search_query:
        movies = tmdb_client.search_movie(search_query=search_query)
    else:
        movies = []
    return render_template("search.html", movies=movies, search_query=search_query)

@app.route("/airing")
def airing():
    today = datetime.date.today()
    movies = tmdb_client.airing_today()
    return render_template("airing.html", movies=movies, today=today)

FAVORITES = set()

@app.route("/favorites/add", methods=["POST"])
def add_to_favorites():
    data = request.form
    movie_id = data.get("movie_id")
    title = data.get("movie_title")
    if movie_id and title:
        FAVORITES.add(movie_id)
    flash(f"{title} added to favourites")
    return redirect(url_for("homepage"))

@app.route("/favorites")
def favorites():
    movies = []
    if FAVORITES:
        for item in FAVORITES:
            result = tmdb_client.get_single_movie(item)
            movies.append(result)

    return render_template("favorites.html", movies=movies)

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


import json

from app.config import db, app

class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    chatId = db.Column(db.BigInteger, nullable=False)
    sub_status = db.Column(db.Boolean, default=False)
    username = db.Column(db.String(64), default="N/A")
    quiz_current = db.Column(db.Integer, default=0)
    gpt_context = db.Column(db.JSON)

    def __repr__(self):
        return '<Account %r>' % self.chatId

    def __init__(self, chatId: int, username: str):
        with app.app_context():
            if User.query.filter_by(chatId = chatId).first():
                print("false")
            else:
                 self.chatId = chatId
                 self.username = username
                 db.session.add(self)
                 db.session.commit()

def theEconomistSub(chatId: int, key:int):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        if key == 1:
            user.sub_status = True
            db.session.commit()
        else:
            user.sub_status = False
            db.session.commit()

def quizCompleteCounter(chatId):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        user.quiz_current+=1
        db.session.commit()

def createUser(chatId, username):
    with app.app_context():
        if User.query.filter_by(chatId=chatId).first():
            pass
        else:
            User(chatId=chatId, username=username)

def getUsername(chatId: int):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
    return user.username

def getUser(chatId: int):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
    return user

def getSubStatus(chatId):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
    return user.sub_status

def zeroingQuiz(chatId):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        user.quiz_current = 0
        db.session.commit()

def addContext(chatId, data):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        data = json.dumps(data)
        user.gpt_context = data
        db.session.commit()

def clearContext(chatId):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        user.gpt_context = None
        db.session.commit()

def getContext(chatId):
    with app.app_context():
        user = User.query.filter_by(chatId=chatId).first()
        if user.gpt_context != None:
            text = json.loads(user.gpt_context)
        else:
            text = []
        return text

# data = []
# data.append({"role": "user", "content": "{}".format("test")})
# data.append({"role": "assistant", "content": "{}".format("test")})
#
# # addContext(479516545, data)
#
# print(getContext(479516545))
# clearContext(479516545)
# with app.app_context():
#     user = User.query.filter_by(chatId=479516545).first()
#     user.economist_issue = '2023#12'
#     db.session.commit()

# def fetchAllUsers():
#     with app.app_context():
#         return User.query.filter(User.test == "asd").filter(User.chatId == 12).all()

#updateUser(chatId=10, test="asd")
# c = User(chatId=3, test="asd")
# with app.app_context():
#     db.session.commit()

# with app.app_context():
#     User.query.filter(User.chatId ==3).delete()
#     db.session.commit()

# with app.app_context():
# #     b = User.query.filter_by(chatId=13).first()
# #     b.updateUser(test="sad")
# #     db.session.commit()
#
# print(fetchAllUsers())


import risar
import math
import random
from PyQt5.QtWidgets import QMessageBox

class Ball:
    def __init__(self, color):
        self.x, self.y = risar.nakljucne_koordinate()
        self.speed_x = random.randrange(-5, 5)
        self.speed_y = math.sqrt((5 * 5) - self.speed_x * self.speed_x)
        self.color = color
        self.width = 10
        self.krog = risar.krog(self.x, self.y, self.width, self.color, 2)
        self.exploded = False
        self.time = 4
        self.dead = False

    def set_pos(self, x, y):
        self.x = x
        self.y = y
        self.krog.setPos(x, y)

    def set_width(self, width):
        self.width = width
        self.krog.setRect(-width, -width, width * 2, width * 2)

    def set_color(self, r, g, b):
        self.krog.setBorder(risar.barva(r, g, b))

    def explode(self, exploading):
        if not self.exploded:
            self.exploded = True
            self.set_width(30)
            c = self.krog.pen().color().lighter()
            c.setAlpha(192)
            self.krog.setBrush(c)
            exploading.append(self)

    def update(self, time, exploading, dead):
        if self.dead:
            return

        if self.exploded:
            self.time -= time
            if self.time < 0:
                self.krog.hide()
                self.dead = True
                dead[0] += 1
                exploading.remove(self)
        else:
            self.x += self.speed_x
            self.y += self.speed_y

            if self.x - self.width < 0:
                self.speed_x *= -1
                self.x = self.width
            if self.x + self.width > risar.maxX-1:
                self.speed_x *= -1
                self.x = risar.maxX-1 - self.width
            if self.y - self.width < 0:
                self.speed_y *= -1
                self.y = self.width
            if self.y + self.width > risar.maxY-1:
                self.speed_y *= -1
                self.y = risar.maxY-1 - self.width

            self.set_pos(self.x, self.y)

    def collide(self, ball):
        if self.dead or ball.dead:
            return False

        d_x = self.x - ball.x
        d_y = self.y - ball.y
        d = math.sqrt(pow(d_x, 2) + pow(d_y, 2))
        if d < self.width + ball.width:
            return True
        else:
            return False

tick = 0.02

exploding = []
zoge = []
for i in range(30):
    zoge.append(Ball(risar.nakljucna_barva()))

cursor = Ball(risar.barva(255, 255, 255))
cursor.set_width(30)
stopped = False

running = True
dead = [0]
while running:
    for zoga in zoge:
        zoga.update(tick, exploding, dead)

    if risar.klik:
        stopped = True
        cursor.explode(exploding)
        risar.klik = False

    if stopped:
        cursor.update(tick, exploding, dead)
        if len(exploding) > 0:
            for e in exploding:
                for zoga in zoge:
                    if zoga.collide(e):
                        zoga.explode(exploding)
        else:
            QMessageBox.information(None, "Konec", "Uničenih " + str(dead[0]) + " od 30")
            running = False
            break
    else:
        mouse_pos = risar.miska
        cursor.set_pos(mouse_pos[0], mouse_pos[1])

    risar.obnovi()
    risar.cakaj(tick)


from flask import Blueprint, render_template, redirect, request, url_for, flash , Flask , Response , session, flash, send_file
from app import app, bcrypt, mysql
from app.forms import *
from PIL import Image
from uuid import uuid4
import os
from app.utils import *
basedir = os.getcwd()

endpoint = Blueprint("product", __name__)

@endpoint.route('/product')
@is_admin
def product():
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product')
    products = cursor.fetchall()
    return render_template('admin/product/product.html', products=products)

@endpoint.route('/addproduct', methods=['GET', 'POST'])
@is_admin
def addproduct():
    form = ProductForm(request.form)
    if request.method == 'POST' and form.validate():
        cursor = mysql.connection.cursor()
        cursor.execute('SELECT * FROM product WHERE product_name = %s', (form.productname.data,))
        product = cursor.fetchone()
        if product is None:
            product_id = str(uuid4())[:8]
            cursor.execute('INSERT INTO product VALUES (%s, %s, %s, %s, %s, %s)', (product_id, form.productname.data, form.productdesc.data, form.productprice.data, form.productstock.data, 'Active',))
            cursor.connection.commit()
            img = Image.open(request.files["productimage"])
            img.load()
            img.resize((1200, 600))
            img.convert("RGB")
            img.save(f"{basedir}/app/static/media/product_img/{product_id}.png")
            return redirect(url_for('product.product'))
        else:
            flash('Product Exists', category='error')
            return redirect(request.referrer)
    return render_template('admin/product/product_form.html', form=form)

@endpoint.route('/productdetails/<id>')
@is_admin
def productdetails(id):
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product WHERE product_id = %s', (id,))
    product = cursor.fetchone()
    return render_template('admin/product/productdetails.html', product=product)

# @endpoint.route('/updateproduct/<id>', methods=['GET', 'POST'])
# def updateproduct(id):
#     form = ProductForm(request.form)
#     if request.method == 'POST' and form.validate():
#         cursor = mysql.connection.cursor()
#         cursor.execute('UPDATE product SET WHERE')

@endpoint.route('/deleteproduct/<id>', methods=['POST'])
@is_admin
def deleteproduct(id):
    cursor = mysql.connection.cursor()
    cursor.execute('DELETE FROM product WHERE product_id = %s', (id,))
    cursor.connection.commit()
    return redirect(request.referrer)

@endpoint.route('/status_product/<id>', methods=['POST'])
@is_admin
def product_status(id):
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product WHERE product_id = %s', (id,))
    product = cursor.fetchone()
    if product['product_status'] == 'Active':
        cursor.execute('UPDATE product SET product_status = %s WHERE product_id = %s', ('Inactive', id,))
    else:
        cursor.execute('UPDATE product SET product_status = %s WHERE product_id = %s', ('Active', id,))
    cursor.connection.commit()
    return redirect(request.referrer)

@endpoint.route('/deleteimg/')
def deleteimg():
    filepath = request.args.get('filepath', type=str, default="")
    if filepath != '':
        try:
            if os.path.isfile('app/'+filepath):
                os.remove('app/'+filepath)
            else:
                print('error deleting')
        except:
            print('some error idk')
    else:
        print('error')
    return redirect(request.referrer)


import os

from flask import Flask

def create_app():
    app = Flask(__name__)
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'EventCal.sqlite'),
    )

    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    from . import db, auth, calendarview

    db.init_app(app)
    app.register_blueprint(auth.bp)
    app.register_blueprint(calendarview.bp)
    app.add_url_rule('/', endpoint='index')
    return app

app = create_app()

@app.before_first_request
def on_startup():
    from . import db
    # db.update_db()


#coding:utf-8
from PIL import Image

import overfeat
import tensorflow as tf
from tensorflow.python.platform import test
from common import read_data
import numpy as np
from tensorflow.python import debug as tfdbg
import os

num_classes = 5749
train_batch_size = 50
train_height, train_width = 231, 231
train_channel = 3

# 测试overfeat
class OverFeatTest(test.TestCase):
 def testTrainEvalWithReuse(self):
     train_batch_size = 2
     eval_batch_size = 1
     train_height, train_width = 231, 231
     eval_height, eval_width = 281, 281
     num_classes = 1000
     with self.test_session():
         # 训练阶段
         train_inputs = tf.Variable(tf.random_uniform(
             [train_batch_size, train_height, train_width, 3]))
         logits, _ = overfeat.overfeat(train_inputs)
         self.assertListEqual(logits.get_shape().as_list(),
                              [train_batch_size, num_classes])
         tf.get_variable_scope().reuse_variables()
         # 评估阶段
         eval_inputs = tf.random_uniform(
             (eval_batch_size, eval_height, eval_width, 3))
         logits, _ = overfeat.overfeat(
             eval_inputs, is_training=False, spatial_squeeze=False)
         self.assertListEqual(logits.get_shape().as_list(),
                              [eval_batch_size, 2, 2, num_classes])
         # 评估获得正确率
         logits = tf.reduce_mean(logits, [1, 2])
         predictions = tf.argmax(logits, 1)
         self.assertEquals(predictions.get_shape().as_list(), [eval_batch_size])

def get_inputs(n = None):
    """
    获取输入
    :return:
    """
    labels, filenames = read_data.get_lfw_paths(n) #[index, path]
    # 文件名的queue，已经包含了enqueue_many操作，已经定义了一个queue runner处理enqueue操作
    filenames_queue = tf.train.string_input_producer(filenames, shuffle=False)
    labels_queue = tf.train.input_producer(labels, shuffle=False)
    # filename = filenames_queue.dequeue()
    # 从queue中dequeue一个文件名，并读取数据
    reader = tf.WholeFileReader()
    filename, image = reader.read(filenames_queue)
    label = labels_queue.dequeue()
    # 解码数据
    #  tf.image.decode_jpeg对图片进行解码，如果用decode_raw结果是不一样的
    image = tf.image.decode_jpeg(image)
    image = tf.cast(image, tf.float32)
    image = tf.reshape(image, [250, 250, train_channel])
    image = tf.random_crop(image, [train_height, train_width, train_channel])
    label = tf.cast(label, tf.int32)
    # 创建一个shuffle queue，并添加enqueue以及dequeue操作
    images, filenames, labels = tf.train.shuffle_batch(
        [image, filename, label],
        batch_size=train_batch_size,
        num_threads=4,
        capacity=2 + 3 * train_batch_size,
        min_after_dequeue=0
    )
    return images, filenames, labels
    #return filename, image, label

def train_LFW():
    # 读取数据
    images, filenames, labels0 = get_inputs()

    images = tf.nn.batch_normalization(images, 0, 1, 0, 1, 10e-8)
    coord = tf.train.Coordinator()
    with tf.Session() as sess:
        #sess = tfdbg.LocalCLIDebugWrapperSession(sess)
        # 前向传播
        logits, fc8 = overfeat.overfeat(images, num_classes)
        # 计算loss函数
        cross_entropy = overfeat.loss(logits, labels0, train_batch_size, num_classes)
        # 反向求导，梯度下降
        train_step = tf.train.AdamOptimizer(0.05).minimize(cross_entropy)

        # 保存数据
        saver = tf.train.Saver(tf.all_variables())
        merged = tf.summary.merge_all()
        tb_writer = tf.summary.FileWriter("../result/overfeat")
        # 执行
        sess.run(tf.global_variables_initializer())
        qrs = tf.train.start_queue_runners(sess=sess, coord=coord)
        for i in range(1000):
            cross_entropy_, summary, _ = sess.run([cross_entropy, merged, train_step])
            print(cross_entropy_)
            # 保存数据
            if i % 100 == 0:
                tb_writer.add_summary(summary, i)
            if i % 100 == 0 or (i + 1) == 1000:
                checkpoint_path = os.path.join("./result/overfeat/model", 'model.ckpt')
                saver.save(sess, checkpoint_path, global_step=i)

        tb_writer.close()
        coord.request_stop()
        coord.join(qrs)

if __name__ == '__main__':
    #test.main()
    train_LFW()


from vit_seg_modeling import Transformer
import torch
from torch import nn
import torch.nn.functional as F
from vit_seg_modeling import Transformer, CONFIGS

resnet_channels = [64, 256, 512, 768]

def norm_layer(channel, norm_name='gn'):
    if norm_name == 'bn':
        return nn.BatchNorm2d(channel)
    elif norm_name == 'gn':
        return nn.GroupNorm(min(32, channel // 4), channel)

def Increasing_Dimension(in_):
    out_ = in_.view(in_.size(0) // 5, 5, in_.size(1), in_.size(2), in_.size(3)).permute(0, 2, 1, 3, 4)
    return out_

def Reducing_Dimension(in_):
    in_ = in_.permute(0, 2, 1, 3, 4)
    out_ = in_.contiguous().view(in_.size(0) * in_.size(1), in_.size(2), in_.size(3), in_.size(4))
    return out_

class BasicConv2d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, norm=True, relu=True):
        super(BasicConv2d, self).__init__()
        self.norm = norm
        self.relu = relu
        self.conv = nn.Conv2d(in_planes, out_planes,
                              kernel_size=kernel_size, stride=stride,
                              padding=padding, dilation=dilation, bias=False)
        if norm:
            self.bn_layer = norm_layer(out_planes)
        if relu:
            self.relu_layer = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.conv(x)
        if self.norm:
            x = self.bn_layer(x)
        if self.relu:
            x = self.relu_layer(x)
        return x

class ChannelAttention(nn.Module):
    def __init__(self, in_channel, out_channel):
        super(ChannelAttention, self).__init__()
        self.in_channel = in_channel
        self.out_channel = out_channel
        self.pool = nn.AdaptiveAvgPool2d(1)
        self.linear1 = nn.Sequential(nn.Linear(out_channel, out_channel // 4, bias=False), nn.ReLU())
        self.linear2 = nn.Sequential(nn.Linear(out_channel // 4, out_channel, bias=False), nn.Sigmoid())

        self.conv = nn.Sequential(nn.Conv2d(in_channel, out_channel, 1, 1, bias=False),
                                  norm_layer(out_channel),
                                  nn.ReLU())
        self.conv2 = nn.Sequential(nn.Conv2d(out_channel, out_channel, 3, 1, 1, bias=False),
                                   norm_layer(out_channel))

    def forward(self, x):
        n, c, h, w = x.shape
        x = self.conv(x)
        y1 = self.pool(x)
        y1 = y1.reshape((n, -1))
        y1 = self.linear1(y1)
        y1 = self.linear2(y1)
        y1 = y1.reshape((n, self.out_channel, 1, 1))

        y1 = y1.expand_as(x).clone()
        y = x * y1
        return F.relu(y + self.conv2(y))

class UBlock(nn.Module):
    def __init__(self, in_channels, channels):
        super(UBlock, self).__init__()
        convs = []
        convs.append(nn.Sequential(
            nn.Conv2d(in_channels, channels, 3, 2, 1, bias=False),
            norm_layer(channels)
        ))
        for i in range(2, 4):
            convs.append(nn.Sequential(
                nn.Conv2d(channels, channels, 3, 2, 1, bias=False),
                norm_layer(channels)
            ))
        convs.append(nn.Sequential(
            nn.Conv2d(channels, channels, 3, 1, 2, dilation=2, bias=False),
            norm_layer(channels)
        ))

        convs2 = []
        for i in range(1, 4):
            convs2.append(nn.Sequential(
                nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
                norm_layer(channels)
            ))
        self.convs = nn.ModuleList(convs)
        self.convs2 = nn.ModuleList(convs2)
        self.final = nn.Sequential(
            nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
            norm_layer(channels)
        )
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        res = []
        target_shape = x.shape[2:]
        for i in range(len(self.convs)):
            x = self.convs[i](x)
            res.append(x)

        for i in range(len(res) - 1, 0, -1):
            res[i] = F.interpolate(res[i], res[i - 1].shape[2:], mode='bilinear', align_corners=True)
            res[i - 1] = res[i] + res[i - 1]
            res[i - 1] = self.convs2[i - 1](res[i - 1])
        return self.final(F.interpolate(res[0], target_shape, mode='bilinear', align_corners=True))

# Temporal contextual module
class TCM(nn.Module):
    def __init__(self, channels):
        super(TCM, self).__init__()
        self.conv1 = nn.Sequential(
            nn.Conv3d(channels, channels, kernel_size=(3, 1, 1), stride=1, padding=(0, 0, 0), dilation=(1, 1, 1)),
            norm_layer(channels),
        )
        self.conv2 = nn.Sequential(
            nn.Conv3d(channels, channels, kernel_size=(3, 1, 1), stride=1, padding=(0, 0, 0), dilation=(2, 1, 1)),
            norm_layer(channels)
        )
        self.conv3 = nn.Sequential(
            nn.Conv3d(channels, channels, kernel_size=(3, 1, 1), stride=1, padding=(0, 0, 0), dilation=(3, 1, 1)),
            norm_layer(channels)
        )
        self.conv4 = nn.Sequential(
            nn.Conv3d(channels, channels, kernel_size=(3, 1, 1), stride=1, padding=(0, 0, 0), dilation=(4, 1, 1)),
            norm_layer(channels)
        )
        self.reduce = nn.Sequential(
            nn.Conv3d(channels, channels, (4, 1, 1), stride=1, padding=0), norm_layer(channels),
            nn.ReLU(inplace=True)
        )
        self.conv_cat = nn.Sequential(
            nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
            norm_layer(channels), nn.ReLU(inplace=True),
            nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
            norm_layer(channels),
        )
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x1 = Increasing_Dimension(x)
        x1 = x1.repeat(1, 1, 3, 1, 1)
        out1 = self.conv1(x1[:, :, 4:11, :, :])
        out2 = self.conv2(x1[:, :, 3:12, :, :])
        out3 = self.conv3(x1[:, :, 2:13, :, :])
        out4 = self.conv4(x1[:, :, 1:14, :, :])

        out1 = Reducing_Dimension(out1).unsqueeze(2)
        out2 = Reducing_Dimension(out2).unsqueeze(2)
        out3 = Reducing_Dimension(out3).unsqueeze(2)
        out4 = Reducing_Dimension(out4).unsqueeze(2)

        out_cat = torch.cat([out1, out2, out3, out4], dim=2)
        out_cat = self.reduce(out_cat).squeeze()
        # out_cat = Reducing_Dimension(out_cat)

        # 2021.08.11
        # out_cat = self.conv_cat(out_cat)
        return self.relu(x + out_cat)

        # x = x + x * torch.sigmoid(out_cat)
        # return self.relu(x + self.conv_cat(x))

# Spatial contextual module
class SCM(nn.Module):
    def __init__(self, channels):
        super(SCM, self).__init__()
        self.ublock = UBlock(channels, channels)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        return self.relu(x + self.ublock(x))

class FusionD(nn.Module):
    def __init__(self, config):
        super(FusionD, self).__init__()
        self.config = config
        self.relu = nn.ReLU()
        self.fuse_high = nn.Sequential(
            nn.Conv2d(config.channels, config.channels, 3, 1, 1, bias=False), nn.Sigmoid()
        )
        self.fuse_middle = nn.Sequential(
            nn.Conv2d(config.channels, config.channels, 3, 1, 1, bias=False), norm_layer(config.channels)
        )
        self.fuse_cat = nn.Sequential(
            nn.Conv2d(config.channels * 2, config.channels, 3, 1, 1, bias=False), norm_layer(config.channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(config.channels, config.channels, 3, 1, 1, bias=False), norm_layer(config.channels),
        )
        self.scm = SCM(channels=config.channels)

    def forward(self, low, middle, high=None):
        if high is not None:
            high = F.interpolate(high, low.shape[2:], mode='bilinear', align_corners=True)
        middle = F.interpolate(middle, low.shape[2:], mode='bilinear', align_corners=True)
        middle = self.fuse_middle(middle) + low
        if high is not None:
            high = self.fuse_high(high) * low
            middle_high_cat = torch.cat([middle, high], dim=1)
            fused = self.fuse_cat(middle_high_cat)
        else:
            fused = middle
        fused = self.relu(fused)
        fused = self.scm(fused)

        return fused

class FinetuneNet(nn.Module):
    def __init__(self, config):
        super(FinetuneNet, self).__init__()
        self.config = config
        self.encoder = Transformer(config=CONFIGS['R50-ViT-B_16'], img_size=config.trainsize, vis=False)

        compress = []
        for i in range(4):
            compress.append(ChannelAttention(in_channel=resnet_channels[i], out_channel=config.channels))
        self.compress = nn.ModuleList(compress)

        fusion = []
        for i in range(3):
            fusion.append(FusionD(config))

        self.fusion = nn.ModuleList(fusion)

        self.tcm = TCM(channels=config.channels)

        predict = []
        for i in range(4):
            predict.append(nn.Conv2d(config.channels, 1, 1))
        self.predict = nn.ModuleList(predict)

    def _init_weight(self, pretrained):
        pretrained_state_dict = torch.load(pretrained)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.normal_(m.weight.data, std=0.01)
                if m.bias is not None:
                    m.bias.data.zero_()

        state_dict = self.state_dict()
        all_params = {}
        for k, v in self.state_dict().items():
            if k in pretrained_state_dict.keys():
                v = pretrained_state_dict[k]
                all_params[k] = v

        state_dict.update(all_params)
        self.load_state_dict(state_dict)

    def forward(self, x):
        x = x.reshape(x.size(0) * x.size(1), x.size(2), x.size(3), x.size(4))
        x_size = x.shape[2:]
        x4, attn_weights, features = self.encoder(x)
        x3, x2, x1 = features

        x1 = self.compress[0](x1)
        x2 = self.compress[1](x2)
        x3 = self.compress[2](x3)
        x4 = self.compress[3](x4)

        x4 = self.tcm(x4)

        x3 = self.fusion[0](x3, x4)
        x2 = self.fusion[1](x2, x3, x4)
        x1 = self.fusion[2](x1, x2, x4)

        x1 = self.predict[0](x1)
        x2 = self.predict[1](x2)
        x3 = self.predict[2](x3)
        x4 = self.predict[3](x4)

        x1_pred = F.interpolate(x1, x_size, mode='bilinear', align_corners=True)
        x2_pred = F.interpolate(x2, x_size, mode='bilinear', align_corners=True)
        x3_pred = F.interpolate(x3, x_size, mode='bilinear', align_corners=True)
        x4_pred = F.interpolate(x4, x_size, mode='bilinear', align_corners=True)
        return torch.sigmoid(x1_pred), torch.sigmoid(x2_pred), torch.sigmoid(x3_pred), torch.sigmoid(x4_pred)


import torch
import torch.optim as optim
from models.umberto_custom import UmbertoCustom
from data.loaders import get_train_valid_test_coarse, get_train_valid_test_fine
from test import evaluate
from utils.training_utils import save_checkpoint, load_checkpoint
import time

def train(model, optimizer, train_loader, valid_loader, num_epochs, eval_every,
          file_path, best_valid_loss=float("Inf")):
    # initialize running values
    running_loss = 0.0
    valid_running_loss = 0.0
    global_step = 0
    train_loss_list = []
    valid_loss_list = []
    global_steps_list = []

    # training loop
    model.train()
    print("init train")
    for epoch in range(num_epochs):
        for labels, text in train_loader:
            labels = labels.type(torch.LongTensor)
            labels = labels.to(device)
            text = text.type(torch.LongTensor)
            text = text.to(device)
            output = model(text, labels)
            loss, _ = output

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            # update running values
            running_loss += loss.item()
            global_step += 1

            # evaluation step
            if global_step % eval_every == 0:
                model.eval()
                with torch.no_grad():

                    # validation loop
                    for val_labels, val_text in valid_loader:
                        val_labels = val_labels.type(torch.LongTensor)
                        val_labels = val_labels.to(device)
                        val_text = val_text.type(torch.LongTensor)
                        val_text = val_text.to(device)
                        output = model(val_text, val_labels)
                        loss, _ = output

                        valid_running_loss += loss.item()

                # evaluation
                average_train_loss = running_loss / eval_every
                average_valid_loss = valid_running_loss / len(valid_loader)
                train_loss_list.append(average_train_loss)
                valid_loss_list.append(average_valid_loss)
                global_steps_list.append(global_step)

                # resetting running values
                running_loss = 0.0
                valid_running_loss = 0.0
                model.train()

                # print progress
                print('Epoch [{}/{}], Step [{}/{}], Train Loss: {:.4f}, Valid Loss: {:.4f}'
                      .format(epoch + 1, num_epochs, global_step, num_epochs * len(train_loader),
                              average_train_loss, average_valid_loss))

                # checkpoint
                if best_valid_loss > average_valid_loss:
                    best_valid_loss = average_valid_loss
                    save_checkpoint(file_path + '/' + 'model2.pt', model, best_valid_loss)

    print('Finished Training!')

if __name__ == "__main__":
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    print(device)

    bert_model = "Musixmatch/umberto-commoncrawl-cased-v1"
    # bert_model = "idb-ita/gilberto-uncased-from-camembert"
    num_classes = 11

    bert = UmbertoCustom(bert_model=bert_model, num_classes=num_classes).to(device)

    train_iter, valid_iter, test_iter = get_train_valid_test_fine(bert_model=bert_model, max_seq_lenght=512)

    opt = optim.Adam(bert.parameters(), lr=2e-5)
    init_time = time.time()

    train(model=bert, optimizer=opt, train_loader=train_iter, valid_loader=valid_iter, num_epochs=5,
          eval_every=len(train_iter) // 2, file_path="../data/models/")

    tot_time = time.time() - init_time
    print("time taken:", int(tot_time // 60), "minutes", int(tot_time % 60), "seconds")

    best_model = UmbertoCustom(bert_model=bert_model, num_classes=num_classes).to(device)

    load_checkpoint("../data/models" + '/model2.pt', best_model, device)

    evaluate(best_model, test_iter, num_classes, device)