#!/usr/bin/env python

import os
import sys
import argparse
import wikimap
from itertools import imap

class GridSearch(object):
    """
    This class iterates through different combinations of parameters.

    For each argument a value or a list of values is given. At each step of the
    iteration one value from each list is chosen.
    """

    def __init__(self, grid_args):
        """
        Initialize the grid search.

        `grid_args` is an iterable of pairs consisting of a name of an argument
                    and a list of possible values (or a single value)
        """
        self._grid_args = [
            (arg_name, self._maybe_wrap_with_list(arg_values))
            for (arg_name, arg_values)
            in grid_args
            if arg_values is not None]

        self.max_config_num = max(sum(1 for _ in self), 1)

    def __iter__(self):
        """
        Iterate configs.

        Each value in _grid_args is a list. Each step of iteration yields
        a different combination of elements from lists (with one element per
        list at the same time).
        """
        def recursive_iterator(grid):
            if not grid:
                yield []
            else:
                key, value_axis = grid[0]
                for value in value_axis:
                    for tail in recursive_iterator(grid[1:]):
                        yield [(key, value)] + tail

        if not self._grid_args:
            return iter([{}])  # default config
        else:
            return imap(dict, iter(recursive_iterator(self._grid_args)))

    def _maybe_wrap_with_list(self, value):
        if isinstance(value, list):
            return value
        else:
            return [value]

def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        '--target', '-t',
        dest='target_jobs',
        default=wikimap.DEFAULT_TARGET_JOBS,
        type=wikimap.Utils.parse_comma_separated_strings,
        help="Choose jobs to do. Their dependencies will also be included. "
             "The jobs should be specified as their aliases. Aliases can be "
             "obtained with '--print-jobs' option. Multiple comma-separated "
             "aliases are allowed. A wildcard 'all' can be used to select all "
             "jobs.")
    parser.add_argument(
        '--forced', '-f',
        dest='forced_jobs',
        default=wikimap.DEFAULT_FORCED_JOBS,
        type=wikimap.Utils.parse_comma_separated_strings,
        help=("Add targets (like '-t' option) but also mark them for "
              "recomputation, even if their results could be copied from "
              "previous runs. It expects the same kind of arguments as '-t'."))
    parser.add_argument(
        '--skip', '-s',
        dest='skipped_jobs',
        default=wikimap.DEFAULT_SKIPPED_JOBS,
        type=wikimap.Utils.parse_comma_separated_strings,
        help=("Choose jobs to skip unconditionally. Can't conflict with "
              "forced jobs. It expects the same kind of arguments as '-t'."))
    parser.add_argument(
        '--buildpath', '-b',
        type=str,
        default=os.environ.get("WIKIMAP_BUILDPATH", None),
        help=("Choose a directory for builds. Each build will create a new "
              "subdirectory inside. Can also be set by WIKIMAP_BUILDPATH "
              "environment variable."))
    parser.add_argument(
        '--prefix', '-p',
        type=str,
        default='build',
        help="Choose a prefix for subdirectories inside the builds directory.")
    parser.add_argument(
        '--lang',
        dest='meta.language',
        type=wikimap.Utils.parse_comma_separated_strings,
        default=wikimap.DEFAULT_LANGUAGE,
        help="Choose an edition of wikipedia to use. Should be a valid "
             "wikipedia code like 'en' or 'pl'. "
             "https://en.wikipedia.org/wiki/List_of_Wikipedias provides a "
             "list.")
    parser.add_argument(
        '--base',
        dest='base_build_index',
        type=int,
        default=-1,
        help=("Choose an index of a base build. The program will try to skip "
              "parts of the build if it thinks they would have the same "
              "results. By default the last build is used."))
    parser.add_argument(
        '--print-config',
        action='store_true',
        help="Print the full configuration of the build and quit.")
    parser.add_argument(
        '--print-jobs',
        action='store_true',
        help="Print a list of jobs included in the build and quit.")
    parser.add_argument(
        '--ldnn.neighbors_count',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_NEAREST_NEIGHBORS_COUNT,
        help=("Choose a number of nearest neighbors computed for each point "
              "in map. Can also be a comma-separated list of ints."))
    parser.add_argument(
        '--embed.context_size',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_CONTEXT_SIZE,
        help=("Choose a context size of word embedding method. Can also be "
              "a comma-separated list of ints."))
    parser.add_argument(
        '--embed.backtrack_probability',
        type=wikimap.Utils.parse_comma_separated_floats,
        default=wikimap.DEFAULT_BACKTRACK_PROBABILITY,
        help=("Choose a probability of backtracking in a random walk "
              "through link graph. Can also be a comma-separated list of "
              "floats."))
    parser.add_argument(
        '--embed.dimension',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_DIMENSION,
        help=("Choose a dimension of embeddings. Can also be a "
              "comma-separated list of ints."))
    parser.add_argument(
        '--embed.walks_per_node',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_WALKS_PER_NODE,
        help=("Choose a number of random walks per node in graph-based "
              "embedding algorithms. Can also be a comma-separated list of "
              "ints."))
    parser.add_argument(
        '--embed.method',
        type=wikimap.Utils.parse_comma_separated_strings,
        default=wikimap.DEFAULT_EMBEDDING_METHOD,
        help=("Choose an embedding method. Has to be one of the following: "
              "{}. Can also be a comma-separated list of the above.".format(
                ', '.join(wikimap.EMBEDDING_METHODS))))
    parser.add_argument(
        '--embed.node_count',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_EMBEDDING_NODE_COUNT,
        help=("Choose a number of embedded nodes (wikipedia titles). Can also "
              "be a comma-separated list of ints."))
    parser.add_argument(
        '--embed.epoch_count',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_EPOCH_COUNT,
        help=("Choose a number of epochs to use during training. Can also be "
              "a comma=separated list of ints."))
    parser.add_argument(
        '--embed.walk_length',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_WALK_LENGTH,
        help=("Choose a maximum walk length of random walks during embedding. "
              "Can also be a comma-separated list of ints."))
    parser.add_argument(
        '--embed.categories',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_USE_CATEGORIES,
        help=("Train also on links from pages to categories. Use 0 (off) and "
              "1 (on). Can also be a comma-separated list of ints."))
    parser.add_argument(
        '--embed.negative_samples',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_NEGATIVE_SAMPLES,
        help=("Number of noise samples drawn for each real sample coming from "
              "data. Can also be a comma-separated list of ints."))
    parser.add_argument(
        '--tsne.point_count',
        type=wikimap.Utils.parse_comma_separated_ints,
        default=wikimap.DEFAULT_TSNE_POINT_COUNT,
        help=("Number of points in t-SNE projection to compute. Can also be a "
              "comma-separated list of ints."))

    args = parser.parse_args()

    if not args.buildpath:
        sys.exit("Choose a build path, by using --buildpath (-b) option or by "
                 "setting the WIKIMAP_BUILDPATH environment variable.")

    wikimap.Utils.config_logging()
    logger = wikimap.Utils.get_logger(__name__)

    grid_arg_names = [
        'ldnn.neighbors_count', 'embed.context_size', 'embed.walks_per_node',
        'embed.backtrack_probability', 'embed.dimension', 'embed.node_count',
        'embed.method', 'embed.epoch_count', 'embed.walk_length',
        'embed.categories', 'embed.negative_samples', 'meta.language',
        'tsne.point_count']
    grid_args = [
        (arg_name, vars(args)[arg_name])
        for arg_name
        in grid_arg_names]

    build_configs = GridSearch(grid_args)

    for config_no, config in enumerate(build_configs):
        build = wikimap.Build(
            builds_dir=args.buildpath,
            build_prefix=args.prefix,
            base_build_index=args.base_build_index,
            target_jobs=args.target_jobs,
            forced_jobs=args.forced_jobs,
            skipped_jobs=args.skipped_jobs,
            config=config)

        if args.print_jobs:
            build.print_jobs()
        elif args.print_config:
            build.print_config()
        else:
            logger.important(wikimap.Utils.thick_line_separator)
            format_str = 'STARTING BUILD [{{:{}}}/{{}}]'.format(
                wikimap.Utils.get_number_width(build_configs.max_config_num))
            logger.important(format_str.format(
                config_no + 1,
                build_configs.max_config_num))

            build.run()

if __name__ == "__main__":
    main()


"""
Swithing between color spaces - systems of representing colors
RGB, Grayscale, HSV, LAB
"""

import cv2 as cv
from matplotlib import pyplot as plt

img_path='snip.jpg'
img = cv.imread(img_path)

# BGR (Blue Green Red) to Grayscale
# Grayscale shows you the distribution of intensities in an image
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# BGR to HSV - Hue Saturation Value, similar to human perception
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

# BGR to LAB - L x A x B
lab = cv.cvtColor(img, cv.COLOR_BGR2LAB)

# BGR to RGB (when you have problems with color inversion)
# matplotlib assumes RGB color order
rgb = cv.cvt.Color(img, cv.COLOR_BGR2RGB)

# HSV to BGR
hsv_bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)

# LAB to BGR
lab_bgr = cv.cvtColor(lab, cv.COLOR_HSV2BGR)

# cv.imshow('snip_img', lab)

cv.waitKey(0)


import cv2
import numpy as np

pathBGD = 'Resources/Background.png'
pathA = 'Resources/Typa_A.png'
pathB = 'Resources/Typa_B.png'
pathC = 'Resources/Typa_C.png'
pathD = 'Resources/Typa_D.png'
pathTest = 'Resources/Ahw0145.png'

imgTest = cv2.imread(pathTest)
imgBGD = cv2.imread(pathBGD)
imgCopy = imgTest.copy()
maskA = cv2.imread(pathA)
maskB = cv2.imread(pathB)
maskC = cv2.imread(pathC)
maskD = cv2.imread(pathD)
rows,cols,channels = maskA.shape
sumA,sumB,sumC,sumD = 0,0,0,0
absA,absB,absC,absD = 0,0,0,0

def compare_img_hist(img1, img2):
    img1_hist = cv2.calcHist([img1], [1], None, [256], [0,256])
    img1_hist = cv2.normalize(img1_hist, img1_hist, 0, 1, cv2.NORM_MINMAX, -1)

    img2_hist = cv2.calcHist([img2], [1], None, [256], [0,256])
    img2_hist = cv2.normalize(img2_hist, img2_hist, 0, 1, cv2.NORM_MINMAX, -1)

    similarity = cv2.compareHist(img1_hist, img2_hist, 0)
    print(similarity)

    return similarity

for i in range(rows):
    for j in range(cols):
        for k in range(channels):
            if maskA[i][j][k] == 0 or maskA[i][j][k] == 255:
                continue
            else:
                imgCopy[i,j] = maskA[i,j]
        absA = np.abs(imgCopy[i][j],imgBGD[i][j])
        sumA = sumA + absA
new_img = imgCopy
cv2.imshow("Type_A",new_img)
compare_img_hist(imgBGD, new_img)

imgCopy = imgTest.copy()
for i in range(rows):
    for j in range(cols):
        for k in range(channels):
            if maskC[i][j][k] == 0 or maskC[i][j][k] == 255:
                continue
            else:
                imgCopy[i,j] = maskC[i,j]
        absC = np.abs(imgCopy[i][j],imgBGD[i][j])
        sumC = sumC + absC
new_img2 = imgCopy
cv2.imshow("Type_C",new_img2)
compare_img_hist(imgBGD, new_img2)

print(sumA,sumB,sumC,sumD)
cv2.waitKey(0)


import openpyxl
from find_code import *
from converter import converter

def main():
    try:
        # Если файл имеет расширения не .xlsx, то сохраняю его в этот формат.
        converter()
    except:
        # Иначе пропустить.
        pass

    create_document()

def create_document():
    upd = openpyxl.open('upd.xlsx')
    sheet = upd.active

    numberDocument = sheet['B17'].value[17:24].strip()  # номер документа
    data = sheet['B17'].value[27:].split()  # Дата
    if len(data[0]) > 1:
        day = data[0]   # День
    else:
        day = f'0{data[0]}'  # День
    month = FC.edit_month(data[1]) # Месяц
    year = data[2]  # Год
    data_document = f'{day}/{month}/{year}'

    inn = '9201002117'
    comment = '=)'

    one_string = f'{numberDocument};{data_document};;;{inn};;;;;;;;;;;{comment};'

    print('Ожидайте, сейчас происходит магия =)')

    with open('tdm.txt', 'w') as new_file:
        new_file.write(one_string + '\n')
        for row in range(25, sheet.max_row + 1):
            if sheet[row][3].value != None:
                if 'SQ' in sheet[row][3].value[:2]:
                    n = FindCode(sheet[row][3].value)
                    new_code = n.find_tdm()
                    new_string = f';{new_code};;;;;;{sheet[row][50].value};;;{sheet[row][60].value};'
                    new_file.write(new_string + '\n')
                elif len(sheet[row][3].value) == 5:
                    n = FindCode(sheet[row][3].value)
                    new_code = n.find_fortisflex()
                    new_string = f';{new_code};;;;;;{sheet[row][50].value * 100};;;{sheet[row][60].value / 100};'
                    new_file.write(new_string + '\n')
                else:
                    new_string = f';{sheet[row][3].value};;;;;;{sheet[row][50].value};;;{sheet[row][60].value};'
                    new_file.write(new_string + '\n')

    print('\nВсе готово!')

if __name__ == '__main__':
    main()


from flask_redis import FlaskRedis
from ..utils.eventlet import eventlet
from flask_socketio import emit
import time

redis_store = FlaskRedis()

def redisReader():
	pubsub = redis_store.pubsub()
	pubsub.subscribe('msg')
	print ('Starting Redis subscriber')
	for msg in pubsub.listen():
	#print ('>>>>>', msg)
		print('Redis says : ' + str(msg['data']))
		#emit('message', {'msg':  msg['msg'], 'time': time.strftime("%H:%M"), 'name': manager}, room=room, namespace='/chat')
		print('emmited!')

def setupRedis():
	pool = eventlet.GreenPool()
	pool.spawn(redisReader)
	print('setupRedis')


from flask import render_template, redirect, request, session
from flask_app import app
from flask_app.config.mysqlconnection import connectToMySQL
from flask_app.models.users_model import User
from flask_app.models.recipes_model import Recipe

@app.route('/new/recipe') # to show the create recipe page
def new():
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":session['user_id']
    }
    return render_template("create.html", user=User.get_by_id(data))

@app.route('/create/recipe', methods=['POST']) # to actually create a new user and redirect back to home; POST method because data is being submitted
def create_recipe():
    if 'user_id' not in session:
        return redirect('/logout')
    if not Recipe.validate_recipe(request.form):
        return redirect('/new/recipe')
    data = {
        "name": request.form["name"],
        "description": request.form["description"],
        "instructions": request.form["instructions"],
        "under_thirty": int(request.form["under_thirty"]),
        "date_made": request.form["date_made"],
        "user_id": session['user_id']
    }
    Recipe.save_recipe(data)
    return redirect('/dashboard')

@app.route('/view/recipe/<int:id>')
def show_recipe(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    user_data = {
        "id":session['user_id']
    }
    return render_template("view_recipe.html",recipe=Recipe.get_one(data),user=User.get_by_id(user_data))

@app.route('/edit/recipe/<int:id>')
def edit_recipe(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    user_data = {
        "id":session['user_id']
    }
    return render_template("edit_recipe.html",edit=Recipe.get_one(data),user=User.get_by_id(user_data))

@app.route('/update/recipe',methods=['POST'])
def update_recipe():
    if 'user_id' not in session:
        return redirect('/logout')
    if not Recipe.validate_recipe(request.form):
        return redirect('/dashboard')
    data = {
        "name": request.form["name"],
        "description": request.form["description"],
        "instructions": request.form["instructions"],
        "under_thirty": int(request.form["under_thirty"]),
        "date_made": request.form["date_made"],
        "id": request.form["id"]
    }
    Recipe.update(data)
    return redirect('/dashboard')

@app.route('/destroy/recipe/<int:id>')
def destroy_recipe(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    Recipe.destroy(data)
    return redirect('/dashboard')


from json import load
from itsdangerous import exc
import VideoPage
from PyQt5 import QtWidgets
import data
import loadingPage
import pafy
import videoLoading
import urllib.request
from PyQt5.QtGui import *

class PlayList:
    def __init__(self,Ui,con):
        self.ui=Ui
        self.con=con # 굳이 매개변수로 할필요 없었다

        self.load=loadingPage.Loading(self.ui)
        self.Videoload=videoLoading.LoadingVideo(self.ui)
        self.video=VideoPage.Video(self.ui)  # None 으로 해놓고 객체를 삭제하는 방법을 찾아야했다

        self.db=data.Database()
        self.dialog=QtWidgets.QDialog()     # dialog checkedit
        self.dialog2=QtWidgets.QDialog()    # dialogPlayList
        self.dialog3=QtWidgets.QDialog()    # dialog check
        self.dialog4=QtWidgets.QDialog()    # dialogYesNo
        self.id=None
        self.playListText=[]
        self.playList=[]
        self.playListClick()# 이름
        self.playListbtnEvent() # control 버튼 이름 이름이 너무 비슷해서 유지보수가 힘들다

    def playListbtnEvent(self):
        self.ui.playListBack.clicked.connect(self.backEvent)
        for index in range(0,len(self.ui.playListBtnList)):
            self.ui.playListBtnList[index].clicked.connect(lambda event,value=index : self.playListEvent(value))
    def receiveId(self,id):
        self.id=id
        self.playListClick()

    def playListClick(self):
        # search update insert delete
        for index in range(0,len(self.ui.mainLogoListBtn)):
           self.ui.mainLogoListBtn[index].clicked.connect(lambda event,value=index : self.moveEvent(value))

    def playListEvent(self,number):
        if number==0:#search
            self.searchList()
        elif number==1:
            self.updateList()
        elif number==2:
            self.ui.dialogCheckEdit(self.dialog,"insert")
            self.ui.dialogCheckEditBtn.clicked.connect(lambda event : self.insertPlayList())
            self.dialog.exec()
        else:
            self.deleteList()

    def insertPlayList(self):
        listData=[self.id,self.ui.dialogText.text()]
        checkPlayListRepeat=self.db.readData("playList",["id","playList"],listData,self.db.cursor2)
        print(len(checkPlayListRepeat))
        if len(checkPlayListRepeat)==0:
            self.db.insertData("playList",self.db.column2Value,listData,self.db.cursor2,self.db.connect2)
            self.dialog.close()
            self.playListSet()
        else:
            self.ui.dialogCheck(self.dialog3,"repeat")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()

    def playListSet(self):
        listData=self.db.readData("playList",["id"],[self.id],self.db.cursor2)
        self.playListText=[]
        for index in range (0,len(listData)):
            self.playListText.append(listData[index][2])

        self.videoListText=[]
        for index in range(0,len(listData)):
            listData2=self.db.readData("playVideo",["id","playList"],[self.id,self.playListText[index]],self.db.cursor3)
            try:
                self.videoListText.append(listData2[0][3])
            except:
                self.videoListText.append("")
        print("비디오제목은:"+str(self.videoListText))
        self.ui.playList(self.playListText,self.videoListText)
        self.playListClick()

    def moveEvent(self,number):
        #비디오 객체 선언
        self.load.setMovie(4)
        self.video.id=self.id
        self.video.playList=self.playListText[number]
        self.video.videoPlay(0)
        self.presentList=self.playListText[number]
        self.video.videoListSet()

    def backEvent(self):
        self.ui.stackedWidget.setCurrentIndex(0)
        self.con.setTextClear()
        #객체 삭제
        # event 버튼 등등 모두 clear

    def updateList(self):
        self.ui.dialogPlayList(self.dialog2,"update",self.playListText)
        self.ui.Listcheckbtn[1].clicked.connect(lambda event : self.dialog2.close())
        self.ui.Listcheckbtn[0].clicked.connect(lambda event : self.updateName())
        self.dialog2.exec()

    def updateName(self):
        state=[]
        count=0
        indexState=None
        for index in range(0,len(self.ui.dialogListBox)):
            state.append(self.ui.dialogListBox[index].isChecked())
            if state[index]==True:
                count+=1
                indexState=index
        if count>=2 :
            self.ui.dialogCheck(self.dialog3,"repeat input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count<=0 :
            self.ui.dialogCheck(self.dialog3,"pls input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count==1:
            self.ui.dialogCheckEdit(self.dialog,"update")
            self.ui.dialogCheckEditBtn.clicked.connect(lambda event : self.updateData(indexState))
            self.dialog.exec()

    def updateData(self,number):
        listData=[self.id,self.ui.dialogText.text()]
        checkPlayListRepeat=self.db.readData("playList",["id","playList"],listData,self.db.cursor2)
        print(checkPlayListRepeat)
        if len(checkPlayListRepeat)==0:
            playList=self.ui.dialogListBox[number].text()
            data=self.db.readData("playList",["id","playList"],[self.id,playList],self.db.cursor2)
            updateData=["sequance",data[0][0]]
            self.db.updateData("playList",["playList",self.ui.dialogText.text()],updateData,self.db.cursor2,self.db.connect2)
            self.dialog2.close()
            self.dialog.close()
            self.playListSet()
        else:
            self.ui.dialogCheck(self.dialog3,"repeat")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()

    def deleteList(self):
        self.ui.dialogPlayList(self.dialog2,"delete",self.playListText)
        self.ui.Listcheckbtn[1].clicked.connect(lambda event : self.dialog2.close())
        self.ui.Listcheckbtn[0].clicked.connect(lambda event : self.deleteEvent())
        self.dialog2.exec()

    def deleteEvent(self):
        state=[]
        count=0
        indexState=None
        for index in range(0,len(self.ui.dialogListBox)):
            state.append(self.ui.dialogListBox[index].isChecked())
            if state[index]==True:
                count+=1
                indexState=index
        if count>=2 :
            self.ui.dialogCheck(self.dialog3,"repeat input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count<=0 :
            self.ui.dialogCheck(self.dialog3,"pls input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count==1:
            self.ui.dialogYesNo(self.dialog4,"delete?")
            self.ui.dialogYesNoBtn[0].clicked.connect(lambda event : self.deleteData(indexState))
            self.ui.dialogYesNoBtn[1].clicked.connect(lambda event : self.dialog4.close())
            self.dialog4.exec()

    def deleteData(self,number):
        playList=self.ui.dialogListBox[number].text()
        data=self.db.readData("playList",["id","playList"],[self.id,playList],self.db.cursor2)
        deleteData=["sequance",data[0][0]]
        data=self.db.readData("playVideo",["id","playList"],[self.id,playList],self.db.cursor3)
        try:
            deleteData2=["sequance",data[0][0]]
            self.db.deleteData("playList",deleteData,self.db.cursor2,self.db.connect2)
            self.db.deleteData("playVideo",deleteData2,self.db.cursor3,self.db.connect3)
            self.dialog4.close()
            self.dialog2.close()
            self.playListClick()
            self.playListSet()
        except:
            self.db.deleteData("playList",deleteData,self.db.cursor2,self.db.connect2)
            self.dialog4.close()
            self.dialog2.close()
            self.playListClick()
            self.playListSet()

            # rdData 통해서 id 랑 입력된 text 로 시퀀스 찾아서 그 시퀀스 딜리트

    def searchList(self):
        self.ui.dialogPlayList(self.dialog2,"search",self.playListText)
        self.ui.Listcheckbtn[1].clicked.connect(lambda event : self.dialog2.close())
        self.ui.Listcheckbtn[0].clicked.connect(lambda event : self.videoInsertEvent())
        self.dialog2.exec()

    def insertVideo(self,number):
        playList=self.ui.dialogListBox[number].text()
        videoData=self.storeVideo(self.ui.dialogText.text())
        try:
            listData=[self.id,playList,videoData[0],videoData[1],videoData[2]]
            print(listData)
            checkPlayListRepeat=self.db.readData("playVideo",["id","playList","video","time","imageURL"],listData,self.db.cursor3)
            print(len(checkPlayListRepeat))
            if len(checkPlayListRepeat)==0:
                self.dialog2.close()
                self.dialog.close()
                self.presentList=playList
                self.db.insertData("playVideo",self.db.column3Value,listData,self.db.cursor3,self.db.connect3)
                self.playListClick()
                qPixmapVar = QPixmap()
                urlString = videoData[2]
                imageFromWeb = urllib.request.urlopen(urlString).read()
                qPixmapVar.loadFromData(imageFromWeb)
                qPixmapVar=qPixmapVar.scaled(480,270)
                qPixmapVar.save("thumbnail/"+videoData[0]+".PNG")
                self.Videoload.setDown(self.best)
                self.playListSet()
            else:
                self.ui.dialogCheck(self.dialog3,"repeat")
                self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
                self.dialog3.exec()
        except:
            self.ui.dialogCheck(self.dialog3,"URL wrong")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()

    def videoInsertEvent(self):
        state=[]
        count=0
        indexState=None
        for index in range(0,len(self.ui.dialogListBox)):
            state.append(self.ui.dialogListBox[index].isChecked())
            if state[index]==True:
                count+=1
                indexState=index
        if count>=2 :
            self.ui.dialogCheck(self.dialog3,"repeat input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count<=0 :
            self.ui.dialogCheck(self.dialog3,"pls input")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()
        elif count==1:
            self.ui.dialogCheckEdit(self.dialog,"Insert Video")
            self.ui.dialogCheckEditBtn.clicked.connect(lambda event : self.insertVideo(indexState))
            self.dialog.exec()

    def storeVideo(self,url):
        try:
            video = pafy.new(url)
            streams = video.streams
            for i in streams:
                print(i)
            # get best resolution regardless of format
            self.best = video.getbest()
            print(self.best.resolution, self.best.extension)
            # Download the video

            sec=int(video.duration[0])*36000+int(video.duration[1])*3600+int(video.duration[3])*600+int(video.duration[4])*60+int(video.duration[6])*10+int(video.duration[7])
            videoName=video.title
            videoImage = video.bigthumb

            return videoName,sec,videoImage
        except:
            self.ui.dialogCheck(self.dialog3,"URL wrong")
            self.ui.dialogCheckbtn.clicked.connect(lambda event : self.dialog3.close())
            self.dialog3.exec()


from zope import component

from Acquisition import aq_inner
from AccessControl import ClassSecurityInfo

from Products.CMFCore.permissions import View
from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from raptus.article.maps.interfaces import IMarkers
from raptus.article.mapsjunaio.interfaces import IHtmlParser

class View(BrowserView):

    def __call__(self):
        return 'junaio ws service'

    def search(self):
        """ search method for junaio
        """
        return ViewPageTemplateFile('junaio.pt')(self)

    def __init__(self, context, request):
        super(View,self).__init__(context, request)
        self.props = getToolByName(self.context, 'portal_properties').raptus_article

    def markers(self):
        context = aq_inner(self.context)
        markers = list()
        for brain in IMarkers(context).getMarkers():
            object = brain.getObject()
            scales = component.queryMultiAdapter((object, object.REQUEST), name='images')
            di = dict(brain = brain,
                      obj = object,
                      uid = brain.UID,
                      title = object.Title(),
                      text = IHtmlParser(object).getText(),
                      latitude = object.getLatitude(),
                      longitude = object.getLongitude(),
                      icon = self._thumbnail(object, scales),
                      thumbnail = self._icon(object, scales)
                      )
            markers.append(di)
        return markers

    def _thumbnail(self, object, scales):
        thumb = None
        thumbnail_w = self.props.getProperty('junaio_thumbnail_width')
        thumbnail_h = self.props.getProperty('junaio_thumbnail_height')
        if scales.field('image'):
            thumb = scales.scale('image', width=thumbnail_w, height=thumbnail_h)
        if thumb is not None:
            return thumb.absolute_url()
        else:
            return self._default(self.props.getProperty('junaio_thumbnail_default'))

    def _icon(self, object, scales):
        icon = None
        icon_w = self.props.getProperty('junaio_icon_width')
        icon_h = self.props.getProperty('junaio_icon_height')
        if scales.field('image'):
            icon = scales.scale('image', width=icon_w, height=icon_h)
        if icon is not None:
            return icon.absolute_url()
        else:
            return self._default(self.props.getProperty('junaio_icon_default'))

    def _default(self, name):
        portal_state = component.getMultiAdapter((self.context, self.request), name=u'plone_portal_state')
        site = portal_state.portal()
        return '%s/%s' %(site.absolute_url(), name)


from sys import argv
from os.path import abspath
from os import getenv
import json
import codecs

type_ = argv[1]
alias, code_dir = argv[2:4]
home = '/home/'+getenv("SUDO_USER")
if type_ == "file":
	code_lit = ""
	with open(abspath(code_dir),'r') as codeF:
		line = codeF.readline()
		while line:
			code_lit += line
			line = codeF.readline()
else:
	code_lit = code_dir

with open(f'{home}/.SHDev/program.json','r') as programF:
	aliases = json.load(programF)
	if alias in aliases:
		print(f"Alias {alias} already exist")
		exit()
	else:
		aliases[alias] = code_lit
with open(f'{home}/.SHDev/program.json','w') as programF:
	json.dump(aliases,programF)
with open(f'{home}/.SHDev/SHDev.sh',"w") as SHDevF:
	for value in aliases.values():
		SHDevF.write(value+'\n')


# Util classes from utils file
from utils import Stack
from utils import Queue

# This BFS will take the player back to the nearest room that has an unexplored exit
def uncharted_path(currentPath, room_id, player):
    # Create an empty set to store visited nodes
    visited = set()
    # Create an empty Queue and enqueue A PATH TO the starting vertex
    q = Queue()
    path = [room_id]
    q.enqueue(path)
    # While the queue is not empty...
    while q.size() > 0:
        # Dequeue the first PATH
        p = q.dequeue()
        # GRAB THE VERTEX FROM THE START OF THE PATH
        v = p[0]
        # IF VERTEX == TARGET ('?'), SET PATH THEN BREAK
        if v == '?':
            path = p[1:]
            break
        # If that vertex has not been visited...
        if v not in visited:
            # Mark it as visited
            visited.add(v)
            # Then add A PATH TO all of its neighbors to the back of the queue
            for neighbors in currentPath[v]:
                node = currentPath[v][neighbors]
                new_path = p.copy()
                new_path.insert(0, node)
                q.enqueue(new_path)
    # this list will contain the directions that the player needs to move back
    movements = []

    # While loop runs trying to create a path of movements
    while len(path) > 1:
        # remove the last room and store as a variable
        current = path.pop(-1)
        # find the direction that will take you to the prior room and add it to a movements list
        for route in currentPath[current]:
            if currentPath[current][route] == path[-1]:
                movements.append(route)

    # for every element in movements, move in that direction until you reach the spot
    for move in movements:
        player.travel(move)

    # return the movements to be appended to traversalPath
    return movements

# This function is only for getting the opposite compass pointer to update our question marks for the room we just came from
def inverse_point(point):
    if point == 'n':
        direc = 's'
    elif point == 's':
        direc = 'n'
    elif point == 'e':
        direc = 'w'
    elif point == 'w':
        direc = 'e'
    return direc


from django.urls import path
from . import views

# start with blog
urlpatterns = [
    # http://localhost:8000/oas/
    path('', views.article_list, name='article_list'),
    path('<int:article_pk>', views.article_detail, name="article_detail"),
    path('type/<int:err_type_pk>', views.article_with_type, name="article_with_type"),
    path('date/<int:year>/<int:month>', views.article_with_date, name="article_with_date"),
]


# #!/usr/bin/env python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions

class SwagLab:
# Start the browser and login with standard_user
    options = ChromeOptions()
    options.add_argument("--no-sandbox")
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.binary_location = "/usr/bin/chromium-browser"
    driver = webdriver.Chrome(chrome_options=options)

    def login (self, user, password):
        print ('Starting the browser...')
        # --uncomment when running in Azure DevOps.
        # options = ChromeOptions()
        # options.add_argument("--headless")
        # driver = webdriver.Chrome(options=options)
        driver = self.driver
        print ('Browser started successfully')
        print ('Navigating to the demo page to login.')
        driver.get('https://www.saucedemo.com/')
        print ('User {'+user+'} trying to login now')
        driver.find_element_by_css_selector("input[id='user-name']").send_keys(user)
        driver.find_element_by_css_selector("input[id='password']").send_keys(password)
        driver.find_element_by_css_selector("input[class='btn_action']").click()
        products = driver.find_element_by_css_selector("div[class='product_label']").text
        print('We are on page '+ products)

        if(products == 'Products'):
            print('User {'+ user +'} able to login successfully')
        else:
            print('Error something went Wrong while login')
    #login('standard_user', 'secret_sauce')

    def click_on_products(self, products, action):
        for product in products:
            name = product.find_element_by_css_selector('div[class="inventory_item_name"]').text
            print(action +' Product to Cart :'+name)
            product.find_element_by_css_selector("div[class='pricebar'] > button").click()

    #Add all products into cart and then remove its
    def add_to_cart(self):
        self.login('standard_user', 'secret_sauce')
        driver = self.driver
        products = driver.find_elements_by_css_selector("div[class='inventory_item']")
        self.click_on_products(products,'Adding')
        noOfProductsAdded = driver.find_element_by_css_selector('span[class="fa-layers-counter shopping_cart_badge"]').text
        print("Total no of products added " + noOfProductsAdded )
        assert "6" in [noOfProductsAdded]
        self.click_on_products(products, 'Removing')
        noOfProductsAdded = len(driver.find_elements_by_css_selector('span[class="fa-layers-counter shopping_cart_badge"]'))
        print("Total no of products Removed " + str(noOfProductsAdded))
        assert "0" in [str(noOfProductsAdded)]
x = SwagLab()
x.add_to_cart()


import timeit;

program_start_time = timeit.default_timer()
import random

random.seed(int(timeit.default_timer()))

from general_tools import *

import logging
import formatting, preprocessWavs

logger = logging.getLogger('PrepTCDTIMIT')
logger.setLevel(logging.DEBUG)
FORMAT = '[$BOLD%(filename)s$RESET:%(lineno)d][%(levelname)-5s]: %(message)s '
formatter = logging.Formatter(formatting.formatter_message(FORMAT, False))

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
logger.addHandler(ch)

nbMFCCs = 39  # 13= just mfcc (13 features). 26 = also derivative (26 features). 39 = also 2nd derivative (39 features)
nbPhonemes = 39

############### DATA LOCATIONS  ###################
root = os.path.expanduser("~/TCDTIMIT/audioSR/")  # ( keep the trailing slash)
dataset = "TCDTIMIT"
forceOverwrite = False
###################
normalizePkl_path = root + dataset + "/binary" + str(nbPhonemes) + os.sep + dataset + "MeanStd.pkl"

def main():
    noiseTypes = ['white','voices']
    ratio_dBs = [0, -3, -5, -10]

    for noiseType in noiseTypes:
        for ratio_dB in ratio_dBs:
            oneTypeToPkl(noiseType, ratio_dB)

def oneTypeToPkl(noiseType, ratio_dB):
    global target_path, dataList
    dataRootDir = root + dataset + "/fixed" + str(nbPhonemes) + "_" + noiseType + os.sep + "ratio" + str(
        ratio_dB) + os.sep + 'TEST'
    outputDir = root + dataset + "/binary" + str(nbPhonemes) + "_" + noiseType + \
                os.sep + "ratio" + str(ratio_dB) + os.sep + dataset
    FRAC_TRAINING = 0.0  # TOTAL = TRAINING + TEST = TRAIN + VALIDATION + TEST
    ### store path
    target = os.path.join(outputDir, dataset + '_' + str(nbMFCCs) + '_ch');
    target_path = target + '.pkl'
    if not os.path.exists(outputDir):
        os.makedirs(outputDir)

    # Already exists, ask if overwrite
    if (os.path.exists(target_path)):
        if not forceOverwrite:
            logger.info("This file already exists, skipping", target_path)
            return 0

    ##### The PREPROCESSING itself #####
    logger.info('Preprocessing data ...')

    # FIRST, gather the WAV and PHN files, generate MFCCs, extract labels to make inputs and targets for the network
    # for a dataset containing no TRAIN/TEST subdivision, just a bunch of wavs -> choose training set yourself
    def processDataset(FRAC_TRAINING, data_source_path, logger=None):
        logger.info('  Data: %s ', data_source_path)
        X_test, y_test, valid_frames_test = preprocessWavs.preprocess_dataset(source_path=data_source_path,
                                                                              nbMFCCs=nbMFCCs,
                                                                              logger=logger, debug=None)
        assert len(X_test) == len(y_test) == len(valid_frames_test)

        logger.info(' Loading data complete.')
        logger.debug('Type and shape/len of X_test')
        logger.debug('type(X_test): {}'.format(type(X_test)))
        logger.debug('type(X_test[0]): {}'.format(type(X_test[0])))
        logger.debug('type(X_test[0][0]): {}'.format(type(X_test[0][0])))
        logger.debug('type(X_test[0][0][0]): {}'.format(type(X_test[0][0][0])))

        return X_test, y_test, valid_frames_test

    X_test, y_test, valid_frames_test = processDataset(FRAC_TRAINING, dataRootDir, logger)
    logger.info("  test X: %s", len(X_test))
    logger.info("  test y: %s", len(y_test))
    logger.info("  test valid_frames: %s", len(valid_frames_test))
    ### NORMALIZE data ###
    logger.info('Normalizing data ...')
    logger.info('    Each channel mean=0, sd=1 ...')
    mean_val, std_val = unpickle(normalizePkl_path)
    X_test = preprocessWavs.normalize(X_test, mean_val, std_val)
    # make sure we're working with float32
    X_data_type = 'float32'
    X_test = preprocessWavs.set_type(X_test, X_data_type)
    y_data_type = 'int32'
    y_test = preprocessWavs.set_type(y_test, y_data_type)
    valid_frames_data_type = 'int32'
    valid_frames_test = preprocessWavs.set_type(valid_frames_test, valid_frames_data_type)
    # print some more to check that cast succeeded
    logger.debug('X test')
    logger.debug('  %s %s', type(X_test), len(X_test))
    logger.debug('  %s %s', type(X_test[0]), X_test[0].shape)
    logger.debug('  %s %s', type(X_test[0][0]), X_test[0][0].shape)
    logger.debug('  %s %s', type(X_test[0][0][0]), X_test[0][0].shape)
    logger.debug('y test')
    logger.debug('  %s %s', type(y_test), len(y_test))
    logger.debug('  %s %s', type(y_test[0]), y_test[0].shape)
    logger.debug('  %s %s', type(y_test[0][0]), y_test[0][0].shape)
    ### STORE DATA ###
    logger.info('Saving data to %s', target_path)
    dataList = [X_test, y_test, valid_frames_test]
    saveToPkl(target_path, dataList)

    logger.info('Preprocessing complete!')
    logger.info('Total time: {:.3f}'.format(timeit.default_timer() - program_start_time))

if __name__ == "__main__":
    main()


from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

from app1 import views
app_name='app1'
urlpatterns = [
    path('',views.fn1,name='fn1'),
    path('delete/<int:id>/',views.deletefn,name='deletefn'),
    path('update/<int:id>/',views.updatefn,name='updatefn'),
    path('list/',views.list.as_view(),name='list'),
    path('detail/<int:pk>/',views.detail.as_view(),name='detail'),
    path('update1/<int:pk>/',views.update.as_view(),name='update'),
    path('delete1/<int:pk>/',views.delete.as_view(),name='delete'),
]

if settings.DEBUG:
    urlpatterns +=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
    urlpatterns +=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)


import socket # for connecting to the server
import _thread # to manage multiple clients
import json # to enconde and decode the data

host = '127.0.0.1'
port = 5000  # initiate port no above 1024

clients = {}

def server_program():
    print('Starting Relay Server at ' + host + ':' + str(port))  # show in terminal
    print('Waiting for clients...')

    server_socket = socket.socket()  # get instance
    server_socket.bind((host, port))  # bind host address and port together

    # configure how many clients the server can listen simultaneously
    server_socket.listen(2)

    while True:
        conn, address = server_socket.accept()  # accept new connection
        _thread.start_new_thread(on_new_client,(conn, address)) #puts into a thread.

    server_socket.close()  # close the connection

def on_new_client(clientsocket, addr):
    # print("Connection from: " + str(addr))
    # print("Waiting for client name...")

    # wait for the first message.
    msgRaw = clientsocket.recv(1024).decode()
    # print("Message received: " + msgRaw)

    # Register the socket name at a list.
    msgDict = json.loads(msgRaw)
    print(msgDict['client_id'] + " connected")
    clients[msgDict['client_id']] = clientsocket

    wait_for_next_message(clientsocket, msgDict['client_id'])

def wait_for_next_message(clientsocket, client_id):
    # wait for a message.
    msgRaw = clientsocket.recv(1024).decode()

    while msgRaw:
        print("Message received from " + client_id + ": " + msgRaw)
        msgDict = json.loads(msgRaw)

        if msgDict['to'] in clients.keys():
            #reformat the message
            formattedMsg = json.dumps({'from': client_id, 'data': msgDict['data']})
            # sending it to the next partner
            clients[msgDict['to']].send(formattedMsg.encode())  # send data to the client
        else:
            print(msgDict['to'] + ' is not connected')
            # could not find the other socket
            formattedMsg = json.dumps({'error':msgDict['to']+ ' not found'})
            # sending error message back.
            clientsocket.send(formattedMsg.encode())  # send data to the client

        #wait for next message
        msgRaw = clientsocket.recv(1024).decode()

    clientsocket.close()

if __name__ == '__main__':
    server_program()


import os
import json
import importlib
from io import StringIO

import h2o.exceptions
import pytest
import pandas as pd
import insolver
from insolver import InsolverDataFrame
from insolver.wrappers import InsolverGLMWrapper
from insolver.transforms import (
    InsolverTransform,
    TransformAge,
    TransformMapValues,
    TransformPolynomizer,
    TransformAgeGender,
)

class TransformExp:
    def __init__(self, column_driver_minexp, exp_max=52):
        self.priority = 1
        self.column_driver_minexp = column_driver_minexp
        self.exp_max = exp_max

    @staticmethod
    def _exp(exp, exp_max):
        if pd.isnull(exp):
            exp = None
        elif exp < 0:
            exp = None
        else:
            exp = exp // 12
        if exp > exp_max:
            exp = exp_max
        return exp

    def __call__(self, df):
        df[self.column_driver_minexp] = df[self.column_driver_minexp].apply(self._exp, args=(self.exp_max,))
        return df

features = [
    'LicAge',
    'Gender',
    'MariStat',
    'DrivAge',
    'HasKmLimit',
    'BonusMalus',
    'RiskArea',
    'Age_m',
    'Age_f',
    'Age_m_2',
    'Age_f_2',
]
target = 'ClaimAmount'

train_df = (
    'LicAge,Gender,MariStat,DrivAge,HasKmLimit,BonusMalus,RiskArea,ClaimAmount\r\n'
    '55,Female,Alone,37,0,95,11.0,3689.5413897281\r\n'
    '346,Male,Other,50,0,50,10.0,791.593957703927\r\n'
    '473,Male,Other,60,0,50,4.0,1096.88972809668\r\n'
    '159,Female,Other,40,1,54,9.0,179.258610271903\r\n'
    '419,Female,Other,66,0,50,3.0,84.4567975830816\r\n'
    '393,Female,Other,58,0,50,9.0,1415.59395770393\r\n'
)

test_df = (
    'LicAge,Gender,MariStat,DrivAge,HasKmLimit,BonusMalus,RiskArea,ClaimAmount\r\n'
    '393,Female,Other,58,0,50,9.0,1415.59395770393\r\n'
)

train_df = InsolverDataFrame(pd.read_csv(StringIO(train_df)))
test_df = pd.read_csv(StringIO(test_df))

InsTransforms = InsolverTransform(
    train_df,
    [
        TransformAge('DrivAge', 18, 75),
        TransformExp('LicAge', 57),
        TransformMapValues('Gender', {'Male': 0, 'Female': 1}),
        TransformMapValues('MariStat', {'Other': 0, 'Alone': 1}),
        TransformAgeGender('DrivAge', 'Gender', 'Age_m', 'Age_f', age_default=18, gender_male=0, gender_female=1),
        TransformPolynomizer('Age_m'),
        TransformPolynomizer('Age_f'),
    ],
)
InsTransforms.ins_transform()
InsTransforms.save('transforms.pickle')

x_train = InsTransforms.loc[InsTransforms.index.tolist()[:-1], features]
y_train = InsTransforms.loc[InsTransforms.index.tolist()[:-1], target]
x_test = InsTransforms.loc[[InsTransforms.index.tolist()[-1]], features]

iglm = InsolverGLMWrapper(backend='h2o', family='gamma', link='log')
iglm.fit(x_train, y_train)
iglm.save_model(name='test_glm_model')

predict = iglm.predict(x_test)
request_json_h2o = {'df': json.loads(test_df.iloc[0].to_json())}

with open("./dev/test_request_frempl.json", 'r') as file_:
    request_json = json.load(file_)

@pytest.mark.xfail(raises=h2o.exceptions.H2OServerError)
def test_h2o_model():
    os.environ['model_path'] = './test_glm_model.h2o'
    os.environ['transforms_path'] = './transforms.pickle'

    from insolver.serving.flask_app import app

    os.remove("test_glm_model.h2o")
    app.testing = True

    with app.test_client() as client:
        response = client.post(
            '/predict',
            data=json.dumps(request_json_h2o),
            content_type='application/json',
        )
        data = json.loads(response.get_data(as_text=True))
        assert response.status_code == 200
        assert round(data['predicted'][0], 7) == round(predict[0], 7)

def test_index_page():
    os.environ['model_path'] = './dev/insolver_gbm_lightgbm_1657653374832.pickle'
    os.environ['transforms_path'] = './dev/transforms'
    importlib.reload(insolver.serving.flask_app)
    from insolver.serving.flask_app import app

    app.testing = True
    with app.test_client() as client:
        response = client.get()
        assert response.status_code == 200

# def test_flask_transforms_inference():
#     os.environ['model_path'] = './dev/insolver_gbm_lightgbm_1657653374832.pickle'
#     os.environ['transforms_path'] = './dev/transforms'
#     importlib.reload(insolver.serving.flask_app)
#     from insolver.serving.flask_app import app
#
#     os.remove("transforms.pickle")
#
#     app.testing = True
#
#     with app.test_client() as c:
#         response = c.post(
#             '/predict',
#             data=json.dumps(request_json),
#             content_type='application/json',
#         )
#         data = json.loads(response.get_data(as_text=True))
#         print(data)
#         assert round(data['predicted'][0], 5) == {"predicted": [1598.11057]}['predicted'][0]
#         assert response.status_code == 200


import uuid

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _

class TimeStampedMixin(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class UUIDMixin(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    class Meta:
        abstract = True

class Genre(UUIDMixin, TimeStampedMixin):
    name = models.CharField(_('name'), max_length=255)
    description = models.TextField(_('description'), blank=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'content"."genre'
        verbose_name = _('genre')
        verbose_name_plural = _('genres')

class Person(UUIDMixin, TimeStampedMixin):
    full_name = models.TextField(_('full_name'))
    birth_date = models.DateField(_('birth_date'), blank=True, null=True)

    def __str__(self):
        return self.full_name

    class Meta:
        db_table = 'content"."person'
        verbose_name = _('person')
        verbose_name_plural = _('persons')

class FilmWork(UUIDMixin, TimeStampedMixin):
    class FilmWorkTypeChoices(models.TextChoices):
        MOVIE = 'movie', _('movie')
        TV_SHOW = 'tv_show', _('tv_show')

    title = models.CharField(_('title'), max_length=255)
    description = models.TextField(_('description'), blank=True, null=True)
    creation_date = models.DateField(_('creation_date'), blank=True, null=True)
    rating = models.FloatField(
        _('rating'),
        blank=True,
        null=True,
        validators=[MinValueValidator(0), MaxValueValidator(100)]
    )
    type = models.CharField(
        _('type'),
        max_length=7,
        choices=FilmWorkTypeChoices.choices,
        default=FilmWorkTypeChoices.MOVIE,
    )
    genres = models.ManyToManyField(Genre, through='GenreFilmWork', verbose_name=_('genres'), )
    persons = models.ManyToManyField(Person, through='PersonFilmWork', verbose_name=_('persons'))
    certificate = models.CharField(_('certificate'), max_length=512, blank=True, null=True)
    # Параметр upload_to указывает, в какой подпапке будут храниться загружемые файлы.
    # Базовая папка указана в файле настроек как MEDIA_ROOT
    file_path = models.FileField(_('file'), blank=True, null=True, upload_to='movies/')

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'content"."film_work'
        verbose_name = _('film_work')
        verbose_name_plural = _('film_works')

class GenreFilmWork(UUIDMixin):
    film_work = models.ForeignKey('FilmWork', on_delete=models.RESTRICT)
    genre = models.ForeignKey('Genre', on_delete=models.RESTRICT, verbose_name=_('genre'))
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'content"."genre_film_work'
        verbose_name = _('film_work_genre_rel')
        verbose_name_plural = _('film_work_genre_rel_plural')

        indexes = [
            models.Index(fields=['genre'], name='genre_film_work_genre_idx'),
            models.Index(fields=['film_work'], name='genre_film_work_film_work_idx'),
        ]

        constraints = [
            models.UniqueConstraint(fields=['film_work', 'genre'], name='unique_film_work_genre')
        ]

class PersonFilmWork(UUIDMixin, TimeStampedMixin):
    class PersonFilmWorkRoleChoices(models.TextChoices):
        DIRECTOR = 'director', _('director')
        WRITER = 'writer', _('writer')
        ACTOR = 'actor', _('actor')

    film_work = models.ForeignKey('FilmWork', on_delete=models.RESTRICT)
    person = models.ForeignKey('Person', on_delete=models.RESTRICT)
    role = models.CharField(
        _('role'),
        max_length=8,
        choices=PersonFilmWorkRoleChoices.choices,
        default=PersonFilmWorkRoleChoices.ACTOR,
        null=True
    )

    class Meta:
        db_table = 'content"."person_film_work'
        verbose_name = _('person_film_work_rel_plural')
        verbose_name_plural = _('person_film_work_rel_plural')

        indexes = [
            models.Index(fields=['person'], name='person_film_work_person_idx'),
            models.Index(fields=['film_work'], name='person_film_work_film_work_idx'),
        ]

        constraints = [
            models.UniqueConstraint(fields=['person', 'film_work', 'role'], name='unique_film_work_member')
        ]


import sys
from collections import deque
from itertools import combinations
import copy

input = sys.stdin.readline

N,M = map(int, input().split())
board = [[0 for _ in range(M)] for _ in range(N)]
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
answer = -1

empty_pos = []
virus_pos = []
for i in range(N):
    row = list(map(int, input().split()))
    for j in range(len(row)):
        if row[j] == 0:
            empty_pos.append((i,j))
        if row[j] == 2:
            virus_pos.append((i,j))
        board[i][j] = row[j]

for c in combinations(empty_pos, 3):
    for x,y in c:
        board[x][y] = 1
    qu = deque()
    visited = [[0 for _ in range(M)] for _ in range(N)]
    num = 3
    for x,y in virus_pos:
        qu.append((x,y))
        visited[x][y] = 1
    while qu:
        now_x, now_y = qu.popleft()
        if board[now_x][now_y] == 0:
            num += 1
        for i in range(4):
            next_x, next_y = now_x + dx[i], now_y + dy[i]
            if next_x<0 or next_x>=N or next_y<0 or next_y>=M or visited[next_x][next_y] or board[next_x][next_y]==1:
                continue
            qu.append((next_x, next_y))
            visited[next_x][next_y] = 1

    answer = max(answer, len(empty_pos)-num)
    for x,y in c:
        board[x][y] = 0

print(answer)


import datetime
from typing import Callable, List

MIGRATIONS: List[Callable] = []
migration = MIGRATIONS.append

def migrate(db):
    ensure_migrations_table(db)
    already_applied = {r["name"] for r in db["_llm_migrations"].rows}
    for fn in MIGRATIONS:
        name = fn.__name__
        if name not in already_applied:
            fn(db)
            db["_llm_migrations"].insert(
                {"name": name, "applied_at": str(datetime.datetime.utcnow())}
            )
            already_applied.add(name)

def ensure_migrations_table(db):
    if not db["_llm_migrations"].exists():
        db["_llm_migrations"].create(
            {
                "name": str,
                "applied_at": str,
            },
            pk="name",
        )

@migration
def m001_initial(db):
    # Ensure the original table design exists, so other migrations can run
    if db["log"].exists():
        # It needs to have the chat_id column
        if "chat_id" not in db["log"].columns_dict:
            db["log"].add_column("chat_id")
        return
    db["log"].create(
        {
            "provider": str,
            "system": str,
            "prompt": str,
            "chat_id": str,
            "response": str,
            "model": str,
            "timestamp": str,
        }
    )

@migration
def m002_id_primary_key(db):
    db["log"].transform(pk="id")

@migration
def m003_chat_id_foreign_key(db):
    db["log"].transform(types={"chat_id": int})
    db["log"].add_foreign_key("chat_id", "log", "id")

@migration
def m004_column_order(db):
    db["log"].transform(
        column_order=(
            "id",
            "model",
            "timestamp",
            "prompt",
            "system",
            "response",
            "chat_id",
        )
    )

@migration
def m004_drop_provider(db):
    db["log"].transform(drop=("provider",))

@migration
def m005_debug(db):
    db["log"].add_column("debug", str)
    db["log"].add_column("duration_ms", int)

@migration
def m006_new_logs_table(db):
    columns = db["log"].columns_dict
    for column, type in (
        ("options_json", str),
        ("prompt_json", str),
        ("response_json", str),
        ("reply_to_id", int),
    ):
        # It's possible people running development code like myself
        # might have accidentally created these columns already
        if column not in columns:
            db["log"].add_column(column, type)

    # Use .transform() to rename options and timestamp_utc, and set new order
    db["log"].transform(
        column_order=(
            "id",
            "model",
            "prompt",
            "system",
            "prompt_json",
            "options_json",
            "response",
            "response_json",
            "reply_to_id",
            "chat_id",
            "duration_ms",
            "timestamp_utc",
        ),
        rename={
            "timestamp": "timestamp_utc",
            "options": "options_json",
        },
    )

@migration
def m007_finish_logs_table(db):
    db["log"].transform(
        drop={"debug"},
        rename={"timestamp_utc": "datetime_utc"},
        drop_foreign_keys=("chat_id",),
    )
    with db.conn:
        db.execute("alter table log rename to logs")

@migration
def m008_reply_to_id_foreign_key(db):
    db["logs"].add_foreign_key("reply_to_id", "logs", "id")

@migration
def m008_fix_column_order_in_logs(db):
    # reply_to_id ended up at the end after foreign key added
    db["logs"].transform(
        column_order=(
            "id",
            "model",
            "prompt",
            "system",
            "prompt_json",
            "options_json",
            "response",
            "response_json",
            "reply_to_id",
            "chat_id",
            "duration_ms",
            "timestamp_utc",
        ),
    )

@migration
def m009_delete_logs_table_if_empty(db):
    # We moved to a new table design, but we don't delete the table
    # if someone has put data in it
    if not db["logs"].count:
        db["logs"].drop()

@migration
def m010_create_new_log_tables(db):
    db["conversations"].create(
        {
            "id": str,
            "name": str,
            "model": str,
        },
        pk="id",
    )
    db["responses"].create(
        {
            "id": str,
            "model": str,
            "prompt": str,
            "system": str,
            "prompt_json": str,
            "options_json": str,
            "response": str,
            "response_json": str,
            "conversation_id": str,
            "duration_ms": int,
            "datetime_utc": str,
        },
        pk="id",
        foreign_keys=(("conversation_id", "conversations", "id"),),
    )

@migration
def m011_fts_for_responses(db):
    db["responses"].enable_fts(["prompt", "response"], create_triggers=True)


import mysql_config
import mysql.connector
from mysql.connector import errorcode
import datetime
import decimal
import plotly.express as px
import seaborn as sns
import matplotlib as mpl
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np
import plotly.graph_objects as go
import io
import time
#from base64 import b64encode

#server only
import os
import output_template

cnx = mysql.connector.connect(**mysql_config.config)

class wu_forecast():
    def __init__(self, connection):
        self.wunderground_forecast_column_list = [
        'date_gathered',
        'date_forecast',
        'max_temp',
        'min_temp',
        'qpf',
        'precip_type_day',
        'precip_type_night',
        'precip_chance_day',
        'precip_chance_night',
        'relative_humidity_day',
        'relative_humidity_night',
        'wx_phrase_day',
        'wx_phrase_night',
        'snow_amount_day',
        'snow_amount_night',
        'wind_direction_day',
        'wind_direction_cardinal_day',
        'wind_direction_night',
        'wind_direction_cardinal_night',
        'wind_speed_day',
        'wind_speed_night',
        'cloud_cover_chance_day',
        'cloud_cover_chance_night'
        ]
        self.date = str(datetime.datetime.now())[:-13]
        #print (datetime.datetime.now().date())

        self.connection = connection
        self.cursor = self.connection.cursor()
        self.get_forecast_data()
        self.out_list_test()

    def get_forecast_data(self):
        table = {39: None, 91: None, 93: None}
        # does this get every forecast from today, or only the last one?
        sql = "SELECT {0} FROM wunderground_forecast WHERE date_gathered LIKE '{1}%' ORDER BY date_forecast DESC".format(str(self.wunderground_forecast_column_list).translate(table), self.date)
        self.cursor.execute(sql)
        self.forecast_data = self.cursor.fetchall()

    def get_out_list(self):
        """this should return a list of dictionaries for each day"""
        out_list = []
        shortened_out_list = []
        x = 0
        for day in self.forecast_data:
            out_dict = {}
            inc = 0
            for key in self.wunderground_forecast_column_list:
                if key == 'date_forecast':
                    #day[inc] = day[inc].date()
                    out_dict[key] = day[inc].date()
                elif type(day[inc]) == decimal.Decimal and key != 'qpf':
                    out_dict[key] = str(day[inc])[:-3]
                else:
                    out_dict[key] = day[inc]
                inc += 1

            out_list.append(out_dict)

        last_date = self.get_last_gathered_date(out_list)

        for day in out_list:
            if day['date_gathered'] == last_date:
                shortened_out_list.append(day)

        shortened_out_list.reverse()

        return shortened_out_list

    def get_last_gathered_date(self, in_list):
        """ takes a list of all databse entries gathered this hour, and returns the date the last one was gathered on"""
        date_gathered_list = []
        #print (in_list)
        for out_day in in_list:
            for y in out_day:
                #print (y, ': ', out_day[y])
                if y == "date_gathered":
                    date_gathered_list.append(out_day[y])
        date_gathered_list = list(set(date_gathered_list))
        print (date_gathered_list)
        last_date = date_gathered_list[0]
        for date in date_gathered_list:
            if date > last_date:
                last_date = date
        return last_date

    def out_list_test(self):
        index = 0
        for forecast_day in self.forecast_data:
            #print (len(day))
            #print (type(day))
            for item in self.wunderground_forecast_column_list:
                #print (item[self.wunderground_forecast_column_list.index(item)], ': ', forecast_day)
                pass

class wunder_data():
    def __init__(self, connection, location):
        self.location = location
        self.connection = connection
        self.cursor = self.connection.cursor()
        self.get_data()
        self.get_current_data()
        self.get_last_dates()
        self.get_weekly_precip()
        self.get_temp_list()
        #self.out_web_file()

    def __str__(self):
        output = ''
        for entry in self.data_list:
            output += entry + ": " + str(self.current_conditions[entry])
            output +='\n'
            #print (entry + " : ")
            #print (self.current_conditions[entry])
        output +=('Rainfall for the last 7 days :\n')
        #for entry in self.total_dict:
        #    #output += date.date + ": " + value
        #    #output += str(entry)
        #    output += str(entry.date()) + ": "
        #    #output += str(self.total_dict[entry]) + "\n"
        for entry in self.total_list:
            output += str(entry[0].date()) + ": " + str(entry[1]) + "\n"
            #output += str(
        output += ("\nTotal rainfall for this week is : " + str(self.weekly_precip))
        return output

    def get_temp_list(self):
        """Gets last temp:time list"""
        data_list = ['current_temp', 'date']
        temp_list = []
        day = datetime.datetime.now()
        from_day = day - datetime.timedelta(days=1)
        #location = 'KWACARNA1'
        sql = f"SELECT current_temp, date FROM wunderground WHERE date > '{str(from_day)}' and location='{self.location}' ORDER BY date DESC"
        self.cursor.execute(sql)
        info_list = self.cursor.fetchall()
        #print (info_list)
        time_list = []
        for item in info_list:
            time_list.append(np.datetime64(item[1]))
            temp_list.append(item[0])
        f_date = mpl.dates.DateFormatter('%H')
        print (self.location)
        #for x in time_list:
        #    print(x)
        print (len(time_list))
        print (len(temp_list))

        #Matplotlib
        #fig, ax  = plt.subplots(figsize=(3.5,3))
        #ax.plot(time_list, temp_list)
        #ax.xaxis.set_major_formatter(f_date)
        #ax.grid(visible=True, which='major')

        #fig.write_html('/var/www/weather_app/graph.html')
        #file_name = f'/var/www/weather_app/temp{self.location}.png'
        #fig.savefig(file_name)
        #self.graph = f'/temp{self.location}.png'

        #Plotlyexpress
        #file_name = f'/var/www/weather_app/temp{self.location}.html'
        #self.graph = f'/temp{self.location}.html'
        #print (time_list, temp_list)
        fig = px.line(x=time_list, y=temp_list, labels=dict(x="Time", y="Temperature"))
        #fig = sns.lineplot(x=time_list, y=temp_list)
        max_temp = temp_list[0]
        min_temp = temp_list[0]
        for temp in temp_list:
            if temp > max_temp:
                max_temp = temp
            if temp < min_temp:
                min_temp = temp

        for temp in temp_list:
            if temp == max_temp:
                ind = temp_list.index(temp)
                fig.add_annotation(x=time_list[ind], y=temp, text=str(temp))
            if temp == min_temp:
                ind = temp_list.index(temp)
                fig.add_annotation(x=time_list[ind], y=temp, text=str(temp))
        #print (plot(fig))
        #fig.write_html(file_name)
        buffer_s = io.StringIO()
        fig.write_html(buffer_s, include_plotlyjs='cdn')
        self.html_graph = buffer_s.getvalue()
        buffer_s.close()
        print (buffer_s.closed)
        del buffer_s
        del fig

        #print (type(self.html_graph))

    def template_out_dict(self):
        out_dict = {}
        rain_list = []
        for entry in self.data_list:
            out_dict[entry] = self.current_conditions[entry]
        for entry in self.total_list:
            out = (str(entry[0].date()), str(entry[1]))
            rain_list.append(out)
        out_dict['rain_list'] = rain_list
        if self.location =='KWACARNA1':
            out_dict['class'] = 'left'
        else:
            out_dict['class'] = 'right'

        out_dict['pressure_direction'] = self.get_point_list()
        print("Here")
        print(out_dict['today_precip'])
        out_dict['weekly_rain'] = str((self.weekly_precip + out_dict['today_precip']))
        #out_dict['temp_graph'] = str(self.graph)
        out_dict['html_graph'] = str(self.html_graph)
        return out_dict

    def out_web_file(self):
        with open('/var/www/weather_app/index.html', 'w') as out:
            out_text = ' \n  \n'
            for entry in self.data_list:
                out_text += '%s: %s
 \n' % (str(entry), str(self.current_conditions[entry]))

            out_text +=('Rainfall for the last 7 days :
\n')
            try:
                for entry in self.total_list:
                    out_text += str(entry[0].date()) + ": " + str(entry[1]) + "
 \n"
                    #output += str(
                out_text += ("\nTotal rainfall for this week is : " + str(self.weekly_precip + self.current_conditions[self.data_list[3]]) + "
")
            except AttributeError:
                out_text += ("\n There is not enough data for total rainfall yet, please check back later.")

            out_text += ' \n  \n'
            out.write(out_text)

    def get_data(self):
        table = {39: None, 91: None, 93: None}
        self.data_list = ['date', 'location', 'current_pressure', 'current_temp', 'today_precip', 'current_humidity', 'wind_speed', 'wind_direction', 'wind_gust', 'wind_chill', 'dew_point']
        #sql = f"SELECT {str(self.data_list).translate(table)} FROM wunderground WHERE location='{self.location}' ORDER BY date DESC"

        now = datetime.datetime.now()
        first_date = now - datetime.timedelta(days=8)
        #print (first_date)
        sql = f"SELECT {str(self.data_list).translate(table)} FROM wunderground WHERE date > '{first_date}' and location='{self.location}' ORDER BY date DESC"
        self.cursor.execute(sql)
        self.data = self.cursor.fetchall()
        #print (self.data)

    def get_current_data(self):
        out_dict = {}
        x = 0
        inc = 0
        print(self.data_list)
        for key in self.data_list:
            print(key)
            #print(self.data[x][inc])
            #print(self.data)
            out_dict[key] = self.data[x][inc]
            #out_dict[key] = self.data[inc]
            inc +=1
            #print (inc)
            #print (out_dict)
        self.current_conditions = out_dict
        #print (out_dict)

    def return_value_list(self, data, name):
        """data is data list, name is key of wanted value"""
        out_dict = {}
        inc = 0
        for key in self.data_list:
            out_dict[key] = data[inc]
            inc +=1
        return out_dict[name]

    def get_last_dates(self):
        """ can only be called after get_data has been called.
        This method will then go through all the data and get the last entry from each day"""
        sql =  "SELECT date FROM wunderground ORDER BY date ASC"
        self.cursor.execute(sql)
        dates = self.cursor.fetchall()
        out_dates = []
        self.last_time_of_day_list = []
        last_day = dates[0][0].date()
        last_time = dates[0][0].time()
        possible_day = ''
        for date in dates:
            if date[0].date() == last_day:
                if date[0].time() > last_time:
                    last_time = date[0].time()
                    possible_day = date[0]
                    #last_time_of_day_list.append(date[0])
            elif date[0].date() > last_day:
                self.last_time_of_day_list.append(possible_day)
                # this won't collect data from a day if there is only one entry from that day
                last_day =  date[0].date()
                last_time = date[0].time()

            if date[0].date() < last_day:
                pass

            out_dates.append(date[0])
            # TESTING
            #print (self.last_time_of_day_list)
        #for date in self.last_time_of_day_list:
        #    print (date)

    def return_daily_precip(self, date):
        """Only call after get_last_dates.
        This method will get the today_precip from each of those entries"""
        #for date in self.last_time_of_day_list:
        for entry in self.data:
            if date in entry:
                #TESTING
                #print (self.return_value_list(entry))
                return (self.return_value_list(entry, 'today_precip'))

    def get_weekly_precip(self):
        """should this always return info for the last week, or should it take a day as input?"""
        #changing to list of tuples to keep order
        #self.total_dict = {}
        self.total_list = []
        self.weekly_precip = 0
        for date in self.last_time_of_day_list[-7:]:
            if date != '':
                self.total_list.append(tuple((date, self.return_daily_precip(date))))
                #self.total_dict[date] = self.return_daily_precip(date)

        try:
            for day in self.total_list:
                if day[1] != None:
                    self.weekly_precip += day[1]
        except TypeError as error:
            #raise error
            pass

    def get_yearly_precip(self):
        pass

    def get_pressure_direction(self):
        out_list = []
        for entry in self.data[:7]:

            #pressure = self.return_value_list(entry, 'current_pressure')
            out_list.append(entry[2])
        out_list.reverse()
        return out_list

    def get_point_list(self):
        pressure_list = self.get_pressure_direction()
        if len(pressure_list) < 6:
            out_html = 'No data'
            print( self.location, ': low data')
            return out_html
        if (abs(pressure_list[6]) - abs(pressure_list[5])) > .03 or (abs(pressure_list[6]) - abs(pressure_list[4])) > .02:
            if (pressure_list [6] > pressure_list[5]) or (pressure_list [6] > pressure_list[4]):
                out_var = "10,30 10,0 0,4 20,4, 10,0"
                out_html = '&#8593'
                print (self.location, ': up')
            else:
                out_var = "10,0 10,30, 0,26, 20,26 10,30"
                out_html = '&#8595'
                print (self.location, ': down')

        else:
            out_var = "10,0 10,30 0,26 20,26, 10,30"
            out_html = '&#8594'
            print (self.location, ': steady')

        return out_html

if __name__=="__main__":
    start = time.process_time()
    location_list = ['KWACARNA1', 'KWAFALLC80', 'KWAFALLC81']
    #location_list = ['KWACARNA1', 'KWAFALLC80']
    #location_list = ['KWAFALLC80', 'KWACARNA1' ]
    out_list = []
    for location in location_list:
        weather_data = wunder_data(cnx, location)
        out_list.append(weather_data.template_out_dict())

    forecast_data = wu_forecast(cnx)
    forecast_list = forecast_data.get_out_list()

    #print (out_list)
    output_text = output_template.render_template(out_list, forecast_list)

    with open('/var/www/weather_app/index.html', 'w') as out:
            out.write(output_text)
    end = time.process_time()
    print (end - start)


"""
Pytorch Lightning models for MNIST dataset.
"""

from typing import Callable, List, Optional, Union
from lightning.pytorch.utilities.types import EVAL_DATALOADERS
import torch
from torch import nn
from torch.nn import functional as F
from torch.utils.data import DataLoader, random_split
from torchmetrics import Accuracy
from torchvision import transforms
from torchvision.datasets import MNIST

from .base import ItwinaiBasePlModule, ItwinaiBasePlDataModule

class MNISTDataModule(ItwinaiBasePlDataModule):
    """Pytorch Lightning data module for MNIST dataset

        Args:
            data_dir (str): path to dataset directory
            batch_size (int, optional): batch size. Defaults to 32.
            train_prop (float, optional): proportion of examples in the train
                split, after dataset is split into train and validation.
                Defaults to 0.7.
            transform (Optional[Callable], optional): transformations to apply
                to the loaded images. Defaults to None.
    """

    def __init__(
        self,
            data_dir: str,
            batch_size: int = 32,
            train_prop: float = 0.7,
            transform: Optional[Callable] = None,
    ) -> None:
        super().__init__()
        self.data_dir = data_dir
        self.batch_size = batch_size
        self.train_prop = train_prop
        if transform is None:
            self.transform = transforms.Compose(
                [
                    transforms.ToTensor(),
                    transforms.Normalize((0.1307,), (0.3081,)),
                ]
            )
        else:
            self.transform = transform

    def setup(self, stage=None):
        # Assign train/val datasets for use in dataloaders
        if stage == "fit" or stage is None:
            mnist_full = MNIST(
                self.data_dir, train=True,
                transform=self.transform,
                download=False
            )
            n_train_samples = int(self.train_prop * len(mnist_full))
            n_val_samples = len(mnist_full) - n_train_samples
            self.mnist_train, self.mnist_val = random_split(
                mnist_full, [n_train_samples, n_val_samples]
            )

        # Assign test dataset for use in dataloader(s)
        if stage == "test" or stage is None:
            self.mnist_test = MNIST(
                self.data_dir,
                train=False,
                download=False,
                transform=self.transform
            )

        if stage == "predict":
            self.mnist_predict = MNIST(
                self.data_dir,
                train=False,
                download=False,
                transform=self.transform
            )

    def train_dataloader(self):
        return DataLoader(
            self.mnist_train,
            batch_size=self.batch_size,
            num_workers=4,
        )

    def val_dataloader(self):
        return DataLoader(
            self.mnist_val,
            batch_size=self.batch_size,
            num_workers=4,
        )

    def test_dataloader(self):
        return DataLoader(
            self.mnist_test,
            batch_size=self.batch_size,
            num_workers=4,
        )

    def predict_dataloader(self) -> EVAL_DATALOADERS:
        return DataLoader(
            self.mnist_predict,
            batch_size=self.batch_size,
            num_workers=4,
        )

    def preds_to_names(
        self,
        preds: Union[torch.Tensor, List[torch.Tensor]]
    ) -> List[str]:
        """Convert predictions to class names."""
        # Convert prediction to label: in this case is easy, as the label
        # is an integer.
        if not isinstance(preds, list):
            preds = [preds]

        names = []
        for p in preds:
            p += 1
            names.extend([str(el) for el in p.tolist()])
        return names

class LitMNIST(ItwinaiBasePlModule):
    """
    Simple PL model for MNIST.
    Adapted from
    https://lightning.ai/docs/pytorch/stable/notebooks/lightning_examples/mnist-hello-world.html
    """

    def __init__(
        self,
        hidden_size: int = 64,
    ):
        super().__init__()

        # Automatically save constructor args as hyperparameters
        self.save_hyperparameters()

        # Set our init args as class attributes
        self.hidden_size = hidden_size

        # Hardcode some dataset specific attributes
        self.num_classes = 10
        self.dims = (1, 28, 28)
        channels, width, height = self.dims
        self.transform = transforms.Compose(
            [
                transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,)),
            ]
        )

        # Define PyTorch model
        self.model = nn.Sequential(
            nn.Flatten(),
            nn.Linear(channels * width * height, hidden_size),
            nn.ReLU(),
            nn.Dropout(0.1),
            nn.Linear(hidden_size, hidden_size),
            nn.ReLU(),
            nn.Dropout(0.1),
            nn.Linear(hidden_size, self.num_classes),
        )

        self.val_accuracy = Accuracy(task="multiclass", num_classes=10)
        self.test_accuracy = Accuracy(task="multiclass", num_classes=10)

    def forward(self, x):
        x = self.model(x)
        return F.log_softmax(x, dim=1)

    def training_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)

        # Log metrics with autolog
        self.log(
            "train_loss",
            loss,
            on_step=True,
            on_epoch=True
        )

        # Good alternative
        # # Log with generic logger
        # self.logger.log_metrics(
        #     metrics=dict(train_loss=loss.item()),
        #     step=self.global_step
        # )

        return loss

    def validation_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        preds = torch.argmax(logits, dim=1)
        self.val_accuracy.update(preds, y)

        self.log(
            "val_loss",
            loss,
            prog_bar=True,
            on_step=True,
            on_epoch=True
        )
        self.log(
            "val_acc",
            self.val_accuracy,
            prog_bar=True,
            on_step=True,
            on_epoch=True
        )

        # good alternative
        # # Log with generic logger
        # self.logger.log_metrics(
        #     metrics=dict(val_loss=loss.item()),
        #     step=self.global_step
        # )
        # self.logger.log_metrics(
        #     metrics=dict(val_acc=acc.item()),
        #     step=self.global_step
        # )

    def test_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        preds = torch.argmax(logits, dim=1)
        self.test_accuracy.update(preds, y)

        self.log("test_loss", loss)
        self.log("test_acc", self.test_accuracy)

    def predict_step(self, batch, batch_idx, dataloader_idx=0):
        x, _ = batch
        logits = self(x)
        preds = torch.argmax(logits, dim=1)
        return preds


'''
This pyspark script reads parquet file and displays its content
'''

from pyspark.sql import SparkSession, DataFrame

# Create Spark Session
# here 3.0.3 is the spark version;refer using https://mvnrepository.com/artifact/org.apache.spark/spark-sql-kafka-0-10
spark = SparkSession \
    .builder \
    .appName("Spark Structured Streaming") \
    .config("spark.jars.packages", "org.apache.spark:spark-sql-kafka-0-10_2.12:3.0.3") \
    .master("local[*]") \
    .getOrCreate()

# Set Spark logging level to ERROR to avoid various other logs on console.
spark.sparkContext.setLogLevel("ERROR")

print("Reading data from initial parquet file")

df2 = spark.read.parquet("D:/Datasets/BusinessScenario-Dataset/BusinessScenario-Dataset/initial_file") \
    .createOrReplaceTempView("ParquetTable")
spark.sql("select * from ParquetTable").show(1000)


from django.core.mail import send_mail
from django.utils.translation import gettext

from FamilyBackend import settings
from core.services.email.system import render_email

def send_item_email(timetable: str, row: str, start_time: str,
                    item_title: str, family: str, email: list):
	context = {"timetable": timetable, "row": row,
	           "item_title": item_title,
	           "family": family, "start_time": start_time}
	message = render_email(f"email/timetable/item_email.txt", context)
	subject = gettext(f"{timetable}: {item_title}")
	send_mail(
		subject,
		gettext(message),
		settings.DEFAULT_FROM_EMAIL,
		email,
		fail_silently=True,
	)
	return


"""
自定义中间件
"""
import hashlib

from django.core.cache import cache
from django.http import JsonResponse

SHA1_GEN_PROTO = hashlib.sha1()

def check_user_sign(get_response):

    def middleware(request):
        if request.path.startswith('/api'):
            data = request.GET if request.method == 'GET' else request.data
            try:
                user_id = data['user_id']
                user_token = cache.get(f'fang:user:{user_id}')
                user_sign = data['user_sign']
                hasher = SHA1_GEN_PROTO.copy()
                hasher.update(f'{user_id}:{user_token}'.encode('utf-8'))
                if hasher.hexdigest() == user_sign:
                    return get_response(request)
            except KeyError:
                pass
            return JsonResponse({'msg': '身份验证失败拒绝访问'})
        else:
            return get_response(request)

    return middleware