from django.shortcuts import render
from django.shortcuts import redirect
from django.http import JsonResponse
from rest_framework import generics

import json
import matplotlib
import matplotlib.pyplot as plt
import networkx as nx
import nltk
import pandas as pd
import os
import json
import pickle
import re
import spacy

from nltk.corpus import stopwords
from sklearn.feature_extraction.text  import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer

import json
import matplotlib
import matplotlib.pyplot as plt
import networkx as nx
import nltk
import numpy as np
import pandas as pd
import os
import json
import pickle
import re
import spacy

from nltk.corpus import stopwords
from sklearn.feature_extraction.text  import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import MinMaxScaler
from sklearn.neighbors import NearestNeighbors

nlp = spacy.load("en_core_web_sm")
stop_words = set(stopwords.words('english'))

def get_tfidf(product_details):
    clean_product = []
    product_name = list(product_details)
    for i in range(len(product_name)):
        words = ""

        doc = nlp(product_name[i].lower())
        for token in doc:
            token.lemma_ = re.sub(r'\W',' ',token.lemma_)
            token.lemma_ = token.lemma_.strip()
            if not token.lemma_.endswith("ml") and not token.lemma_.endswith("ms") and not token.lemma_.isdigit() and not token.lemma_ in stop_words:
                if len(token.lemma_) > 2 or token.lemma_ == 'uv':
                    words += token.lemma_.lower() + " "

        if len(words) > 0:
            clean_product.append(str(words.strip()))

    tfidf_vectorizer=TfidfVectorizer(use_idf=True)
    tfidf_vectorizer_vectors=tfidf_vectorizer.fit_transform(clean_product)
    first_vector_tfidfvectorizer=tfidf_vectorizer_vectors[0]

    df = pd.DataFrame(first_vector_tfidfvectorizer.T.todense(), index=tfidf_vectorizer.get_feature_names(),
                      columns=["tfidf"])
    df = df.sort_values(by=["tfidf"], ascending=False).reset_index()

    return df

def index(request):
    return render(request, 'wishlist/index.html')

def register(request):
    return render(request, 'registration/register.html')

def forgot_password(request):
    return render(request, 'registration/forgot_password.html')

def mywishlist(request):
    return render(request, 'wishlist/my_wishlist.html')

def community(request):
    return render(request, 'wishlist/community.html')

class SearchWishlist(generics.ListAPIView):

    def get(self, request):
        result = []
        product_name = self.request.query_params.get('product-name', '')

        with open('/Users/rhey.magcalas/codes/research/secret_santa_web/main/network_theory.pickle','rb') as fe_data_file:
            G = pickle.load(fe_data_file)

        with open('/Users/rhey.magcalas/codes/research/secret_santa_web/main/betweenness_centraility.json') as f:
            between_centrality_json = json.load(f)

        overall_data = pd.read_csv('/Users/rhey.magcalas/codes/research/secret_santa_web/main/cleaned_data.csv', error_bad_lines=False)

        sub_category_list_2 = list(overall_data['Sub Category 2'].str.lower().unique())

        doc = nlp(product_name.strip().lower())
        result_categories = []

        for token in reversed(doc):
            if token.text in list(G.nodes()):
                print(token.lemma_)
                closeness_centrality_list = []
                betweness_centrality_list = []
                degree_list = []
                neighbor_list = []
                shortest_path_list = []
                length_list = []

                for _neighbors in list(G.neighbors(token.text)):
                    if _neighbors in sub_category_list_2:
                        neighbor_list.append(_neighbors)
                        betweness_centrality_list.append(between_centrality_json[_neighbors])
                        shortest_path = nx.shortest_path(G, source=_neighbors, target=token.lemma_)
                        shortest_path_list.append(len(shortest_path))
                        length_list.append(overall_data.loc[overall_data['Sub Category 2'] == _neighbors].shape[0])

                network_result = pd.DataFrame(neighbor_list, columns=['neighbor'])
                network_result['betweeness_centrality'] = betweness_centrality_list
                network_result['shortest_path'] = shortest_path_list

                if len(betweness_centrality_list) > 0:
                    if network_result[network_result['shortest_path'] == min(shortest_path_list)]['neighbor'].shape[0] < 2:
                        if list(network_result[network_result['shortest_path'] == min(shortest_path_list)]['neighbor'])[0] not in result_categories:
                            result_categories.append(list(network_result[network_result['shortest_path'] == min(shortest_path_list)]['neighbor'])[0])
                    else:
                        if list(network_result[network_result['betweeness_centrality'] == min(betweness_centrality_list)]['neighbor'])[0] not in result_categories:
                            result_categories.append(list(network_result[network_result['betweeness_centrality'] == min(betweness_centrality_list)]['neighbor'])[0])
        merge_products = []
        for _result_categories in result_categories:
            merge_products.append(overall_data.loc[(overall_data['Sub Category 2'] == _result_categories.title())])

        selected_category = pd.concat(merge_products).reset_index()

        vectorize = TfidfVectorizer(stop_words='english')
        tfidf_response= vectorize.fit_transform(selected_category['Product Name'])
        dtm = pd.DataFrame(tfidf_response.todense(), columns = vectorize.get_feature_names())

        nn = NearestNeighbors(n_neighbors=selected_category.shape[0])
        nn.fit(dtm)
        wishlist = [product_name.strip().lower()]

        new = vectorize.transform(wishlist)
        knn_model_result = nn.kneighbors(new.todense())

        knn_result = pd.DataFrame(knn_model_result[0][0][0:], columns=['Distance'])
        knn_result["Product Name"] = selected_category['Product Name'][knn_model_result[1][0][0:]]

        merged_result = pd.merge(selected_category, knn_result, on='Product Name', how='inner')
        merged_result = merged_result.drop_duplicates(subset='Product Name', keep="first")

        scaler = MinMaxScaler()

        scoring_criteria = ['Trusted', 'Highly Rated', 'Discounted', 'Top Selling', 'High Interest']
        df_eng = merged_result.copy()
        df_eng['Discount Percent'] = df_eng['Discount Range']-df_eng['Price Range']
        df_eng['Total Sold'] = scaler.fit_transform(df_eng[['Total Sold']])
        df_eng['High Interest'] = scaler.fit_transform(df_eng[['Favorite']])

        # Conditions
        df_eng['Highly Rated'] = df_eng['Current Rating'].astype(float).map(lambda x: True if x>4.2 else False)
        df_eng['Discounted'] = df_eng['Discount Percent'].astype(float).map(lambda x: True if x>0.03 else False)
        df_eng['Top Selling'] = df_eng['Total Sold'].map(lambda x: True if x>0.15 else False)
        df_eng['High Interest'] = df_eng['High Interest'].map(lambda x: True if x>0.15 else False)

        # New Columns
        df_eng['Trusted'] = df_eng.apply(lambda x: x['Preferred'] | x['Mall'], axis=1)

        model_features = ['Price Range']
        scoring_criteria = ['Trusted', 'Highly Rated', 'Discounted', 'Top Selling', 'High Interest']
        if df_eng.shape[0] < 10:
            prd_list = df_eng.sample(n=df_eng.shape[0])
        else:
            prd_list = df_eng.head(50)
        prd_list['relevance'] = np.random.uniform(0, 1, prd_list.shape[0])
        prd_list['score'] = prd_list['relevance']

        scored_list = prd_list[prd_list['Current Rating'] > 3.8]

        # Scoring System
        trusted_bias = 0.05
        highly_rated_bias = 0.05
        discounted_bias = 0.05
        top_selling_bias = 0.05
        high_interest_bias = 0.05

        scored_list['score'] = scored_list.apply(lambda x: x['score']+trusted_bias if x['Trusted'] == True else x['score'], axis=1)
        scored_list['score'] = scored_list.apply(lambda x: x['score']+highly_rated_bias if x['Highly Rated'] == True else x['score'], axis=1)
        scored_list['score'] = scored_list.apply(lambda x: x['score']+discounted_bias if x['Discounted'] == True else x['score'], axis=1)
        scored_list['score'] = scored_list.apply(lambda x: x['score']+top_selling_bias if x['Top Selling'] == True else x['score'], axis=1)
        scored_list['score'] = scored_list.apply(lambda x: x['score']+high_interest_bias if x['High Interest'] == True else x['score'], axis=1)
        scored_list

        for index, row  in scored_list.iterrows():
            current_data = overall_data[overall_data['Product ID'] == row['Product ID']]
            # print(current_data['URL'].iloc[0])

            image_url = ''
            if 0 in current_data['Image URL'].index:
                image_url = current_data['Image URL'].iloc[0]

            result.append({
                'url': current_data['URL'].iloc[0],
                'name': current_data['Product Name'].iloc[0],
                'image_url': image_url,
                'rating': str(current_data['Current Rating'].iloc[0]),
                'price': str(current_data['Price Range'].iloc[0]),
                'total_sold': str(current_data['Total Sold'].iloc[0]),
                'total_rating': str(current_data['Total Rating'].iloc[0]),
                'free_shipping': str(current_data['Free Shipping Info'].iloc[0])
            })

        return JsonResponse(result, safe=False)


import torch
import argparse
from kobert.pytorch_kobert import get_pytorch_kobert_model
from sklearn.model_selection import train_test_split
from dataset import *
from model import *
from loss import *
from transformers import AdamW
from adamp import AdamP

from transformers import ElectraModel, ElectraTokenizer
import random
import gluonnlp as nlp
from kobert.utils import get_tokenizer
from transformers.optimization import get_cosine_schedule_with_warmup
from torch.utils.tensorboard import SummaryWriter
from pathlib import Path
import glob
import re
from sklearn.model_selection import StratifiedKFold
import wandb

def calc_accuracy(X,Y):
    max_vals, max_indices = torch.max(X, 1)
    train_acc = (max_indices == Y).sum().data.cpu().numpy()/max_indices.size()[0]
    return train_acc

def increment_path(path, exist_ok=False):
    """ Automatically increment path, i.e. runs/exp --> runs/exp0, runs/exp1 etc.
    Args:
        path (str or pathlib.Path): f"{model_dir}/{args.name}".
        exist_ok (bool): whether increment path (increment if False).
    """
    path = Path(path)
    if (path.exists() and exist_ok) or (not path.exists()):
        return str(path)
    else:
        dirs = glob.glob(f"{path}*")
        matches = [re.search(rf"%s(\d+)" % path.stem, d) for d in dirs]
        i = [int(m.groups()[0]) for m in matches if m]
        n = max(i) + 1 if i else 2
        return f"{path}{n}"

def seed_everything(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)  # if use multi-GPU
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False
    np.random.seed(seed)
    random.seed(seed)

import os

def train():
	# 1. Start a new run
	wandb.init(project='Pstage2', entity='ekzm8523')

	# 2. Save model inputs and hyperparameters
	config = wandb.config
	config.update(args)

	###################################
	# 한번만 실행하면 되는 데이터 처리
	# dataset_path = r"/opt/ml/input/data/train/train.tsv"
	# dataset = load_data(dataset_path)
	# dataset['sentence'] = dataset['entity_01'] + ' [SEP] ' + dataset['entity_02'] + ' [SEP] ' + dataset['sentence']
	# dataset[['sentence','label']].to_csv("/opt/ml/input/data/train/train_train.txt", sep='\t', index=False)

	# dataset_train = pd.read_csv("/opt/ml/input/data/train/train_train.txt", delimiter='\t')
	# train_sentence = dataset_train['sentence'].tolist()
	# train_labels = dataset_train['label'].tolist()
	# skf = StratifiedKFold(n_splits=5, shuffle=True)
	#
	# for fold, (train_idx, val_idx) in enumerate(skf.split(dataset_train, dataset_train.label)):
	# 	train_dataset = [[train_sentence[i], train_labels[i]] for i in train_idx]
	# 	val_dataset = [[train_sentence[i], train_labels[i]] for i in val_idx]
	# 	train_dataset = pd.DataFrame(train_dataset)
	# 	train_dataset[[0, 1]].to_csv(f"/opt/ml/input/data/train/train_data{fold}.txt", sep='\t', index=False)
	# 	val_dataset = pd.DataFrame(val_dataset)
	# 	val_dataset[[0, 1]].to_csv(f"/opt/ml/input/data/train/val_data{fold}.txt", sep='\t', index=False)
	######################################

	seed_everything(args.seed)

	################
	max_len = args.max_len
	batch_size = args.batch_size
	warmup_ratio = args.warmup_ratio
	epochs = args.epochs
	max_grad_norm = args.max_grad_norm
	logging_steps = args.logging_steps
	learning_rate = args.lr
	device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')
	################

	for fold in range(5):
		train_dataset = nlp.data.TSVDataset(
			f"/opt/ml/input/data/train/train_data{fold}.txt",
			field_indices=[0, 1],
			num_discard_samples=1
		)
		val_dataset = nlp.data.TSVDataset(
			f"/opt/ml/input/data/train/val_data{fold}.txt",
			field_indices=[0, 1],
			num_discard_samples=1
		)

		bert_model, vocab = get_pytorch_kobert_model()
		tokenizer = get_tokenizer()
		tok = nlp.data.BERTSPTokenizer(tokenizer, vocab, lower=False)
		model = BERTClassifier(bert_model, dr_rate=0.5).to(device)

		no_decay = ['bias', 'LayerNorm.weight']
		optimizer_grouped_parameters = [
			{
				'params': [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)],
			 	'weight_decay': 0.01
			},
			{
				'params': [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)],
				'weight_decay': 0.0
			}
		]
		# optimizer = AdamW(optimizer_grouped_parameters, lr=learning_rate)
		optimizer = AdamP(optimizer_grouped_parameters, lr=learning_rate, betas=(0.9, 0.999), weight_decay=1e-2)

		train_dataset = BERTDataset(train_dataset, 0, 1, tok, max_len, True, False)
		val_dataset = BERTDataset(val_dataset, 0, 1, tok, max_len, True, False)

		train_iter = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=5)
		val_iter = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, num_workers=5)

		loss_fn = LabelSmoothingLoss()

		t_total = len(train_iter) * epochs
		warmup_step = int(t_total * warmup_ratio)
		print(f"t_total : {t_total}\t warmup_step : {warmup_step}")

		scheduler = get_cosine_schedule_with_warmup(optimizer, num_warmup_steps=warmup_step, num_training_steps=t_total)
		wandb.watch(model)

		for e in range(epochs):
			train_acc_sum = 0.0
			test_acc = 0.0
			best_acc = 0.0
			test_loss = 0.0
			best_loss = 0.0

			model.train()
			for batch_id, (token_ids, valid_length, segment_ids, label) in enumerate(train_iter):
				optimizer.zero_grad()
				token_ids = token_ids.long().to(device)
				segment_ids = segment_ids.long().to(device)
				valid_length = valid_length
				label = label.long().to(device)
				out = model(token_ids, valid_length, segment_ids)
				loss = loss_fn(out, label)
				loss.backward()
				torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)
				optimizer.step()
				scheduler.step()
				train_acc_sum += calc_accuracy(out, label)

				if batch_id % logging_steps == 0:
					train_loss = loss.data.cpu().numpy()
					print("fold {} epoch {} batch id {} loss {} train acc {}".format(fold, e + 1, batch_id + 1,
																					 train_loss,
																					 train_acc_sum / (batch_id + 1)))
					wandb.log({f"train_loss": train_loss, "train_accuracy": train_acc_sum / (batch_id + 1)})

			print("epoch {} train acc {}".format(e + 1, train_acc_sum / (batch_id + 1)))
			model.eval()
			for batch_id, (token_ids, valid_length, segment_ids, label) in enumerate(val_iter):
				token_ids = token_ids.long().to(device)
				segment_ids = segment_ids.long().to(device)
				valid_length = valid_length
				label = label.long().to(device)
				out = model(token_ids, valid_length, segment_ids)
				test_acc += calc_accuracy(out, label)
			print("epoch {} test acc {}".format(e + 1, test_acc / (batch_id + 1)))

			if test_acc >= best_acc:
				best_acc = test_acc
				torch.save(model.state_dict(), f"/opt/ml/model/{args.name}{fold}.pt")
			wandb.log({"val accuracy": test_acc/(len(val_dataset)/batch_size)})
if __name__ == '__main__':

	parser = argparse.ArgumentParser()
	# parser.add_argument('--model', type=str, default="Bert", help="transform model choice (default : Bert) ")
	# parser.add_argument('--pretrained_model', type=str, default="bert-base-multilingual-cased", help='Which pretrained model will you bring? (default : bert-base-multilingual-cased)')
	parser.add_argument('--seed', type=int, default=42)
	parser.add_argument('--epochs', type=int, default=20, help='number of epochs to train (default: 1)')
	parser.add_argument('--batch_size', type=int, default=32, help='input batch size for training (default: 64)')
	parser.add_argument('--lr', type=float, default=3e-5, help='learning rate (default: 5e-5)')
	parser.add_argument('--warmup_ratio', type=float, default=0.01, help='weight ratio (default: 0.01)')
	parser.add_argument('--warmup_steps', type=int, default=500, help='number of warmup steps for learning rate scheduler (default : 500)')
	parser.add_argument('--max_len', type=int, default=128)
	parser.add_argument('--max_grad_norm', type=int, default=1)

	parser.add_argument('--logging_steps', type=int, default=100, help='logging steps (default : 100)')
	parser.add_argument('--logging_dir', type=str, default='./logs', help='directory for storing logs (default : ./logs)')
	parser.add_argument('--output_dir', type=str, default='./results', help='save checkpoint (default : ./results/expr)')
	parser.add_argument('--train_dir', type=str, default="/opt/ml/input/data/train")
	parser.add_argument('--model_dir', type=str, default=os.environ.get('SM_MODEL_DIR', './model'))
	parser.add_argument('--name', type=str, default="kobert")

	args = parser.parse_args()
	print(args)
	print(vars(args))

	train()


import pygame as pg

def reveal_solution(screen, nbr_cases_x, nbr_cases_y, solution, images):  # Fonction de révélation de toutes les cases
    for k in range(nbr_cases_y):
        for t in range(nbr_cases_x):
            screen.blit(images[solution[k][t]], (22*t, 22*k))

def reveal_case(screen, nbr_cases_x, nbr_cases_y, images, solution, is_reveal, coords):  # Fonction de révélation d'une case choisie
    revealed_case_counter = 0  # Initialisation à 0 du nombre de cases révélés par la fonction
    defeat = False
    y, x = coords[0], coords[1]
    if not is_reveal[y][x]:  # Si la case n'est pas déjà révélé
        is_reveal[y][x] = True  # Sauvegarde de la case comme révélé
        if solution[y][x] == -1:  # Si la case est une bombe
            is_reveal[y][x] = False  # Enlèvement de la sauvegarde comme révélé pour ne pas provoquer de victoire
            screen.blit(images[solution[y][x]], (x * 22, y * 22))  # Affichage d'une bombe à l'emplacement de la case
            clock = pg.time.Clock()
            for k in range(nbr_cases_y):  # Affichage de toutes les bombes au rythme de 20 par secondes
                for t in range(nbr_cases_x):
                    for event in pg.event.get():
                        if event.type == pg.QUIT:
                            quit()
                    if solution[k][t] == -1 and not(k == y and t == x):
                        screen.blit(images[-1], (t * 22, k * 22))
                        clock.tick(20)
                        pg.display.flip()

            reveal_solution(screen, len(solution[0]), len(solution), solution, images)  # Révélation de toute la grille
            defeat = True  # Déclaration de la partie comme perdue

        elif solution[y][x] > 0:  # Si la case n'est pas une bombe ou un 0
            screen.blit(images[solution[y][x]], (x * 22, y * 22))  # Affichage de la case voulue
            revealed_case_counter += 1

        else:  # Si la case est un 0
            revealed_case_counter += 1
            screen.blit(images[solution[y][x]], (x * 22, y * 22))
            for i in range(-1, 2):  # Reveal des cases autour des cases 0 par récursivité
                for j in range(-1, 2):
                    if 0 <= y + i < nbr_cases_y and 0 <= x + j < nbr_cases_x:
                        temporaire, defeat = reveal_case(screen, nbr_cases_x, nbr_cases_y, images, solution, is_reveal, [y + i, x + j])
                        revealed_case_counter += temporaire
    return revealed_case_counter, defeat

def flag_case(screen, images, flags, is_reveal, coords):  # Fonction gérant l'affichage des drapeaux
    if coords not in flags:  # Si la case n'a pas déjà de drapeau
        if not is_reveal[coords[0]][coords[1]]:
            flags.append(coords)  # Ajout de la case à la liste des drapeaux
            screen.blit(images[-3], (coords[1]*22, coords[0]*22))  # Affichage d'un drapeau
    else:  # Si la case est un drapeau
        del flags[flags.index(coords)]  # Suppression de la case de la liste des drapeaux
        screen.blit(images[-2], (coords[1]*22, coords[0]*22))  # Affichage du case cachée à la place de l'ancien drapeau

def reveal_easy_start(screen, nbr_cases_x, nbr_cases_y, images, solution, is_reveal):  # Fonction jouant 1 coup automatique de départ pour l'utilisateur
    min_case = 9  # Iniatialisation du minimum à une valeur impossible
    coords = []
    for y in range(nbr_cases_y):  # Recherche de la case de plus basse proximité dans la grille
        for x in range(nbr_cases_x):
            if solution[y][x] < min_case and solution[y][x] != -1:
                coords = [y, x]
                min_case = solution[y][x]

    # révalation de la case choisie
    new_revealed_case, defeat = reveal_case(screen, nbr_cases_x, nbr_cases_y, images, solution, is_reveal, coords)
    return new_revealed_case


from django.shortcuts import render
from django.views.generic import View
from .models import Notification
import time
from django.http import JsonResponse

from security.response import set_response_header
from authentication.auth import check_authentication
from user.method import get_user
from .serialize import notification_serialize

# Create your views here.

class FetchNoti(View):
    def get(self, request):
        if check_authentication(request):
            user = get_user(request)
            try:
                currentIndex = int(request.GET.get('currentIndex'))
            except ValueError:
                currentIndex = 0
            noti_type = ['status-a','status-b']
            notis = Notification.objects.filter(user = user, noti_type__in = noti_type).order_by('-time')[currentIndex:currentIndex+10]
            unread_noti = len(Notification.objects.filter(user = user, read = False, noti_type__in = noti_type))
            data = {
                'data': notification_serialize(notis),
                'unread': unread_noti,
                'status_code': 'ok'
                }
            response = JsonResponse(data)
            set_response_header(response)
            return response
        else:
            data = {
            'status_code': 'error'
            }
            response = JsonResponse(data)
            set_response_header(response)
            return response


import datetime

class Shape:

    def __init__(self, colour, material):
        self.colour = colour
        self.material = material
        self.create_date = datetime.datetime.now().strftime("%x")

        # this date will be the same for all Shapes, we do not need to pass this create parameter


from time import time
import inspect
import io
import contextlib

func_list = {}
class timer_func:
    def __init__(self,func):
        self.func = func
        timer_func.count = 0
    def __call__(self,*args,**kwargs):
        timer_func.count += 1
        self.arguments = args
        start = time()
        with contextlib.redirect_stdout(io.StringIO()) as output:
            self.func(*args, **kwargs)
        end= time()
        exec_time = end - start
        global fun_list
        with open('log.txt', 'a+') as log:
            log.writelines(self.func.__name__ + " call" + str(timer_func.count)+ " executed in "+ str(exec_time)+ " sec\n")
            log.writelines(f"Name: {self.func.__name__}\n")
            log.writelines(f"Type: {type(self.func)}\n")
            log.writelines(f"Sign: {inspect.signature(self.func)}\n")
            log.writelines(f"Doc:  {self.func.__doc__}\n")
            log.writelines(f"Source:  {inspect.getsource(self.func)}\n")
            log.writelines(f"Output:{output.getvalue()}\n")
        func_list.append((self.func.__name__, exec_time))
        return self.func


from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

from time import sleep
import threading

from tkinter import *
from tkinter import ttk

import sys
sys.path.append('./Busca_Arquivo_Mensagem')

from buscaeEnvio import *

#envia as mensagens
def sendMensagem(mensagem,midia,send,event,barra,button_start, driver,contatos):
    i=0
    tam=len(contatos)
    print(contatos)
    for contato in contatos:
        button_start["text"] = "Cancelar"
        if event.is_set():
            break

        try:
            buscar_contato(contato, driver)
            enviar_midia(midia, driver)
            enviar_mensagem(mensagem, driver)

            #envia a mendagem
            ActionChains(driver)\
                    .pause(0.3)\
                    .send_keys(Keys.ENTER)\
                    .perform()

            print("Enviado -> contato: "+str(contato)+"\n")
            i+=1
            if (i%100==0):
                button_start["text"] = "Descanso 60s"
                sleep(60)
                button_start["text"] = "Cancelar"
            progress = (i/tam)*100
            barra.set(progress)
            send.update()
        except:
            print("\nerro: "+contato)
            button_start["text"] = "Erro"
    button_start["text"] = "Fechar"
    barra.set(100)
    send.update()

def enviar(mensagem,midia,driver,contatos):

    def start ():
        envioMensagem.start()

        button_start.config (text = 'Cancelar')
        button_start.config (command = cancelar)

    def cancelar():
        event.set()
        close()

    def close():
        send.destroy()

    send = Toplevel()
    send.title('Envio')

    lbl = Label(send)
    lbl["text"] = mensagem
    lbl.pack()

    barra = DoubleVar(send,value=0)

    minha_barra = ttk.Progressbar(send, variable=barra, maximum=100)
    minha_barra.pack()

    button_start = Button(send)
    button_start["text"] = "Confirmar"
    button_start["command"] = start
    button_start.pack()

    event = threading.Event()
    envioMensagem = threading.Thread(target=sendMensagem, args=(mensagem,midia,send,event,barra,button_start,driver,contatos), name='envioMensagem')

    send.mainloop()
    # return resultado


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 多页抓取和二级页面抓取解析

import requests
from bs4 import BeautifulSoup
import json

def start_request(url):
    r = requests.get(url)
    return r.content

# 解析一级页面
def get_page(text):
    soup = BeautifulSoup(text, 'html.parser')
    movies = soup.find_all('div', class_ = 'info')
    pages = []
    for movie in movies:
        url = movie.find('div', class_ = 'hd').a['href']
        pages.append(url)
    return pages

# 解析二级页面
def parser_page(text):
    soup = BeautifulSoup(text, 'html.parser')
    mydict = {}
    mydict['title'] = soup.find('span', property = 'v:itemreviewed').text
    mydict['duration'] = soup.find('span', property = 'v:runtime').text
    mydict['time'] = soup.find('span', property = 'v:initialReleaseDate').text
    return mydict

# 数据存储到json中
def write_json(result):
    s = json.dumps(result, indent=4, ensure_ascii=False)
    with open('movies.json', 'w', encoding='utf-8')as f:
        f.write(s)

def main():
    for i in range(7, 9):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)
        text = start_request(url)
        # 解析一级页面
        pageurls = get_page(text)
        for pageurl in pageurls: # 解析二级页面,pageurls为字典，包含了所有获取的二级页面的url地址，遍历pageurls获得单个pagerul
            get_second_page = start_request(pageurl) # 将单个的二级url传入函数start_request()进行数据获取
            second_mydict = parser_page(get_second_page) # 将单个解析后的值传入parser_page函数进行二级页面解析
            result_list.append(second_mydict)
            print(second_mydict)
    write_json(result_list)

if __name__ == '__main__':
    result_list = []
    main()


import pygame

class Tear(pygame.sprite.Sprite):

    def __init__(self,player,direction):
        super().__init__()
        self.velocity = 15
        self.image = pygame.image.load('assets/tear.png')
        self.image = pygame.transform.scale(self.image, (30, 30))
        self.player = player
        self.rect = self.image.get_rect()
        self.rect.move_ip(player.hitbox.x+50,player.hitbox.y+40)
        self.initial_momentum = (player.velocity[0],player.velocity[1])
        self.direction = direction
        self.current_range = 0

    def remove_tear(self):
        self.player.all_projectiles.remove(self)

    def move(self):
        if 0 < self.rect.x < 1300 and 0 < self.rect.y <750 and self.current_range < self.player.range:
            if self.direction == 0:
                if self.initial_momentum[0] > 0:
                    self.rect.x += self.velocity + self.initial_momentum[0]
                else:
                    self.rect.x += self.velocity
                self.current_range += self.velocity
                self.rect.y += self.initial_momentum[1]/2

            elif self.direction == 1:
                if self.initial_momentum[1] < 0:
                    self.rect.y -= (self.velocity - self.initial_momentum[1])
                else:
                    self.rect.y -= self.velocity
                self.current_range += self.velocity
                self.rect.x += self.initial_momentum[0]/2

            elif self.direction == 2:
                self.rect.x -= self.velocity
            elif self.direction == 3:
                self.rect.y += self.velocity
        else:
            self.remove_tear()


# coding: utf-8
from django.shortcuts import render, get_object_or_404, redirect, render_to_response
from .models import Category, Product, Rating, NewsBlock, ActionBlock, AboutUsBlock, DeliveryBlock, ContactsBlock
from cart.forms import CartAddProductForm
from django.db.models import Q, Avg, Sum, Max, Min, Count
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger, InvalidPage, EmptyPage
from .forms import RatingCreateForm, MailCreateForm, MyFilterForm
from myshop.tasks import *
from .decorators import check_recaptcha

def search(query, category=None):
    # обработка поиска
    q = str(query).strip()
    q1 = q.lower()
    q2 = q.title()
    if not category:
        return Product.objects.filter(Q(description__icontains=q1, available=True) |
                               Q(description__icontains=q2, available=True) |
                               Q(name__name__icontains=q1, available=True) |
                               Q(name__name__icontains=q2, available=True) |
                               Q(color__name__icontains=q1, available=True) |
                               Q(color__name__icontains=q2, available=True) |
                               Q(firm__name__icontains=q, available=True) |
                               Q(firm__name__icontains=q1, available=True) |
                               Q(firm__name__icontains=q2, available=True)).order_by('-created')
    else:
        return Product.objects.filter(Q(description__icontains=q1, category=category, available=True)|
                                   Q(description__icontains=q2, category=category, available=True)|
                                   Q(name__name__icontains=q1, category=category, available=True)|
                                   Q(name__name__icontains=q2, category=category, available=True)|
                                   Q(color__name__icontains=q1, category=category, available=True)|
                                   Q(color__name__icontains=q2, category=category, available=True)|
                                   Q(firm__name__icontains=q, category=category, available=True)|
                                   Q(firm__name__icontains=q1, category=category, available=True)|
                                   Q(firm__name__icontains=q2, category=category, available=True)).order_by('-created')

# автокомплит слов для jquery
def wordslistAutocomplete(prod):
    w = []
    for k in list(prod.values('name__name', 'color__name', 'firm__name')):
        if '-' in k['name__name'].lower():
            for i in k['name__name'].lower().split('-'):
                if i not in w:
                    w.append(i)
        else:
            if k['name__name'].lower() not in w:
                w.append(k['name__name'].lower())
        if k['color__name'].lower() not in w:
            w.append(k['color__name'].lower())
        for i in k['firm__name'].split():
            if i not in w:
                w.append(i)
    words = list(set(w))
    return words

# Пагинатор страниц
def pager(prod, pages, request):
    paginator = Paginator(prod, pages)
    page = request.GET.get('page')
    try:
        prod = paginator.page(page)
    except PageNotAnInteger:
        prod = paginator.page(1)
    except EmptyPage:
        prod = paginator.page(paginator.num_pages)
    return prod

def MainView(request):
    query = request.GET.get('query')
    products = Product.objects.filter(available=True).order_by('-created')
    bestseller = products.filter(available=True, order_items__gt=1).annotate(sells=Count('order_items')).order_by(
        '-sells')[:6]
    recommended = products.filter(available=True, recommended=True).order_by('-created')[:6]
    novosti = NewsBlock.objects.all().order_by('-created')
    if len(novosti) >= 2:
        novosti = novosti[:2]
    actions = ActionBlock.objects.all()
    if len(actions) >= 3:
        action1, action2, action3 = actions[:3]
    else:
        action1, action2, action3 = ('', '', '')

    if query:
        products = search(query)
        return render(request, 'base_home.html', {'bestseller':bestseller, 'recommended':recommended,
                                                      'products': products, 'qflag': query, 'novosti': novosti})

    ### Выбираем id  только по одному имени каждого товара из новых для главной страницы  ###
    m = {}
    for n in list(products.values('name', 'id')):
        if n['name'] not in m:
            m[n['name']] = n['id']
    products = products.filter(id__in=list(m.values()))[:8]
    return render(request, 'base_home.html', {'products':products, 'action1': action1, 'action2': action2,'action3': action3,
                'bestseller':bestseller, 'recommended':recommended, 'novosti': novosti})

def AboutView(request):
    text = AboutUsBlock.objects.all()
    return render(request, 'about-us.html', {'text': text})

def NewsView(request):
    novosti = NewsBlock.objects.all().order_by('-created')[:20]
    novosti = pager(novosti, 3, request)
    return render(request, 'news.html', {'novosti': novosti})

def NewsViewDetail(request, id):
    novost = get_object_or_404(NewsBlock, id=id)
    return render(request, 'newsdetail.html', {'novost': novost})

@check_recaptcha
def ContactsView(request):
    text = ContactsBlock.objects.all()
    mailing_form = MailCreateForm()
    if request.method == "POST":
        mailing_form = MailCreateForm(request.POST)
        if mailing_form.is_valid() and not request.POST['honey'] and request.recaptcha_is_valid:
            cd = mailing_form.cleaned_data
            tel = cd['tlf'] if cd['tlf'] else 'Не оставлено'
            text = '\n от: %s.\n e-mail: %s\n тел: %s\n Сообщение: %s.\n' \
                 % (cd['author'].title(), cd['email'], tel, cd['message'].capitalize())
            sender_mail.delay('Оставлено сообщение на сайте онлайн магазина DocSimvol', text)
            return render(request, 'messagecreated.html', {'author': cd['author']})

    return render(request, 'contact-us.html', {'mailing_form': mailing_form, 'text': text})

def DeliveryView(request):
    text = DeliveryBlock.objects.all()
    return render(request, 'delivery.html', {'text': text})

def ProductList(request):
    category = None
    categories = Category.objects.all()
    all_products = Product.objects.all()
    actions = ActionBlock.objects.all()
    query = request.GET.get('query')
    form = MyFilterForm(request.POST or request.GET or None)
    if request.method == "GET":
        if form.is_valid():
            cleandata = form.cleaned_data
            st_select = cleandata.get('t')
            sp_select = cleandata.get('p')
            price_min = cleandata.get('p_min')
            price_max = cleandata.get('p_max')
            sc_select = cleandata.get('c')
            if st_select or sp_select or price_max or price_min or sc_select:
                products = all_products.filter(available=True)
                if st_select != ' ' and st_select:
                    products = products.filter(tips__name=st_select)
                if price_min or price_max:
                    if price_max and not price_min:
                        products = products.filter(price__lte=price_max).order_by('price')
                    if price_min and not price_max:
                        products = products.filter(price__gte=price_min).order_by('price')
                    if price_max and price_min:
                        if price_max == price_min:
                           products = products.filter(price=price_min)
                        else:
                            products = products.filter(price__gte=price_min, price__lte=price_max).order_by('price')
                if sp_select != ' ' and sp_select:
                    if sp_select == 'Дороже':
                        products = products.order_by('-price')
                    if sp_select == 'Дешевле':
                        products = products.order_by('price')
                if sc_select != ' ' and sc_select and sc_select != '':
                    products = products.filter(color__name=sc_select)

                filteredproducts = pager(products, 9, request)
                return render(request, 'shop-product.html', {'category': category, 'categories': categories, 'actions':actions,
                                            'products': filteredproducts, 'form': form, 'words': wordslistAutocomplete(products)})
    if query:
        # поиск
        products = search(query)
        queryproducts = pager(products, 9, request)
        return render(request, 'shop-product.html', {'category': category, 'categories': categories,
                        'products': queryproducts, 'qflag': query, 'form': form, 'words': wordslistAutocomplete(products)})

    products = all_products.filter(available=True).order_by('-created')
    ### Выбираем id  только по одному имени каждого товара из новых для главной страницы  ###
    m = {}
    for n in list(products.values('name', 'id')):
        if n['name'] not in m:
            m[n['name']] = n['id']
    products = products.filter(id__in=list(m.values()))[:9]

    return render(request, 'shop-product.html', {'category': category,'categories': categories, 'actions':actions,
    'products': products, 'form': form, 'words': wordslistAutocomplete(all_products)})

def ProductCatItemList(request, category_slug):
    category = get_object_or_404(Category, slug=category_slug)
    categories = Category.objects.all()
    actions = ActionBlock.objects.all()
    form = MyFilterForm(request.POST or request.GET or None)
    if request.method == "GET":
        if form.is_valid():
            cleandata = form.cleaned_data
            st_select = cleandata.get('t')
            sp_select = cleandata.get('p')
            price_min = cleandata.get('p_min')
            price_max = cleandata.get('p_max')
            sc_select = cleandata.get('c')
            if st_select or sp_select or price_max or price_min or sc_select:
                products = Product.objects.filter(available=True, category=category)
                if st_select != ' ' and st_select:
                    products = products.filter(tips__name=st_select)
                if price_min or price_max:
                    if price_max and not price_min:
                        products = products.filter(price__lte=price_max).order_by('price')
                    if price_min and not price_max:
                        products = products.filter(price__gte=price_min).order_by('price')
                    if price_max and price_min:
                        if price_max == price_min:
                           products = products.filter(price=price_min)
                        else:
                            products = products.filter(price__gte=price_min, price__lte=price_max).order_by('price')
                if sp_select != ' ' and sp_select:
                    if sp_select == 'Дороже':
                        products = products.order_by('-price')
                    if sp_select == 'Дешевле':
                        products = products.order_by('price')
                if sc_select != ' ' and sc_select:
                    products = products.filter(color__name=sc_select)

                filteredproducts = pager(products, 9, request)
                return render(request, 'shop-product-category.html', {'category': category, 'categories': categories, 'actions':actions,
                        'products': filteredproducts, 'form': form, 'words': wordslistAutocomplete(products)})

    query = request.GET.get('query')
    if query:
        # поиск
        products = search(query, category)
        queryproducts = pager(products, 9, request)
        return render(request, 'shop-product-category.html', {'category': category, 'categories': categories,
             'products': queryproducts,  'form': form, 'qflag': query, 'words': wordslistAutocomplete(products)})

    products = Product.objects.filter(available=True, category=category).order_by('name')
    return render(request, 'shop-product-category.html', {'category': category,'categories': categories, 'actions':actions,
    'products': products, 'form': form, 'words': wordslistAutocomplete(products)})

def ProductDetail(request, id, slug):
    rating_form = RatingCreateForm()
    cart_product_form = CartAddProductForm()
    categories = Category.objects.all()
    product = get_object_or_404(Product, id=id, slug=slug, available=True)
    ## все цвета и размеры на станице товара для данной модели ##
    clrs = []
    sizs = []
    for cs in list(Product.objects.filter(slug=slug).values('size__sz', 'color__name')):
        if cs['color__name'] not in clrs:
            clrs.append(cs['color__name'])
        if cs['size__sz'] not in sizs:
            sizs.append(cs['size__sz'])
    clrs = (', ').join(clrs)
    sizs = (', ').join(sizs)
    ######
    if request.method == "POST":
        rating_form = RatingCreateForm(request.POST)
        if rating_form.is_valid():
            cd = rating_form.cleaned_data
            Rating.objects.create(rating=cd['rating'], product_id=product.id, email=cd['email'],
                                  author=cd['author'], ratingcomment=cd['ratingcomment'])
            link = 'http://www.docsimvol.ru' + product.get_absolute_url()
            text = 'от: %s. \ne-mail: %s. \nОтзыв: %s. \nПоставил(а) оценку: %s. \nссылка на товар: %s \nНапоминание: необходимо разрешить показывать' \
                   ' этот отзыв на сайте или удалить...' % (
                   cd['author'].title(), cd['email'], cd['ratingcomment'].capitalize(), cd['rating'], link)
            sender_mail.delay('Оставлен новый комментарий о товаре', text)
            return render(request, 'ratecreated.html', {'author': cd['author']})

    return render(request, 'product-detail.html', {'categories': categories,
    'product': product,  'cart_product_form': cart_product_form, 'clrs':clrs, 'sizs':sizs, 'rating_form': rating_form})


# Librerias de python
from tkinter import *
from tkinter import messagebox as MessageBox
from io import open
from tkinter import filedialog
from tkinter.filedialog import asksaveasfile
import os
import re

# Analizadores lexicos
from Analizadores.AnalizadorLexicocss import *
from Analizadores.AnalizadorLexicoJS import *
from Analizadores.AnalizadorLexicohtml import *
from Analizadores.Lexrmt import *

# Analizador sintactico de expresiones
from Analizadores.Sintactico import *

textoArchivo = ""
bitacora = ""

def abrirArchivo():
    # ABRIENDO ARCHIVO
    filename = filedialog.askopenfilename(
        initialdir="C://Users//jsola//Desktop", title="Seleccionar archivo",
        filetypes=(("archivos javascript", "*.js"), ("archivos HTML", "*.html"), ("archivos CSS", "*.css"), ("archivos rmt", "*.rmt")))
    # imprime la ruta
    ruta = filename
    # print(filename)
    split_ = os.path.splitext(filename)
    #print("Extensión del archivo '% s': " %filename, split_[1], "\n")
    extension = split_[1]
    labelFormato.config(text=extension)
    try:
        with open(filename, 'r') as UseFile:
            textoArchivo = UseFile.read()
            textoEntrada.insert(INSERT, textoArchivo)
            # print(UseFile.read())

    except:
        print("El archivo no existe.")

#######################

def limpiarCajaTexto():
    textoEntrada.delete('1.0', END)
    textoSalida.delete('1.0', END)

#######################

def analizarEntrada():
    # atrapa la extensión del archivo
    ext = labelFormato['text']

    if ext == ".js":

        entrada = textoEntrada.get("1.0", "end-1c")
        MessageBox.showinfo(
            "Aviso", "Analisis del archivo JavaScript iniciado")
        analizadorJS = AnalizadorLexicoJS()
        analizadorJS.Escanear(entrada)
        print("\n\n")
        analizadorJS.ImprimirListaTokens()
        analizadorJS.GenerarReporte()
        analizadorJS.GenerarSalida()
        tokens = analizadorJS.ImprimirListaTokens()
        textoSalida.insert(INSERT, "\t :: LISTADO DE TOKENS :: \n")
        textoSalida.insert(INSERT, tokens)
        print(analizadorJS.fila)

    elif ext == ".css":

        entrada = textoEntrada.get("1.0", "end-1c")
        MessageBox.showinfo("Aviso", "Analisis del archivo CSS iniciado.")
        analizadorCSS = AnalizadorLexicocss()
        analizadorCSS.Escanear(entrada)
        analizadorCSS.ImprimirListaTokens()
        analizadorCSS.ImprimirListaErrores()
        analizadorCSS.GenerarReporte()
        bitacora = analizadorCSS.GenerarBitacora()
        analizadorCSS.GenerarArchivoSalida()
        textoSalida.insert(INSERT, bitacora)
        # print(bitacora)
        print(analizadorCSS.fila)

    elif ext == ".html":

        entrada = textoEntrada.get("1.0", "end-1c")
        MessageBox.showinfo("Aviso", "Analisis del archivo HTML iniciado")
        analizadorHTML = AnalizadorLexicohtml()
        analizadorHTML.Escanear(entrada)
        tokensHTML = analizadorHTML.imprimirListaTokens()
        textoSalida.insert(INSERT, "\t :: LISTADO DE TOKENS :: \n")
        textoSalida.insert(INSERT, tokensHTML)
        analizadorHTML.GenerarReporteErrores()
        analizadorHTML.GenerarSalida()
        print(analizadorHTML.fila)

    elif ext == ".rmt":

        entrada = textoEntrada.get("1.0", "end-1c")
        MessageBox.showinfo("Aviso", "Analisis del archivo rmt iniciado")
        analizadorRMT = Lexrmt()
        analizadorRMT.Escanear(entrada)
        analizadorRMT.imprimirExpresiones()
        # Iniciar analisis sintactico
        sintactico = Sintactico()
        sintactico.Parse(analizadorRMT.listaExpr)
        # print(sintactico.pilaVacia())
        resultadoSintactico = sintactico.mostrarReporte()
        textoSalida.insert(INSERT, resultadoSintactico)
        sintactico.GenerarReporteErrores()
        #sintactico = AnalizadorSintactico()
        # sintactico.Parsear(analizadorRMT.ListaTokens)

    else:
        print("Formato no permitido / archivo no cargado")

#######################

def guardarArchivo():

    archivos = [('Archivos Javascript', '*.js'), ('Archivos CSS', '*.css'),
                ('Archivos HTML', '*.html'), ('Archivos rmt', '*.rmt')]

    archivo = asksaveasfile(mode='w', filetypes=archivos,
                            defaultextension=archivos)
    archivoDestino = textoEntrada.get(1.0, END)
    archivo.write(archivoDestino)
    archivo.close()

#######################

def colorearJS():
    pass

#######################

ventana = Tk()
ventana.title("OLC PROYECTO 1 - 201800496")
ventana.resizable(False, False)

# insertar frame
miFrame = Frame(ventana, width=950, height=600, bg="#292D3E")
miFrame.pack()

# BARRA DE MENÚ
# insetar barra de menu
barraMenu = Menu(ventana)
ventana.config(menu=barraMenu)

filemenu = Menu(barraMenu)
filemenu = Menu(barraMenu, tearoff=0)
filemenu.add_command(label="Nuevo")
filemenu.add_command(label="Abrir", command=abrirArchivo)
filemenu.add_command(label="Guardar", command=guardarArchivo)
filemenu.add_separator()
filemenu.add_command(label="Salir")

analizar = Menu(barraMenu)
analizar = Menu(barraMenu, tearoff=0)
analizar.add_command(label="Ejecutar análisis")

reportes = Menu(barraMenu)
reportes = Menu(barraMenu, tearoff=0)
reportes.add_command(label="Ver reportes")

# titulos de las pestañas de la barra de menu
barraMenu.add_cascade(label="Archivo", menu=filemenu)
barraMenu.add_cascade(label="Analizar", menu=analizar)
barraMenu.add_cascade(label="Reportes", menu=reportes)

# COMPONENTES QUE VAN DENTRO DEL FRAME
labelTitulo = Label(ventana, text="Editor de texto")
labelTitulo.place(x=10, y=10)
labelTitulo.config(padx=5, pady=5, font=("sans-serif", 10))

labelFormato = Label(ventana, text="")
labelFormato.place(x=120, y=10)
labelFormato.config(padx=5, pady=5, font=("sans-serif", 10))

# scroll bar1
scrollbar1 = Scrollbar(ventana)
scrollbar1.pack(side=RIGHT, fill=Y)

# CAJA TEXTO ENTRADA
textoEntrada = Text(ventana)
textoEntrada.place(x=10, y=60)
textoEntrada.insert(INSERT, textoArchivo)
textoEntrada.config(width=65, height=35, font=("Consolas", 9),
                    padx=5, pady=5, yscrollcommand=scrollbar1.set)
scrollbar1.config(command=textoEntrada.yview)

# scroll bar1
scrollbar2 = Scrollbar(ventana)
scrollbar2.pack(side=RIGHT, fill=Y)

# CAJA TEXTO QUE MUESTRA LA SALIDA
textoSalida = Text(ventana)
textoSalida.place(x=505, y=60)
textoSalida.config(width=60, height=35, font=("Consolas", 9),
                   padx=5, pady=5, yscrollcommand=scrollbar2.set)
scrollbar2.config(command=textoSalida.yview)

# BOTONES
botonAnalizar = Button(ventana, text="Analizar")
botonAnalizar.place(x=780, y=10)
botonAnalizar.config(padx=3, pady=3, font=(
    "sans-serif", 10), command=analizarEntrada)

botonBorrar = Button(ventana, text="Borrar")
botonBorrar.place(x=850, y=10)
botonBorrar.config(padx=3, pady=3, font=(
    "sans-serif", 10), command=limpiarCajaTexto)

ventana.mainloop()


# coding:utf-8

#1画像からネジを検出し、画像の中心座標を求める
#2画像の中心座標から一定の幅を持つ四角形で画像をsaveする

#以下の3か所に調べたいネジを含むファイル名、出力ファイル名を記載する
#image = cv2.imread("imageCopy_M8-16_15b.png",0)
#image3 = cv2.imread("imageCopy_M8-16_15b.png",1)
#cv2.imwrite('imageCopy_M8-16_15b.png', image3[a:b,c:d])

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

#個別ファイルを指定する場合は以下
image = cv2.imread("imageCopy_M6-15_1b.png",0)
# plt.imshow(image)
# plt.show()

#二値化
thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] #閾値0, 最大値255 = 白

# plt.imshow(thresh)
# plt.show()

imgEdge,contours,hierarchy = cv2.findContours(thresh, 1, 2) #1 = cv2.RETR_TREE?, 2= cv2.CHAIN_APPROX_SIMPLE?
for cnt in contours:
	x,y,w,h = cv2.boundingRect(cnt)
	if h < 400: #画像の外枠の情報を取得しないようにする
		img = cv2.rectangle(image, (x,y),(x+w,y+h), (0,0,255), 2)
		plt.imshow(img)
		plt.show()

		print ("X: {}".format(x + w/2) )
		print ("Y: {}".format(y + h/2) )
		print ("X-200 {}".format((x + w/2)-200))
		print ("X+200 {}".format((x + w/2)+200))
		print ("Y-200 {}".format((y + h/2)-200))
		print ("Y+200 {}".format((y + h/2)+200))

		centerX = (x + w/2)
		centerY = (y + h/2)

		a = centerY - 200
		b = centerY + 200
		c = centerX - 200
		d = centerX + 200

		#401pixelで画像を取得　(ネジの中心(外接矩形中心)= (centerX,centerY) )
		img2 = cv2.rectangle(image, (centerY-200, centerY + 200),(centerX - 200, centerX + 200), (0,0,255), 2)
		plt.imshow(img2) #ここは外接矩形のチェックを行う際には実行する
		plt.show()

#二値化していない元の画像に対して枠を作成、表示する
image3 = cv2.imread("imageCopy_M6-15_1b.png",1)
# img3 = cv2.rectangle(image3, (centerY-200, centerY + 200),(centerX-200, centerX + 200), (0,0,255), 2)
# cv2.imwrite('demo.jpg', image3[y:y + hight, x:x + width])
cv2.imwrite('imageCopy_M6-15_1bcut.png', image3[a:b,c:d])  #[y:y + hight, x:x + width]で範囲を指定できる
#上記の値はcntの中から最適と判断したものを仕様

# plt.imshow(img4)
# plt.show()


# 프로그래머스 LV1 - 완주하지 못한 선수(Counter 활용)
# https://programmers.co.kr/learn/courses/30/lessons/42576?language=python3
import collections

def solution(participant, completion):
    answer = '' # 리턴할 값 answer

    '''
    participant와 completion 길이의 차는 1이다.
    이를 활용하기 위해 Counter 클래스를 활용하면 된다.
    participant와 completion 배열 간의 차를 구하고
    마지막 Counter에서 Key 값을 읽어오기 위해 list(value.keys())[0]를 answer에 대입한다.
    '''
    value = collections.Counter(participant) - collections.Counter(completion)

    answer = list(value.keys())[0]

    return answer

participant = ["mislav", "stanko", "mislav", "ana"]
completion = 	["stanko", "ana", "mislav"]
print(solution(participant, completion))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"Running jobs on all TaskCacheList"

from   multiprocessing            import Process, Pipe
from   multiprocessing.connection import Connection
from   typing                     import (
    Dict, Callable, List, Optional, Set, Union, Any, Iterator, Tuple,
    AsyncIterator, ContextManager
)
import asyncio

import pandas as pd

from data.trackio           import TrackIOError
from taskcontrol.processor  import ProcessorException
from taskmodel.dataframe    import DataFrameTask
from taskmodel.processors   import TaskCacheList
from utils.logconfig        import getLogger

LOGS  = getLogger(__name__.replace("_", ""))
STORE = Dict[int, Union[Exception, pd.DataFrame]]

class JobConfig:
    "Pool config"
    def __init__(self):
        self.name:          str   = "peakcalling.precomputations"
        self.ncpu:          int   = 2
        self.waittime:      float = .1
        self.stoptime:      float = .3
        self.maxkeysperjob: int   = 10
        self.multiprocess:  bool  = True

class JobDisplay:
    "Pool live info"
    def __init__(self):
        self.name:   str  = "peakcalling.precomputations"
        self.calls:  int  = 1
        self.active: bool = True
        self.last:   int  = 1

    @property
    def needsrefresh(self) -> bool:
        "return whether to refresh"
        return self.active and self.last < self.calls

class JobEventNames:
    """Deals with emitting job-related events"""
    def __init__(self, ctrl = None):
        self.eventname:     str = getattr(ctrl, 'eventname', 'peakcalling.view.jobs')
        self.eventjobstart: str = getattr(ctrl, 'eventjobstart', f'{self.eventname}.start')
        self.eventjobstop:  str = getattr(ctrl, 'eventjobstop', f'{self.eventname}.stop')

class JobModel:
    """
    the model for launching computations
    """
    def __init__(self, mdl: Optional['JobModel'] = None):
        self.config:  JobConfig  = JobConfig()  if mdl is None else mdl.config
        self.display: JobDisplay = JobDisplay() if mdl is None else mdl.display

    def swapmodels(self, ctrl):
        "swap models for those in the controller"
        self.config  = ctrl.theme.swapmodels(self.config)
        self.display = ctrl.display.swapmodels(self.display)

    def launch(
            self,
            processors: List[TaskCacheList],
            emitter:    Optional[JobEventNames] = None,
            **kwa
    ):
        """
        Runs jobs synchronously or asynchronously depending on configuration

        Parameters
        ----------

        processors:
            a list of TaskCacheList to run
        emitter:
            in charge of launching start & end events
        """
        return _JobRunner(self).dolaunch(
            processors,
            _JobEventEmitter(emitter, processors = processors, **kwa)
        )

class _JobCanceled(StopIteration):
    pass

class _JobEventEmitter(JobEventNames):
    """Deals with emitting job-related events"""
    _evt: ContextManager

    def __init__(
            self,
            ctrl = None,
            **args
    ):
        super().__init__(ctrl)
        self.ctrl   = getattr(ctrl, '_ctrl', ctrl)
        self.idval  = None
        self.args   = args

    def __call__(self, idval):
        self.idval = idval
        return self

    def __enter__(self):
        "emits a *job starting* event"
        if self.ctrl:
            LOGS.debug("Starting job %s", self.idval)
            self.ctrl.display.handle(
                self.eventjobstart,
                self.ctrl.emitpolicy.outasdict,
                {'idval': self.idval, **self.args}
            )
            self._evt = self.ctrl.display(self.eventname, args = {})
            return self._evt.__enter__()
        return lambda *_, **__: None

    def __exit__(self, extype, *_, **__):
        if hasattr(self, '_evt'):
            out = self._evt.__exit__()
            del self._evt
            if extype is _JobCanceled:
                LOGS.debug("Cancelled job %s", self.idval)

            if extype is not _JobCanceled:
                LOGS.debug("Done job %s", self.idval)
                self.ctrl.display.handle(
                    self.eventjobstop,
                    self.ctrl.emitpolicy.outasdict,
                    {'idval': self.idval, **self.args}
                )
                return out
            return True
        return None

class _JobRunner(JobModel):
    "Running jobs on all TaskCacheList"
    def dolaunch(
            self,
            processors: List[TaskCacheList],
            emitter:    _JobEventEmitter
    ):
        """
        Runs jobs synchronously or asynchronously depending on configuration

        Parameters
        ----------

        processors:
            a list of TaskCacheList to run
        emitter:
            in charge of launching start & end events
        """
        idval = self.display.calls

        if self.config.multiprocess:

            async def _run():
                if idval != self.display.calls:
                    return

                with emitter(idval) as emitup:
                    if self.config.ncpu > 1:
                        await self.run(processors,  emitup, idval)
                    else:
                        self.syncrun(processors)

                    if idval != self.display.calls:
                        raise _JobCanceled()

                    if self.config.ncpu > 1:
                        await asyncio.sleep(self.config.stoptime)

            asyncio.create_task(_run())
            return

        LOGS.info("Starting SYNCH jobs")
        with emitter(idval):
            self.syncrun(processors)
            if idval != self.display.calls:
                raise _JobCanceled()
        LOGS.info("SYNCH jobs done")

    def syncrun(self, processors: List[TaskCacheList]):
        """
        runs all processors sequentially

        Parameters
        ----------

        processors:
            a list of TaskCacheList to run
        emitter:
            in charge of launching start & end events
        """
        for procs in processors:
            frame = next(iter(procs.run()), None)
            if frame is None:
                continue

            if callable(getattr(frame, 'bead', None)):
                raise NotImplementedError()

            store: STORE = procs.data.getcache(DataFrameTask)()

            for keys in self.__split(lambda*_: None, procs):
                if self.config.ncpu <= 0:
                    continue

                for i in keys:
                    try:
                        store[i] = frame[i]
                    except (TrackIOError, ProcessorException) as exc:
                        store[i] = exc

    async def run(
            self,
            processors: List[TaskCacheList],
            events:     Callable[[Dict[str, Any]], None],
            idval:      Optional[int] = None
    ):
        """
        run jobs on provided processors

        Parameters
        ----------

        processors:
            a list of TaskCacheList to run
        events:
            a method emitting an event every time it is called
        """
        # freeze current config
        idcall = self.display.calls if idval is None else idval

        ncpu:  int        = self.config.ncpu
        nprocs: List[int] = [ncpu]

        def _evtfcn(procs: TaskCacheList, beads: List[int]):
            LOGS.debug("-> Processed track %d, beads %s", processors.index(procs), beads)
            try:
                events(dict(idval = idcall, taskcache = procs, beads = beads))
            except Exception as exc:  # pylint: disable=broad-except
                LOGS.exception(exc)

        # create a list allows sending events for all beads already treated
        jobs: List[Tuple[TaskCacheList, Set[int]]] = [
            (procs, keys)
            for procs in processors
            for keys in self.__split(_evtfcn, procs)
        ]

        async def _watchjob(procs: TaskCacheList, keys: Set[int]):
            LOGS.debug("Processing track %d, beads %s", processors.index(procs), keys)
            try:
                async for beads in self.__startjob(procs, keys, idcall):
                    _evtfcn(procs, beads)
            finally:
                nprocs[0] += 1

        if ncpu <= 0:
            return

        # now iterate throught remaining keys
        LOGS.info("%d jobs running in %d separate processes", len(jobs), ncpu)
        for procs, keys in jobs:
            while self.__keepgoing(idcall, nprocs[0] > 0):
                await asyncio.sleep(self.config.waittime)

            if not self.__keepgoing(idcall):
                return

            nprocs[0] -= 1
            asyncio.create_task(_watchjob(procs, keys))

        while self.__keepgoing(idcall, nprocs[0] == ncpu):
            await asyncio.sleep(self.config.waittime)

    @staticmethod
    def _runjob(pipe: Connection, procs: TaskCacheList, keys: List[int]):
        "runs a job"
        if pipe.poll():
            return

        frame = next(iter(procs.run()), None)
        if frame is None:
            pipe.send((None, None))
            return

        if callable(getattr(frame, 'bead', None)):
            raise NotImplementedError()

        for i in keys:
            if pipe.poll():
                return

            try:
                out = (i, frame[i])
            except ProcessorException as exc:
                out = (i, exc)

            if pipe.poll():
                return

            pipe.send(out)

        if not pipe.poll():
            pipe.send((None, None))

    async def __startjob(
            self,
            procs: TaskCacheList,
            keys:  Set[int],
            idval: int
    ) -> AsyncIterator[List[int]]:
        "run a single job"
        cache: Callable[[], STORE] = procs.data.getcache(DataFrameTask)
        store: STORE               = cache()
        if store is None:
            return

        def _keepgoing(done) -> bool:
            return self.__keepgoing(idval, done) and cache() is not None

        pipein, pipeout = Pipe()
        Process(
            target = self._runjob,
            args   = (pipeout, procs.cleancopy(), keys)
        ).start()

        done = False
        while _keepgoing(done):
            await asyncio.sleep(self.config.waittime)

            found: List[int] = []
            while _keepgoing(done or not pipein.poll()):
                ibead, data = pipein.recv()
                done        = ibead is None
                if _keepgoing(done):
                    store[ibead] = data
                    found.append(ibead)

            if _keepgoing(False) and found:
                yield found

        if not done:
            pipein.send(False)

    def __keepgoing(self, idval, done = False) -> bool:
        return not done and idval == self.display.calls

    def __split(
            self,
            events: Callable[[TaskCacheList, List[int]], None],
            procs:  TaskCacheList
    ) -> Iterator[Set[int]]:
        cache = procs.data.getcache(DataFrameTask)()

        try:
            keys = set(next(iter(procs.run()), {}).keys())
        except TrackIOError:
            keys = set(cache if cache else ())

        if cache:
            LOGS.debug("%s has %d processed keys", procs.model[0].path, len(keys - set(cache)))

            keys -= set(cache)
            events(procs, list(cache))

        if keys:
            lkeys = sorted(keys)
            njobs = max(1, len(lkeys) // self.config.maxkeysperjob)

            if (len(lkeys) % self.config.maxkeysperjob) > njobs:
                njobs += 1

            batch = len(lkeys) // njobs
            rem   = len(lkeys) % batch

            LOGS.debug("%s requires %d jobs", procs.model[0].path, len(lkeys)//batch+1)

            for i in range(0, len(lkeys), batch):
                ix1 = i + min(rem, i)
                ix2 = min(ix1 + batch + (i < rem), len(lkeys))
                if ix1 < ix2:
                    yield set(lkeys[ix1:ix2])


import boto3
import botocore
# import jsonschema
import json
import traceback
import zipfile
import os
import hashlib

from botocore.exceptions import ClientError, ParamValidationError

from extutil import remove_none_attributes, account_context, ExtensionHandler, ext, \
    current_epoch_time_usec_num, component_safe_name, lambda_env, random_id, \
    handle_common_errors, create_zip

eh = ExtensionHandler()

ses = boto3.client('sesv2')

def lambda_handler(event, context):
    try:
        print(f"event = {event}")
        # account_number = account_context(context)['number']
        region = account_context(context)['region']
        eh.capture_event(event)

        prev_state = event.get("prev_state") or {}
        project_code = event.get("project_code")
        repo_id = event.get("repo_id")
        cdef = event.get("component_def")
        cname = event.get("component_name")

        name = cdef.get("name") or component_safe_name(
            project_code, repo_id, cname, max_chars=64
        )

        redirect_domain = cdef.get("redirect_domain")
        tls_policy = cdef.get("tls_policy") or "OPTIONAL"
        sending_pool_name = cdef.get("sending_pool_name")

        reputation_metrics_enabled = cdef.get("reputation_metrics_enabled", False)

        #Not doing suppression list for now
        # vdm_engagement_metrics = cdef.get("vdm_engagement_metrics", False)
        # vdm_optimized_shared_delivery = cdef.get("vdm_optimized_shared_delivery", False)

        tags = cdef.get("tags") or {}
        trust_level = cdef.get("trust_level")

        if event.get("pass_back_data"):
            print(f"pass_back_data found")
        elif event.get("op") == "upsert":
            if trust_level == "full":
                eh.add_op("compare_defs")
            else:
                eh.add_op("get_configuration_set")

        elif event.get("op") == "delete":
            eh.add_op("delete_configuration_set", {"create_and_remove": False, "name": name})

        compare_defs(event)

        configuration = remove_none_attributes({
            "ConfigurationSetName": name,
            "TrackingOptions": remove_none_attributes({
                "CustomRedirectDomain": redirect_domain
            }) or None,
            "DeliveryOptions": remove_none_attributes({
                "TlsPolicy": tls_policy,
                "SendingPoolName": sending_pool_name
            }) or None,
            "ReputationOptions": remove_none_attributes({
                "ReputationMetricsEnabled": reputation_metrics_enabled
            }) or None,
            "SendingOptions": {
                "SendingEnabled": True
            },
            "Tags": format_tags(tags),
            # "VdmOptions": {
            #     "DashboardOptions": {
            #         "EngagementMetrics": vdm_engagement_metrics,
            #     },
            #     "GuardianOptions": {
            #         "OptimizedSharedDelivery": vdm_optimized_shared_delivery
            #     }
            # }
        })

        print(f"configuration = {configuration}")

        get_configuration_set(prev_state, name, configuration, region, tags)
        create_configuration_set(name, configuration, region)
        put_configuration_set_tracking_options()
        put_configuration_set_sending_options()
        put_configuration_set_reputation_options()
        put_configuration_set_delivery_options()
        add_tags()
        remove_tags()
        delete_configuration_set()

        return eh.finish()

    except Exception as e:
        msg = traceback.format_exc()
        print(msg)
        eh.add_log("Unexpected Error", {"error": msg}, is_error=True)
        eh.declare_return(200, 0, error_code=str(e))
        return eh.finish()

@ext(handler=eh, op="compare_defs")
def compare_defs(event):
    old_digest = event.get("prev_state", {}).get("props", {}).get("def_hash")
    new_rendef = event.get("component_def")

    _ = new_rendef.pop("trust_level", None)

    dhash = hashlib.md5()
    dhash.update(json.dumps(new_rendef, sort_keys=True).encode())
    digest = dhash.hexdigest()
    eh.add_props({"def_hash": digest})

    if old_digest == digest:
        eh.add_links(event.get("prev_state", {}).get('links'))
        eh.add_props(event.get("prev_state", {}).get('props'))
        eh.add_log("Full Trust, No Change: Exiting", {"old_hash": old_digest})

    else:
        eh.add_log("Definitions Don't Match, Deploying", {"old": old_digest, "new": digest})
        eh.add_op("get_configuration_set")

@ext(handler=eh, op="get_configuration_set")
def get_configuration_set(prev_state, name, configuration, region, tags):

    if prev_state and prev_state.get("props") and prev_state.get("props").get("name"):
        prev_name = prev_state.get("props").get("name")
        if name != prev_name:
            eh.add_op("delete_configuration_set", {
                "create_and_remove": True,
                "name": prev_name
            })

    try:
        params = {"ConfigurationSetName": name}
        response = ses.get_configuration_set(**params)

        print(f"Get Configuration Set: {response}")

        eh.add_log("Found Configuration Set", response)
        eh.add_props({"name": response['ConfigurationSetName']})
        eh.add_links({"Configuration Set": gen_configuration_set_link(name, region)})

        if response.get("TrackingOptions") != configuration.get("TrackingOptions"):
            eh.add_op("put_configuration_set_tracking_options", {"redirect_domain", configuration.get("TrackingOptions", {}).get("CustomRedirectDomain")})
        if response.get("DeliveryOptions") != configuration.get("DeliveryOptions"):
            eh.add_op("put_configuration_set_delivery_options", {"tls_policy": configuration.get("DeliveryOptions", {}).get("TlsPolicy"), "sending_pool_name": configuration.get("DeliveryOptions", {}).get("SendingPoolName")})
        if response.get("ReputationOptions", {}).get("ReputationMetricsEnabled") != configuration.get("ReputationOptions", {}).get("ReputationMetricsEnabled"):
            eh.add_op("put_configuration_set_reputation_options", {"reputation_enabled": configuration.get("ReputationOptions", {}).get("ReputationMetricsEnabled")})
        if response.get("SendingOptions") != configuration.get("SendingOptions"):
            eh.add_op("put_configuration_set_sending_options")

        print(f"tags response = {response}")
        current_tags = unformat_tags(response.get("Tags") or [])

        if tags != current_tags:
            remove_tags = [k for k in current_tags.keys() if k not in tags]
            add_tags = {k:v for k,v in tags.items() if k not in current_tags.keys()}
            if remove_tags:
                eh.add_op("remove_tags", remove_tags)
            if add_tags:
                eh.add_op("add_tags", add_tags)

    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == 'NotFoundException':
            eh.add_op("create_configuration_set")
        else:
            handle_common_errors(e, eh, "Get Configuration Set", 10)

@ext(handler=eh, op="create_configuration_set")
def create_configuration_set(name, desired_config, region):

    try:
        response = ses.create_configuration_set(**desired_config)
        eh.add_log("Created Configuration Set", response)
        eh.add_props({
            "name": name
        })
        eh.add_links({"Configuration Set": gen_configuration_set_link(name, region)})
    except ClientError as e:
        handle_common_errors(
            e, eh, "Create Configuration Set Failed", 20,
            perm_errors=[
                "LimitExceededException",
                "RepositoryAlreadyExistsException",
                "InvalidParameterException",
                "InvalidTagParameterException",
                "TooManyTagsException"
            ]
        )
    except ParamValidationError as e:
        eh.add_log("Invalid Parameters for Configuration Set", {"error": str(e)}, is_error=True)
        eh.perm_error("Invalid Parameters for Configuration Set", 20)

@ext(handler=eh, op="put_configuration_set_tracking_options")
def put_configuration_set_tracking_options():
    name = eh.props.get("name")
    redirect_domain = eh.ops['put_configuration_set_tracking_options']['redirect_domain']

    try:
        response = ses.put_configuration_set_reputation_options(
            ConfigurationSetName=name,
            CustomRedirectDomain= redirect_domain
        )
        eh.add_log("Updated Configuration Set Tracking Options", response)
    except ClientError as e:
        handle_common_errors(
            e, eh, "Update Configuration Set Tracking Options Failed", 44,
            perm_errors=[
                "NotFoundException",
                "BadRequestException"
            ]
        )

@ext(handler=eh, op="put_configuration_set_sending_options")
def put_configuration_set_sending_options():
    name = eh.props.get("name")

    try:
        response = ses.put_configuration_set_sending_options(
            ConfigurationSetName=name,
            SendingEnabled=True
        )
        eh.add_log("Set Configuration Set To Be Active", response)
    except ClientError as e:
        handle_common_errors(
            e, eh, "Settting Configuration Set Active Failed", 46,
            perm_errors=[
                "NotFoundException",
                "BadRequestException"
            ]
        )

@ext(handler=eh, op="put_configuration_set_reputation_options")
def put_configuration_set_reputation_options():
    name = eh.props.get("name")
    reputation_enabled = eh.ops['put_configuration_set_reputation_options']['reputation_enabled']

    try:
        response = ses.put_configuration_set_reputation_options(
            ConfigurationSetName=name,
            ReputationMetricsEnabled= reputation_enabled
        )
        eh.add_log("Updated Configuration Set Reputation Options", response)
    except ClientError as e:
        handle_common_errors(
            e, eh, "Update Configuration Set Reputation Options Failed", 48,
            perm_errors=[
                "NotFoundException",
                "BadRequestException"
            ]
        )

@ext(handler=eh, op="put_configuration_set_delivery_options")
def put_configuration_set_delivery_options():
    name = eh.props.get("name")
    tls_policy = eh.ops['put_configuration_set_delivery_options']['tls_policy']
    pool_name = eh.ops['put_configuration_set_delivery_options']['sending_pool_name']

    try:
        response = ses.put_configuration_set_delivery_options(
            ConfigurationSetName=name,
            TlsPolicy= tls_policy,
            SendingPoolName= pool_name
        )
        eh.add_log("Updated Configuration Set Delivery Options", response)
    except ClientError as e:
        handle_common_errors(
            e, eh, "Update Configuration Set Delivery Options Failed", 52,
            perm_errors=[
                "NotFoundException",
                "BadRequestException"
            ]
        )

# @ext(handler=eh, op="put_configuration_set_vdm_options")
# def put_configuration_set_vdm_options():
#     name = eh.props.get("name")
#     vdm_engagement_metrics = eh.ops['put_configuration_set_vdm_options']['vdm_engagement_metrics']
#     vdm_optimized_shared_delivery = eh.ops['put_configuration_set_vdm_options']['vdm_optimized_shared_delivery']

#     try:
#         response = ses.put_configuration_set_vdm_options(
#             ConfigurationSetName=name,
#             VdmOptions= {
#                 "DashboardOptions": {
#                     "EngagementMetrics": vdm_engagement_metrics,
#                 },
#                 "GuardianOptions": {
#                     "OptimizedSharedDelivery": vdm_optimized_shared_delivery,
#                 }
#             }
#         )
#         eh.add_log("Updated Configuration Set VDM Options", response)

#     except ClientError as e:
#         handle_common_errors(
#             e, eh, "Update Configuration Set VDM Options Failed", 56,
#             perm_errors=[
#                 "NotFoundException",
#                 "BadRequestException"
#             ]
#         )

@ext(handler=eh, op="delete_configuration_set")
def delete_configuration_set():
    config_set_name = eh.ops['delete_configuration_set'].get("name")
    car = eh.ops['delete_configuration_set'].get("create_and_remove")

    try:
        params = {
            "ConfigurationSetName": config_set_name
        }

        _ = ses.delete_configuration_set(**params)
        eh.add_log("Deleted Configuration Set", {"name": config_set_name})

    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == "NotFoundException":
            eh.add_log("Old Set Does Not Exist", {"name": config_set_name})
        else:
            handle_common_errors(e, eh, "Delete Config Set Failed", 80 if car else 10)

@ext(handler=eh, op="add_tags")
def add_tags():
    tags = format_tags(eh.ops['add_tags'])
    arn = eh.props['arn']

    try:
        ses.tag_resource(
            ResourceArn=arn,
            Tags=tags
        )
        eh.add_log("Tags Added", {"tags": tags})

    except ClientError as e:
        handle_common_errors(e, eh, "Add Tags Failed", 50, ['InvalidParameterValueException'])

@ext(handler=eh, op="remove_tags")
def remove_tags():
    arn = eh.props['arn']

    try:
        ses.untag_resource(
            ResourceArn=arn,
            TagKeys=eh.ops['remove_tags']
        )
        eh.add_log("Tags Removed", {"tags": eh.ops['remove_tags']})

    except botocore.exceptions.ClientError as e:
        handle_common_errors(e, eh, "Remove Tags Failed", 65, ['InvalidParameterValueException'])

def format_tags(tags_dict):
    return [{"Key": k, "Value": v} for k,v in tags_dict]

def unformat_tags(tags_list):
    return {t["Key"]: t["Value"] for t in tags_list}

def gen_configuration_set_link(name, region):
    return f"https://{region}.console.aws.amazon.com/ses/home?region={region}#/configuration-sets/{name}"


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

import configparser
import os

from pymongo import MongoClient, DESCENDING, ASCENDING

path = os.path.dirname(os.path.abspath(__file__))
config = configparser.ConfigParser()
config.read(path + '''/../config/configuration.cfg''')

def connect_to_mongodb():
    client = MongoClient(
        'mongodb://' + config['MONGODB']['User'] + ':' + config['MONGODB']['Password'] + '@' + config['MONGODB'][
            'Host'] + ':' + config['MONGODB']['Port'] + '/admin')
    return client

def query_offers(client, geolocation, price_filter, surface_filter, ground_surface_filter, price_per_m2_filter,
                 price_per_are_filter, magic_ratio_filter, property_types_filter, sort, sort_order, limit_offers):
    collection = client['antunedo']['offers']
    field_to_sort_by, direction = convert_sort_instructions(sort, sort_order)
    results = []
    query = collection.find({**{'ratio_to_average_price': {'$lt': -14.9}, 'geo.country': 'lu', 'is_online': True},
                             **geolocation,
                             **price_filter,
                             **surface_filter,
                             **ground_surface_filter,
                             **price_per_m2_filter,
                             **price_per_are_filter,
                             **magic_ratio_filter,
                             **property_types_filter}) \
                .sort([(field_to_sort_by, direction)]) \
                .limit(limit_offers)
    for i in query:
        try:
            insertion_date = int(i['insertion_time'])
        except KeyError:
            insertion_date = -1
        try:
            url = "https://athome.lu" + i['meta']['permalink']['fr']
        except KeyError:
            url = "https://athome.lu"
        try:
            immo_type = i['immotype']
        except KeyError:
            immo_type = "Bien inconnu"
        try:
            bedrooms = i['characteristic']['bedrooms_count']
        except KeyError:
            bedrooms = 0
        try:
            city = i['geo']['city']
        except KeyError:
            city = ""
        try:
            surface = i['characteristic']['property_surface']
        except KeyError:
            surface = 0
        title = immo_type + " " + str(bedrooms) + " chambres à " + city
        try:
            region = i['completeGeoInfos']['levels']['L4']
        except KeyError:
            region = ""
        try:
            price = i['price']
        except KeyError:
            price = 0
        if price != 0 and surface != 0:
            price_per_m2 = price / surface
        else:
            price_per_m2 = 0
        try:
            energy_pass = i['property']['energy_efficiency']['lu_energy_class']
        except KeyError:
            energy_pass = ""
        try:
            magic_ratio = i['ratio_to_average_price']
        except KeyError:
            magic_ratio = 0
        try:
            switcher = {
                1: "(simple)",
                2: "(ch)",
                3: "(quartier)",
                4: "(ch + quartier)"
            }
            pertinence = str(int(i['properties_used_to_calculate_average'])) + " biens " \
                               + switcher[int(i['average_price_pertinence_level'])]
        except KeyError:
            pertinence = ""
        try:
            latitude = i['completeGeoInfos']['pin']['lat']
            longitude = i['completeGeoInfos']['pin']['lon']
            maps_link = "https://www.google.com/maps/search/?api=1&query=" + str(latitude) + "," \
                        + str(longitude)
        except KeyError:
            maps_link = None
        try:
            ground_surface = i['characteristic']['ground_surface']
        except KeyError:
            ground_surface = 0
        if price != 0 and ground_surface != 0:
            price_per_are = price / ground_surface
        else:
            price_per_are = 0
        results.append({
            "id": i['id'],
            "insertion_date": insertion_date,
            "title": title,
            "url": url,
            "surface": surface,
            "city": city,
            "region": region,
            "bedrooms": bedrooms,
            "price": price,
            "price_per_m2": price_per_m2,
            "energy_pass": energy_pass,
            "magic_ratio": magic_ratio,
            "maps_link": maps_link,
            "pertinence": pertinence,
            "ground_surface": ground_surface,
            "price_per_are": price_per_are
        })
    return results

def convert_sort_instructions(sort, sort_order):
    if sort is None:
        return 'insertion_time', DESCENDING
    else:
        switcher = {
            'date': 'insertion_time',
            'city': 'geo.city',
            'price': 'price',
            'surface': 'characteristic.property_surface',
            'pricePerM2': 'price_by_m2',
            'groundSurface': 'characteristic.ground_surface',
            'pricePerAre': 'price_per_are',
            'ratio': 'ratio_to_average_price'
        }
        field = switcher.get(sort, 'insertion_time')
        return field, DESCENDING if sort_order == 'desc' else ASCENDING

def property_type_enumerations(client):
    collection = client['antunedo']['offers']
    result = []
    p_types_cursor = collection.aggregate([
        {
            '$group': {
                '_id': None,
                'property_types': {'$addToSet': '$property.immotype.label'}
            }
        }
    ])
    for i in p_types_cursor:
        result += i['property_types']
    return result

def geolocation_enumerations(client):
    collection = client['antunedo']['geographical_filter_options']
    result = []
    for i in collection.find({}):
        result += i['options']
    return result

def geolocation_enumerations_obsolete(client):
    collection = client['antunedo']['offers']
    cities = []
    iterator = collection.aggregate([
        {
            '$group': {
                '_id': {
                    'type': 'city',
                    'name': '$geo.city',
                    'country': '$geo.country'
                }
            }
        },
        {
            '$sort': {
                '_id.name': 1
            }
        },
        {
            '$group': {
                '_id': None,
                'cities': {'$push': '$_id'}
            }
        },
    ])
    for i in iterator:
        cities = i['cities']
        break
    countries = []
    iterator = collection.aggregate([
        {
            '$group': {
                '_id': {
                    'type': 'country',
                    'name': '$geo.country',
                    'country': '$geo.country'
                }
            }
        },
        {
            '$sort': {
                '_id.name': 1
            }
        },
        {
            '$group': {
                '_id': None,
                'countries': {'$push': '$_id'}
            }
        },
    ])
    for i in iterator:
        countries = i['countries']
        break
    regions_and_other = []
    iterator = collection.aggregate([
        {
            '$project': {
                'pays': '$geo.country',
                'completeGeoInfos.levels.L4': 1,
                'completeGeoInfos.levels.L5': 1,
                'completeGeoInfos.levels.L7': 1,
                'completeGeoInfos.levels.L10': 1,
            }
        },
        {
            '$project': {
                'pays': 1,
                'levels': {'$objectToArray': '$completeGeoInfos.levels'}
            }
        },
        {
            '$unwind': '$levels'
        },
        {
            '$group': {
                '_id': {
                    'type': '$levels.k',
                    'length': {'$strLenCP': '$levels.k'},
                    'name': '$levels.v',
                    'country': '$pays'
                }
            }
        },
        {
            '$sort': {
                '_id.length': 1,
                '_id.type': 1,
                '_id.name': 1
            }
        },
        {
            '$project': {
                '_id.type': 1,
                '_id.name': 1,
                '_id.country': 1
            }
        },
        {
            '$group': {
                '_id': None,
                'regions_and_other': {'$push': '$_id'}
            }
        }
    ])
    for i in iterator:
        regions_and_other = i['regions_and_other']
        break
    return countries + cities[3:] + regions_and_other


import gdal
import os
import sys
import cv2
import numpy as np
from PIL import Image
from matplotlib import pyplot as plt
from functools import reduce

from MoreOne import Ui_Dialog
from PyQt5.QtWidgets import QDialog, QFileDialog,QApplication
from base_functions import drawMatchesKnn_cv2, save_matchedpoints_in_file

import sys

class myWindow(QDialog, Ui_Dialog):
    def __init__(self):
        super(myWindow,self).__init__()
        self.setupUi(self)

    def sopen1(self):
        fileName, filetype = QFileDialog.getOpenFileName(self,
                                    "选取文件",
                                    "/home/scrc/",
                                    "image Files (*.tif);;All Files (*)")
        self.lineEdit_one.setText(fileName)

    def sopen2(self):
        fileName, filetype = QFileDialog.getOpenFileName(self,
                                                         "选取文件",
                                                         "/home/scrc/",
                                                         "image Files (*.tif);;All Files (*)")
        self.lineEdit_two.setText(fileName)

    def sok(self):
        filename_first=self.lineEdit_one.text()
        filename_second = self.lineEdit_two.text()
        root = os.path.split(filename_first)[0]

        temp = list(filter(str.isdigit, os.path.split(filename_first)[1]))
        s_1 = reduce(lambda x, y:str(x)+str(y), temp)
        temp = list(filter(str.isdigit, os.path.split(filename_second)[1]))
        s_2 = reduce(lambda x, y: str(x)+str(y), temp)
        #    print ("{}_{}".format(s_1,s_2))
        # textfile = "{}_{}.txt".format(s_1, s_2)

        dataset = gdal.Open(filename_first)
        if dataset == None:
            print(filename_first + '文件无法打开')
            sys.exit(1)
        im_width = dataset.RasterXSize
        im_height = dataset.RasterYSize
        im_bands = dataset.RasterCount

        if not 1 == im_bands:
            print("image bands > 1")
            sys.exit(0)

        im_data = dataset.ReadAsArray(0, 0, im_width, im_height)
        del dataset

        img_1 = im_data.astype(np.uint8)
        img_ss = np.zeros((im_height, im_width, 3), dtype=np.uint8)
        for i in range(3):
            img_ss[:, :, i] = img_1

        dataset_2 = gdal.Open(filename_second)
        if dataset_2 == None:
            print(filename_second + '文件无法打开')
            sys.exit(1)
        im_width_2 = dataset_2.RasterXSize
        im_height_2 = dataset_2.RasterYSize
        im_data_2 = dataset_2.ReadAsArray(0, 0, im_width_2, im_height_2)
        del dataset_2

        img_2 = im_data_2.astype(np.uint8)
        img_sp = np.zeros((im_height_2, im_width_2, 3), dtype=np.uint8)
        for i in range(3):
            img_sp[:, :, i] = img_2

        """
        采用sift算子，提取匹配点，并存放到TXT文件中
        """
        # sift = cv2.xfeatures2d.SIFT_create()
        orb = cv2.ORB_create(5000)
        kp1, des1 = orb.detectAndCompute(img_ss, None)
        kp2, des2 = orb.detectAndCompute(img_sp, None)
        bf = cv2.BFMatcher(cv2.NORM_HAMMING)
        # bf = cv2.BFMatcher()
        matches = bf.knnMatch(des1, trainDescriptors=des2, k=2)

        goodMatch = []
        for m, n in matches:
            if m.distance < 0.75 * n.distance:
                goodMatch.append(m)

        num_matched_point = len(goodMatch)
        print("匹配的点有{}个".format(num_matched_point))
        if num_matched_point < 2:
            print("match point less than 2")
            # continue

        imgfile = "{}_{}.png".format(s_1, s_2)
        out_img_file = os.path.join(root, imgfile)
        drawMatchesKnn_cv2(img_ss, kp1, img_sp, kp2, goodMatch, out_img_file)

        textfile = "{}_{}.txt".format(s_1, s_2)
        out_txt_file = os.path.join(root, textfile)
        save_matchedpoints_in_file(im_data, kp1, im_data_2, kp2, goodMatch, out_txt_file)

if __name__=='__main__':
    app = QApplication(sys.argv)
    window = myWindow()
    window.show()
    sys.exit(app.exec_())


from django.shortcuts import redirect
from django.urls import path, re_path

from .models import *
from . import views

app_name = 'survey'
urlpatterns = [
    path('', lambda request: redirect('survey:site_overview',
        Checklist.objects.filter(is_active=True).last().id), name='index'),
    re_path(r'^(?P<checklist_id>[0-9]+)/$', views.index, name='site_overview'),
    re_path(r'^(?P<checklist_id>[0-9]+)/(?P<site_id>[0-9]+)/$', views.evaluate, name='evaluate'),
    re_path(r'^(?P<checklist_id>[0-9]+)/summary/$', views.SummaryListView.as_view(), name='summary-list'),
    re_path(r'^(?P<checklist_id>[0-9]+)/summary-by-user/$',
        views.SummaryByUserListView.as_view(), name='summary-by-user-list'),
    re_path(r'^compare/(?P<checklist_id>[0-9]+)/(?P<site_id>[0-9]+)/$', views.CompareListView.as_view(), name='compare'),
    re_path(r'^(?P<checklist_id>[0-9]+)/export/$', views.export, name='export'),
    re_path(r'^discuss/(?P<checklist_id>[0-9]+)/(?P<user_id>[0-9]+)/$', views.DiscussionView.as_view(), name='discuss'),
    re_path(r'^review/(?P<eval_id>[0-9]+)/$', views.ReviewDetailView.as_view(), name='review'),
    re_path(r'^import/$', views.ImportChecklistView.as_view(), name='import-checklist'),
    re_path(r'^apply-import/(?P<checklist_id>[0-9]+)/$', views.apply_import, name='apply-import'),
    re_path(r'^ajax/clear-discussion/(?P<answerchoice_id>[0-9]+)/$', views.clear_discussion, name='clear-discussion'),
]


import json
from utils.file_io import FileIO

class IOjson(FileIO):
    def import_file(
        self, bucket: str, file_key_s3: str,
    ):
        '''
        import_json allows to import json file containing the addresses
        with any vscode service on the datalab thanks to management of
        environment variables
        returns a json
        '''
        file_system = self.get_credentials()
        file_path_s3 = bucket + "/" + file_key_s3

        with file_system.open(file_path_s3, mode="r") as file_input:
            dict_file = json.load(file_input)
        return dict_file

    def export_file(self, dict_file, bucket: str, file_key_s3: str):
        '''
        export_json allow to transform a dictionnary into a csv file
        and to export it with any vscode service on the datalab using
        management of env variables
        '''
        file_system = self.get_credentials()
        file_path_s3 = bucket + "/" + file_key_s3

        with file_system.open(file_path_s3, 'w') as file_output:
            json.dump(dict_file, file_output)


from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated

from .permissions import IsAuthorOrReadOnly
from .serializer import CommentSerializer, PostSerializer, GroupSerializer
from posts.models import Post, Group

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthorOrReadOnly, IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

class CommentViewSet(viewsets.ModelViewSet):
    serializer_class = CommentSerializer
    permission_classes = [IsAuthorOrReadOnly, IsAuthenticated]

    def get_post(self):
        return get_object_or_404(Post, pk=self.kwargs.get('post_id'))

    def perform_create(self, serializer):
        serializer.save(author=self.request.user, post=self.get_post())

    def get_queryset(self):
        return self.get_post().comments

class GroupViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Group.objects.all()
    serializer_class = GroupSerializer


import pennylane as qml
from pennylane import numpy as np
from arithmetic import compute_tensor
from utils import uniform_superposition, tensor_to_qubits
import matplotlib.pyplot as plt

QUBITS_PER_NUM = 1
PROBLEM_SIZE = 2
SOLUTION_RANK = 3

sizes = (SOLUTION_RANK, PROBLEM_SIZE, QUBITS_PER_NUM)
params_per_edge = SOLUTION_RANK * PROBLEM_SIZE * QUBITS_PER_NUM
wires_a = list(range(0, params_per_edge))
wires_b = list(range(params_per_edge, 2*params_per_edge))
wires_c = list(range(2*params_per_edge, 3*params_per_edge))
wires_counter = list(range(3*params_per_edge, 3*params_per_edge + (PROBLEM_SIZE**3) * QUBITS_PER_NUM))

# The tensor that we wish to decompose
complex_mul_tensor = np.array([[[1, 0], [0, -1]], [[0, 1], [1, 0]]])
assert complex_mul_tensor.shape == (PROBLEM_SIZE, PROBLEM_SIZE, PROBLEM_SIZE)
omega = tensor_to_qubits(complex_mul_tensor, sizes)

dev = qml.device("default.qubit", wires = wires_a + wires_b + wires_c + wires_counter)

@qml.qnode(dev)
def grover_TRD(omega, wires_a, wires_b, wires_c, wires_counter, iterations=1):

    # Bring input to uniform superposition
    uniform_superposition(wires_a + wires_b + wires_c)

    for _ in range(iterations):

        # Compute the tensor from a,b,c
        compute_tensor(wires_a, wires_b, wires_c, wires_counter, sizes)

        # Apply Grover's oracle
        qml.FlipSign(omega, wires=wires_counter)

        # Uncompute the tensor
        qml.adjoint(compute_tensor)(wires_a, wires_b, wires_c, wires_counter, sizes)

        # Apply Grover's diffusion operator
        qml.GroverOperator(wires = wires_a + wires_b + wires_c)

    return qml.probs(wires=wires_a)

result = grover_TRD(omega, wires_a, wires_b, wires_c, wires_counter, iterations=1)
plt.bar(range(2 ** len(wires_a)), result)
plt.xlabel("Basic states")
plt.ylabel("Probability")
plt.show()