import sys
sys.path.insert(0, 'learning/')
from aspect_importance import dict_movie_aspect
from dictify_ratings import tuple_dict_from_ratings
import pickle
import json
import operator
import pandas as pd
import numpy as np

def film_strength(user_id, film_id, films, ratings, all_actors, all_directors, all_genres, all_similarities, testing_users_cold_start_for_user, movies_genres, movies_directors, movies_actors):
	framework = dict()
	framework['att'] = []
	framework['supp'] = []
	framework['neut'] = []
	framework['genres'] = []
	framework['directors'] = []
	framework['actors'] = []
	framework['films'] = []

	nSimUsers = 20 # number of similar users to use

	users_actors_prefs = testing_users_cold_start_for_user["actors"][user_id]
	users_directors_prefs = testing_users_cold_start_for_user["directors"][user_id]
	users_genres_prefs = testing_users_cold_start_for_user["genres"][user_id]
	similarities_for_new_user = testing_users_cold_start_for_user["sims"]

	# change similarity to only include the 20 (?) most similar users and the current user
	simsSorted = sorted(similarities_for_new_user, key = operator.itemgetter(1), reverse = True)

	# add a similarity of 1 from this user to this user
	sims = simsSorted[:nSimUsers]
	#sims.append((user_id,1))

	film = films[film_id]

	# mu constants for this user
	MUR = 0.3
	MUG = 0.3
	MUA = 0.5
	MUD = 0.2

	# take an average of each of the the genre's average ratings
	nGenres = 0
	dGenres = 0
	if type(film['genre']) is str:
		film['genre'] = [film['genre']]
	for genre in film['genre']:

		aspect_value =  movies_genres[genre].to_dict()
		movie_ids_with_aspect_value = [k.split("_")[0] for k,v in aspect_value.items() if v == 1]

		# get the average rating for each film of that genre and take an average
		nGenre = 0
		dGenre = 0
		for genrefilm in movie_ids_with_aspect_value:
			#if (genrefilm, user_id) in ratings.keys():
			#	avg_rat = ((ratings[(genrefilm, user_id)] - 1) / 2)-1
			#else:
			avg_rat = average_rating(sims, genrefilm, ratings)

			if avg_rat:
				dGenre += avg_rat
				nGenre += 1

		if nGenre > 0:
			avGenre = dGenre / nGenre
			cmbGenre = ((((users_genres_prefs[genre]- 1) / 2)-1) + (MUR*avGenre)) / (1+MUR)

		else:
			cmbGenre = (((users_genres_prefs[genre]- 1) / 2)-1)

		framework['genres'].append((genre, cmbGenre))

		dGenres += cmbGenre
		nGenres += 1

	if nGenres > 0:
		avgGenreRating = dGenres / nGenres
	else:
		avgGenreRating = 0

	# take an average of each of the the actor's average ratings
	nActors = 0
	dActors = 0
	if type(film['actors']) is str:
		film['actors'] = [film['actors']]
	for actor in film['actors']:

		aspect_value =  movies_actors[actor].to_dict()
		movie_ids_with_aspect_value = [k.split("_")[0] for k,v in aspect_value.items() if v == 1]

		# get the average rating for each film with that actor and take an average
		nActor = 0
		dActor = 0
		for actorfilm in movie_ids_with_aspect_value:

			#if (actorfilm, user_id) in ratings.keys():
			#	avg_rat = ((ratings[(actorfilm, user_id)] - 1) / 2)-1
			#else:
			avg_rat = average_rating(sims, actorfilm, ratings)

			if avg_rat:
				dActor += avg_rat
				nActor += 1

		if nActor > 0:
			# dActors += (((users_actors_prefs[actor]- 1) / 2)-1) * dActor / nActor
			avActor = dActor / nActor
			cmbActor = ((((users_actors_prefs[actor]- 1) / 2)-1) + (MUR*avActor)) / (1+MUR)
		else:
			cmbActor = (((users_actors_prefs[actor]- 1) / 2)-1)

		framework['actors'].append((actor, cmbActor))

		dActors += cmbActor
		nActors += 1

	if nActors > 0:
		avgActorRating = dActors / nActors
	else:
		avgActorRating = 0

	# take an average of each of the the director's average ratings
	nDirectors = 0
	dDirectors = 0
	if type(film['director']) is str:
		film['director'] = [film['director']]
	for director in film['director']:

		aspect_value =  movies_directors[director].to_dict()
		movie_ids_with_aspect_value = [k.split("_")[0] for k,v in aspect_value.items() if v == 1]

		# get the average rating for each film with that actor and take an average
		nDirector = 0
		dDirector = 0
		for directorfilm in movie_ids_with_aspect_value:

			#if (directorfilm, user_id) in ratings.keys():
			#	avg_rat = ((ratings[(directorfilm, user_id)] - 1) / 2)-1
			#else:
			avg_rat = average_rating(sims, directorfilm, ratings)

			if avg_rat:
				dDirector += avg_rat
				nDirector += 1

		if nDirector > 0:
			# dDirectors += (((users_directors_prefs[director]- 1) / 2)-1) * dDirector / nDirector
			#dDirectors += dDirector / nDirector
			avDirector = dDirector / nDirector
			cmbDirector = ((((users_directors_prefs[director]- 1) / 2)-1) + (MUR*avDirector)) / (1+MUR)
		else:
			cmbDirector = (((users_directors_prefs[director]- 1) / 2)-1)

		framework['directors'].append((director, cmbDirector))

		dDirectors += cmbDirector
		nDirectors += 1

	if nDirectors > 0:
		avgDirectorRating = dDirectors / nDirectors
	else:
		avgDirectorRating = 0

	# calculates the item strength
	avg_rat = average_rating(sims, film_id, ratings)

	if avg_rat is None:
		item_strength = ((MUG * avgGenreRating) + (MUA * avgActorRating)+ (MUD * avgDirectorRating)) / (MUG + MUA + MUD)
	else:
		item_strength = ((MUR * avg_rat) + (MUG * avgGenreRating) + (MUA * avgActorRating)+ (MUD * avgDirectorRating)) / (MUR + MUG + MUA + MUD)

	film_strength = (((item_strength + 1)*2)+1)

	framework['films'].append((film_id, film_strength))

	for (genre, strength) in framework['genres']:
		if strength < 0:
			framework['att'].append((genre, film_id))
		elif strength > 0:
			framework['supp'].append((genre, film_id))
		else:
			framework['neut'].append((genre, film_id))

	for (director, strength) in framework['directors']:
		if strength < 0:
			framework['att'].append((director, film_id))
		elif strength > 0:
			framework['supp'].append((director, film_id))
		else:
			framework['neut'].append((director, film_id))

	for (actor, strength) in framework['actors']:
		if strength < 0:
			framework['att'].append((actor, film_id))
		elif strength > 0:
			framework['supp'].append((actor, film_id))
		else:
			framework['neut'].append((actor, film_id))

	framework_file = "%s_%s.json" % (user_id, film_id)
	with open(framework_file, 'w') as f:
		json.dump(framework, f, indent = 4, ensure_ascii = False)

	return film_strength

def average_rating(sims, film_id, ratings):
	# counts and totals for each type of aspect
	nRatings = 0
	dRatings = 0

	# cycles through each of the similar users
	for sim in sims:

		user_id = sim[0]
		similarity = sim[1]

		# if a rating exists by this user on the film
		if (film_id, user_id) in ratings.keys():
			user_rating = ratings[(film_id, user_id)]

			scaled_rating = ((user_rating - 1) / 2)-1
			# print(user_rating)
			# print(scaled_rating)
			dRatings += scaled_rating * similarity
			nRatings += 1

	if nRatings == 0:
		avg_rat = None
	else:
		avg_rat = dRatings / nRatings

	return avg_rat

if __name__ == "__main__":

	ids = ['tt0289992','tt0338013','tt0308644','tt0162222','tt0362227','tt0203009','tt0373926','tt0264464','tt0315733','tt0327056']
	paper_ids = ['tt0264464', 'tt0203009']
	sample_users = ['1824033', '1409354', '2435946', '553658', '608915', '1753259', '2615678', '1443524', '771174']

	paper_films = pickle.load(open("db/paper_films.pkl", "rb"))
	paper_ratings = pickle.load(open("db/paper_ratings.pkl", "rb"))
	preferences = pickle.load(open("arg/preference_genre_False_normalized_10.pkl","rb"))

	films = dict()
	ratings = dict()

	for i in ids:
		films[i] = paper_films[i]
		ratings[i] = paper_ratings[i]

	movies_watched = viewed_matrix(ratings, films, sample_users)
	print (pd.DataFrame.from_dict(movies_watched, orient='index').to_string())

	df = pd.DataFrame.from_dict(movies_watched, orient='index')
	df = df.replace(np.nan, 0)
	print (df.to_string())

	movies_genres = dict_movie_aspect(films, "genre")
	movies_genres = pd.DataFrame.from_dict(movies_genres, dtype='int64', orient='index')
	movies_genres = movies_genres.replace(np.nan, 0)

	movies_directors = dict_movie_aspect(films, "director")
	movies_directors = pd.DataFrame.from_dict(movies_directors, dtype='int64', orient='index')
	movies_directors = movies_directors.replace(np.nan, 0)

	movies_actors = dict_movie_aspect(films, "actors")
	movies_actors = pd.DataFrame.from_dict(movies_actors, dtype='int64', orient='index')
	movies_actors = movies_actors.replace(np.nan, 0)

	all_actors = pickle.load(open("arg/preference_actors_False_normalized_10.pkl", "rb"))
	all_directors = pickle.load(open("arg/preference_director_False_normalized_10.pkl", "rb"))
	all_genres = pickle.load(open("arg/preference_genre_False_normalized_10.pkl", "rb"))
	all_similarities = pickle.load(open("arg/similarity_False_normalized_10.pkl", "rb"))

	ratings = tuple_dict_from_ratings(ratings)


import json

from app.main import bp
from app.models import Hieroglyph

from flask import render_template, request, current_app, url_for
from flask_login import login_required

def create_model_generator(model):
    for i, h in enumerate(model):
        model[i].onyomi = ', '.join(json.loads(h.onyomi))
        model[i].kunyomi = ', '.join(json.loads(h.kunyomi))
        model[i].translation = ', '.join(json.loads(h.translation))
    model_gen = ((model[n: n + 4], model[n:])[n + 4 > len(model)] for n in range(0, len(model), 4))
    return model_gen

@bp.route('/')
@bp.route('/index')
@login_required
def index():
    page = request.args.get('page', 1, type=int)
    model = Hieroglyph.query.filter_by(level=1).paginate(page, current_app.config['HIEROGLYPHS_PER_PAGE'])
    next_url = (None, url_for('main.index', page=model.next_num))[model.has_next]
    prev_url = (None, url_for('main.index', page=model.prev_num))[model.has_prev]
    return render_template('main/index.html', model=create_model_generator(model.items),
                           next_page=next_url, prev_page=prev_url)


import torch
import numpy as np

from torch import nn
from torch.optim import Adam, SGD, RMSprop
from torch.nn.utils.clip_grad import clip_grad_norm_

from .latent_temp_crf_rl import LatentTemplateCRFRL
from .ftmodel import FTModel

import torch
import traceback
from torch import autograd

class LatentTemplateCRFRLModel(FTModel):

  def __init__(self, config):
    super(LatentTemplateCRFRLModel, self).__init__()
    self.model = LatentTemplateCRFRL(config)
    self.optimizer = Adam(self.model.parameters(), lr=config.learning_rate)

    self.z_tau_init = config.z_tau_init
    self.x_lambd_start_epoch = config.x_lambd_start_epoch
    self.x_lambd_increase_interval = config.x_lambd_increase_interval
    self.max_grad_norm = config.max_grad_norm
    self.num_sample_nll = config.num_sample_nll
    self.num_sample_rl = config.num_sample_rl
    self.post_process_start_epoch = config.post_process_start_epoch
    self.dataset = config.dataset
    self.device = config.device
    self.temp_rank_strategy = config.temp_rank_strategy

    self.task = config.task
    return

  def train_step(self, batch, n_iter, ei, bi, schedule_params, debug=False):
    model = self.model

    # tau annealing
    tau = self.z_tau_init - n_iter * schedule_params['tau_decrease_interval']

    # x_lambd annealing
    if(ei < self.x_lambd_start_epoch):
      x_lambd = 0.
    else:
      x_lambd = ((ei - self.x_lambd_start_epoch) *\
        schedule_params['train_num_batches'] + bi)
      x_lambd *= self.x_lambd_increase_interval
      if(x_lambd >= 1.): x_lambd = 1.

    post_process = ei >= self.post_process_start_epoch
    if(self.dataset == 'e2e'):
      sentences = torch.from_numpy(batch['sent_dlex']).to(self.device)
    elif(self.dataset == 'mscoco'):
      sentences = torch.from_numpy(batch['sentences']).to(self.device)
    else:
      raise NotImplementedError('dataset %s not implemented' % self.dataset)

    # DEBUG
    # with GuruMeditation():
    model.zero_grad()
    loss, out_dict = model(
      keys=torch.from_numpy(batch['keys']).to(self.device),
      vals=torch.from_numpy(batch['vals']).to(self.device),
      sentences=sentences,
      sent_lens=torch.from_numpy(batch['sent_lens']).to(self.device),
      tau=tau,
      x_lambd=x_lambd,
      num_sample=self.num_sample_rl,
      post_process=post_process,
      debug=debug,
      return_grad=False
      )
    loss.backward()
    clip_grad_norm_(model.parameters(), self.max_grad_norm)
    self.optimizer.step()

    out_dict['tau'] = tau
    out_dict['x_lambd'] = x_lambd
    return out_dict

  def inspect_grad(self, batch, n_iter, ei, bi, schedule_params):
    model = self.model

    # tau annealing
    tau = self.z_tau_init - n_iter * schedule_params['tau_decrease_interval']

    # x_lambd annealing
    if(ei < self.x_lambd_start_epoch):
      x_lambd = 0.
    else:
      x_lambd = ((ei - self.x_lambd_start_epoch) *\
        schedule_params['train_num_batches'] + bi)
      x_lambd *= self.x_lambd_increase_interval
      if(x_lambd >= 1.): x_lambd = 1.

    post_process = ei >= self.post_process_start_epoch
    if(self.dataset == 'e2e'):
      sentences = torch.from_numpy(batch['sent_dlex']).to(self.device)
    elif(self.dataset == 'mscoco'):
      sentences = torch.from_numpy(batch['sentences']).to(self.device)
    else:
      raise NotImplementedError('dataset %s not implemented' % self.dataset)

    debug = False

    model.zero_grad()
    loss, out_dict = model(
      keys=torch.from_numpy(batch['keys']).to(self.device),
      vals=torch.from_numpy(batch['vals']).to(self.device),
      sentences=sentences,
      sent_lens=torch.from_numpy(batch['sent_lens']).to(self.device),
      tau=tau,
      x_lambd=x_lambd,
      num_sample=self.num_sample_rl,
      post_process=post_process,
      debug=debug,
      return_grad=True
      )

    retain_keys = [
      'g_seq_mean', 'g_seq_std', 'g_seq_r',
      'g_step_m_mean', 'g_step_m_std', 'g_step_m_r',
      'g_step_bt_mean', 'g_step_bt_std', 'g_step_bt_r',
      'g_step_ut_mean', 'g_step_ut_std', 'g_step_ut_r',
      'log_p_score',
      'reward_seq', 'learning_signal_seq',
      'reward_step_m', 'learning_signal_step_m',
      'reward_step_bt', 'learning_signal_step_bt',
      'reward_step_ut', 'learning_signal_step_ut',
      ]
    out_dict_ = {}
    for k in retain_keys:
      out_dict_[k] = out_dict[k]
    out_dict = out_dict_

    print('score func grad, seq level:   mean: %.4g, std: %.4g, r: %.4g' %
      (out_dict['g_seq_mean'], out_dict['g_seq_std'], out_dict['g_seq_r']))
    print('g_step_m:                     mean: %.4g, std: %.4g, r: %.4g' %
      (out_dict['g_step_m_mean'], out_dict['g_step_m_std'],
      out_dict['g_step_m_r']))
    print('g_step_bt:                    mean: %.4g, std: %.4g, r: %.4g' %
      (out_dict['g_step_bt_mean'], out_dict['g_step_bt_std'],
      out_dict['g_step_bt_r']))
    print('g_step_ut:                    mean: %.4g, std: %.4g, r: %.4g' %
      (out_dict['g_step_ut_mean'], out_dict['g_step_ut_std'],
      out_dict['g_step_ut_r']))

    print('log reconstruction: %.4g' % out_dict['log_p_score'])
    print('score func seq,             reward: %.4g, learning_sig:%.4g'%
      (out_dict['reward_seq'], out_dict['learning_signal_seq']))
    print('score func step marginal,   reward: %.4g, learning_sig:%.4g'%
      (out_dict['reward_step_m'], out_dict['learning_signal_step_m']))
    print('score fstep biased trans,   reward: %.4g, learning_sig:%.4g'%
      (out_dict['reward_step_bt'], out_dict['learning_signal_step_bt']))
    print('score fstep unbiased trans, reward: %.4g, learning_sig:%.4g'%
      (out_dict['reward_step_ut'], out_dict['learning_signal_step_ut']))
    return out_dict

  def valid_step(self, template_manager, batch, n_iter, ei, bi,
    mode='dev', dataset=None, schedule_params=None):
    model = self.model

    # tau annealing
    tau = self.z_tau_init - n_iter * schedule_params['tau_decrease_interval']

    # x_lambd annealing
    if(ei < self.x_lambd_start_epoch):
      x_lambd = 0.
    else:
      x_lambd = ((ei - self.x_lambd_start_epoch) *\
        schedule_params['train_num_batches'] + bi)
      x_lambd *= self.x_lambd_increase_interval
      if(x_lambd >= 1.): x_lambd = 1.

    if(self.dataset == 'e2e'):
      batch_c, batch = batch
    else: batch_c = batch

    post_process = ei >= self.post_process_start_epoch
    if(self.dataset == 'e2e'):
      sentences = torch.from_numpy(batch_c['sent_dlex']).to(self.device)
    elif(self.dataset == 'mscoco'):
      sentences = torch.from_numpy(batch_c['sentences']).to(self.device)
    else:
      raise NotImplementedError('dataset %s not implemented' % self.dataset)

    with torch.no_grad():
      out_dict = {}

      # likelihood evaluation
      if(self.task == 'density'):
        out_dict_ = model.infer_marginal(
          keys=torch.from_numpy(batch_c['keys']).to(self.device),
          vals=torch.from_numpy(batch_c['vals']).to(self.device),
          sentences=sentences,
          sent_lens=torch.from_numpy(batch_c['sent_lens']).to(self.device),
          x_lambd=x_lambd,
          num_sample=self.num_sample_nll)
      elif(self.task == 'generation'):
        # TBC
        pass
      out_dict.update(out_dict_)

    return out_dict


# -*-coding=utf-8-*-

# @Time : 2019/6/20 17:54
# @File : semaphore_demo.py
import threading,time,datetime,random
# class MyThread(threading.Thread):

# 	def run(self):
# 		if semaphore.acquire():
# 			print(datetime.datetime.now().strftime('%H:%M:%S'),self.name)
# 			time.sleep(2)
# 			semaphore.release()

# if __name__=='__main__':
# 	semaphore = threading.Semaphore(5)
# 	threads=[]

# 	for i in range(100):
# 		threads.append(MyThread())

# 	for t in threads:
# 		t.start()

class MyThread(threading.Thread):

	def run(self):
		# if semaphore.acquire():
		# threading.Thread.
		time.sleep(random.random())
		print(datetime.datetime.now().strftime('%H:%M:%S'),self.name)
			# semaphore.release()

if __name__=='__main__':
	threads=[]

	for i in range(100):
		threads.append(MyThread())

	for t in threads:
		t.start()

	for t in threads:
		t.join()

	print('Done')


"""Initial migration.

Revision ID: b3ec8f39b084
Revises:
Create Date: 2021-01-14 00:32:09.399304

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'b3ec8f39b084'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('category',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('name', sa.String(), nullable=False),
                    sa.PrimaryKeyConstraint('id'),
                    sa.UniqueConstraint('name')
                    )
    op.create_table('user',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('name', sa.String(length=80), nullable=False),
                    sa.Column('description', sa.String(), nullable=True),
                    sa.Column('email', sa.String(length=120), nullable=False),
                    sa.Column('create_at', sa.String(), nullable=True),
                    sa.Column('password', sa.String(
                        length=1024), nullable=False),
                    sa.Column('user_type', sa.String(
                        length=50), nullable=True),
                    sa.PrimaryKeyConstraint('id'),
                    sa.UniqueConstraint('email')
                    )
    op.create_table('news',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('title', sa.String(length=1024), nullable=False),
                    sa.Column('subtitle', sa.Text(), nullable=True),
                    sa.Column('content', sa.Text(), nullable=False),
                    sa.Column('upvotes', sa.Integer(), nullable=True),
                    sa.Column('downvotes', sa.Integer(), nullable=True),
                    sa.Column('create_at', sa.String(), nullable=True),
                    sa.Column('approved', sa.Boolean(), nullable=True),
                    sa.Column('author', sa.Integer(), nullable=True),
                    sa.ForeignKeyConstraint(['author'], ['user.id'], ),
                    sa.PrimaryKeyConstraint('id'),
                    sa.UniqueConstraint('content'),
                    sa.UniqueConstraint('title')
                    )
    op.create_table('news_category',
                    sa.Column('news_id', sa.Integer(), nullable=True),
                    sa.Column('category_id', sa.Integer(), nullable=True),
                    sa.ForeignKeyConstraint(
                        ['category_id'], ['category.id'], ),
                    sa.ForeignKeyConstraint(['news_id'], ['news.id'], )
                    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('news_category')
    op.drop_table('news')
    op.drop_table('user')
    op.drop_table('category')
    # ### end Alembic commands ###


import pickle
import os, platform, sys
import numpy as np
import csv
import string
import random
import re

def wd():
    if platform.platform().find('Linux') >= 0:
        path = '/media/bruno/data/img2txt_project/im2txt_repo/im2txt/regex_learning'
    else:
        path = 'C:/Users/bruno/PycharmProjects/img2txt_project/im2txt_repo/im2txt/regex_learning'

    sys.path.append(path)
    os.chdir(path)
    return path

home_dir = wd()

import random_regex

alphabet = [str(i) for i in range(10)] + [string.ascii_lowercase[i] for i in range(len(string.ascii_lowercase))]

def char2locvec(ch):
    return list(map(lambda i: int(alphabet[i]==ch),range(len(alphabet))))

def string2locvec(s):
    return [char2locvec(s[i]) for i in range(len(s))]

def generate_sample(reg):
    rex = random_regex.gen(reg,size=10000)
    rex = [(i, 1) for i in rex]
    n = len(rex)

    ## generation of 0 group
    freq = np.bincount([len(i) for i in rex])
    sad = np.cumsum(freq) / len(rex)

    ## just 10% from original is random
    reg1 = "^" + reg + "$"
    for i in range(n):
        pattern = rex[i][0]
        n1 = len(pattern)
        m = np.round(n1*0.1)
        ind = np.random.choice(n1, m).astype(np.int32)

        # checking if random pattern isn't actually from class 1
        pattern1 = [ np.random.choice(alphabet,1)[0] if u in ind else pattern[u] for u in range(len(pattern))]
        pat1 = "".join(list(pattern1))
        rex.append((pattern1, 0 if re.match(reg1,pat1)==None else 1 ))

    ## totally random
    for i in range(n*2):
        eps = random.uniform(0, 1)
        for length in range(len(sad)):
            if eps < sad[length]: break
        seq = ''.join(np.random.choice(alphabet, length, replace=True))
        rex.append((seq, 0))

    with open('random_regex.csv', 'w') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerow(rex)

    ## converting to local vector representation
    rexloc = [(np.array(string2locvec(s[0])).astype(np.float32), s[1]) for s in rex]

    ## ordinring in baches by size
    inds = [len(s[0]) for s in rexloc]
    inds = inds - np.min(inds)

    rexloc_batches = []
    s = []
    for i0 in np.unique(inds):
        x = np.array([rexloc[i][0] for i in range(len(inds)) if inds[i] == i0])
        y = [rexloc[i][1] for i in range(len(inds)) if inds[i] == i0]
        rexloc_batches.append((x, y))
    return rexloc_batches

### easy data
# rexloc_batches_train = generate_sample("[0-9]{4,8}[a-z]{4,8}[0-9]{4,8}")
# rexloc_batches_test = generate_sample("[0-9]{4,8}[a-z]{4,8}[0-9]{4,8}")
# pickle.dump(rexloc_batches_train, open("rexloc_batches_easy.pickle", "wb"))
# pickle.dump(rexloc_batches_test, open("rexloc_batches_easy_test.pickle", "wb"))

### hard data
reg = "[0-9]{15,20}[a-z]{15,20}" +\
      "[0-9]{15,20}[a-z]{15,20}" +\
      "[0-9]{15,20}[a-z]{15,20}"

reg_for_print = reg\
    .replace('[','\left[')\
    .replace(']','\right]')\
    .replace('{','\{')\
    .replace('}','\}')
print(reg_for_print)

rexloc_batches_train = generate_sample(reg)
rexloc_batches_test = generate_sample(reg)
pickle.dump(rexloc_batches_train, open("rexloc_batches_easy.pickle", "wb"))
pickle.dump(rexloc_batches_test, open("rexloc_batches_easy_test.pickle", "wb"))


import os
import pickle as pk

import matplotlib as mpl

mpl.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import torch
from scipy.misc import imresize
from torchvision import transforms, datasets

log_dir = 'logs'

def trainloader(batch_size):
    dset = trainloader_helper()
    train_loader = torch.utils.data.DataLoader(dset, batch_size=batch_size, shuffle=True, num_workers=6)
    return train_loader

def trainloader_helper():
    data_dir = '/data/milatmp1/considib/img_align_celebA/celebA/'
    resized_dir = '/data/milatmp1/considib/resized_celebA/'
    if not os.path.isdir(resized_dir):
        _preprocess_celeb(data_dir, resized_dir)

    transform = transforms.Compose([
        # transforms.Resize(64),
        transforms.ToTensor(),
        transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
    ])

    data_dir = '/data/milatmp1/considib/resized_celebA'
    dset = datasets.ImageFolder(data_dir, transform)
    print("Loaded {} images for training".format(len(dset)))
    return dset

def _preprocess_celeb(root, save_root):
    resize_size = 64

    if not os.path.isdir(save_root):
        os.mkdir(save_root)
    if not os.path.isdir(save_root + 'celebA'):
        os.mkdir(save_root + 'celebA')
    img_list = os.listdir(root)

    # ten_percent = len(img_list) // 10
    print(len(img_list))

    for i in range(len(img_list)):
        img = plt.imread(root + img_list[i])
        img = imresize(img, (resize_size, resize_size))
        plt.imsave(fname=save_root + 'celebA/' + img_list[i], arr=img)

        if (i % 1000) == 0:
            print('%d images complete' % i)

def save(discriminator, generator, epoch=0):
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    gen_model_name = "{0}_{1}_G.pkl".format(generator.model_name, epoch)
    disc_model_name = "{0}_{1}_D.pkl".format(discriminator.model_name, epoch)
    torch.save(generator.state_dict(), os.path.join(log_dir, gen_model_name))
    torch.save(discriminator.state_dict(), os.path.join(log_dir, disc_model_name))

def save_losses(minibatch_disc_losses, minibatch_gen_losses, model_name):
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    fname1 = model_name + '_minibatch_disc_losses.pk'
    fname2 = model_name + '_minibatch_gen_losses.pk'

    with open(os.path.join(log_dir, fname1), "wb") as f:
        pk.dump(minibatch_disc_losses, f)
    with open(os.path.join(log_dir, fname2), "wb") as f:
        pk.dump(minibatch_gen_losses, f)

def plot_result(G, fixed_noise, num_epoch, fig_size=(8, 8)):
    G.eval()
    fixed_noise = fixed_noise.cuda()
    generate_images = G(fixed_noise)
    G.train()

    n_rows = n_cols = 8
    fig, axes = plt.subplots(n_rows, n_cols, figsize=fig_size)

    for ax, img in zip(axes.flatten(), generate_images):
        ax.axis('off')
        ax.set_adjustable('box-forced')
        img = (((img - img.min()) * 255) / (img.max() - img.min())).cpu().data.numpy().transpose(1, 2, 0).astype(
            np.uint8)
        ax.imshow(img, cmap=None, aspect='equal')
    plt.subplots_adjust(wspace=0, hspace=0)
    title = 'Epoch {0}'.format(num_epoch)
    fig.text(0.5, 0.04, title, ha='center')

    filename = "{0}_epoch_{1}.png".format(G.model_name, num_epoch)
    if not os.path.exists(log_dir):
        os.mkdir(log_dir)
    plt.savefig(os.path.join(log_dir, filename))
    plt.close()


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

def harris(image):
    dst1 = cv2.GaussianBlur(image, (5, 5), 0)
    gray = cv2.cvtColor(dst1, cv2.COLOR_BGR2GRAY)

    cv2.imshow("gray", gray)
    ret, binary = cv2.threshold(gray, 0,255,  cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
    cv2.imshow("binary", binary)

    kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (23, 23))
    erode = cv2.erode(binary, kernel=kernel1)
    cv2.imshow("erode", erode)

    kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    dilate = cv2.dilate(erode, kernel=kernel2)
    cv2.imshow("dilate", dilate)

    corners = cv2.goodFeaturesToTrack(dilate,4,0.1,135)
    corners = np.int0(corners)
    print(corners)
    for i in corners:
        x,y = i.ravel()
        cv2.circle(image,(x,y),3,255,-1)
    cv2.imshow("image", image)

    '''dilate1 = np.float32(dilate)
    img = cv2.cornerHarris(dilate1, 2, 23, 0.04)

    image[dst > 0.01 * dst.max()] = [0, 0 , 255]
    while True:
        cv2.imshow('Corner', image)
        if cv2.waitKey() & 0xff == ord('q'):
            break  '''

    '''dilate = np.float32(dilate)    #将gray转化为float32的输入图像 blocksize=2，ksize=3
    dst = cv2.cornerHarris(dilate,2,3,0.04)

     #result is dilated for marking the corners, not important
    dst = cv2.dilate(dst,None)

    # Threshold for an optimal value, it may vary depending on the image
    #将img图像中检测到的角点涂上红色
    image[dst>0.01*dst.max()]=[0,0,255]

    cv2.imshow('cornerHarris',image) '''

    pts1 = np.float32(corners)
    pts2 = np.float32([[0,330 ], [0, 0], [550, 330], [550, 0]])
    M = cv2.getPerspectiveTransform(pts1, pts2)

    # 进行透视变换

    img = cv2.warpPerspective(image, M, (550, 330))
    cv2.imshow("img", img)
    return img

capture = cv2.VideoCapture(0)
while(True):
    ret, frame = capture.read()
    frame = cv2.flip(frame, 1)
    img1 = harris(frame)
    img2 = harris(frame)
    img3 = harris(frame)
    img4 = harris(frame)
    cv2.imshow("img1",img1)
    cv2.imshow("img1",img1)
    cv2.imshow("img1",img1)
    cv2.imshow("img1",img1)

    harris(frame)
    if cv2.waitKey(10)==27:
        break

capture.release()
#cv2.destroyAllWindows()


from django.shortcuts import render, get_object_or_404, redirect, Http404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Post
from .forms import PostForm
from django.contrib import messages

def post_home(request):
    query_list = Post.objects.order_by('-timestamp')

    query = request.GET.get('q')
    if query:
        query_list = query_list.filter(title__icontains=query)

    paginator = Paginator(query_list, 5)

    page = request.GET.get('page')

    try:
        query_set = paginator.page(page)
    except PageNotAnInteger:
        query_set = paginator.page(1)
    except EmptyPage:
        query_set = paginator.page(paginator.num_pages)
    context = {'list': query_set}
    return render(request, 'posts/post_home.html', context)

def post_create(request):
    if not request.user.is_staff and not request.user.is_superuser:
        raise Http404("you are not a staff or superuser")
    form = PostForm()
    context = {'form': form}
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES or None)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.user = request.user
            instance.save()
            messages.success(request, 'successfully created')
            return redirect('posts:detail', instance.slug)

        else:
            messages.error(request, ' not successfully created')
            context = {'error_message': 'invalid form input'}
            return render(request, 'posts/post_create.html', context)
    else:
        return render(request, 'posts/post_create.html', context)

def post_detail(request, post_title_slug):
    instance = get_object_or_404(Post, slug=post_title_slug)
    context = {'instance': instance}
    return render(request, 'posts/post_detail.html', context)

def post_update(request, post_title_slug):
    if not request.user.is_staff and not request.user.is_superuser:
        raise Http404("You are not a staff or superuser")
    instance = get_object_or_404(Post, slug=post_title_slug)
    author = False

    if request.method == 'POST':

        form = PostForm(request.POST or None, request.FILES, instance=instance)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.save()
            messages.success(request, 'successfully updated')
            return redirect('posts:detail', instance.slug)
        context = {'instance': instance,
                   'form': form}

        return render(request, 'posts/post_update.html', context)
    else:
        form = PostForm(instance=instance)
        context={'form': form}
        return render(request, 'posts/post_update.html', context)

def post_delete(request, post_title_slug):
    if not request.user.is_staff and not request.user.is_superuser:
        raise Http404("you are not a staff or superuser")
    instance = get_object_or_404(Post, slug=post_title_slug)
    instance.delete()
    messages.success(request, 'deleted')
    return redirect('posts:home')


###Реализация парсинга из excel###
from openpyxl import load_workbook

wb = load_workbook('C:\XXXX\ИТМО\НИР\Задача№3_Мат_описание\lineranalysis\InputData.xlsx', data_only=True)  # Грузим эксель, первый аргумент - название файла эксель
#Целевая функция
data_for_calculating = []  # Создаем массив для данных
if 'ObjFunction' in wb.sheetnames:  # Проверяем есть ли данный лист в экселе
    ws = wb['ObjFunction']  # Присваиваем переменной ws нужный лист
    for cell in ws[2]:  # Пробегаемся по каждой ячейке во второй строке
        if cell.value == 0:
            break
        # Грузим в массив данные по каждой ячейке
        data_for_calculating.append(cell.value)
else:
    print('List Numbers does not exists')

#Правая сторона ограничений ежемесячного объема производства (тонн)
data_for_calculating1 = []  # Создаем массив для данных
if 'Restrictions' in wb.sheetnames:  # Проверяем есть ли данный лист в экселе
    ws = wb['Restrictions']  # Присваиваем переменной ws нужный лист
    for cell in ws[2]:  # Пробегаемся по каждой ячейке во второй строке
        if cell.value == 0:
            break
        # Грузим в массив данные по каждой ячейке
        data_for_calculating1.append(cell.value)
else:
    print('List Numbers does not exists')

#Границы каждой переменной
data_for_calculating2 = []  # Создаем массив для данных
if 'Boudaries' in wb.sheetnames:  # Проверяем есть ли данный лист в экселе
    ws = wb['Boudaries']  # Присваиваем переменной ws нужный лист
    for cell in ws[2]:  # Пробегаемся по каждой ячейке во второй строке
        if cell.value == 0:
            break
        # Грузим в массив данные по каждой ячейке
        data_for_calculating2.append(cell.value)
else:
    print('List Numbers does not exists')

###Реализация симплекс-метода###
from scipy.optimize import linprog
#linprog решает только задачи минимизации

obj = data_for_calculating[0:7]

#Левая сторона ограничений
lhs_ineq = [[ -1, 0, 0, 0, 0, 0, 0],  #-x1: ежемесячный объем производства (тонн)
            [0, -1, 0, 0, 0, 0, 0],  #-x2: ежемесячный объем производства (тонн)
            [ 0, 0, -1, 0, 0, 0, 0],  #-x3: ежемесячный объем производства (тонн)
            [ 0, 0, 0, -1, 0, 0, 0],  #-x4: ежемесячный объем производства (тонн)
            [0, 0, 0, 0, -1, 0, 0],  #-x5: ежемесячный объем производства (тонн)
            [ 0, 0, 0, 0, 0, -1, 0],  #-x6: ежемесячный объем производства (тонн)
            [ 0, 0, 0, 0, 0, 0, -1], #-x7: ежемесячный объем производства (тонн)
            [ 1, 1, 1, 1, 1, 1, 1] #x1+x2+x3+x4+x5+x6+x7
            ]

#Правая сторона ограничений ежемесячного объема производства (тонн)
rhs_ineq = data_for_calculating1[0:8]

#Определение границ каждой переменной
bnd = [(-8000000, 80000), #x1
       (-8000000, 72000), #x2
       (-8000000, 78000), #x3
       (-8000000, 73000), #x4
       (-8000000, 79000), #x5
       (-8000000,67000), #x6
       (-8000000, 40000) #x7
       ]

#obj содержит коэффициенты целевой функции
#lhs_ineq и rhs_ineq содержат коэффициенты из ограничений-неравенств для x.

opt = linprog(c=obj, A_ub=lhs_ineq, b_ub=rhs_ineq, bounds=bnd, method="simplex")
print(opt)


from flask import Flask

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Restaurant, Base, MenuItem

engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()

app = Flask(__name__)

@app.route('/')
@app.route('/restaurants/<int:restaurant_id>/')
def restaurantMenu(restaurant_id):
	restaurant = session.query(Restaurant).first()
	items = session.query(MenuItem).filter_by(restaurant_id = restaurant.id).all()
	s = ""
	for item in items:
		s += "%s </br> %s </br> %s </br> </br>" % (item.name, item.price, item.description)
	return s

if __name__ == '__main__':
	app.debug = True
	app.run(host = '0.0.0.0', port = 5000)


from past import autotranslate
autotranslate('pydepta')

from glob import glob
from pydepta import Depta

REPEATS = 5

depta = Depta()
for fname in glob('pydepta/tests/resources/*.html'):
    with open(fname, 'rt') as fhandle:
        html = fhandle.read()
        for _ in range(REPEATS):
            depta.extract(html)


import wikiquote
from random import choice
import discord
from Core.Fonctions.AuteurIcon import auteur

async def embedWikiQuote(args):
    lang="fr"
    search=wikiquote.search(args,lang="fr")
    if search==[]:
        lang="en"
        search=wikiquote.search(args)
    assert search!=[], "Cette page n'existe pas."
    quote=choice(wikiquote.quotes(search[0],lang=lang))
    embedW=discord.Embed(title=search[0],description=quote,color=0xfcfcfc)
    embedW.set_footer(text="OT!wikiquote")
    link=""
    for i in search[0].split(" "):
        link+=i+"_"
    embedW=auteur("https://"+lang+".wikiquote.org/wiki/"+link[0:len(link)-1],0,0,embedW,"wp")
    return embedW

async def embedWikiQOTD():
    search=wikiquote.qotd(lang="fr")
    embedW=discord.Embed(title=search[1],description=search[0],color=0xfcfcfc)
    embedW.set_footer(text="OT!wikiquote")
    link=""
    for i in search[1].split(" "):
        link+=i+"_"
    embedW=auteur("https://fr.wikiquote.org/wiki/"+link[0:len(link)-1],0,0,embedW,"wp")
    return embedW


import tensorflow as tf

def weight_variable(shape):
  return tf.get_variable('weight', shape,
                         initializer=tf.truncated_normal_initializer(stddev=0.1))

def bias_variable(shape):
  return tf.get_variable('bias', shape, initializer=tf.constant_initializer(0.01))

def conv_2d(input, w_shape, b_shape, strides, name, padding='SAME', act_func=tf.nn.relu):
  with tf.variable_scope(name):
    w = weight_variable(w_shape)
    b = bias_variable(b_shape)
    conv = tf.nn.conv2d(input, w, strides=strides, padding=padding)
    conv = tf.nn.bias_add(conv, b)

    if act_func != None:
      conv = act_func(conv)

    return conv

def max_pool_2d(x, ksize, strides, name, padding='SAME'):
  with tf.variable_scope(name):
    return tf.nn.max_pool(x, ksize=ksize,
                          strides=strides, padding=padding)

def fully_connected(name, input, w_shape, b_shape, regularizer, need_dropout=False, keep_prob=1.0,
                    act_function=tf.nn.relu):
  with tf.variable_scope(name):
    w = weight_variable(w_shape)
    b = bias_variable(b_shape)
    if regularizer != None:
      tf.add_to_collection('losses', regularizer(w))

    fc = tf.matmul(input, w)
    fc += b

    if act_function != None:
      fc = act_function(fc)

    if need_dropout:
      fc = tf.nn.dropout(fc, keep_prob)
    return fc


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

from __future__ import division, print_function, absolute_import
from matplotlib import pyplot as plt
import os
from timeit import time
import warnings
import sys
import cv2
import numpy as np
from PIL import Image
from yolo import YOLO
import pandas as pd
from deep_sort import preprocessing
from deep_sort import nn_matching
from deep_sort.detection import Detection
from deep_sort.tracker import Tracker
from tools import generate_detections as gdet
from deep_sort.detection import Detection as ddet

warnings.filterwarnings('ignore')
def findbbx(frame, frame_idx, df):
    '''

    :param frame: number of frame
    :param df: dataframe which saves the det
    :return: a list of bbox[x,y,w,h]
    '''
    bbx = []
    while True:
        if frame_idx >= df.shape[0]:
            break
        if df['frame'][frame_idx] != frame:
            break
        t, l, w, h = df['t'][frame_idx] , df['l'][frame_idx] , df['w'][frame_idx] , df['h'][frame_idx]
        bbx.append([t, l, w, h])

        frame_idx += 1
    #print(bbx)
    return bbx, frame_idx

def test():
    MOT_path = r'E:\projects\deep_sort_yolov3\data\MOT17/'
    img_path = '1.jpg'
    frame = cv2.imread(img_path)
    print(frame)
    bbox = [343.8498840332031,821.2205810546875,125.63116455078125,258.70751953125]
    cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[0])+int(bbox[2]), int(bbox[1])+int(bbox[3])), (255, 0, 0), 2)
    cv2.imshow(' ', frame)
    cv2.waitKey()
    cv2.destroyAllWindows()

def main(yolo):
    MOT_path = '/home/wangshuai/projects/data/CVPR19/test/CVPR19-06'
    # Definition of the parameters
    max_cosine_distance = 0.70
    nn_budget = None
    nms_max_overlap = 1.0
    # load det
    det_df = pd.read_csv(MOT_path+'/det/det_csv.csv')
    # deep_sort
    model_filename = 'model_data/mars-small128.pb'
    encoder = gdet.create_box_encoder(model_filename, batch_size=1)
    # det_df_idx
    det_df_idx = 0
    metric = nn_matching.NearestNeighborDistanceMetric("ad_cosine", max_cosine_distance, nn_budget)
    tracker = Tracker(metric, n_init=3, max_age=30)

    writeVideo_flag = False

    if writeVideo_flag:
        # Define the codec and create VideoWriter object
        w = 1920
        h = 734
        fourcc = cv2.VideoWriter_fourcc(*'MJPG')
        out = cv2.VideoWriter('output.avi', fourcc, 15, (w, h))
        list_file = open('detection.txt', 'w')
    frame_index = 0
    imgs = os.listdir(MOT_path+'/img1')
    fps = 0.0
    imgs.sort()
    print(imgs)
    for img_path in imgs:
        if '.jpg' not in img_path:
            continue
        print('---------------------------------', frame_index + 1, '------------------')
        print(img_path)

        frame = cv2.imread(MOT_path + '/img1/' + img_path)
        # while True:
        #   ret, frame = video_capture.read()  # frame shape 640*480*3
        #  if ret != True:
        #     break
        t1 = time.time()

        image = Image.fromarray(frame)
        image = Image.fromarray(frame[..., ::-1])  # bgr to rgb
        boxs,det_df_idx = findbbx(frame_index+1,det_df_idx, det_df)
        # print("box_num",len(boxs))
        features = encoder(frame, boxs)

        # score to 1.0 here).
        detections = [Detection(bbox, 1.0, feature) for bbox, feature in zip(boxs, features)]

        # Run non-maxima suppression.
        boxes = np.array([d.tlwh for d in detections])
        scores = np.array([d.confidence for d in detections])
        indices = preprocessing.non_max_suppression(boxes, nms_max_overlap, scores)
        detections = [detections[i] for i in indices]

        # Call the tracker
        tracker.predict()
        matches = tracker.update(detections)

        cv2.putText(frame, 'frame: ' + str(frame_index + 1), (30, 30), 0, 5e-3 * 200, (0, 255, 0), 2)

        for track in tracker.tracks:
            if not track.is_confirmed() or track.time_since_update > 1:
                continue
            bbox = track.to_tlbr()
            # cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), (255, 255, 255), 2)  # 白色
            cv2.putText(frame, str(track.track_id), (int(bbox[0]), int(bbox[1])), 0, 5e-3 * 200, (0, 255, 0),
                        2)  # 绿色的字 + ' (' + str(bbox[0]) + ',' + str(bbox[1]) + ')'

        for i, det in enumerate(detections):
            bbox = det.to_tlbr()
            cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), (255, 0, 0), 2)

       # cv2.imshow('', frame)

        if writeVideo_flag:
            # save a frame

            out.write(frame)
            frame_index = frame_index + 1
            # print('frame',frame_index)
            # print('check', matches)
            # print(len(tracker.tracks))
            for track_id, det_idx in matches:
                bbox = detections[det_idx].tlwh
                # print('(',track_id,det_idx,')',end=' ')
                id = track_id
                list_file.write(str(frame_index) + ',' + str(id) + ',' + str(bbox[0]) + ',' + str(bbox[1]) + ',' + str(
                    bbox[2]) + ',' + str(bbox[3]) + ',1,-1,-1')
                list_file.write('\n')
            # list_file.write(str(frame_index)+' ')
            # if len(boxs) != 0:
            #     for i in range(0,len(boxs)):
            #         list_file.write(str(boxs[i][0]) + ' '+str(boxs[i][1]) + ' '+str(boxs[i][2]) + ' '+str(boxs[i][3]) + ' ')
        # list_file.write('\n')

        fps = (fps + (1. / (time.time() - t1))) / 2
        print("fps= %f" % (fps))

        # Press Q to stop!
        # if cv2.waitKey(1) & 0xFF == ord('q'):
        #     break

    if writeVideo_flag:
        out.release()
        list_file.close()
    #cv2.destroyAllWindows()

if __name__ == '__main__':
    #test()
    main(YOLO())


#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
    author='BilibiliRiven',
    author_email='BilibiliRiven@gmail.com'or'958403316@qq.com'
    fuction:
    Day:%s
"""
import bai_du
import you_dao

class Translater(object):
    def __init__(self, a):  # 参数传入1，用百度翻译，否则用有道翻译。
        if a == 1:
            self.sendor = bai_du.BaiDu()
        else:
            self.sendor = you_dao.You_Dao()

tras = Translater(1)  # 此时用百度翻译
print(tras.sendor.send("Hello World"))


import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from utils import init_params

class Learner(nn.Module):
    def __init__(self, nway=5, base_lr=1e-2):
        super(Learner, self).__init__()
        self.conv1 = nn.Conv2d(3,32,3,1,0)
        self.relu1 = nn.ReLU()
        self.bn1 = nn.BatchNorm2d(32)
        self.maxpool1 = nn.MaxPool2d(2,2,0)

        self.conv2 = nn.Conv2d(32,32,3,1,0)
        self.relu2 = nn.ReLU()
        self.bn2 = nn.BatchNorm2d(32)
        self.maxpool2 = nn.MaxPool2d(2,2,0)

        self.conv3 = nn.Conv2d(32,32,3,1,0)
        self.relu3 = nn.ReLU()
        self.bn3 = nn.BatchNorm2d(32)
        self.maxpool3 = nn.MaxPool2d(2,2,0)

        self.conv4 = nn.Conv2d(32,32,3,1,0)
        self.relu4 = nn.ReLU()
        self.bn4 = nn.BatchNorm2d(32)
        self.maxpool4 = nn.MaxPool2d(2,1,0)

        self.fc = nn.Linear(800, 5)

        init_params(self)

        self.base_lr = base_lr

    def forward(self, x):
        x = self.bn1(self.relu1(self.conv1(x)))
        x = self.maxpool1(x)
        x = self.bn2(self.relu2(self.conv2(x)))
        x = self.maxpool2(x)
        x = self.bn3(self.relu3(self.conv3(x)))
        x = self.maxpool3(x)
        x = self.bn4(self.relu4(self.conv4(x)))
        x = self.maxpool4(x)
        x = x.view(x.shape[0],-1)
        x = self.fc(x)
        return x

    def _adapt(self, weights, x, y):
        with torch.enable_grad():
            pred = self._forward_external_weight(weights, x)
            loss = F.cross_entropy(pred, y)
            grad = torch.autograd.grad(loss, weights)

            weights = list(map(lambda p : p[1] - self.base_lr * p[0], zip(grad, weights)))
        return weights

    def _forward_external_weight(self, weights, x, bn_training=True):
        idx = 0
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                x = F.conv2d(x, weights[idx], weights[idx+1], m.stride, m.padding)
                idx += 2
            elif isinstance(m, nn.BatchNorm2d):
                x = F.batch_norm(x, m.running_mean, m.running_var, weights[idx], weights[idx+1], bn_training)
                idx += 2
            elif isinstance(m, nn.Linear):
                x = x.view(x.shape[0], -1)
                x = F.linear(x, weights[idx], weights[idx+1])
                idx += 2
            elif isinstance(m, nn.ReLU):
                x = F.relu(x)
            elif isinstance(m, nn.MaxPool2d):
                x = F.max_pool2d(x, m.kernel_size, m.stride, m.padding)
        return x


with open('./input') as f:
    data = f.read()

groups = [line.rstrip().split("\n") for line in data.split("\n\n")]

def parse_field(field):
    name = field.split(":")[0].strip()
    desc = field.split(":")[1].strip()
    ranges = (name, [list(map(int, r.strip().split("-"))) for r in desc.split("or")])
    return ranges
fields = groups[0]
field_vals = [parse_field(field) for field in fields]
print(field_vals)

my_ticket = groups[1][1].split(",")
print(my_ticket)

nearby = [ticket.split(",") for ticket in groups[2][1:]]
print(nearby)

# Part one
valid_values = set()
for field in field_vals:
    for r in field[1]:
        for i in range(r[0], r[1]+1):
            valid_values.add(i)

error_rate = 0
delete = set()
for i in range(len(nearby)):
    for val in nearby[i]:
        if int(val) not in valid_values:
            error_rate += int(val)
            delete.add(i)
delete = list(delete)
delete.sort()
for i in delete[::-1]:
    print(i)
    nearby.pop(i)
print(nearby)
print(error_rate)

def in_range(x, r):
    if x in range(r[0][0], r[0][1]+1) or x in range(r[1][0], r[1][1]+1):
        return True
    return False

valid_ranges = field_vals
possible_classes = []
all_names = []
print(nearby)
for i in range(len(nearby[0])):
    possible = []
    names = set()
    for r in valid_ranges:
        for ticket in nearby:
            if not in_range(int(ticket[i]), r[1]):
                break
        else:
            print(ticket[i], r[1])
            possible.append(r)
            names.add(r[0])
    possible_classes.append(possible)
    all_names.append(list(names))
#possible_classes = [set([l[0] for l in p]) for p in possible_classes]
print(all_names)

idxs = dict()
def occ(c):
    count = -1
    for e in all_names:
        if c in e:
            count += 1
    return count
while len(idxs) < len(nearby[0]):
    d = []
    for entry in enumerate(all_names):
        for c in entry[1]:
            o = occ(c)
            if o == 0:
                idxs[c] = entry[0]
                d.append(entry[0])
    for i in d[::-1]:
        all_names[i] = []
print(idxs)
sol = 1
for k in idxs:
    if 'departure' in k:
        sol = sol * int(my_ticket[idxs[k]])
print(sol)


import cv2
import tensorflow as tf
import os
import keras as keras
import numpy as np
import pickle
import time
import random
from skimage import data, color
from skimage.transform import rescale, rotate
from skimage.util import random_noise
# COMMMENT OUT WHEN FINDING BALLCENTERS

cap = cv2.VideoCapture('final_FIFACut.mp4')
ret, frame = cap.read()

IMG_SIZE = 25
CIRCLE_RADIUS = 5

second_frame_count = 1

ballPosition = pickle.load(open("ballPosition.pickle","rb"))

while(cap.isOpened()):
    if (second_frame_count == 1500):
         break

    ret, frameRead = cap.read()
    frame = random_noise(frameRead, mode='gaussian', seed=None, clip=True)

    blank_image = np.zeros((674,1200,3), np.uint8)

    cv2.circle(blank_image,(ballPosition[second_frame_count - 1][0],ballPosition[second_frame_count - 1][1]), CIRCLE_RADIUS, (0,255,255), -1)
    print(second_frame_count)
    start = time.time()
    if ballPosition[second_frame_count - 1][0] < IMG_SIZE and ballPosition[second_frame_count - 1][1] < IMG_SIZE:
        end = time.time()
        print(end - start)
        second_frame_count = second_frame_count + 1
        continue
    for i in range(1,5000):
        # print("frame: "+str(second_frame_count))
        # print("iteration "+str(i))
        width = random.randint(1, 1150)
        height = random.randint(1, 624)
        rotation = random.randint(1, 180)
        scale = random.uniform(0.5, 1)

        randompiece_frameWithCircle = blank_image[height:height+IMG_SIZE, width:width+IMG_SIZE]
        randompiece_frameToData = frame[height:height+IMG_SIZE, width:width+IMG_SIZE]

        rotation_frameWithCircle = rotate(randompiece_frameWithCircle, angle=rotation, mode='reflect')
        scale_frameWithCircle = rescale(rotation_frameWithCircle, scale=scale, mode='constant')

        rotation_frameToData = rotate(randompiece_frameToData, angle=rotation, mode='reflect')
        scale_frameToData = rescale(rotation_frameToData, scale=scale, mode='constant')
        # frameWithCircle = keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, zca_epsilon=1e-06, rotation_range=45, width_shift_range=1200, height_shift_range=674, brightness_range=None, shear_range=0.0, zoom_range=[0.025,0.025], channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False, vertical_flip=False, rescale=None, preprocessing_function=None, data_format=None, validation_split=0.0, dtype=None).random_transform(blank_image,seed=i)
        # frameToData = keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, zca_epsilon=1e-06, rotation_range=45, width_shift_range=1200, height_shift_range=674, brightness_range=None, shear_range=0.0, zoom_range=[0.025,0.025], channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False, vertical_flip=False, rescale=None, preprocessing_function=None, data_format=None, validation_split=0.0, dtype=None).random_transform(frame,seed=i)
        frameWithCircle = cv2.resize(scale_frameWithCircle, (IMG_SIZE,IMG_SIZE),interpolation = cv2.INTER_AREA)
        frameToData = cv2.resize(scale_frameToData, (IMG_SIZE,IMG_SIZE),interpolation = cv2.INTER_AREA)

        count = np.count_nonzero(frameWithCircle)

        if(count > 250):
            print(count)
            name = str(second_frame_count)+"_"+str(i)+".png"
            frameToData = frameToData * 255
            image_to_save = frameToData.astype('uint8')
            cv2.imwrite(os.path.join("C:/Users/emilh/Desktop/keras_bachelor/FifaBall/",name), image_to_save )
        else:
            random_number = random.uniform(0, 1)
            if random_number > 1 - 1 / 1000:
                 name = str(second_frame_count)+"_"+str(i)+".png"
                 frameToData = frameToData * 255
                 image_to_save = frameToData.astype('uint8')
                 cv2.imwrite(os.path.join("C:/Users/emilh/Desktop/keras_bachelor/FifaNotBall/",name), image_to_save )

    end = time.time()
    print(end - start)
    second_frame_count = second_frame_count + 1

cap.release()
cv2.destroyAllWindows()


#!/usr/bin/env python3
import re

MAXN = 1000

field = [[0 for _ in range(MAXN)] for _ in range(MAXN)]
line_re = re.compile("#([0-9]*) @ ([0-9]*),([0-9]*): ([0-9]*)x([0-9]*)")
claims = []

while True:
    try:
        r = line_re.match(input())
    except:
        break

    i = int(r[1])
    x0, y0 = int(r[2]), int(r[3])
    w, h = int(r[4]), int(r[5])

    claims.append((i, x0, y0, w, h))

    for y in range(y0, y0+h):
        for x in range(x0, x0+w):
            field[y][x] += 1

for i, x0, y0, w, h in claims:
    overlapped = False
    for y in range(y0, y0+h):
        for x in range(x0, x0+w):
            if field[y][x] > 1:
                overlapped = True
    if not overlapped:
        print(i)


import io

emdict = {'anger' : 0, 'fear' : 1, 'joy' : 2, 'sadness' : 3}
revdict = {0 : 'anger', 1 : 'fear', 2 : 'joy', 3 : 'sadness'}

def eval(infile):
    hit = [0,0,0,0] #anger, fear, joy, sadness
    emotion_guess = [0,0,0,0] #anger, fear, joy, sadness
    emotion_count = [0,0,0,0] #anger, fear, joy, sadness
    precision = [0,0,0,0]
    recall = [0,0,0,0]
    f_score = [0,0,0,0]

    #print(emdict['anger'])

    with open(infile, 'r') as f:
        for line in f:
            line = line.strip('\n').split('\t')
            emotion_count[emdict[line[2]]] += 1
            emotion_guess[emdict[line[3]]] += 1
            if emdict[line[2]] == emdict[line[3]]:
                hit[emdict[line[2]]] += 1

    for i in range(4):
        precision[i] = hit[i]/emotion_guess[i]

    for i in range(4):
        recall[i] = hit[i]/emotion_count[i]

    for i in range(4):
        f_score[i] = (2*precision[i]*recall[i])/(precision[i]+recall[i])

    for i in range(4):
        print("{!s} values:".format(revdict[i]))
        print("Precision : {!s}, recall : {!s}, f-score : {!s}".format(precision[i], recall[i], f_score[i]))


from opentrons import types
from opentrons import protocol_api
import math

metadata = {
    'protocolName': 'Omega Bio-tek Mag-Bind Environmental DNA 96 Kit',
    'author': 'Sakib <sakib.hossain@opentrons.com>',
    'description': 'Custom Protocol Request',
    'apiLevel': '2.9'
}

def run(ctx):

    [debug, samples, m300_mount, m20_mount, tip_type, mm2_vol, vhb_vol,
        elution_buffer_vol, settling_time] = get_values(  # noqa: F821
        "debug", "samples", "m300_mount", "m20_mount", "tip_type", "mm2_vol",
        "vhb_vol", "elution_buffer_vol", "settling_time")

    cols = math.ceil(samples/8)

    tiprack_type = {
        'standard': 'opentrons_96_tiprack_300ul',
        'filter': 'opentrons_96_filtertiprack_200ul'
        }

    # Load Labware/Modules
    temp_mod = ctx.load_module('temperature module gen2', 3)
    temp_plate = temp_mod.load_labware(
                    'opentrons_96_aluminumblock_nest_wellplate_100ul')
    mag_mod = ctx.load_module('magnetic module gen2', 1)
    mag_plate = mag_mod.load_labware('nest_96_wellplate_2ml_deep')
    tipracks = [ctx.load_labware(tiprack_type[tip_type], slot) for slot in
                [4, 7, 8, 9, 10]]
    tip_isolator = ctx.load_labware(tiprack_type[tip_type], 11, 'Tip Isolator')
    res1 = ctx.load_labware('nest_12_reservoir_15ml', 5)
    res2 = ctx.load_labware('nest_12_reservoir_15ml', 2)
    dna_plate = ctx.load_labware('nest_96_wellplate_100ul_pcr_full_skirt', 6)
    trash = ctx.loaded_labwares[12]['A1']

    # Load Pipettes
    m300 = ctx.load_instrument('p300_multi_gen2', m300_mount,
                               tip_racks=tipracks)
    max_tip_volume = tipracks[0]['A1'].geometry.max_volume

    # Reagents
    # Splitting columns for an even 12 column transfer
    # based on volume total
    mm2 = [well for well in res1.wells()[:3] for i in range(4)]
    vhb = [well for well in res1.wells()[4:8] for i in range(3)]
    etoh1 = [well for well in res2.wells()[:4] for i in range(3)]
    etoh2 = [well for well in res2.wells()[4:8] for i in range(3)]
    elution_buffer = res1.wells()[11]
    elution_wells = temp_plate.rows()[0][:cols]

    # Helper Functions
    def debug_mode(msg, debug_setting=debug):
        if debug_setting == "True":
            ctx.pause(msg)

    def supernatant_removal(vol, src, dest, side=-1):
        m300.flow_rate.aspirate = 20
        while vol >= max_tip_volume:
            m300.aspirate(
                max_tip_volume, src.bottom().move(
                    types.Point(x=side, y=0, z=0.5)))
            m300.dispense(max_tip_volume, dest)
            vol -= max_tip_volume

        if vol < max_tip_volume:
            m300.aspirate(vol, src.bottom().move(
                        types.Point(x=side, y=0, z=0.5)))
            m300.dispense(vol, dest)
        m300.flow_rate.aspirate = 50

    def reset_flow_rates():
        m300.flow_rate.aspirate = 94
        m300.flow_rate.dispense = 94

    def pick_up(pip, loc=None):
        """Function that can be used instead of .pick_up_tip() that will pause
        robot when robot runs out of tips, prompting user to replace tips
        before resuming"""
        try:
            if loc:
                pip.pick_up_tip(loc)
            else:
                pip.pick_up_tip()
        except protocol_api.labware.OutOfTipsError:
            pip.home()
            ctx.pause("Replace the tips")
            pip.reset_tipracks()
            pip.pick_up_tip()

    def tip_mix(well, vol, reps, park_tip=False, tip_loc=None, tip_map=None,
                asp_speed=94, disp_speed=94):

        m300.flow_rate.aspirate = asp_speed
        m300.flow_rate.dispense = disp_speed

        if not m300.has_tip:
            if tip_loc:
                pick_up(m300, tip_loc)
            else:
                pick_up(m300)
        ctx.comment('Mixing from the middle')
        m300.mix(reps, vol, well.bottom(z=4))
        ctx.comment('Mixing from the bottom')
        m300.mix(reps, vol, well.bottom())
        ctx.comment('Mixing from the middle')
        m300.mix(reps, vol, well.bottom(z=4))
        m300.blow_out()
        m300.touch_tip()

        if not park_tip:
            m300.drop_tip()
        elif park_tip:
            m300.drop_tip(tip_isolator.columns()[mag_plate_wells[well]][0])
        reset_flow_rates()

    def bind(delay=settling_time):
        if mag_mod.status != 'engaged':
            mag_mod.engage()
        ctx.delay(minutes=delay, msg=f'''Incubating on MagDeck for
                  {delay} minute(s).''')

    def remove(vol, src, dest=trash, use_park_tip=True):
        if use_park_tip:
            pick_up(m300, tip_isolator.columns()[mag_plate_wells[src]][0])
        elif not use_park_tip:
            pick_up(m300)
        supernatant_removal(vol=vol, src=src, dest=dest)
        m300.drop_tip()

    def wash(vol, src, dest):
        m300.flow_rate.dispense = 200
        pick_up(m300)
        m300.transfer(vol, src, dest, new_tip='never')
        m300.drop_tip()
        m300.flow_rate.dispense = 94

    def etoh_wash(reservoir, park=True):
        # Steps 24-25
        # 70% Ethanol Wash
        debug_mode(msg="Debug: Wash with 70% Ethanol")
        for src, dest in zip(reservoir, mag_plate_wells):
            wash(500, src, dest)
        # Tip Mix (Vortex)
        debug_mode(msg="Debug: Tip Mixing (Vortex)")
        for well in mag_plate_wells:
            tip_mix(well, 300, 10, park_tip=park,
                    tip_loc=tip_isolator.columns()[mag_plate_wells[well]][0],
                    tip_map=mag_plate_wells, asp_speed=188, disp_speed=188)

        # Steps 26-27
        debug_mode(msg=f'''Debug: Engage Magnet for {settling_time} minutes
                        and then remove supernatant''')
        bind()
        for well in mag_plate_wells:
            remove(500, well, use_park_tip=False)
        if mag_mod.status == 'engaged':
            mag_mod.disengage()

    # Volume Tracking
    class VolTracker:
        def __init__(self, labware, well_vol, pip_type='single',
                     mode='reagent', start=0, end=12):
            self.labware_wells = dict.fromkeys(labware.wells()[start:end], 0)
            self.well_vol = well_vol
            self.pip_type = pip_type
            self.mode = mode
            self.start = start
            self.end = end

        def tracker(self, vol):
            '''tracker() will track how much liquid
            was used up per well. If the volume of
            a given well is greater than self.well_vol
            it will remove it from the dictionary and iterate
            to the next well which will act as the reservoir.'''
            well = next(iter(self.labware_wells))
            if self.labware_wells[well] >= self.well_vol:
                del self.labware_wells[well]
                well = next(iter(self.labware_wells))
            if self.pip_type == 'multi':
                self.labware_wells[well] = self.labware_wells[well] + vol*8
            elif self.pip_type == 'single':
                self.labware_wells[well] = self.labware_wells[well] + vol
            if self.mode == 'waste':
                ctx.comment(f'''{well}: {int(self.labware_wells[well])} uL of
                            total waste''')
            else:
                ctx.comment(f'''{int(self.labware_wells[well])} uL of liquid
                            used from {well}''')
            return well

    # Track Reagent Volumes
    water = VolTracker(res2, 14400, 'multi', 'reagent', start=9, end=12)

    # Wells
    # mag_plate_wells = mag_plate.rows()[0]
    mag_plate_wells = {well: column for well, column in zip(
                       mag_plate.rows()[0][:cols], range(cols))}
    dna_plate_wells = dna_plate.rows()[0][:cols]

    # Protocol Steps

    # Add 300 uL of Water to each well in tip isolator
    ctx.comment('''Transferring 300 uL of water to
                each well in the tip isolator''')
    pick_up(m300, tip_isolator['A1'])
    for col in tip_isolator.rows()[0]:
        m300.transfer(300, water.tracker(300), col, new_tip='never')

    # Step 14
    # Transfer Master Mix 2 (XP1 Buffer + Mag-Bind® Particles RQ) to Mag Plate
    debug_mode(msg="Debug: Transfer Master Mix 2 to Mag Plate (Step 14)")
    transfer_count = 0
    for mm, dest in zip(mm2, mag_plate_wells):
        if transfer_count == 3:
            transfer_count = 0
        if transfer_count == 0:
            if not m300.has_tip:
                pick_up(m300)
            m300.mix(10, 300, mm.bottom(z=4))
            if cols > 6:
                m300.mix(10, 300, mm2[6].bottom())
            m300.drop_tip()
        pick_up(m300)
        m300.aspirate(mm2_vol, mm)
        m300.dispense(mm2_vol, dest)
        m300.drop_tip()
        transfer_count += 1

    # Step 15
    # Incubate at Room Temp for 10 Minutes while mixing
    debug_mode(msg='''Debug: Incubate at Room Temperature while
               Mixing (Step 15)''')
    for well in mag_plate_wells:
        tip_mix(well, mm2_vol/2, 10, park_tip=True, tip_map=mag_plate_wells,
                asp_speed=94, disp_speed=94)

    for well in mag_plate_wells:
        tip_mix(well, mm2_vol/2, 5, park_tip=True,
                tip_loc=tip_isolator.columns()[mag_plate_wells[well]][0],
                tip_map=mag_plate_wells, asp_speed=94, disp_speed=94)

    # Steps 16-18
    debug_mode(msg=f'''Debug: Engage Magnet for {settling_time} minutes
                    and then remove supernatant (Steps 16-18)''')
    bind()
    for well in mag_plate_wells:
        remove(600, well, use_park_tip=True)
    if mag_mod.status == 'engaged':
        mag_mod.disengage()

    # Steps 19-20
    # Add VHB Buffer
    debug_mode(msg="Debug: Wash with VHB Buffer (Step 19)")
    for src, dest in zip(vhb, mag_plate_wells):
        wash(500, src, dest)
    # Tip Mix (Vortex)
    debug_mode(msg="Debug: Tip Mixing (Vortex) (Step 20)")
    for well in mag_plate_wells:
        tip_mix(well, 300, 10, park_tip=True, tip_map=mag_plate_wells,
                asp_speed=188, disp_speed=188)

    # Steps 21-23
    debug_mode(msg=f'''Debug: Engage Magnet for {settling_time} minutes and
               then remove supernatant (Steps 21-23)''')
    bind()
    for well in mag_plate_wells:
        remove(400, well, use_park_tip=False)
    if mag_mod.status == 'engaged':
        mag_mod.disengage()

    # Steps 24-28
    etoh_wash(etoh1)
    etoh_wash(etoh2, park=False)

    # Step 29
    debug_mode(msg='''Debug: Engaging Magnet for 1 minute and removing any
               supernatant (Step 29)''')
    bind(delay=1)
    for well in mag_plate_wells:
        remove(200, well, dest=trash, use_park_tip=False)

    # Step 30
    debug_mode(msg='''Debug: Engaging Magnet for 10 minutes to allow beads to
               dry (Step 30)''')
    bind(delay=10)

    # Step 31
    debug_mode(msg='''Debug: Transferring Elution Buffer to plate on
               temperature module (Step 31)''')
    m300.transfer(elution_buffer_vol, elution_buffer, elution_wells)
    debug_mode(msg='''Debug: Heating elution buffer on temperature module to
               70C (Step 31)''')
    temp_mod.set_temperature(70)
    debug_mode(msg='''Debug: Transferring elution buffer to sample wells
               (Step 31)''')
    for src, dest in zip(elution_wells, mag_plate_wells):
        m300.transfer(elution_buffer_vol, src, dest)

    # Step 32
    debug_mode(msg='''Debug: Tip Mixing (Vortex) (Step 32)''')
    for well in mag_plate_wells:
        tip_mix(well, elution_buffer_vol/2, 10, park_tip=False, tip_loc=None,
                tip_map=None, asp_speed=94, disp_speed=94)

    # Step 33
    debug_mode(msg='''Debug: Engaging Magnetic Module for 2 minutes to allow
               beads to settle (Step 33)''')
    bind(delay=2)

    # Step 34
    debug_mode(msg='''Debug: Transfer clear supernatant containing purified
               DNA to NEST 0.1 mL 96 Well PCR Plate (Step 34)''')
    for src, dest in zip(elution_wells, dna_plate_wells):
        pick_up(m300)
        m300.aspirate(elution_buffer_vol, src)
        m300.dispense(elution_buffer_vol, dest.bottom(z=5))
        m300.drop_tip()


# coding=utf-8
__author__ = 'etcher3rd'

import sys
import threading
import sbr_string
import sbr_data
import win32com.client
import wmi

from main import __version__
from os import _exit
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QTextCursor, QPixmap, QIntValidator, QIcon
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QThread, QObject, QByteArray, QTimer
from PyQt5.QtWebSockets import QWebSocketServer
from PyQt5.QtNetwork import QTcpSocket, QAbstractSocket, QHostAddress
from custom_logging import mkLogger, logged
from queue import Queue
from logging import Handler, Formatter
from ui import main_ui
from json import dumps

com_errors = 0

STATE_DIC = {
    0: 'déconnecté',
    1: 'résolution de l\'hôte',
    2: 'établissement de la connexion',
    3: 'connecté',
    4: 'server_side_only',
    5: 'internal_use_only',
    6: 'sur le point de fermer'
}

ERROR_DIC = {
    0: 'connexion refusée par le serveur',
    1: 'connexion terminée par le serveur',
    2: 'l\'adresse du serveur n\'a pas été trouvée',
    3: 'privilèges insuffisants',
    4: 'plus de ressources disponibles (trop de sockets ouverts)',
    5: 'time out de l\'opération',
    6: 'datagram trop grand pour l\'OS',
    7: 'erreur réseau',
    8: 'adresse exclusive réservée',  # UDP
    9: 'l\'adresse n\'appartient pas à cet hôte',  # UDP
    10: 'l\'opération demandée n\'est pas supportée par l\'OS',
    11: 'internal_use_only',
    12: 'le proxy requiert une autentification',
    13: 'échec de la connexion sécurisée',
    14: 'la connexion à ce serveur à été refusée par l\'OS',
    15: 'la connexion s\'est terminée de manière innatendue',
    16: 'le serveur n\' pas répondu lors de la phase d\'autentification',
    17: 'l\'adresse du proxy n\'a pas été trouvée',
    18: 'réponse innatendue de la part du serveur proxy'
}

class SiocClient(QObject):
    connected = pyqtSignal()
    disconnected = pyqtSignal()
    msg_from_sioc = pyqtSignal(str)

    logger = None

    @logged
    def __init__(self):
        global data_dico
        self.logger.debug('')
        QObject.__init__(self)
        data_dico = sbr_data.read_data_dico()
        self.data_import = ''.join(["Arn.Inicio:"] + ['{}:'.format(x) for x in data_dico] + ['\n'])

    # noinspection PyUnresolvedReferences
    @pyqtSlot()
    def run(self):
        sioc_socket_v2.stateChanged.connect(self.on_state_changed)
        sioc_socket_v2.error.connect(self.on_error)
        sioc_socket_v2.disconnected.connect(self.on_disconnected)
        sioc_socket_v2.readyRead.connect(self.read_data)
        self.connect_to_sioc()

    @pyqtSlot()
    def connect_to_sioc(self):
        self.logger.info('tentative de connexion à l\'ami SIOC sur {}:{}'.format(sioc_hote, sioc_port))
        while not sioc_socket_v2.state() == 3:
            sioc_socket_v2.connectToHost(sioc_hote, sioc_port)
            if sioc_socket_v2.waitForConnected(1000):
                self.logger.info('connexion établie')
                self.connected.emit()
                sioc_socket_v2.setSocketOption(QAbstractSocket.KeepAliveOption, 1)
                sioc_socket_v2.setSocketOption(QAbstractSocket.LowDelayOption, 1)
                self.write_data(self.data_import)
            else:
                self.disconnected.emit()

    @pyqtSlot()
    def on_state_changed(self):
        self.logger.debug('statut: {}'.format(STATE_DIC[sioc_socket_v2.state()]))

    @pyqtSlot()
    def on_disconnected(self):
        self.logger.warning('connexion SIOC perdue')
        self.connect_to_sioc()

    @pyqtSlot()
    def on_error(self):
        if sioc_socket_v2.error() in [1, 5]:
            self.logger.debug(ERROR_DIC[sioc_socket_v2.error()])
            return
        self.logger.error(ERROR_DIC[sioc_socket_v2.error()])

    @pyqtSlot()
    def read_data(self):
        # self.logger.debug('données disponibles en lecture')
        while not sioc_socket_v2.atEnd():
            msg = sioc_socket_v2.read(4096).decode().strip('\r\n')
            if msg in ['Arn.Vivo:']:
                # self.msg_from_sioc.emit('SIOC ALIVE')  # DEBUG
                break
            # self.logger.debug('message reçu: {}'.format(msg))
            self.msg_from_sioc.emit(msg)

    @pyqtSlot(str)
    def write_data(self, msg):
        sioc_socket_v2.writeData(msg.encode())
        if not sioc_socket_v2.waitForBytesWritten(1000):
            self.logger.error('erreur lors de l\'écriture sur le socket')

class WebSocketServer(QWebSocketServer):
    msg_from_pit = pyqtSignal(str)

    new_client_count = pyqtSignal(int)
    logger, clients = None, []

    @logged
    def __init__(self, *args, **kwargs):
        self.logger.debug('')
        QWebSocketServer.__init__(self, *args, **kwargs)

    def start_listening(self):
        self.logger.info('ouverture du socket WebServer pour le Katze Pit')
        if not self.listen(QHostAddress.Any, link_port):
            if self.error() == 1006:
                self.logger.error('impossible de lier le socket; est-ce qu\'une autre instance du Link tourne déjà ?')
            else:
                try:
                    self.logger.error(ERROR_DIC[self.error()])
                except KeyError:
                    self.logger.exception('erreur inconnue: {}'.format(self.error()))
        else:
            self.logger.info('socket ouvert, en attente de client')
            # noinspection PyUnresolvedReferences
            self.newConnection.connect(self.on_new_connection)

    @pyqtSlot()
    def on_new_connection(self):
        self.logger.debug('')
        client = self.nextPendingConnection()
        self.logger.info('connexion d\'un Katze Pit depuis l\'adresse: {}'.format(client.peerAddress().toString()))
        self.logger.debug(client)
        client.disconnected.connect(self.on_client_disconnect)
        client.textMessageReceived.connect(self.process_text_message)
        client.pong.connect(self.on_pong)
        client.error.connect(self.on_error)
        client.stateChanged.connect(self.on_client_state_changed)
        self.clients.append(client)
        self.new_client_count.emit(self.clients_count)

    @property
    def clients_count(self):
        return len(self.clients)

    @pyqtSlot()
    def on_close(self):
        self.logger.debug('')
        self.ws_v2.newConnection.disconnect()

    @pyqtSlot(int, str)
    def on_pong(self, elapsed_time, _):
        self.logger.debug('ping reçu après {}ms'.format(elapsed_time))

    @pyqtSlot()
    def on_client_state_changed(self):
        client = self.sender()
        self.logger.debug(STATE_DIC[client.state()])

    @pyqtSlot()
    def on_error(self):
        client = self.sender()
        self.logger.error(ERROR_DIC[client.error()])

    @pyqtSlot()
    def on_client_disconnect(self):
        self.logger.debug('')
        client = self.sender()
        self.logger.info('déconnexion du Katze Pit: {}'.format(client.peerAddress().toString()))
        client.deleteLater()
        self.clients.remove(client)
        self.new_client_count.emit(self.clients_count)

    @pyqtSlot(QByteArray)
    def process_text_message(self, msg):
        # client = self.sender()
        # self.logger.debug(msg)
        self.msg_from_pit.emit(msg)

    @pyqtSlot(str)
    def write_data(self, msg):
        # self.logger.debug(msg)
        for client in self.clients:
            # self.logger.debug(client)
            client.sendTextMessage(msg)

class FocusDCS(QObject):
    logger = None

    @logged
    def __init__(self):
        self.logger.debug('')
        QObject.__init__(self)
        self.timer = QTimer()
        # noinspection PyUnresolvedReferences
        self.timer.timeout.connect(self.on_timeout)
        self.__is_running = False

    def start(self, interval):
        self.__is_running = True
        self.timer.start(interval)

    def stop(self):
        self.__is_running = False
        self.timer.stop()

    @pyqtSlot()
    def on_timeout(self):
        # self.logger.debug('')
        raise_dcs_window()

    @property
    def is_running(self):
        return self.__is_running

class Gui():
    def __init__(self):
        pass

    class LoggingHandler(QObject, Handler):

        sig_send_text = pyqtSignal(str)

        def __init__(self):
            QObject.__init__(self)
            self.q = Queue()

        def emit(self, record):
            if record.levelno > 10:
                self.q.put(record)

        @pyqtSlot()
        def run(self):
            while True:
                text = self.format(self.q.get())
                self.sig_send_text.emit(text)

    class Main(QMainWindow, main_ui.Ui_MainWindow):

        logger = None
        sioc_thread, sioc_client = None, None
        logger_thread, logger_handler = None, None
        dcs_focus_timer, dcs_focus_timer_thread = None, None
        server = None

        @logged
        def __init__(self):
            self.logger.debug('')
            QMainWindow.__init__(self)
            self.setupUi(self)
            self.setWindowTitle('Katze Link {}'.format(__version__))
            self.show()
            self.start_logger_handler()
            self.start_sioc_client()
            self.start_ws_server()
            self.start_dcs_focus_timer()
            # noinspection PyUnresolvedReferences
            self.dcs_focus_button.clicked.connect(self.on_dcs_focus_button_state_clicked)
            self.dcs_focus_timeout.setValidator(QIntValidator(50, 5000))
            self.sioc_address_label.setText("Adresse SIOC: {}:{}".format(sioc_hote, sioc_port))

        @pyqtSlot()
        def start_logger_handler(self):
            self.logger_thread = QThread(self)
            self.logger_handler = Gui.LoggingHandler()
            formatter = Formatter('%(levelname)s - %(name)s - %(funcName)s - %(message)s')
            self.logger_handler.setFormatter(formatter)
            self.logger_handler.moveToThread(self.logger_thread)
            # noinspection PyUnresolvedReferences
            self.logger_thread.started.connect(self.logger_handler.run)
            self.logger_handler.sig_send_text.connect(self.log)
            logger.addHandler(self.logger_handler)
            self.logger_thread.start()

        @pyqtSlot()
        def start_sioc_client(self):
            self.sioc_thread = QThread(self)
            self.sioc_client = SiocClient()
            # noinspection PyUnresolvedReferences
            sioc_socket_v2.connected.connect(self.on_sioc_connect)
            # noinspection PyUnresolvedReferences
            sioc_socket_v2.disconnected.connect(self.on_sioc_disconnect)
            self.sioc_client.msg_from_sioc.connect(self.on_sioc_msg)
            self.sioc_client.moveToThread(self.sioc_thread)
            # noinspection PyUnresolvedReferences
            self.sioc_thread.started.connect(self.sioc_client.run)
            self.sioc_thread.start()

        @pyqtSlot()
        def start_ws_server(self):
            self.logger.debug('')
            self.server = WebSocketServer('', QWebSocketServer.NonSecureMode)
            self.server.start_listening()
            if self.server.isListening():
                self.server.new_client_count.connect(self.on_client_count_change)
                self.server.msg_from_pit.connect(self.on_pit_msg)
                self.on_ws_listening()

        @pyqtSlot()
        def start_dcs_focus_timer(self):
            self.dcs_focus_timer_thread = QThread(self)
            self.dcs_focus_timer = FocusDCS()
            self.dcs_focus_timer.moveToThread(self.dcs_focus_timer_thread)
            self.dcs_focus_timer_thread.start()

        @pyqtSlot(str)
        def log(self, text):
            self.log_window.moveCursor(QTextCursor.End)
            self.log_window.append(text)

        @pyqtSlot()
        def on_sioc_connect(self):
            self.sioc_state_pic.setPixmap(QPixmap(':/pics/green_light.png'))

        @pyqtSlot()
        def on_sioc_disconnect(self):
            self.sioc_state_pic.setPixmap(QPixmap(':/pics/red_light.png'))

        @pyqtSlot(str)
        def on_sioc_msg(self, msglist):
            # self.logger.debug('message SIOC brut: {}'.format(msglist))
            for msg in msglist.split('\r\n'):
                # self.logger.debug('raw splitted message: {}'.format(msg))
                if msg in ['Arn.Vivo:'] or not msg:
                    continue
                # self.logger.debug('message SIOC: {}'.format(msg))
                formatted_msg = sbr_string.sioc_read(msg)
                dic = {}
                for k in formatted_msg.keys():
                    dic[data_dico[k][0]] = round(formatted_msg[k] * data_dico[k][1], 0)
                self.server.write_data(dumps(dic))

        @pyqtSlot(str)
        def on_pit_msg(self, msg):
            msg = msg.strip('\u0000')
            # self.logger.debug('message Pit: {}'.format(msg))
            # send ACK
            # self.server.write_data(dumps(ack_dico))
            chan = int(msg.split('=')[0])
            if chan == 4:
                # TODO: CACH3
                pass
            if chan == 5:
                # self.logger.error('erreur Pit: {}'.format(msg))
                global com_errors
                com_errors += 1
                msg = '5={}'.format(com_errors)
            msg = 'Arn.Resp:{}:\n'.format(msg)
            # self.logger.debug('envoi du message à SIOC: {}'.format(msg))
            self.sioc_client.write_data(msg)

        @pyqtSlot()
        def on_ws_listening(self):
            self.ws_state_pic.setPixmap(QPixmap(':/pics/orange_light.png'))

        @pyqtSlot()
        def on_ws_disconnect(self):
            self.ws_state_pic.setPixmap(QPixmap(':/pics/red_light.png'))

        @pyqtSlot()
        def on_ws_connect(self):
            self.ws_state_pic.setPixmap(QPixmap(':/pics/green_light.png'))

        @pyqtSlot(str)
        def on_ws_msg(self, msg):
            self.logger.debug('message ws: {}'.format(msg))

        @pyqtSlot(int)
        def on_client_count_change(self, i):
            self.logger.debug(i)
            self.clients_count.setText(str(i))
            if i == 0:
                self.on_ws_listening()
            else:
                self.on_ws_connect()

        @pyqtSlot()
        def on_dcs_focus_button_state_clicked(self):
            if self.dcs_focus_timer.is_running:
                self.dcs_focus_timer.stop()
                self.dcs_focus_timeout.setEnabled(True)
                self.dcs_focus_button.setText('Activer')
                self.dcs_focus_state.setPixmap(QPixmap(':/pics/red_light.png'))
            else:
                if raise_dcs_window(refresh_pid=True):
                    self.dcs_focus_timeout.setEnabled(False)
                    interval = int(self.dcs_focus_timeout.text())
                    if interval < 100:
                        interval = 100
                    self.dcs_focus_button.setText('Désactiver')
                    self.dcs_focus_state.setPixmap(QPixmap(':/pics/green_light.png'))
                    self.dcs_focus_timer.start(interval)

def raise_dcs_window(refresh_pid=False):
    global dcs_pid
    if dcs_pid is None or refresh_pid:
        c = wmi.WMI()
        dcs_pid = None
        for process in c.Win32_Process(name='dcs.exe'):
            dcs_pid = process.ProcessId
        if dcs_pid is None:
            logger.warning('le processus DCS.exe n\'a pas été trouvé. Notez que "DCS.exe" n\'existe QUE si vous êtes '
                           'cockpit ou sur l\'interface multijoueur. L\'interface principale de DCS (avec les options, '
                           'l\'éditeur de mission etc...) ne compte pas')
            return
    shell.AppActivate(dcs_pid)
    shell.SendKeys('')
    return True

dcs_pid = None
shell = win32com.client.Dispatch("WScript.Shell")
logger = mkLogger('__main__')
data_config = sbr_data.read_config()
data_dico = sbr_data.read_data_dico()
sioc_hote = data_config["sioc_hote"]
sioc_port = int(data_config["sioc_port"])
sioc_plage = int(data_config["sioc_plage"])
cach3_hote = data_config["ts_hote"]
cach3_port = int(data_config["ts_port"])
link_hote = data_config["link_hote"]
link_port = int(data_config["link_port"])

sioc_socket_v2 = QTcpSocket()

qt_app = QApplication(sys.argv)
link_icon = QIcon(':/ico/link.ico')
ui_main = Gui.Main()
ui_main.setWindowIcon(link_icon)
_exit(qt_app.exec())


# uncompyle6 version 3.7.4
# Python bytecode 3.5 (3351)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /home/www.django/searchwally/codenerix/management/commands/colors.py
# Compiled at: 2017-11-28 06:03:36
# Size of source mod 2**32: 2163 bytes
import os
try:
    from subprocess import getstatusoutput
    pythoncmd = 'python3'
except:
    from commands import getstatusoutput
    pythoncmd = 'python2'

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from codenerix.lib.debugger import Debugger
from codenerix.lib.colors import colors

class Command(BaseCommand, Debugger):
    help = 'Show colors for Debugger'

    def handle(self, *args, **options):
        self.set_name('CODENERIX')
        self.set_debug()
        keys = []
        for key in colors.keys():
            keys.append((colors[key][0], colors[key][1], key))

        keys.sort()
        for color in keys:
            simplebit, subcolor = colors[color[2]]
            print('{0:1d}:{1:02d} - \x1b[{2:1d};{3:02d}m{4:<14s}\x1b[1;00m{5:<s}'.format(simplebit, subcolor, simplebit, subcolor, color[2], color[2]))
            appname = settings.ROOT_URLCONF.split('.')[0]
            basedir = settings.BASE_DIR
            appdir = os.path.abspath('{}/{}'.format(basedir, appname))
            status, output = getstatusoutput("find {}/ -type f -name '*.pyc' -delete".format(appdir))
            if status:
                raise CommandError(output)


from setuptools import setup, find_packages

version = '1.0b4'

setup(name='collective.googleanalytics',
      version=version,
      description="Tools for pulling statistics from Google Analytics.",
      long_description=open("README.txt").read() + "\n" +
                       open("CHANGES.txt").read(),
      # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers
      classifiers=[
        "Framework :: Plone",
        "Programming Language :: Python",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Topic :: Internet :: Log Analysis",
        "Topic :: Internet :: WWW/HTTP :: Site Management",
        "Development Status :: 3 - Alpha",
        ],
      keywords='Google Analytics Plone statistics portlet integration',
      author='Matt Yoder',
      author_email='mattyoder@onenw.org',
      url='http://svn.plone.org/svn/collective/collective.googleanalytics/trunk',
      license='GPL',
      packages=find_packages(exclude=['ez_setup']),
      namespace_packages=['collective'],
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          'setuptools',
          # -*- Extra requirements: -*-
          'gdata>=2.0.4',
      ],
      entry_points="""
      [z3c.autoinclude.plugin]
      target = plone
      """
      )