#!/usr/bin/env python
import os
import shutil
import argparse
import subprocess
import random
import pandas as pd
import numpy as np
import pickle as pkl
import scipy as sp
import networkx as nx
import scipy.stats as stats
import scipy.sparse as sparse

from torch import nn
from torch import optim
from torch.nn import functional as F

from scripts.ulity import *
from scripts.preprocessing import *
from scripts.cnnscript import *
from shutil import which
from collections import Counter
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio.Blast.Applications import NcbiblastnCommandline
from models.phamer import Transformer
from models.CAPCNN import WCNN
from models.PhaGCN import GCN
from models import Cherry
from scipy.special import softmax
from scripts.data import load_data, preprocess_features, preprocess_adj, sample_mask

parser = argparse.ArgumentParser(description="""Main script of PhaSUIT.""")
parser.add_argument('--contigs', help='FASTA file of contigs',  default = 'inputs.fa')
parser.add_argument('--threads', help='number of threads to use', type=int, default=4)
parser.add_argument('--len', help='minimum length of contigs', type=int, default=3000)
parser.add_argument('--reject', help='threshold to reject prophage',  type=float, default = 0.2)
parser.add_argument('--rootpth', help='rootpth of the user', default='user_0/')
parser.add_argument('--out', help='output path of the user', default='out/')
parser.add_argument('--midfolder', help='mid folder for intermidiate files', default='midfolder/')
parser.add_argument('--dbdir', help='database directory',  default = 'database/')
parser.add_argument('--scriptpth', help='path of parameters',  default = 'scripts/')
parser.add_argument('--parampth', help='path of parameters',  default = 'parameters/')
parser.add_argument('--proteins', help='FASTA file of predicted proteins (optional)')
inputs = parser.parse_args()

contigs   = inputs.contigs
midfolder = inputs.midfolder
rootpth   = inputs.rootpth
db_dir    = inputs.dbdir
out_dir   = inputs.out
parampth  = inputs.parampth
threads   = inputs.threads
length    = inputs.len
scriptpth = inputs.scriptpth

if not os.path.exists(db_dir):
    print(f'Database directory {db_dir} missing or unreadable')
    exit(1)

check_path(os.path.join(rootpth, out_dir))
check_path(os.path.join(rootpth, midfolder))

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if device == 'cpu':
    print("running with cpu")
    torch.set_num_threads(inputs.threads)

###############################################################
#######################  Filter length ########################
###############################################################

rec = []
ID2length = {}
for record in SeqIO.parse(contigs, 'fasta'):
    ID2length[record.id] = len(record.seq)
    if len(record.seq) > inputs.len:
        rec.append(record)

if not rec:
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            file_out.write(f'{record.id},filtered,0\n')
    exit()

SeqIO.write(rec, f'{rootpth}/filtered_contigs.fa', 'fasta')

###############################################################
##########################  PhaMer ############################
###############################################################

translation(rootpth, os.path.join(rootpth, midfolder), 'filtered_contigs.fa', 'test_protein.fa', threads, inputs.proteins)
run_diamond(f'{db_dir}/phamer_database.dmnd', os.path.join(rootpth, midfolder), 'test_protein.fa', 'phamer', threads)
convert_xml(os.path.join(rootpth, midfolder), 'phamer', scriptpth)
if os.path.getsize(f'{rootpth}/{midfolder}/phamer_results.abc') == 0:
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            if len(record.seq) > inputs.len:
                file_out.write(f'{record.id},non-phage,0\n')
            else:
                file_out.write(f'{record.id},filtered,0\n')
    exit()
contig2sentence(db_dir, os.path.join(rootpth, midfolder), 'test_protein.fa', 'phamer')

pcs2idx = pkl.load(open(f'{rootpth}/{midfolder}/phamer_pc2wordsid.dict', 'rb'))
num_pcs = len(set(pcs2idx.keys()))

src_pad_idx = 0
src_vocab_size = num_pcs+1

model, optimizer, loss_func = reset_model(Transformer, src_vocab_size, device)
try:
    pretrained_dict=torch.load(f'{parampth}/transformer.pth', map_location=device)
    model.load_state_dict(pretrained_dict)
except:
    print('cannot find pre-trained model')
    exit(1)

sentence   = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence.feat', 'rb'))
id2contig  = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence_id2contig.dict', 'rb'))
proportion = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence_proportion.feat', 'rb'))
contig2id  = {item: key for key, item in id2contig.items()}

all_pred = []
all_score = []
with torch.no_grad():
    _ = model.eval()
    for idx in range(0, len(sentence), 500):
        try:
            batch_x = sentence[idx: idx+500]
            weight  = proportion[idx: idx+500]
        except:
            batch_x = sentence[idx:]
            weight  = proportion[idx:]
        batch_x = return_tensor(batch_x, device).long()
        logit = model(batch_x)
        logit = torch.sigmoid(logit.squeeze(1))
        logit = reject_prophage(logit, weight, inputs.reject)
        pred  = ['phage' if item > 0.5 else 'non-phage' for item in logit]
        all_pred += pred
        all_score += [float('{:.3f}'.format(i)) for i in logit]

#FLAGS
if len(set(all_pred)) == 1 and all_pred[0] == 'non-phage':
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            file_out.write(f'{record.id},non-phage,0\n')
    exit()

### Add filtered label (Nov. 8th)
contigs_list = list(id2contig.values())
contigs_add = []
pred_rec = []
seq_dict = {}
phage_rec = []
for record in SeqIO.parse(f'{contigs}', 'fasta'):
    seq_dict[record.id] = str(record.seq)
    if record.id not in contigs_list:
        if len(record.seq) < inputs.len:
            contigs_add.append(record.id)
            all_pred.append('filtered')
            all_score.append(0)
            continue
        contigs_add.append(record.id)
        all_pred.append('non-phage')
        all_score.append(0)

contigs_list += contigs_add
length_list = [ID2length[item] for item in contigs_list]

pred_csv = pd.DataFrame({"Accession":contigs_list, "Length":length_list, "Pred":all_pred, "Score":all_score})
pred_csv.to_csv(f'{rootpth}/{out_dir}/phamer_prediction.csv', index = False)
phage_list = pred_csv[pred_csv['Pred'] == 'phage']['Accession'].values

for record in SeqIO.parse(f'{contigs}', 'fasta'):
    if record.id in phage_list:
        phage_rec.append(record)

SeqIO.write(phage_rec, f'{rootpth}/predicted_phage.fa', 'fasta')

##### for phage-only results #####
blast_df = pd.read_csv(f"{rootpth}/{midfolder}/phamer_results.abc", sep=' ', names=['query', 'ref', 'evalue'])
protein2evalue = parse_evalue(blast_df, f'{rootpth}/{midfolder}', 'phamer')
rec = []
for record in SeqIO.parse(f'{rootpth}/{midfolder}/test_protein.fa', 'fasta'):
    try:
        protein2evalue[record.id]
        rec.append(record)
    except:
        pass
SeqIO.write(rec, f'{rootpth}/{out_dir}/significant_proteins.fa', 'fasta')
os.system(f"cp {rootpth}/{midfolder}/phamer_results.tab {rootpth}/{out_dir}/blast_results.tab")
os.system(f"sed -i '1i\qseqid\tsseqid\tpident\tlength\tmismatch\tgapopen\tqstart\tqend\tsstart\tsend\tevalue' {rootpth}/{out_dir}/blast_results.tab")


from comparison_sol import str_path
#from Global_alignment_MM_functions import seq_to_alignement
from matplotlib import colors
import argparse
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import os

# This is a script to visualize SCRaMbLEd chromosomes using an arrow plot.
# Created by Marco Monti. email address: marcomonti.mm94@gmail.com
# Last updated on 17/04/2022
# ---------------------------------------------------------------

def reverse_path(path):
    rev_path = []
    for i in path:
        rev_path.insert(0, i)
    return rev_path

def arrowplot(path, max_LU=0, essential=[], CEN=[], names="", essential_col=True, filename="Arrowplot", REF=False, Show=True):
    if isinstance(path, str):
        path = str_path(path)
    if isinstance(path[0], int):  # There is only one path in the list
        path = [path]
    # This will reverse the order of the paths. It is useful to plot the paths from the top to the bottom.
    path = reverse_path(path)

    if names == "":
        names = range(len(path))
    names = reverse_path(names)

    # Create the folder where the output will be created
    if not os.path.exists("arrow_plots"):
        os.makedirs("arrow_plots")

    # get discrete colormap
    # Find the biggest LUs in the list.
    if max_LU == 0:
        #max_LU = max([max(x) for x in path])
        path_join = []
        for P in path:
            path_join = path_join + P
        path_abs = [abs(x) for x in path_join]
        max_LU = max(path_abs)
    # You can choose different gradients here: https://matplotlib.org/stable/tutorials/colors/colormaps.html
    colors_non_esse = cm.Blues(np.linspace(0, 1, max_LU - len(essential)))
    if CEN != []:
        colors_esse = cm.Reds(np.linspace(0, 1, len(essential)-1))      # -1 because there is one centromere in yellow
    else:
        colors_esse = cm.Reds(np.linspace(0, 1, len(essential)))
    # Choose the colour gradient. I like gist_rainbow and jet. jet might be a little be better for color blindness. Other options are: jet, gist_rainbow, hsv, viridis, plasma, magma, gnuplot2, rainbow
    colors_rainbow = cm.jet(np.linspace(0, 1, max_LU))
    ALL_colour = np.zeros(shape=(max_LU, 4))
    counter_esse = 0
    counter_non_esse = 0

    # Add the reference in the first line
    if REF:
        path.append(range(1, max_LU + 1))
        if names != "":
            names.append("ref")

    # Plot the arrows
    for LU in range(0, max_LU):
        if LU in CEN:
            ALL_colour[LU] = [1., 1., 0., 1.]   # this is yellow
        elif LU in essential:
            ALL_colour[LU] = colors_esse[counter_esse]
            counter_esse += 1
        else:
            ALL_colour[LU] = colors_non_esse[counter_non_esse]
            counter_non_esse += 1
    #print("ALL_colour =", ALL_colour)

    # Plot the arrow plot
    longest_path = max([len(x) for x in path])
    dpi = 250
    plt.figure(figsize=(longest_path, len(path)*1.8))
    #plt.figure(figsize=(8, len(path)*0.6), dpi=dpi)     # 8 inches
    for i in range(len(path)):  # y-axis
        #plt.scatter(range(len(path[i])), [i for _ in path[i]], color="black", label=">", s=50, zorder=3)
        for j in range(len(path[i])):  # x-axis
            if essential_col:
                colour = ALL_colour[abs(path[i][j]) - 1]
            else:
                colour = colors_rainbow[abs(path[i][j]) - 1]
            if [abs(path[i][j])] == CEN:    # If the triangle is the centromere, change the colour of the edge
                edgecolor = "red"
                linewidth = 4
            else:
                edgecolor = "dimgrey"
                linewidth = 2

            if path[i][j] >= 0:
                #plt.scatter(j, i, color=colour, marker=">", s=100, zorder=-1, edgecolor="dimgrey", label=abs(path[i][j]))
                # Use this if you want to center the triangles in each point (e.g. center at x=1)
                #triangle = plt.Polygon([[j-0.5,i+0.25], [j-0.5,i-0.25], [j+0.5,i]], facecolor=colour, edgecolor="dimgrey")
                # Use this if you want to center the triangles between two points (e.g. center at x=0.5)
                triangle = plt.Polygon([[j, i+0.25], [j, i-0.25], [j+1, i]], facecolor=colour, edgecolor=edgecolor, label=abs(path[i][j]), linewidth=linewidth)
                plt.gca().add_patch(triangle)
            else:
                #plt.scatter(j, i, color=colour, marker="<", s=100, zorder=-1, edgecolor="dimgrey", label=abs(path[i][j]))
                #triangle = plt.Polygon([[j+0.5,i+0.25], [j+0.5,i-0.25], [j-0.5,i]], facecolor=colour, edgecolor="dimgrey")
                triangle = plt.Polygon([[j+1, i+0.25], [j+1, i-0.25], [j, i]], facecolor=colour, edgecolor=edgecolor, label=abs(path[i][j]), linewidth=linewidth)
                plt.gca().add_patch(triangle)

    # Font size
    SMALL_SIZE = 35     #12
    MEDIUM_SIZE = 45    #15
    BIGGER_SIZE = 50    #18
    plt.rc('font', size=SMALL_SIZE)
    plt.rc('axes', titlesize=SMALL_SIZE)
    plt.rc('axes', labelsize=MEDIUM_SIZE)
    plt.rc('xtick', labelsize=SMALL_SIZE)
    plt.rc('ytick', labelsize=SMALL_SIZE)
    plt.rc('legend', fontsize=SMALL_SIZE)
    plt.rc('figure', titlesize=BIGGER_SIZE)
    # Axis
    plt.yticks(ticks=range(len(path)), labels=names)
    plt.ylim([-0.5, len(path)-0.5])
    plt.xlim([-0.5, longest_path+0.5])
    plt.xlabel("LoxPsym Units (LUs)")
    # This will make sure that the labels in the legend don't get duplicated
    #handles, labels = plt.gca().get_legend_handles_labels()
    #by_label = dict(zip(labels, handles))
    #plt.legend(by_label.values(), by_label.keys())
    if essential_col:
        esse = "_essential"
    else:
        esse = ""
    plt.savefig("arrow_plots/" + filename + esse + "_arrowplot.png", format="png", dpi=dpi, bbox_inches='tight')
    plt.savefig("arrow_plots/" + filename + esse + "_arrowplot.svg", format="svg", dpi=dpi, bbox_inches='tight')
    if Show:
        plt.show()
    plt.close()
    return None

if __name__ == '__main__':
    # These are for global alignment
    match_score = 2
    mismatch_score = -1
    gap_penalty = -2  # gap penalty (gamma)

    A = [1,2,3,9,4,5]
    B = [2,3,5,-1,7,4,5]
    #arrowplot([A,B], essential_col=False, REF=False)
    #print(seq_to_alignement(A,B, match_score, mismatch_score, gap_penalty))
    JS731_SR = [1, 2, 3, 4, 5, 6, 7, -13, -12, -1, -44, -43, -42, -41, -40, 39, -38, -37, -36, 8, 9, 11, 14, 15, 16, 17, 19, 20, 21, -37, -36, 19, 20, 14, 15, 16, -24, -23, -22, 17, 18, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -17, -16, -15, -14, -11, -10, -9, -8, 36, 37, 38, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, 38, -39, 40, 41, 42, 43, 44]
    JS731_LR = [1, 2, 3, 4, 5, 6, 7, -13, -12, -1, -44, -43, -42, -41, -40, 39, -38, -37, -36, 8, 9, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, -21, -20, -19, -17, -38, -37, -36, 8, 9, 10, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, 38, -39, 40, 41, 42, 43, 44]

    # Syn9R SCRaMbLE
    synIXR = list(range(1, 45, 1))
    essential = [2, 7, 9, 10, 12, 20]
    CEN = [2]
    names = ["synIXR", "JS731_SR", "JS731_LR"]
    #arrowplot([synIXR], max_LU=44, essential=essential, CEN=CEN, names=["synIXR"], essential_col=False, filename="synIXR0", REF=False)
    #arrowplot([synIXR, JS731_SR, JS731_LR], max_LU=44, essential=essential, CEN=CEN, names=names, essential_col=False, filename="JS731", REF=False)
    #arrowplot([synIXR, JS731_SR, JS731_LR], max_LU=44, essential=essential, CEN=CEN, essential_col=False, filename="A_test")

    # Syn3 SCRaMbLE
    syn3 = list(range(1, 100, 1))
    essential_3 = [7, 9, 13, 20, 28, 36, 37, 48, 70, 73, 74, 84, 97]
    CEN3 = [37]


from django.conf.urls import url
from . import views

app_name = 'food'

urlpatterns = [
    url(r'^order/$', views.order, name="order"),
    url(r'^$', views.homepage, name="home"),
    url(r'^prepare/$', views.prepare, name="prepare"),
    url(r'^success/$', views.success, name="success"),
    url(r'^business/$', views.business, name="business"),
    url(r'^orderlist/$', views.OrderList.as_view(), name="list"),
    # pk stands for primary key; as_view() means we are using generic view
    url(r'^orderdetail/(?P<pk>[0-9]+)/$', views.OrderDetail.as_view(), name="detail"),
]


import boto3
import sys
import json
from pygments import highlight, lexers, formatters
from src.s3_event_config import S3EventConfig, TopicConfig, QueueConfig, LambdaConfig

class S3Events:
    def __init__(self, client):
        self.Config = {}
        self.Client = client

    def __str__(self, pretty=True):
        json_txt = json.dumps((self.Config), indent = 4)
        if pretty is True:
            json_txt = highlight(
                json_txt,
                lexers.JsonLexer(),
                formatters.TerminalFormatter()
            )
        return(json_txt)

    # Update client object
    def update_client(self, client):
        self.Client = client
        return(self)

    def get_bucket_notifications(self, bucket_name):
        self.Config = self.Client.get_bucket_notification_configuration(
            Bucket=bucket_name
        )
        self.ResponseMetadata = self.Config.pop('ResponseMetadata', None)

    # Add notification to an existing configuration
    def add_notification_config(
        self, notif_type, dest_arn, events,
        id=None, filter_prefix=None, filter_suffix=None, verbose=False
    ):
        config_params = {
            'id': id,
            'dest_arn': dest_arn,
            'events': events,
            'filter_prefix': filter_prefix,
            'filter_suffix': filter_suffix
        }

        notif_type_map = {
            'topic': TopicConfig(config_params),
            'queue': QueueConfig(config_params),
            'lambda': LambdaConfig(config_params)
        }
        if notif_type not in notif_type_map:
            raise ValueError("Invalid notif_type: {}. Valid types: [\"topic\",\"queue\",\"lambda\"]".format(notif_type))
        notif_config = notif_type_map[notif_type]

        # notif_config = TopicConfig(config_params)
        notif_config.construct_config()
        self.Config = notif_config.attach_config(self.Config)

        print("Config {} added".format(id))

    # Remove notification by Id
    def remove_notification(self, id):
        print("This method currently does nothing!")
        pass

    def put_notification(self, bucket_name):
        response = self.Client.put_bucket_notification_configuration(
            Bucket=bucket_name,
            NotificationConfiguration=self.Config
        )

        return(response)


from PyQt5.QtWidgets import QWidget, QLabel, QPushButton
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QGridLayout

from PyQt5.QtGui import QPixmap, QImage

import numpy as np

class Panel(QWidget):

    def __PrivateMethod(self):
        print("private method, value of")
        return

    def __init__(self):
        QWidget.__init__(self)
        self.initWidgets()
        pass

    def resizePanel(self, w , h ):
        self._width = w
        self._height = h
        self.resize(w, h)
        return

    def initWidgets(self):
        self.resizePanel(800, 600);

        # control
        self.btnOpenCamera=QPushButton(self)
        self.btnOpenCamera.setText("Open")

        self.btnCloseCamera=QPushButton(self)
        self.btnCloseCamera.setText("Close")

        self.btnStopCamera=QPushButton(self)
        self.btnStopCamera.setText("Stop")

        # img show
        self.lbl_img = QLabel(self)
        self.lbl_img1 = QLabel(self)
        self.lbl_img2 = QLabel(self)
        self.lbl_img3 = QLabel(self)

        self.lbl_img.resize(400, 300)
        self.lbl_img1.resize(400, 300)
        self.lbl_img2.resize(400, 300)
        self.lbl_img3.resize(400, 300)

        layCtl = QHBoxLayout()
        layCtl.addWidget(self.btnOpenCamera)
        layCtl.addWidget(self.btnStopCamera)
        layCtl.addWidget(self.btnCloseCamera)

        lay = QGridLayout()
        lay.addWidget(self.lbl_img, 0, 0)
        lay.addWidget(self.lbl_img1, 1, 1)
        lay.addWidget(self.lbl_img2, 1, 0)
        lay.addWidget(self.lbl_img3, 0, 1)

        mainLay = QVBoxLayout()
        mainLay.addLayout(layCtl)
        mainLay.addLayout(lay)

        self.setLayout(mainLay)

        return

    def showCvImg(self, cv_img):

        h, w, d = cv_img.shape
        qimg = QImage(cv_img.data, w, h, w*d, QImage.Format_Grayscale16)
        pix_map = QPixmap(qimg)
        pix_map = pix_map.scaled(400, 300)

        qimg1 = QImage(cv_img.data, w, h, w*d, QImage.Format_RGB888)
        pix_map1 = QPixmap(qimg1)
        pix_map1 = pix_map1.scaled(400, 300)

        self.lbl_img.setPixmap(pix_map)
        self.lbl_img1.setPixmap(pix_map1)
        pass


from datetime import datetime
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from asgiref.sync import sync_to_async
from .models import Room,Message

class ChatConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f'chat_{self.room_name}'
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name,
        )
        print(f'Aceitando conexão do usuário {self.scope["user"].username}')
        await self.accept()

    async def disconnect(self, code):
        await self.channel_layer.group_discard(self.room_group_name,self.channel_name)

    async def receive_json(self, content, **kwargs):
        await self.save_message(content)
        content['type'] = 'chat_message'
        content['date_added'] = datetime.isoformat(datetime.now())
        await self.channel_layer.group_send(self.room_group_name, content)

    async def chat_message(self,content):
        await self.send_json(content)

    @sync_to_async
    def save_message(self,data):
        Message.objects.create(
            user=self.scope['user'],
            content=data['message'],
            room=Room.objects.get(slug=data['room'])
        )


from flask_restplus import Api
from flask import Blueprint

from .offices import offices
from .meetings import meetings

blueprint = Blueprint('api', __name__, url_prefix='/api')

api = Api(
    blueprint,
    title='Office Data Manager',
    description='Manages and provides data about each office, meeting, and suggested changes.',
    version='1.0',
    doc='/doc'
)

api.add_namespace(offices, path='/v1/offices')
api.add_namespace(meetings, path='/v1/meetings')


import torch
import numpy as np
from torch.utils.data import DataLoader
import pandas as pd
from sklearn.model_selection import train_test_split
from keras.datasets import mnist
from torch.autograd import Variable
import matplotlib.pyplot as plt
import torch.nn as nn
import warnings
warnings.filterwarnings("ignore")

(x_train,y_train),(x_test,y_test)=mnist.load_data()
print(y_test.shape)
x_train=x_train/255
x_test=x_test/255
x_train=np.array(x_train,dtype='f')
x_test=np.array(x_test,dtype='f')

featureTrain=torch.from_numpy(x_train)
targetTrain=torch.from_numpy(y_train).type(torch.LongTensor)

featureTest=torch.from_numpy(x_test)
targetTest=torch.from_numpy(y_test).type(torch.LongTensor)

#hyperparameters
batch_size=100
n_iters=18000 #(60.000 input // batch_size)*numberofepochs(30)
epochs=n_iters/(len(featureTrain)/batch_size)
epochs=int(epochs)

train=torch.utils.data.TensorDataset(featureTrain,targetTrain)
test=torch.utils.data.TensorDataset(featureTest,targetTest)

train_loader=DataLoader(train,batch_size=batch_size,shuffle=False)
test_loader=DataLoader(test,batch_size=batch_size,shuffle=False)

class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()
        #Convolutional layer1
        self.cnn1=nn.Conv2d(in_channels=1,out_channels=16,kernel_size=5,stride=1,padding=0)
        self.relu1=nn.ReLU()
        #maxpooling
        self.maxpool1=nn.MaxPool2d(kernel_size=2)

        #Convolutional layer1
        self.cnn2=nn.Conv2d(in_channels=16,out_channels=32,kernel_size=5,stride=1,padding=0)
        self.relu2=nn.ReLU()
        #maxpooling
        self.maxpool2=nn.MaxPool2d(kernel_size=2)

        #fully connected
        self.fc1=nn.Linear(32*4*4,10)
    def forward(self,x):
        #conv1
        out=self.cnn1(x)
        out=self.relu1(out)
        out=self.maxpool1(out)

        #conv2
        #conv1
        out=self.cnn2(out)
        out=self.relu2(out)
        out=self.maxpool2(out)

        #flatten
        out=out.view(out.size(0),-1)

        out=self.fc1(out)

        return out

model=CNNModel()

#crossentropyloss
error=nn.CrossEntropyLoss()

#SGD optimizer
lr=0.02
optimizer=torch.optim.SGD(model.parameters(),lr=lr)

#CNN model training
count=0
loss_list=[]
iteration_list=[]
accuracy_list=[]
for epoch in range(epochs):
    for i, (images,labels) in enumerate(train_loader):
        train=Variable(images.view(100,1,28,28))
        labels=Variable(labels)

        optimizer.zero_grad()

        outputs=model(train)

        loss=error(outputs,labels)

        loss.backward()

        optimizer.step()

        count+=1

        if count%10==0:
             #accuracy
            correct=0
            total=0

            for images,labels in test_loader:
                test=Variable(images.view(100,1,28,28))

                outputs=model(test)
                predicted=torch.max(outputs.data,1)[1]

                total+=len(labels)
                correct+=(predicted==labels).sum()

            accuracy=100*correct/float(total)

            loss_list.append(loss.data)
            iteration_list.append(count)
            accuracy_list.append(accuracy)
        if count%10==0:
            print("iteration: {} Loss: {} Accuracy: {}%".format(count,loss.data,accuracy))

plt.figure(figsize=(25,25))
plt.plot(loss_list,c="orange")
plt.xlabel("Steps",fontsize=25)
plt.ylabel("Loss",fontsize=25)
plt.show()


from .colors import Color
from fastapi import APIRouter, Response
from jinja2 import Template
from os import path

class SvgResponse(Response):
    media_type = "image/svg+xml"

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(media_type="image/svg+xml", *args, **kwargs)

class Markers:
    def __init__(self, min: float, max: float) -> None:
        self.min = min
        self.max = max
        template_path = path.join(path.dirname(__file__), "pin.svg")
        self.template = Template(open(template_path).read())
        self.min_color = Color(rgb=(1, 0, 0))
        self.max_color = Color(rgb=(0, 1, 0))

    def get_router(self) -> APIRouter:
        router = APIRouter()

        @router.get("/{score}", response_class=SvgResponse, status_code=200)
        def get_marker(score: float):
            factor = score / (self.max - self.min + 1)
            response = SvgResponse(
                content=self.template.render(
                    {
                        "color": self.min_color.lerp(
                            self.max_color, factor
                        ).get_css_color()
                    }
                ),
            )
            response.headers['cache-control'] = 'max-age=3600'
            return response

        return router


import torch
import torchvision
from torch import nn
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.optim import Adam, SGD
from torch.optim.lr_scheduler import ChainedScheduler, LinearLR, MultiStepLR
import argparse
import os
import math
import shutil

from resnet import MakeResnet
from helper_functions import CreateModelName
from conf import get_args
from imagenet_loader import ImagenetDataset
from tiny_imagenet_loader import TinyImagenetDataset
from create_model import CreateBlockwiseResnet

# from helper_functions import CreateModelName
# from imagenet_loader import ImagenetDataset
# from tiny_imagenet_loader import TinyImagenetDataset

def CreateDataLoaderlocal(args):

    if args.dataset == "cifar10":
        mean_dataset_norm = [0.4914, 0.4822, 0.4465]
        std_dataset_norm = [0.247, 0.2434, 0.2615]

    if args.dataset == "cifar100":
        mean_dataset_norm = [0.5071, 0.4867, 0.4408]
        std_dataset_norm = [0.2675, 0.2565, 0.2761]

    if args.dataset == "imagenet":
        mean_dataset_norm = [0.485, 0.456, 0.406]
        std_dataset_norm = [0.229, 0.224, 0.225]

    # must recompute imagenet values for now
    if args.dataset == "tiny_imagenet":
        mean_dataset_norm = [0.485, 0.456, 0.406]
        std_dataset_norm = [0.229, 0.224, 0.225]

    # train_transform = transforms.Compose([transforms.ToTensor(),
    #                                       transforms.Resize((32, 32)),
    #                                       transforms.RandomCrop(32, padding=4),
    #                                       transforms.Normalize(mean=mean_dataset_norm, std=std_dataset_norm),
    #                                       transforms.RandomHorizontalFlip(0.5)])

    test_transform = transforms.Compose([transforms.ToTensor(),
                                         transforms.Resize((32, 32)),
                                         transforms.Normalize(mean=mean_dataset_norm, std=std_dataset_norm)])

    # Defined transforms
    if args.dataset == "cifar10":
        train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, transform=test_transform)
        test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=test_transform)

    if args.dataset == "cifar100":
        train_dataset = torchvision.datasets.CIFAR100(root='./data', train=True, transform=test_transform)
        test_dataset = torchvision.datasets.CIFAR100(root='./data', train=False, transform=test_transform)

    if args.dataset == "imagenet":
        train_dataset = ImagenetDataset(split='train', transforms=test_transform)
        test_dataset = ImagenetDataset(split='val', transforms=test_transform)

    # must recompute imagenet values for now
    if args.dataset == "tiny_imagenet":
        train_dataset = TinyImagenetDataset(split='train', transforms=test_transform)
        test_dataset = TinyImagenetDataset(split='val', transforms=test_transform)

    train_dataloader = DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True)
    test_dataloader = DataLoader(test_dataset, batch_size=args.batch_size, shuffle=False)

    return train_dataloader, test_dataloader

def ConLoss(features1, features2, labels):

    temperature = 0.1

    features = torch.cat((features1, features2), dim=0)
    features = torch.nn.functional.normalize(features, dim=1)
    features = features.view(features.shape[0], features.shape[1], -1)

    labels = labels.view(-1, 1)
    mask = torch.eq(labels, labels.T).float().to(device)
    mask = torch.cat((mask, mask), dim=1)
    mask = torch.cat((mask, mask), dim=0)
    mask = mask - (torch.eye(mask.shape[0]).float().to(device).detach()).detach()

    contrast_feature = torch.cat(torch.unbind(features, dim=1), dim=0) ## reshaped such that first bsz rows are first channel of all inputs, second bsz rows is 2nd channel ...  torch.unbind(features, dim=1) has shape (bsz, feature.shape[-1])

    f_dot_f = torch.matmul(contrast_feature, contrast_feature.T)/temperature

    f_max, _ = torch.max(f_dot_f, dim=1, keepdim=True)
    f_dot_f = f_dot_f - f_max.detach()

    # norm = torch.sqrt(torch.sum(torch.square(f_dot_f), dim=1, keepdim=True)).detach()
    # f_dot_f = f_dot_f/norm

    mask = torch.tile(mask, (features.shape[1], features.shape[1]))
    anchor_dot_pos = torch.mul(f_dot_f, mask)

    mask_all = (torch.ones_like(f_dot_f) - torch.eye(f_dot_f.shape[0]).to(device)).detach()
    anchor_dot_all = torch.exp(torch.mul(f_dot_f, mask_all))

    # print(features.shape, mask.shape, contrast_feature.shape, f_dot_f.shape, anchor_dot_all.shape)
    # print()
    # exit()

    loss = anchor_dot_pos - torch.log(torch.sum(anchor_dot_all, dim=1, keepdim=True))
    loss = loss * (-1/torch.sum(mask, dim=1, keepdim=True))

    loss = loss.mean()

    return loss

def train():

    train_loss = 0
    train_acc = 0
    num_train_images = 0
    for idx, (images, labels) in enumerate(train_dataloader):

        optim.zero_grad()
        images = images.to(device)
        labels = labels.to(device)

        images1 = transform_extra(images)
        images2 = transform_extra(images)

        out1 = model(images1)
        out2 = model(images2)

        pred1 = torch.argmax(out1, dim=1)
        pred2 = torch.argmax(out2, dim=1)

        ce_loss = (cross_entropy_loss(out1, labels) + cross_entropy_loss(out2, labels))/2
        con_loss = ConLoss(out1, out2, labels)
        loss = (ce_loss + con_loss)/2

        train_acc += (torch.sum(torch.where(pred1==labels, 1, 0)) + torch.sum(torch.where(pred2==labels, 1, 0)))/2
        train_loss += loss.item()
        num_train_images += images.shape[0]

        loss.backward()
        optim.step()

    train_acc = train_acc/num_train_images
    # train_loss = train_loss/num_train_images_set

    return train_acc, train_loss, ce_loss, con_loss

def test():

    test_loss = 0
    test_acc = 0
    num_test_images = 0

    for idx,  (images, labels) in enumerate(test_dataloader):

        images = images.to(device)
        labels = labels.to(device)

        images1 = transform_extra(images)
        images2 = transform_extra(images)

        out1 = model(images1)
        out2 = model(images2)

        pred1 = torch.argmax(out1, dim=1)
        pred2 = torch.argmax(out2, dim=1)

        ce_loss = (cross_entropy_loss(out1, labels) + cross_entropy_loss(out2, labels))/2
        con_loss = ConLoss(out1, out2, labels)
        loss = (ce_loss + con_loss)/2

        test_acc += (torch.sum(torch.where(pred1==labels, 1, 0)) + torch.sum(torch.where(pred2==labels, 1, 0)))/2
        test_loss += loss.item()
        num_test_images += images.shape[0]

        # num_test_images += images.shape[0]
        # num_test_images_set += 1

    test_acc = test_acc/num_test_images
    # test_loss = test_loss/num_test_images_set

    return test_acc, test_loss, ce_loss, con_loss

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

    args = get_args()
    parameters = CreateModelName(args)
    writer = SummaryWriter('./runs/{}/{}/'.format(args.dataset, args.model_name))

    train_dataloader, test_dataloader = CreateDataLoaderlocal(args)

    model = parameters['model']
    optim_parameters = parameters['optim_parameters']
    num_layers_below = parameters['num_layers_below']
    base_size = parameters['base_size']
    layer_increase = parameters['layer_increase']
    share_pos = parameters['share_pos']
    num_epochs_per_each_block = parameters['num_epochs_per_each_block']
    output_size = parameters['output_size']

    transform_extra = transforms.Compose([transforms.RandomCrop(32, padding=4),
                                          transforms.RandomHorizontalFlip(0.5),
                                          transforms.RandomVerticalFlip(0.5)])

    model = model.to(device)
    cross_entropy_loss = nn.CrossEntropyLoss(reduction='mean')

    # Set the optimizer and scheduler for non-blockwise training
    if not args.train_solo_layers:
        if not args.share_weights:
            optim = Adam(optim_parameters, lr=args.lr, weight_decay=1e-5)
            lr_scheduler = MultiStepLR(optim, milestones=[0.3*args.n_epochs, 0.6*args.n_epochs, 0.8*args.n_epochs], gamma=0.2, last_epoch=-1)
        else:
            ## Warmup when weight sharing
            optim = Adam(optim_parameters, lr=args.lr, weight_decay=1e-5)
            lr_scheduler = ChainedScheduler([MultiStepLR(optim, milestones=[0.3*args.n_epochs, 0.6*args.n_epochs, 0.8*args.n_epochs], gamma=0.2, last_epoch=-1),
                                             LinearLR(optim, start_factor=1, end_factor=1, total_iters=0.1*args.n_epochs)])

    model.train()
    test_loss_max = 1e9
    prev_epoch = 0

    for epoch in range (args.n_epochs):

        # If adding and training layers sequentially, update the optimizer, scheduler, and num epochs accordingly
        if args.train_solo_layers and args.share_weights and (share_pos == -1 or (share_pos != -1 and epoch-prev_epoch >= num_epochs_per_each_block[share_pos])):
            test_loss_max = 1e9
            prev_epoch = epoch
            share_pos += 1

            if share_pos > 0:
                base_size[share_pos] += layer_increase[share_pos]
                model, optim_parameters = CreateBlockwiseResnet(args, base_size, output_size, './weights/{}/{}/model.pth'.format(args.dataset, args.model_name), share_pos)
                model.to(device)

            for key, value in model.named_parameters():
                print(key, value.requires_grad)

            optim = Adam(optim_parameters, lr=args.lr, weight_decay=1e-5)

            # Warmup
            lr_scheduler = ChainedScheduler([MultiStepLR(optim, milestones=[int(0.3*num_epochs_per_each_block[share_pos]), int(0.6*num_epochs_per_each_block[share_pos]), int(0.8*num_epochs_per_each_block[share_pos])], gamma=0.2, last_epoch=-1),
                                             LinearLR(optim, start_factor=1, end_factor=1, total_iters=0.2*num_epochs_per_each_block[share_pos])])

        train_acc, train_loss, ce_loss_train, con_loss_train = train()
        test_acc, test_loss, ce_loss_test, con_loss_test = test()

        if test_loss < test_loss_max:

            test_loss_max = test_loss
            torch.save(model.state_dict(), './weights/{}/{}/model.pth'.format(args.dataset, args.model_name))

            if args.share_weights:
                # Because of warmup
                torch.save({'train_loss': train_loss,
                            'train_acc': train_acc,
                            'test_loss': test_loss,
                            'test_acc': test_acc,
                            'ce_loss_train': ce_loss_train,
                            'con_loss_train': con_loss_train,
                            'ce_loss_test': ce_loss_test,
                            'con_loss_test': con_loss_test,
                            'epoch': epoch,
                            'lr': lr_scheduler._schedulers[-1].get_last_lr()}, './weights/{}/{}/info.pth'.format(args.dataset, args.model_name))

            else:
                # Because of no warmup
                torch.save({'train_loss': train_loss,
                            'train_acc': train_acc,
                            'test_loss': test_loss,
                            'test_acc': test_acc,
                            'ce_loss_train': ce_loss_train,
                            'con_loss_train': con_loss_train,
                            'ce_loss_test': ce_loss_test,
                            'con_loss_test': con_loss_test,
                            'epoch': epoch,
                            'lr': lr_scheduler.get_last_lr()}, './weights/{}/{}/info.pth'.format(args.dataset, args.model_name))

        if args.share_weights:
            print("Epoch: {}/{}, model: {}, lr multi step: {}, lr final: {}".format(epoch, args.n_epochs, args.model_name, lr_scheduler._schedulers[0].get_last_lr()[0], lr_scheduler._schedulers[-1].get_last_lr()[0]))
        else:
            print("Epoch: {}/{}, model: {}, lr: {}".format(epoch, args.n_epochs, args.model_name, lr_scheduler.get_last_lr()[0]))

        writer.add_scalar('Train Loss', train_loss, epoch)
        writer.add_scalar('Train Acc', train_acc, epoch)
        writer.add_scalar('Val Loss', test_loss, epoch)
        writer.add_scalar('Val Acc', test_acc, epoch)

        lr_scheduler.step()

        if mc.block[mc.cur_pos][-1] == -1:

            # images = torch.cat((images[0], images[1]), dim=0)
            # labels = torch.cat((labels, labels), dim=0)

            # images = images.to(device)
            # labels = labels.to(device)

            # out, features = model(images)

            # _, features1 = model(images1)
            # _, features2 = model(images2)

            # features = torch.stack((features1, features2), dim=1)

            bsz = labels.shape[0]
            images = torch.cat((images[0], images[1]), dim=0)

            images = images.to(device)
            labels = labels.to(device)

            _, f = model(images)

            f1, f2 = torch.split(f, [bsz, bsz], dim=0)
            features = torch.cat([f1.unsqueeze(1), f2.unsqueeze(1)], dim=1)

            ce_loss = torch.tensor(0.).to(device)
            train_acc = torch.tensor(0.).to(device)

            con_loss = contrastive_loss(features, labels)

            loss = con_loss


from collections import deque

N, K = map(int, input().split(' '))

que = deque(list(range(1, N+1))) # 큐로 문제 풀이

tmp_list = []
while que :
    que.rotate(-K + 1)
    tmp_list.append(str(que.popleft()))

print("<",', '.join(tmp_list),">", sep = '')

요세푸스 문제 0.py


# -*- coding: utf-8 -*-
"""
Created on Wed Apr 29 16:40:47 2020

@author: Eric Bianchi
"""
import shutil
import os
import numpy as np
import tensorflow as tf
import cv2

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Try except statements
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def checkDirTryCatch(path):
    try:
        shutil.rmtree(path)
    except:
        print(path + " already removed")

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Remove folder contents
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def removeCon(base_path):

    # Remove the existing folders
    checkDirTryCatch(base_path + '/EMF')
    checkDirTryCatch(base_path + '/GIF')
    checkDirTryCatch(base_path + '/TIFF')
    checkDirTryCatch(base_path + '/WDP')
    checkDirTryCatch(base_path + '/WMF')
    checkDirTryCatch(base_path + '/UnableToOpen')

    os.mkdir(base_path + '/EMF')
    os.mkdir(base_path + '/GIF')
    os.mkdir(base_path + '/TIFF')
    os.mkdir(base_path + '/WDP')
    os.mkdir(base_path + '/WMF')
    os.mkdir(base_path + '/UnableToOpen')

def writeResultOnImage(openCVImage, resultText):
    # ToDo: this function may take some further fine-tuning to show the text well given any possible image size

    imageHeight, imageWidth, sceneNumChannels = openCVImage.shape

    # choose a font
    fontFace = cv2.FONT_HERSHEY_TRIPLEX

    # chose the font size and thickness as a fraction of the image size
    if imageWidth < 800:
        fontScale = imageWidth/800
    else:
        fontScale = 1

    fontThickness = .5

    # make sure font thickness is an integer, if not, the OpenCV functions that use this may crash
    fontThickness = int(fontThickness)

    upperLeftTextOriginX = int(imageWidth * 0.05)
    upperLeftTextOriginY = int(imageHeight * 0.05)

    textSize, baseline = cv2.getTextSize(resultText, fontFace, fontScale, fontThickness)
    textSizeWidth, textSizeHeight = textSize

    # calculate the lower left origin of the text area based on the text area center, width, and height
    lowerLeftTextOriginX = upperLeftTextOriginX
    lowerLeftTextOriginY = upperLeftTextOriginY + textSizeHeight

    rectangle_bgr = (255,255,0)
    box_coords = ((upperLeftTextOriginX - 5, upperLeftTextOriginY - 5), (upperLeftTextOriginX + textSizeWidth + 5, upperLeftTextOriginY + textSizeHeight + 5))
    cv2.rectangle(openCVImage, box_coords[0], box_coords[1], rectangle_bgr, cv2.FILLED)

    # write the text on the image
    cv2.putText(openCVImage, resultText, (lowerLeftTextOriginX, lowerLeftTextOriginY), fontFace, fontScale, (255, 0, 0) , fontThickness)
# end function

def overwrite(original, output):
    try:
        os.rename(original, output)
    except WindowsError:
        os.remove(output)
        os.rename(original, output)

def confidenceSort(onMostLikelyPrediction,confidence,strClassification,cur_name,image_path,DRIVE,image_names,countList, sort_ID, sort_ID_string ,upperBound,lowerBound,x,y):
    if onMostLikelyPrediction and (upperBound > confidence > lowerBound):
        string_upperBound = str(int(100*upperBound))
        string_lowerBound = str(int(100*lowerBound))
        scoreAsAPercent = confidence * 100.0
        # print("the object appears to be a " + strClassification + ", " +
        #       "{0:.2f}".format(scoreAsAPercent) + "% confidence  (" + str(cur_name) + ")")

        if strClassification == (sort_ID.lower()):
            shutil.copyfile(image_path, DRIVE + "DATA/Extraction/Sorted Data/" +
                            sort_ID_string + "/#" + sort_ID +"/" + string_lowerBound +
                            "%-" + string_upperBound + "%/" + image_names[cur_name])
            countList[x][y] = countList[x][y] + 1

        else:
            shutil.copyfile(image_path, DRIVE + "DATA/Extraction/Sorted Data/" +
                            sort_ID_string + "/#Non" + sort_ID +"/" + string_lowerBound +
                            "%-" + string_upperBound + "%/" + image_names[cur_name])
            countList[x+1][y] = countList[x+1][y] + 1

        onMostLikelyPrediction = False
        cur_name = cur_name + 1
    return cur_name, onMostLikelyPrediction

def confidenceSort_(image_path,BASE,image_name,confidence, sort_ID, sort_ID_string, upperBound,lowerBound):
    string_upperBound = str(int(100*upperBound))
    string_lowerBound = str(int(100*lowerBound))
    dest = BASE + "DATA/Extraction/Sorted Data/" + sort_ID_string + "/#" + sort_ID + "/" + string_lowerBound + "%-" + string_upperBound + "%/" + image_name

    from os import path

    if path.exists(dest):
        print(image_name + ': already exists')
    else:
        shutil.copyfile(image_path, dest)
        print('sorted data: ' + image_name + 'to #' + sort_ID + ' ' + string_upperBound)

def buildImageFileList(TEST_IMAGES_DIR):

    imageFilePaths = []
    image_names = []

    for imageFileName in os.listdir(TEST_IMAGES_DIR):
        if imageFileName.endswith(".jpg"):
            imageFilePaths.append(TEST_IMAGES_DIR + imageFileName)
            image_names.append(imageFileName)
        elif imageFileName.endswith(".JPG"):
            imageFilePaths.append(TEST_IMAGES_DIR + imageFileName)
            image_names.append(imageFileName)
        elif imageFileName.endswith(".png"):
            imageFilePaths.append(TEST_IMAGES_DIR + imageFileName)
            image_names.append(imageFileName)
        elif imageFileName.endswith(".jpeg"):
            imageFilePaths.append(TEST_IMAGES_DIR + imageFileName)
            image_names.append(imageFileName)

    return imageFilePaths, image_names

def makePrediction(sess, openCVImage, classifications):
    # get the final tensor from the graph
    finalTensor = sess.graph.get_tensor_by_name('final_result:0')
    activations = sess.graph.get_tensor_by_name('mixed_10/join:0')

    # convert the OpenCV image (numpy array) to a TensorFlow image
    tfImage = np.array(openCVImage)[:, :, 0:3]

    # run the network to get the predictions
    predictions = sess.run(finalTensor, {'DecodeJpeg:0': tfImage})

    activations = sess.run(activations, {'DecodeJpeg:0': tfImage})
    # sort predictions from most confidence to least confidence
    sortedPredictions = predictions[0].argsort()[-len(predictions[0]):][::-1]

    prediction = sortedPredictions[0]
    #*****print("---------------------------------------")
    # keep track of if we're going through the next for loop for the first time so we can show more info about
    # the first prediction, which is the most likely prediction (they were sorted descending above)
    onMostLikelyPrediction = True

    strClassification = classifications[prediction]

    # get confidence, then get confidence rounded to 2 places after the decimal
    confidence = predictions[0][prediction]

    return prediction, onMostLikelyPrediction, sortedPredictions, strClassification, confidence

def addResultToImList(image_path, openCVImage, strClassification, confidence, cur_name):
    # get the score as a %
    scoreAsAPercent = confidence * 100.0
    # show the result to std out
    writeResultOnImage(openCVImage, strClassification + ", " + "{0:.2f}".format(scoreAsAPercent) + "% confidence.")

    return openCVImage

def showResultOnImage(image_path, openCVImage, strClassification, confidence, cur_name):
    # get the score as a %
    scoreAsAPercent = confidence * 100.0
    # show the result to std out
    print("the object appears to be a " + strClassification + ", " + "{0:.2f}".format(scoreAsAPercent) + "% confidence.  (" + str(cur_name) + ")")
    writeResultOnImage(openCVImage, strClassification + ", " + "{0:.2f}".format(scoreAsAPercent) + "% confidence.")

    # finally we can show the OpenCV image
    cv2.imshow(image_path, openCVImage)
    # mark that we've show the most likely prediction at this point so the additional information in
    # this if statement does not show again for this image
    cv2.waitKey()
    # after a key is pressed, close the current window to prep for the next time around
    cv2.destroyAllWindows()

def makeCountList():
    non0 = 0
    non25 = 0
    non65 = 0
    non75 = 0
    non90 = 0
    non95 = 0

    yes0 = 0
    yes25 = 0
    yes65 = 0
    yes75 = 0
    yes90 = 0
    yes95 = 0

    countList = [[0, 0, 0, 0, 0, 0, 0],
                       [0,yes0,yes25, yes65, yes75, yes90, yes95],
                       [0,non0,non25, non65, non75, non90, non95]]
    return countList

def sortPrediction_(image_path, BASE, confidence,strClassification,image_name, sort_ID, sort_ID_string):

    if confidence < 0.2:
        confidenceSort_(image_path,BASE,image_name,confidence,sort_ID,sort_ID_string, 0.2,0)
    elif 0.2 < confidence < 0.4:
        confidenceSort_(image_path,BASE,image_name,confidence,sort_ID,sort_ID_string ,0.4,0.2)
    elif 0.4 < confidence < 0.6:
        confidenceSort_(image_path,BASE,image_name,confidence,sort_ID,sort_ID_string ,0.6,0.4)
    elif 0.6 < confidence < 0.8:
        confidenceSort_(image_path,BASE,image_name,confidence,sort_ID,sort_ID_string ,0.8,0.6)
    elif 0.8 < confidence < 1.0:
        confidenceSort_(image_path,BASE,image_name,confidence,sort_ID,sort_ID_string ,1.0,0.8)

def sortPrediction(onMostLikelyPrediction, confidence,strClassification,image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string, cur_name):

    cur_name, onMostLikelyPrediction = confidenceSort(
        onMostLikelyPrediction, confidence,
        strClassification, cur_name, image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string ,0.2,0.0,1,2)

    cur_name, onMostLikelyPrediction = confidenceSort(
        onMostLikelyPrediction, confidence,
        strClassification, cur_name, image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string ,0.4,0.2,1,3)

    cur_name, onMostLikelyPrediction = confidenceSort(
        onMostLikelyPrediction, confidence,
        strClassification, cur_name, image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string ,0.6,0.4,1,4)

    cur_name, onMostLikelyPrediction = confidenceSort(
        onMostLikelyPrediction, confidence,
        strClassification, cur_name, image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string ,0.8,0.6,1,5)

    cur_name, onMostLikelyPrediction = confidenceSort(
        onMostLikelyPrediction, confidence,
        strClassification, cur_name, image_path,
        BASE, image_names, countList, sort_ID, sort_ID_string ,1.0,0.8,1,6)

def saveAndPrintHistogram(sort_ID, countList):
    text = ( "\n"
    "\n"
    "================== " + sort_ID + " =============" + "\n"
    + sort_ID + " <25%    : " + str(countList[1][1]) + "\n"
    + sort_ID + " 25%-50% : " + str(countList[1][2]) + "\n"
    + sort_ID + " 65%-75% : " + str(countList[1][3]) + "\n"
    + sort_ID + " 75%-90% : " + str(countList[1][4]) + "\n"
    + sort_ID + " 90%-95% : " + str(countList[1][5]) + "\n"
    + sort_ID + " >95%    : " + str(countList[1][6]) + "\n"
    "================== Non-" + sort_ID + " ==================" + "\n"
    + "non" + sort_ID + " <25%        : " + str(countList[2][1]) + "\n"
    + "non" + sort_ID + " 25%-50%     : " + str(countList[2][2]) + "\n"
    + "non" + sort_ID + " 65%-75%     : " + str(countList[2][3]) + "\n"
    + "non" + sort_ID + " 75%-90%     : " + str(countList[2][4]) + "\n"
    + "non" + sort_ID + " 90%-95%     : " + str(countList[2][5]) + "\n"
    + "non" + sort_ID + " >95%        : " + str(countList[2][6]) + "\n")

    print(text)
    histogram = open(sort_ID + ".txt","w")
    lines = [text]
    histogram.writelines(lines)
    histogram.close()

def prettyLabel(classDirectory):
    for class_ in classDirectory:

        for im in directoryPath:
            shutil.copyfile(TEST_IMAGE_DIR + im, FN_PATH + im)
        print('done')

def confusionMatrix(pred, gt):

    if gt == 0 and pred == 0:
        result = 'TP'
    if gt == 1 and pred == 1:
        result = 'TN'
    if gt == 0 and pred == 1:
        result = 'FN'
    if gt == 1 and pred == 0:
        result = 'FP'
    return result

def sortRandomImages(src, dst, number):

    imageFilePaths, image_names = buildImageFileList(src, '')

    import random
    for i in range(0,number):
        randNumber = random.randrange(0, len(imageFilePaths), 1)
        print (randNumber)
        src_rand = imageFilePaths[randNumber]
        shutil.copy(src_rand, dst)
        imageFilePaths.remove(src_rand)

def sortImages(src, dst, image_names):

    if not os.path.exists(dst): # if it doesn't exist already
        os.makedirs(dst)

    for i in range(0,len(image_names)):
        print(image_names[i][0])
        image = image_names[i][0]

        shutil.copy(src+image, dst)

def sortXML(src, dst, image_names):

    if not os.path.exists(dst): # if it doesn't exist already
        os.makedirs(dst)

    for i in range(0,len(image_names)):
        print(image_names[i][0])
        xml = image_names[i][0].split('.')[0]+'.xml'

        shutil.copy(src+xml, dst)

def verboseConfusion(FN, FP, TN, TP):
    print("FALSE NEGATIVE: " + str(FN))
    print("FALSE POSITIVE: " + str(FP))
    print("TRUE NEGATIVE: " + str(TN))
    print("TRUE POSITIVE: " + str(TP))
    Accuracy = (TP + TN)/(TP+TN+FP+FN)
    Precision = TP/(TP + FN)
    Recall = TP/(TP + FP)

    print("Accruacy: " + str(Accuracy))
    print("Precision: " + str(Precision))
    print("Recall: " + str(Recall))

def confusionMatrixValues(eval_gt, eval_pred, imageFilePaths):
    TP = 0
    TN = 0
    FP = 0
    FN = 0

    TP_path = []
    TN_path = []
    FP_path = []
    FN_path = []

    for image in imageFilePaths:
        head, imageName = os.path.split(image)
        gt = eval_gt[imageName]
        prediction = eval_pred[imageName]

        if gt == 0 and prediction == 0:
            TP = TP + 1
            TP_path.append(imageName)
        if gt == 1 and prediction == 1:
            TN = TN + 1
            TN_path.append(imageName)
        if gt == 0 and prediction == 1:
            FN = FN + 1
            FN_path.append(imageName)
            # cv2.imshow("false negative", imagePaths[i])
            # cv2.waitKey()
            # cv2.destroyAllWindows()
        if gt == 1 and prediction == 0:
            FP = FP + 1
            FP_path.append(imageName)
            # cv2.imshow("false positive", imagePaths[i])
            # cv2.waitKey()
            # cv2.destroyAllWindows()
    return FN, FP, TN, TP, FN_path, FP_path, TN_path, TP_path

def presentResults(eval_gt, eval_pred, imageFilePaths):
    FN, FP, TN, TP, FN_path, FP_path, TN_path, TP_path = confusionMatrixValues(eval_gt, eval_pred, imageFilePaths)
    verboseConfusion(FN, FP, TN, TP)
    return FN_path, FP_path, TN_path, TP_path

def saveResults(FN_path, FP_path, CONF_MATRIX_PATH, TEST_IMAGE_DIR, meta_data):
    import csv

    # CONF_MATRIX_PATH = 'D://DATA/Datasets/Detail-NonDetail/confusionMatrix/ensemble/'

    FN_PATH = CONF_MATRIX_PATH + 'FN/'
    for im in FN_path:
        shutil.copyfile(TEST_IMAGE_DIR + im, FN_PATH + im)
    print('FN done')

    FP_PATH = CONF_MATRIX_PATH + 'FP/'
    for im in FP_path:
        shutil.copyfile(TEST_IMAGE_DIR + im, FP_PATH + im)
    print('FP done')

    # field names
    fields = ['Image Name', 'Classifier Prediction', 'Class', 'Classifier Score', 'Ground Truth']

    # name of csv file
    filename = "meta_data_predictions.csv"

    with open(TEST_IMAGE_DIR + filename, 'w', newline='') as f:
        thewriter = csv.DictWriter(f, fieldnames=fields)
        thewriter.writeheader()
        for meta in meta_data:
            thewriter.writerow(meta)
    print('Meta Data done')

def evaluateBinaryClassifier(classifier1, TEST_IMAGE_DIR, eval_gt, sort_ID, classIdx):

    print("starting program . . .")

    # Classifier 1:
    classification_c1, detection_graph_cla1 = classifier1.prepareGraphs()

    sess2 = tf.Session(graph=detection_graph_cla1)

    # Load in file paths
    imageFilePaths, image_names = buildImageFileList(TEST_IMAGE_DIR)

    imageFilePaths.sort()
    cur_name = 0
    eval_pred = {}
    meta_data = []
    for image_path in imageFilePaths:

        head, imageName = os.path.split(image_path)
        openCVImage = cv2.imread(image_path)
        openCVImage = cv2.resize(openCVImage,(400,400))
        # if we were not able to successfully open the image, continue with the next iteration of the for loop
        if openCVImage is None:
            print("unable to open " + image_path + " as an OpenCV image")
            cur_name = cur_name + 1
            continue
        # end if

        prediction, onMostLikelyPrediction, sortedPredictions, strClassification, confidence = makePrediction(sess2,
                                                                                openCVImage,
                                                                                classification_c1)
        head, imageName = os.path.split(image_path)
        gt = eval_gt[imageName]
        #=============================================================================
        if strClassification == (sort_ID.lower()):
            score_class_conf = (confidence-.50)*2
            eval_pred.update({imageName:classIdx(strClassification)})
            meta_data.append({'Image Name':imageName, 'Classifier Prediction':0,'Class':strClassification,
                              'Classifier Score':score_class_conf, 'Ground Truth':gt, 'Conf. Matrix':confusionMatrix(classIdx(strClassification), gt)})
        else:
            score_class_conf = (confidence-.50)*2
            eval_pred.update({imageName:classIdx(strClassification)})
            meta_data.append({'Image Name':imageName, 'Classifier Prediction':classIdx(strClassification),'Class':strClassification,
                              'Classifier Score':score_class_conf, 'Ground Truth':gt, 'Conf. Matrix':confusionMatrix(classIdx(strClassification), gt)})
        #print("==============================================================")
        cur_name = cur_name + 1
        if (cur_name % 100) == 0:
            print ("logging: ..." + str(cur_name))
    # end for
    return eval_pred, imageFilePaths, meta_data
# end main

def sortBinaryClassifier(classifier1, TEST_IMAGE_DIR, eval_gt, sort_ID, classIdx, BASE):

    print("starting program . . .")

    # Classifier 1:
    classification_c1, detection_graph_cla1 = classifier1.prepareGraphs()

    sess2 = tf.Session(graph=detection_graph_cla1)

    # Load in file paths
    imageFilePaths, image_names = buildImageFileList(TEST_IMAGE_DIR)

    imageFilePaths.sort()
    cur_name = 0
    for image_path in imageFilePaths:

        head, imageName = os.path.split(image_path)
        openCVImage = cv2.imread(image_path)
        openCVImage = cv2.resize(openCVImage,(300,300))
        # if we were not able to successfully open the image, continue with the next iteration of the for loop
        if openCVImage is None:
            print("unable to open " + image_path + " as an OpenCV image")
            cur_name = cur_name + 1
            continue
        # end if

        prediction, onMostLikelyPrediction, sortedPredictions, strClassification, confidence = makePrediction(sess2,
                                                                                openCVImage,
                                                                                classification_c1)
        head, imageName = os.path.split(image_path)
        #=============================================================================
        if strClassification == (sort_ID.lower()):
            score_class_conf = (confidence-.50)*2
            sortPrediction_(image_path, BASE, score_class_conf,
                     strClassification, imageName, sort_ID, sort_ID + "-Non" + sort_ID)
        else:
            score_class_conf = (confidence-.50)*2
            sortPrediction_(image_path, BASE, score_class_conf,
                     strClassification, imageName, sort_ID, sort_ID + "-Non" + sort_ID)
        #print("==============================================================")
        cur_name = cur_name + 1
        if (cur_name % 100) == 0:
            print ("logging: ..." + str(cur_name))
# end main

def binary_sort_positive_images(classifier1, SEARCH_DIRECTORY, search_ID, POSITIVE_DESINTATION_DIRECTORY):
    print("starting program . . .")

    # Classifier 1:
    classification_c1, detection_graph_cla1 = classifier1.prepareGraphs()

    sess1 = tf.Session(graph=detection_graph_cla1)

    # Load in file paths
    imageFilePaths, image_names = buildImageFileList(SEARCH_DIRECTORY)

    imageFilePaths.sort()
    cur_name = 0
    for image_path in imageFilePaths:

        head, imageName = os.path.split(image_path)
        openCVImage = cv2.imread(image_path)
        openCVImage = cv2.resize(openCVImage,(300,300))

        # if we were not able to successfully open the image, continue with the next iteration of the for loop
        if openCVImage is None:
            print("unable to open " + image_path + " as an OpenCV image")
            cur_name = cur_name + 1
            continue
        # end if

        prediction, onMostLikelyPrediction, sortedPredictions, strClassification, confidence = makePrediction(sess1,
                                                                                openCVImage,
                                                                                classification_c1)
        head, imageName = os.path.split(image_path)
        #=============================================================================
        if strClassification == (search_ID.lower()):
            print('Found a: ' + search_ID)
            shutil.copy(image_path, POSITIVE_DESINTATION_DIRECTORY + imageName)
        cur_name = cur_name + 1
        if (cur_name % 100) == 0:
            print ("logging: ..." + str(cur_name))
# end main
import csv
def findHeightWidth(directory, csv_file):
    fields = ['filename', 'width', 'height']

    print('starting program...')
    with open(directory + csv_file, 'w', newline='') as f:
        thewriter = csv.writer(f)
        thewriter.writerow(fields)
        print('=================================================================')
        for imageFileName in os.listdir(directory):
            if imageFileName.endswith(".png"):
                print(imageFileName)
                height = cv2.imread(directory+imageFileName).shape[0]
                width = cv2.imread(directory+imageFileName).shape[1]
                thewriter.writerow([imageFileName, width, height])

# def checkAndChangeHeightandWidth(directory, csv_file):
#     print('starting program...')
#     with open(directory + csv_file, 'w', newline='') as f_read:
#         reader = csv.reader(f_read, delimiter=',')
#         with open(directory + csv_file, 'w', newline='') as f:
#             thewriter = csv.writer(f)
#             thewriter.writerow(fields)
#          for row in reader:

#         print('=================================================================')
#         for imageFileName in os.listdir(directory):
#             if imageFileName.endswith(".png"):
#                 print(imageFileName)
#                 height = cv2.imread(directory+imageFileName).shape[0]
#                 width = cv2.imread(directory+imageFileName).shape[1]
#                 thewriter.writerow([imageFileName, width, height])


from tkinter import *
from functools import partial
import connection
import time

def end_shift(user_id,start_time):
  global newTab
  t = time.localtime()
  date_time = time.strftime("%Y/%m/%d, %H:%M:%S",t)
  print(date_time,user_id,start_time)
  query = connection.cur.execute("UPDATE bj_clock_in SET end_time = to_timestamp('{}' , 'YYYY-MM-DD HH24:MI:SS') where job_id = '{}'  and start_time = to_timestamp('{}', 'YYYY-MM-DD HH24:MI:SS')".format(date_time,user_id, start_time))
  connection.connection.commit()
  print("Done Updated")
  newTab.destroy()

newTab = Tk()
newTab.title("User bar")
newTab.geometry("500x300")

user = connection.cur.execute("select job_id,start_time from bj_clock_in order by start_time desc ").fetchone()
user_id = user[0]
start_time = user[1]

name = connection.cur.execute("select first_name from bj_employees where job_id="+str(user_id)).fetchone()

lbl2 = Label(newTab, text = "Shift started at: ").grid(row = 0, column = 3)
lbl1 = Label(newTab, text = "Welcome,").grid(row = 0, column = 1)
lbl3 = Label(newTab, text = name).grid(row = 0, column = 2)
lbl4 = Label(newTab, text = start_time).grid(row = 0, column = 4)

end_shift = partial(end_shift,user_id,start_time)
delButton = Button(newTab,text="End shift", command=end_shift).grid(row =0,column =5)


from datetime import datetime, timedelta
import json
import threading
import logging
from enum import Enum
from const import CONST
from main import send_post
import pykka
import ledPWM

'''
on: time_h=19 photoresistor=50
time_h=18 photoresistor=20 -> nothing
time_h=20 photoresistor=60 -> nothing
time_h=21 photoresistor=40 -> switch on
time_h=3 photoresistor=60 -> ???

off: time_h=6 photoresistor=70
time_h=4 photoresistor=60 -> nothing
time_h=5 photoresistor=75 -> switch off
or
time_h=6 photoresistor=60 -> switch off
'''
# no need for a lock because everything here is single thread

logger = logging.getLogger(__name__)
action = Enum('action', 'turn_on turn_off energy_saving car_detected')
error = Enum('error', 'generic')
C = CONST()

class Lamp(pykka.ThreadingActor):
    def __init__(self, lamp_id, lamp_number, pin, area, pr_proxy, us_proxy_1, us_proxy_2, lamp_policy_on=None,
                 lamp_policy_off=None, lamp_energy=None):
        super(Lamp, self).__init__()
        self.lamp_id = lamp_id
        self.lamp_number = lamp_number
        self.pin = pin
        self.area = area
        self.pr_proxy = pr_proxy
        self.us_proxy_1 = us_proxy_1
        self.us_proxy_2 = us_proxy_2
        self.lamp_policy_on = lamp_policy_on
        self.lamp_policy_off = lamp_policy_off
        self.lamp_energy = lamp_energy
        self.timer_on = threading.Timer(0, None)
        self.timer_energy_on_1 = threading.Timer(0, None)
        self.timer_energy_on_2 = threading.Timer(0, None)
        self.start_energy = threading.Timer(0, None)
        self.timer_energy_timeout = threading.Timer(0, None)
        self.my_proxy = None
        self.start_time_on = None
        self.start_time_energy_on = None
        self.timeout_on_off = 0
        self.timeout_energy = 0
        self.on = False
        self.debug = False
        self.old_intensity = 0
        ledPWM.set_led_intensity(self.pin, 0)
        self.update_schedules()

    def set_self_proxy(self, lamp_proxy):
        self.my_proxy = lamp_proxy

    def update_schedules(self):
        self.timeout_on_off = self.get_delta(self.lamp_policy_on.time_h, self.lamp_policy_on.time_m, 0,
                                             self.lamp_policy_off.time_h, self.lamp_policy_off.time_m, 0)
        self.timeout_energy = self.get_delta(self.lamp_energy.time_h_on, self.lamp_energy.time_m_on, 0,
                                             self.lamp_energy.time_h_off, self.lamp_energy.time_m_off, 0)

    def start_schedule_on(self):
        wait_t = self.get_wait(self.lamp_policy_on.time_h, self.lamp_policy_on.time_m, 0,
                               self.lamp_policy_off.time_h, self.lamp_policy_off.time_m, 0)
        logger.debug("wait = {0}".format(wait_t))
        self.timer_on.cancel()
        self.timer_on = threading.Timer(wait_t, self.pr_proxy.add_actor, [self.my_proxy])
        self.timer_on.start()
        self.start_time_on = datetime.today() + timedelta(seconds=wait_t)

    def start_schedule_energy_on(self):
        wait_t = self.get_wait(self.lamp_energy.time_h_on, self.lamp_energy.time_m_on, 0,
                               self.lamp_energy.time_h_off, self.lamp_energy.time_m_off, 0)
        self.timer_energy_on_1.cancel()
        self.timer_energy_on_1 = threading.Timer(wait_t, self.us_proxy_1.add_actor, [self.my_proxy])
        self.timer_energy_on_1.start()
        self.timer_energy_on_2.cancel()
        self.timer_energy_on_2 = threading.Timer(wait_t, self.us_proxy_2.add_actor, [self.my_proxy])
        self.timer_energy_on_2.start()
        self.start_energy.cancel()
        self.start_energy = threading.Timer(wait_t, self.set_to_energy)
        self.start_energy.start()
        self.start_time_energy_on = datetime.today() + timedelta(seconds=wait_t)

    def update_light(self, current_photoresistor):
        if not self.debug:
            url = C.SERVER_URL + C.CHANGE_LIGHT
            if self.is_in_schedule():
                if self.on and current_photoresistor > self.lamp_policy_off.photoresistor:
                    self.timer_energy_timeout.cancel()
                    ledPWM.set_led_intensity(self.pin, 0)
                    logger.info("lamp off")
                    self.on = False
                    post_fields = self.create_post_fields(action.turn_off.value, 0, current_photoresistor)
                    send_post(url, post_fields)
                elif not self.on and current_photoresistor < self.lamp_policy_on.photoresistor:
                    if self.is_energy_saving_time():
                        ledPWM.set_led_intensity(self.pin, self.lamp_energy.intensity)
                        logger.info("lamp energy")
                        self.on = True
                        post_fields = self.create_post_fields(action.energy_saving.value, self.lamp_energy.intensity,
                                                              current_photoresistor)
                        send_post(url, post_fields)
                    else:
                        ledPWM.set_led_intensity(self.pin, self.lamp_policy_on.intensity)
                        logger.info("lamp on")
                        self.on = True
                        post_fields = self.create_post_fields(action.turn_on.value, self.lamp_policy_on.intensity,
                                                              current_photoresistor)
                        send_post(url, post_fields)
            else:
                logger.info("schedule is over, see you tomorrow")
                ledPWM.set_led_intensity(self.pin, 0)
                logger.info("lamp off")
                self.on = False
                self.pr_proxy.remove_actor(self.my_proxy)
                post_fields = self.create_post_fields(action.turn_off.value, 0, current_photoresistor)
                send_post(url, post_fields)
                self.start_schedule_on()

    def ultrasonic_notify(self, us_timeout, wait_time, right_lane, notified=False):
        logger.info("[{0}]Received an ultrasonic notify".format(self.lamp_id))
        if not self.debug:
            if self.is_in_schedule() and self.is_energy_saving_time():
                if self.on:
                    # If the lamp is off because of the photoresistor, even if there is a car the lamp stay off
                    self.timer_energy_timeout.cancel()
                    if right_lane:
                        position = self.lamp_id
                    else:
                        position = self.lamp_number - self.lamp_id
                    # If this is the last lamp and we were not notified, we notify the nearest rpi
                    if position == self.lamp_number and not notified:
                        from main import notify_nearby
                        threading.Timer(wait_time * position, notify_nearby, [right_lane]).start()
                    threading.Timer(wait_time * position, self.car_detected).start()
                    logger.info("[{0}]There is a car! Lamp full power".format(self.lamp_id))
                    self.timer_energy_timeout.cancel()
                    self.timer_energy_timeout = threading.Timer(us_timeout + wait_time * position, self.set_to_energy)
                    self.timer_energy_timeout.start()
            else:
                self.timer_energy_timeout.cancel()
                logger.info("schedule is over, see you tomorrow")
                self.us_proxy_1.remove_actor(self.my_proxy)
                self.us_proxy_2.remove_actor(self.my_proxy)
                self.start_schedule_energy_on()

    def force_on(self, new_intensity):
        if not self.debug:
            self.debug = True
            self.old_intensity = ledPWM.get_led_intensity(self.pin)
        ledPWM.set_led_intensity(self.pin, new_intensity)

    def force_off(self):
        if not self.debug:
            self.debug = True
            self.old_intensity = ledPWM.get_led_intensity(self.pin)
        ledPWM.set_led_intensity(self.pin, 0)

    def stop_debug(self):
        if self.debug:
            self.debug = False
            ledPWM.set_led_intensity(self.pin, self.old_intensity)

    def car_detected(self):
        ledPWM.set_led_intensity(self.pin, self.lamp_policy_on.intensity)
        logger.info("{0} Car detected".format(ledPWM.get_led_intensity(self.pin)))
        url = C.SERVER_URL + C.CHANGE_LIGHT
        post_fields = self.create_post_fields(action.car_detected.value, self.lamp_policy_on.intensity)
        send_post(url, post_fields)

    def set_to_energy(self):
        ledPWM.set_led_intensity(self.pin, self.lamp_energy.intensity)
        logger.info("{0} Set to energy".format(ledPWM.get_led_intensity(self.pin)))
        url = C.SERVER_URL + C.CHANGE_LIGHT
        post_fields = self.create_post_fields(action.energy_saving.value, self.lamp_energy.intensity)
        send_post(url, post_fields)

    def create_post_fields(self, this_action, intensity, photoresistor=-1, timestamp=0):
        return {'area': self.area, 'action': this_action, 'intensity': intensity, 'photoresistor': photoresistor,
                'timestamp': timestamp}

    def to_json(self):
        return json.dumps([self.lamp_id, self.lamp_policy_on, self.lamp_policy_off, self.lamp_energy],
                          default=lambda o: o.__dict__, indent=4)

    @staticmethod
    def get_delta(start_h, start_m, start_s, end_h, end_m, end_s):
        today = datetime.today()
        start = today.replace(hour=start_h, minute=start_m, second=start_s)
        end = today.replace(hour=end_h, minute=end_m, second=end_s)
        if (end - start).total_seconds() < 1:
            end = end + timedelta(days=1)
        return (end - start).total_seconds()

    @staticmethod
    def get_wait(start_h, start_m, start_s, end_h, end_m, end_s):
        today = datetime.today()
        start = today.replace(hour=start_h, minute=start_m, second=start_s)
        end = today.replace(hour=end_h, minute=end_m, second=end_s)
        if (end - start).total_seconds() < 1:
            end = end + timedelta(days=1)
        if (end - start).total_seconds() > 24*60*60:
            start = start + timedelta(days=1)
        if (today - end).total_seconds() > 1:
            start = start + timedelta(days=1)
        tomorrow = today + timedelta(days=1)
        if (start - tomorrow).total_seconds() < 1 < (end - tomorrow).total_seconds():
            today = today + timedelta(days=1)
        return (start - today).total_seconds()

    def is_in_schedule(self):
        now = datetime.today()
        logger.info("now = {0}".format(now))
        logger.info("start time = {0}".format(self.start_time_on))
        elapsed = (now - self.start_time_on).total_seconds()
        logger.info("elapsed {0} seconds, timeout is {1}".format(elapsed, self.timeout_on_off))
        return elapsed < self.timeout_on_off

    def is_energy_saving_time(self):
        now = datetime.today()
        elapsed = (now - self.start_time_energy_on).total_seconds()
        logger.debug("Are we in energy saving? " + str(0 < elapsed < self.timeout_energy))
        return 0 < elapsed < self.timeout_energy


import tweepy
import logging
import time
from config import create_api, download_media
import os
import glob

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

def check_mentions(api, since_id):
    logger.info("Retrieving mentions")
    new_since_id = since_id
    # fetch items (tweets) from mentions. Use cursor for pagination (aka can do more than request 1 page)
    for tweet in tweepy.Cursor(api.mentions_timeline, since_id=since_id, tweet_mode="extended").items():
        # set new since_id to the highest tweet id (most recent).
        new_since_id = max(tweet.id, new_since_id)

        '''
        Im still trying to figure out what the below code does exactly...

        if tweet.in_reply_to_status_id is not None:
            logger.info("in_reply_to_status_id is not none... restart loop")
            logger.info(tweet.in_reply_to_status_id)
            continue
        logger.info("Detected mention...")
        '''

        # if not following the person who mentioned you, follow them
        if not tweet.user.following:
            tweet.user.follow()

        # download media
        if 'media' in api.get_status(tweet.in_reply_to_status_id).entities:
            logger.info("I found media!")
            media_ids = download_media(api, api.get_status(tweet.in_reply_to_status_id))
            print(media_ids)
            """# tweets the status argument as a reply, to the specified tweet id
            logger.info(f"Answering to {tweet.user.name} and posting pic...")

            api.update_status(status=f"Hey {tweet.user.name}. "
                                     f"I tried to find some faces/eyes in the tweet you showed me.",
                              in_reply_to_status_id=tweet.id,
                              auto_populate_reply_metadata=True,
                              media_ids=media_ids
                              )"""

            # delete downloaded media
            if os.path.exists('C:\\PythonLearning\\TwitterBot\\media'):
                files = glob.glob('.\\media\\*.jpg')
                for f in files:
                    os.remove(f)
                logger.info("Deleted downloaded photos...")
            else:
                logger.info("Could not delete downloaded photo...")
        else:
            logger.info("Sorry could not find media..")
            api.update_status(status=f"Hey {tweet.user.name}, sorry I could not find a photo in the tweet you tagged"
                                     f" me in...",
                              in_reply_to_status_id=tweet.id,
                              auto_populate_reply_metadata=True)
    return new_since_id

def main():
    # Creates Tweepy API object
    api = create_api()
    # since_id is used return only statuses with an ID greater than (more recent than) the specified ID.
    since_id = 1
    while True:
        since_id = check_mentions(api, since_id)
        logger.info("Waiting...")
        time.sleep(60)

if __name__ == "__main__":
    main()


import datetime
from django.shortcuts import render
from .models import Agreement, Period
import json
from django.http import HttpResponse

# Function of separation ID
# Returns a single identifier without a comma
# Returns "None", if not number or 0
def separation(set_in):
    double_comma = 0
    result = []
    set_path = ""
    for char in str(set_in):
        if char == ",":
            double_comma += 1
            if double_comma > 1:
                return None
            if set_path:
                try:
                    result.append(int(set_path))
                except ValueError:
                    return None
                set_path = ""
        elif char == "0" or char == "-":
            return None
        else:
            set_path +=char
            double_comma = 0
    try:
        result.append(int(set_path))
    except ValueError:
        return None
    return result

def home(request):
    context ={
        'page_header': 'Home page title B2B',
    }
    return render(request, 'agreement/home.html', context)

def calendar(request, country=0, negotitator=0, company=0):
    answer = dict()
    # Getting and validation ones ID
    if 'country' in request.GET:
        country = request.GET['country']
        country = separation(country)
        if country == None:
            context = {
                'mes_er':"You made a mistake when entering the country code",
            }
            return render(request, 'agreement/mistake.html', context)
    if 'negotitator' in request.GET:
        negotitator = request.GET['negotitator']
        negotitator = separation(negotitator)
        if negotitator == None:
            context = {
                'mes_er':"You made a mistake when entering the negotiator",
            }
            return render(request, 'agreement/mistake.html', context)
    if 'company' in request.GET:
        company = request.GET['company']
        company = separation(company)
        if company == None:
            context = {
                'mes_er':"You made a mistake when entering the company code",
            }
            return render(request, 'agreement/mistake.html', context)
    if not country:
        country = 0

    # Filter definition
    if country == 0:
        if negotitator == 0:
            if company == 0:
                agreements_all = Agreement.objects.all()
            else:
                agreements_all = Agreement.objects.filter\
                    (company__id__in=company)
        else:
            if company == 0:
                agreements_all = Agreement.objects.filter\
                    (negotiator__id__in=negotitator)
            else:
                agreements_all = Agreement.objects.filter\
                    (company__id__in=company, negotiator__id__in=negotitator)
    else:
        if negotitator == 0:
            if company == 0:
                agreements_all = Agreement.objects.filter\
                    (company__country__in=country)
            else:
                agreements_all = Agreement.objects.filter\
                    (company__country__in=country, company__id__in=company)
        else:
            if company == 0:
                agreements_all = Agreement.objects.filter\
                    (company__country__in=country, negotiator__id__in=\
                        negotitator)
            else:
                agreements_all = Agreement.objects.filter\
                    (company__country__in=country, company__id__in=company,\
                    negotiator__id__in=negotitator)
    if not agreements_all:
        context = {
        'mes_er': "Your sample is empty",
        }
        return render(request, 'agreement/mistake.html', context)

    for select_agreement in agreements_all:
        id_agr = int(select_agreement.id)
        select_periods = Period.objects.filter(agreement__id=id_agr)
        mas_year = 0
        mas_month = 0
        for i in range(len(select_periods)):
            mass = str(select_periods[i])
            if int(mass[11:15]) > mas_year:
                mas_year = int(mass[11:15])
            if int(mass[16:18]) > mas_month:
                mas_month = int(mass[16:18])
        year = answer.get(mas_year, 0)
        if not year:
            answer[mas_year] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        monthes = answer[mas_year]
        monthes[mas_month-1] +=1
        answer[mas_year] = monthes
    return HttpResponse(json.dumps(answer), content_type='application/json')


from django.urls import path
from .views import licence_list, licence_details, ask_licence, buy_licences, release_licence

urlpatterns = [
    path('/', licence_list),
    path('/details/<int:pk>', licence_details),
    path('/get/<int:pk>', ask_licence),
    path('/buy/<str:company_name>/<int:quantity>', buy_licences),
    path('/release/<int:pk>', release_licence)
]


#!/usr/bin/env python

import sys

from setuptools import find_packages, setup

setup_requires = []

# I only release from OS X so markdown/pypandoc isn't needed in Windows
if not sys.platform.startswith('win'):
    setup_requires.extend([
        'setuptools-markdown',
    ])

setup(
    name='serplint',
    author='Beau Gunderson',
    author_email='beau@beaugunderson.com',
    url='https://github.com/beaugunderson/serplint',
    description='A linter for the serpent language',
    long_description_markdown_filename='README.md',
    keywords=['serpent', 'ethereum'],
    version='1.4.0',
    license='MIT',
    packages=find_packages(),
    py_modules=['serplint'],
    entry_points={
        'console_scripts': [
            'serplint = serplint:serplint',
        ]
    },
    install_requires=[
        'click==6.7',
        'ethereum-serpent-augur-temp==2.0.2',
    ],
    setup_requires=setup_requires,
    classifiers=[
        'Development Status :: 5 - Production/Stable',

        'Intended Audience :: End Users/Desktop',

        'License :: OSI Approved :: MIT License',

        'Operating System :: POSIX',
        'Operating System :: Microsoft :: Windows',
        'Operating System :: MacOS :: MacOS X',

        'Topic :: Utilities',

        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
    ])


from datetime import datetime

import scrapy
from scrapy.http import Request

from maksavit_scrapy.items import ScrapyMaksavitItem
from maksavit_scrapy.settings import (CATEGORIES, DOMAIN, LOCATION, MAIN_URL,
                                      PROXY)

class MaksavitSpider(scrapy.Spider):
    name = 'maksavit'
    page = 1
    allowed_domains = [DOMAIN]
    start_urls = []

    def start_requests(self):
        for category in CATEGORIES:
            self.start_urls.append(f'{MAIN_URL}{category}?location={LOCATION}')

        for url in self.start_urls:
            yield Request(url, dont_filter=True, meta=PROXY)

    def parse(self, response):
        print(response.request.url)
        max_page = int(
            response.css(
                'div.app-filter__pagination a::text').getall()[-1].strip()
        )

        for product in response.css('div.product-card-block'):
            link = product.css('a.product-card-block__title::attr(href)').get()
            yield response.follow(link, callback=self.parse_item)
        current_page = int(
            response.css('a.ui-pagination__item_checked::text').get().strip()
        )
        next_page = current_page + 1

        if current_page < max_page:
            url = f'{response.request.url}'.replace(
                f'&page={current_page}', '')
            yield response.follow(
                f'{url}&page={next_page}', callback=self.parse
            )

    def parse_item(self, response):
        timestamp = int(datetime.timestamp(datetime.now()))
        code = response.request.url.split('/')[-2]
        url = response.request.url
        title = response.css('h1.product-top__title::text').get()
        badge = response.css('div.badge-discount::text').get()
        badges = [badge.strip()] if badge is not None else badge
        production = response.css('a.product-info__brand-value::text').get()
        brand = (None if production is None else ', '.join(
            production.strip().split(', ')[:-1]))
        country = (
            None if production is None else production.strip().split(', ')[-1]
        )
        sections = response.css(
            'ul.breadcrumbs li a.breadcrumbs__link span::text').getall()

        current_price = response.css('div.price-info__price span::text').get()
        current_price = (
            float(current_price.split(' ')[0])
            if current_price is not None else None)

        original_price = response.css('div.price-box__old-price::text').get()
        original_price = (current_price if original_price is None else float(
            original_price.replace('\xa0₽', '').replace(' ', '').strip()))

        discount = (((original_price - current_price) / original_price)
                    * 100 if current_price != original_price else 0)
        sale_tag = f'Скидка {discount:.0f}%' if discount != 0 else None

        status = response.css('div.available-count ::text').get()
        status = None if status is None else status[:-1]
        in_stock = True if status == 'сегодня' else False
        # Количество подсчитать невозможно.
        # Ставлю дефолтное None, как указано в ТЗ
        count = None

        img = response.css('div.product-picture img::attr(src)').get()
        main_img = response.urljoin(img) if img != '' else None
        set_img = [response.urljoin(img) if img != '' else None
                   for img in response.css(
            'div.product-picture img::attr(src)').getall()]

        # На сайте не представлено ни одного фото360/видео.
        # Т.к. в ТЗ эти элементы перечислены обязательными,
        # добавил round_view и video для демонстрации их поиска
        round_view = (
            response.css('div.product-picture')
            .xpath('//img[contains(@src, "360view")]/@src')
            .getall()
        )
        video = (
            response.css('div.product-picture')
            .xpath('//img[contains(@src, "video")]/@src')
            .getall()
        )

        info = response.css('div.product-instruction__guide')

        description = info.css('div.ph23 ::text').getall()
        description = (
            ''.join(description).replace('Описание', '')
            if description
            else None
        )

        form = info.css('div.ph14 ::text').getall()
        form = ''.join(form).replace('Форма выпуска', '') if form else None

        exp = info.css('div.ph17 ::text').getall()
        exp = ''.join(exp).replace('Срок годности', '') if exp else None

        quanity = response.css(
            'div.quantity-items-wrapper span::text').getall()
        quanity = len(quanity) if quanity else 1

        price = {
            'current': current_price,
            'original': original_price,
            'sale_tag': sale_tag,
        }
        assets = {
            'main_image': main_img,
            'set_images': set_img,
            'view360': round_view,
            'video': video,
        }
        stock = {'in_stock': in_stock, 'count': count}
        metadata = {
            'description': description,
            'code': code,
            'form': form,
            'exp': exp,
            'production': brand,
            'country': country,
        }
        data = {
            'timestamp': timestamp,
            'RPC': code,
            'url': url,
            'title': title,
            'marketing_tags': badges,
            'brand': brand,
            'section': sections,
            'price': price,
            'stock': stock,
            'assets': assets,
            'metadata': metadata,
            'variants': quanity,
        }
        yield ScrapyMaksavitItem(data)


import requests
import base64
import os

# Obtained from your app dashboard
CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
CLIENT_SECRET = os.getenv("SPOTIFY_CLIENT_SECRET")
# Obtained after the initial user authorization request
CODE = os.getenv("CODE")
STATE = os.getenv("STATE")
# Obtained in the response body when requesting the access token
ACCESS_TOKEN = os.getenv("SPOTIFY_ACCESS_TOKEN")
REFRESH_TOKEN = os.getenv("SPOTIFY_REFRESH_TOKEN")

AUTH_URL = "https://accounts.spotify.com/api/token"

class SpotifyConnector:
    def get_auth_base64(self, id, secret):
        """Used to encode our Client ID and Client Secret when retriving your refresh token"""
        message = f"{id}:{secret}"
        message_bytes = message.encode("ascii")
        base64_bytes = base64.b64encode(message_bytes)
        base64_message = base64_bytes.decode("ascii")
        auth_header = {"Authorization": "Basic" + " " + base64_message}
        return auth_header

    def getToken(self, CLIENT_ID, CLIENT_SECRET):
        """Used to retrieve your access token AFTER the user initially accepts your request"""
        message = f"{CLIENT_ID}:{CLIENT_SECRET}"
        message_bytes = message.encode("ascii")
        base64_bytes = base64.b64encode(message_bytes)
        base64_message = base64_bytes.decode("ascii")
        auth_header = {"Authorization": "Basic" + " " + base64_message}
        auth_data = {
            "grant_type": "authorization_code",
            "code": CODE,
            "redirect_uri": "https://example.com",
        }
        r = requests.post(AUTH_URL, headers=auth_header, data=auth_data)
        response = r.json()

    def get_refresh_token(self):
        """Used to generate a refresh token"""
        refresh_body = {
            "grant_type": "refresh_token",
            "refresh_token": REFRESH_TOKEN,
        }
        headers = self.get_auth_base64(CLIENT_ID, CLIENT_SECRET)
        token = requests.post(AUTH_URL, headers=headers, data=refresh_body).json()
        return token["access_token"]


import os
import sys

from PyQt5 import QtWidgets, QtCore
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.graphWidget = pg.PlotWidget()
        self.graphWidget.setTitle("Temp over Time")
        self.graphWidget.setStyleSheet("QGraphicsTextItem { color:green;}")
        self.setCentralWidget(self.graphWidget)

        hour = [1,2,3,4,5,6,7,8,9,10]
        temperature = [30, 32, 34, 32, 33, 31, 29, 32, 35, 45]

        self.graphWidget.setBackground('w')
        self.graphWidget.setFontColor = (0,0,0)

        pen = pg.mkPen(color=(0,0,255), width=2,style=QtCore.Qt.DashLine)

        self.graphWidget.plot(hour,        \
                              temperature, \
                              pen=pen,     \
                              symbol='+',  \
                              symbolSize=30)

def main():
    app = QtWidgets.QApplication(sys.argv)
    qssfile="./styles.css"
    with open(qssfile,"r") as fh:
        app.setStyleSheet(fh.read())
    app.setStyleSheet("QGraphicsTextItem { color:green;}")
    window = MainWindow()
    #window.setStyleSheet("border:5px solid blue; padding:10px;")

    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()


#DriveMan CLI by OxxoCode
#https://github.com/OxxoCode/DriveMan

import argparse

import gdrive

class DriveMan:
    #Parse any DriveMan arguments passed by the user
    def parse_args(self):
        self.parser = argparse.ArgumentParser()
        self.parser.add_argument('-user', '--username',         nargs=1, help="Specify the username/alias for the account you are accessing")
        self.parser.add_argument('-sv', '--service',            nargs=1, help="Specify the service you are using (gdrive, dbox)")
        self.parser.add_argument('-c', '--copy',                nargs=2, help="Copy a file or folder")
        self.parser.add_argument('-d', '--download',            nargs=2, help="Download a file or folder")
        self.parser.add_argument('-u', '--upload',              nargs='+', help="Copy a file or folder")
        self.parser.add_argument('-m', '--move',                nargs=2, help="Move a file a file or folder")
        self.parser.add_argument('-meta', '--metadata',         nargs=1, help="Get the metadata of a file or folder")
        self.parser.add_argument('-l', '--list',                nargs=1, help="List all files and folders in a folder")
        self.parser.add_argument('-r', '--remove',              nargs=1, help="Remove/delete a file or folder")
        self.parser.add_argument('-s', '--size',                nargs=1, help="Get the size a file or folder")
        self.parser.add_argument('-nohash', '--no-hash-check',  nargs=1, help="Skip hash checking when uploading/downloading a file")
        self.args = self.parser.parse_args()

    #Handle authentication for each service, determined by value of --service
    def auth(self):
        s = self.args.service[0].lower()
        if s == "gdrive":
            self.gd = gdrive.GDrive()
            self.gd.auth( self.args.username[0] )
        elif s == "dbox":
            print('Dropbox is not currently supported. Coming soon!')
        else:
            print("ERROR: Must specify the service being used with -sv or --service.")
            print("Available services are: GDrive")

    #Core functionality of DriveMan
    def run(self):
        #Obtain list of all shared drives accessible by user.
        #Necessary for some functions which behave differently if a file is located in a shared drive
        self.gd.listSharedDrives()

        if self.args.copy:
            self.gd.copy( self.gd.cleanInput(self.args.copy[0]) , self.gd.cleanInput(self.args.copy[1]) )

        elif self.args.download: #Has some bugs - getting HTTP Errors on some files for an unknown reason. Also seems to look at files twice?
            self.gd.download( self.gd.cleanInput(self.args.download[0]) , self.gd.cleanInput(self.args.download[1]) )

        elif self.args.upload:
            #Could potentially improve, but it's a lot of additional code that I can just fix with an if-else, so eh.
            #https://stackoverflow.com/questions/4194948/python-argparse-is-there-a-way-to-specify-a-range-in-nargs
            if len(self.args.upload) == 2:
                self.gd.upload( self.gd.cleanInput(self.args.upload[0]) , self.gd.cleanInput(self.args.upload[1]) )
            else:
                self.gd.upload( self.gd.cleanInput(self.args.upload[0]) )

        elif self.args.move:
            self.gd.move( self.gd.cleanInput(self.args.move[0]) , self.gd.cleanInput(self.args.move[1]) )

        elif self.args.list:
            self.gd.list( self.gd.cleanInput(self.args.list[0]) )

        elif self.args.remove:
            self.gd.remove( self.gd.cleanInput(self.args.remove[0]) )

        elif self.args.size:
            self.gd.size( self.gd.cleanInput(self.args.size[0]) )

        elif self.args.metadata:
            meta =  self.gd.getMetadata( self.gd.cleanInput(self.args.metadata[0]))
            for key in meta.keys():
                print('{} : {}'.format(key, meta[key]))

def main():
    driveman = DriveMan()

    driveman.parse_args()
    driveman.auth()
    driveman.run()

if __name__ == '__main__':
    main()