from __future__ import print_function
import datetime
import json
import re
import pandas as pd
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import threading

filepath = "./Dataset/data4.csv"
tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()
stop_words = stopwords.words()

df = pd.read_csv(filepath)

li = []

# tokenizing the emails
def tokenize_emails(df, li):
    for i in range(len(df)):
        message = tokenizer.tokenize(df.iloc[i]['Content'])
        li.append(message)

# removing all stopwords in the corpus
def rem_stopwords(li):
    for i in range(len(li)):
        temp = []
        for x in range(len(li[i])):
            if(li[i][x] not in stop_words):
                temp.append(li[i][x])
        li[i] = temp

# lemmatization
def lemmatize_emails(li):
    for i in range(len(li)):
        for x in range(len(li[i])):
            li[i][x] = lemmatizer.lemmatize(li[i][x])
            if(len(li[i][x]) > 12):
                li[i].remove(li[i][x])
            if(re.search("\*.*",li[i][x])):
                li[i].remove(li[i][x])

if __name__ == "__main__":
    # creating thread
    print('[1] Reading the csv file', datetime.datetime.now())
    df = pd.read_csv(filepath)
    df.drop(['Unnamed: 0'], axis = 1, inplace = True)
    print(df.columns)

    li1 = []
    li2 = []
    li3 = []
    li4 = []
    li5 = []
    li6 = []
    li7 = []
    li8 = []

    partition = int(len(df)/8)

    print('[2] Initializing multi-thread 1 at ', datetime.datetime.now())
    t1 = threading.Thread(target=tokenize_emails, args=(df[:partition], li1,))
    t2 = threading.Thread(target=tokenize_emails, args=(df[partition:2*partition], li2,))
    t3 = threading.Thread(target=tokenize_emails, args=(df[2*partition:3*partition], li3,))
    t4 = threading.Thread(target=tokenize_emails, args=(df[3*partition:4*partition], li4,))
    t5 = threading.Thread(target=tokenize_emails, args=(df[4*partition:5*partition], li5,))
    t6 = threading.Thread(target=tokenize_emails, args=(df[5*partition:6*partition], li6,))
    t7 = threading.Thread(target=tokenize_emails, args=(df[6*partition:7*partition], li7,))
    t8 = threading.Thread(target=tokenize_emails, args=(df[7*partition:], li8,))

    print('[3] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[4] Joining threads at ', datetime.datetime.now())
    # starting thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[5] Initializing multi-thread 2 at ', datetime.datetime.now())
    t1 = threading.Thread(target=rem_stopwords, args=(li[:partition],))
    t2 = threading.Thread(target=rem_stopwords, args=(li[partition:2*partition],))
    t3 = threading.Thread(target=rem_stopwords, args=(li[2*partition:3*partition],))
    t4 = threading.Thread(target=rem_stopwords, args=(li[3*partition:4*partition],))
    t5 = threading.Thread(target=rem_stopwords, args=(li[4*partition:5*partition],))
    t6 = threading.Thread(target=rem_stopwords, args=(li[5*partition:6*partition],))
    t7 = threading.Thread(target=rem_stopwords, args=(li[6*partition:7*partition],))
    t8 = threading.Thread(target=rem_stopwords, args=(li[7*partition:],))

    print('[6] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[7] Joining threads at ', datetime.datetime.now())
    # joining thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[8] Initializing multi-thread 3 at ', datetime.datetime.now())
    t1 = threading.Thread(target=lemmatize_emails, args=(li[:partition],))
    t2 = threading.Thread(target=lemmatize_emails, args=(li[partition:2*partition],))
    t3 = threading.Thread(target=lemmatize_emails, args=(li[2*partition:3*partition],))
    t4 = threading.Thread(target=lemmatize_emails, args=(li[3*partition:4*partition],))
    t5 = threading.Thread(target=lemmatize_emails, args=(li[4*partition:5*partition],))
    t6 = threading.Thread(target=lemmatize_emails, args=(li[5*partition:6*partition],))
    t7 = threading.Thread(target=lemmatize_emails, args=(li[6*partition:7*partition],))
    t8 = threading.Thread(target=lemmatize_emails, args=(li[7*partition:],))

    print('[9] Starting threads at ', datetime.datetime.now())
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
    # starting thread 3
    t3.start()
    # starting thread 4
    t4.start()
    # starting thread 5
    t5.start()
    # starting thread 6
    t6.start()
    # starting thread 7
    t7.start()
    # starting thread 8
    t8.start()

    print('[10] Joining threads at ', datetime.datetime.now())
    # starting thread 1
    t1.join()
    # joining thread 2
    t2.join()
    # joining thread 3
    t3.join()
    # joining thread 4
    t4.join()
    # joining thread 5
    t5.join()
    # joining thread 6
    t6.join()
    # joining thread 7
    t7.join()
    # joining thread 8
    t8.join()

    print('[11] Creating tokenized corpus at ', datetime.datetime.now())
    li = li1 + li2 + li3 + li4 + li5 + li6 + li7 + li8

    print('[12] Removing all whitespaces in the corpus at ', datetime.datetime.now())
    # removing any whitespace in the words in the list
    for i in range(len(li)):
        for x in range(len(li[i])):
            li[i][x] = li[i][x].strip()

    print('[13] Storing the length of individual emails in the corpus at ', datetime.datetime.now())
    len_li = []
    for i in li:
        len_li.append(len(i))

    df['Tokenized'] = li

    # df.sort_values('Email_Size',inplace = True, ascending = False)
    print('[14] Storing the json in a file')

    dic = {"len_li": len_li}
    js = json.dumps(dic)

    with open("length.json", "w") as outfile:
        outfile.write(js)

    print('[15] Stored the json file')
    df.drop(['Content'], axis = 1, inplace = True)
    print('[16] Dropped the content column and storing the database')
    df.to_csv('./Dataset/data2_1.csv', index = False)
    print('[17] Done!!')


# database - type mysql
def run(server):
    import os, time
    from pyql import data
    log = server.log
    DB_CONNECT_MAX_RETRY = 10
    DB_CONNECT_RETRY_DELAY_IN_SEC = 5

    if os.environ.get('PYQL_CLUSTER_ACTION') == 'test':
        os.environ['DB_USER'] = 'josh'
        os.environ['DB_PASSWORD'] = 'abcd1234'
        os.environ['DB_HOST'] = '192.168.3.33'
        os.environ['DB_PORT'] = '3306'
        os.environ['DB_NAMES'] = 'joshdb'
        os.environ['DB_TYPE'] = 'mysql'

    env = ['DB_USER','DB_PASSWORD','DB_HOST', 'DB_PORT', 'DB_NAMES', 'DB_TYPE']

    def get_db_config():
        config=dict()
        conf = ['user','password','host','port', 'databases', 'type']
        try:
            config = {cnfVal: os.getenv(dbVal).rstrip() for dbVal,cnfVal in zip(env,conf)}
            config['logger'] = log
            if 'PYQL_DEBUG' in os.environ and os.environ['PYQL_DEBUG'] == 'Enabled':
                config['debug'] = True
        except Exception as e:
            log.error(f'Missing an environment variable, {repr(e)}')
            config= {cnfVal: os.getenv(dbVal) for dbVal,cnfVal in zip(env,conf)}
            log.error(config)
            return config, 500
        return config, 200
    def attach(config):
        database = config['database']
        try_count = 0
        #try:
        if config['type'] == 'mysql':
            from mysql.connector import connect as connector
            if config['host'] == 'localhost':
                import socket, os
                config['host'] = socket.gethostbyname(os.environ['HOSTNAME'])
        else:
            import sqlite3.connect as connector
        while try_count < DB_CONNECT_MAX_RETRY:
            try:
                server.data[database] = data.Database(connector, **config)
                return {"message": f"db {database} attached successfully"}, 200
            except Exception as e:
                log.exception(f"enountered exception {repr(e)} during db {database} connect - sleeping {DB_CONNECT_RETRY_DELAY_IN_SEC} sec and retrying")
                time.sleep(DB_CONNECT_RETRY_DELAY_IN_SEC)
                try_count+=1
                continue
        return {"error": log.error(f"db {database} connect failed- check parameters provided / connectivity to {config}")}, 500

    @server.route('/internal/db/<database>/attach')
    def attach_database(database):
        config, rc = get_db_config()
        config['database'] = database
        return attach(config)

    @server.route('/internal/dbs/attach')
    def internal_attach_databases():
        return attach_database()
    def attach_databases():
        config, rc = get_db_config()
        if rc == 500:
            return {
                "status": 500,
                "message": "Missing environment variable(s)",
                "required": env,
                "found": config
            }, 500
        from . import setup
        response = {'results': []}
        for database in config['databases'].split(','):
            errors = ''
            config['database'] = database
            result, rc = attach(config)
            response['results'].append({f'{database}': f'{result}'})
        setup.attach_tables(server)
        return response, 200
    server.attach_databases = attach_databases

    response = attach_databases()
    log.warning(response)


# Libraries
from datetime import timedelta,datetime
from pathlib import Path
import requests
import json
import psycopg2
from airflow import DAG
from sqlalchemy import create_engine
import pandas as pd
import os
import smtplib

# Operadores
from airflow.operators.python_operator import PythonOperator
from airflow.operators.bash import BashOperator

# Obtener el dag del directorio
dag_path = os.getcwd()     #esto direcciona al path original.. el home de la maquina de docker

key_red = os.environ["PASSWORD_REDSHIFT"]
key_fly = os.environ["PASSWORD_flight"]
key_mail = os.environ["PASSWORD_gmail"]

redshift_conn = {
    'host': 'data-engineer-cluster.cyhh5bfevlmn.us-east-1.redshift.amazonaws.com',
    'username': 'auad03_coderhouse',
    'database': 'data-engineer-database',
    'port': '5439'
}

# funcion de extraccion de datos
def extraer_data(exec_date):
    try:  #muestro fecha de ejecucion
        print(f"Adquiriendo data para la  fecha: {exec_date}")
        date = datetime.strptime(exec_date, '%Y-%m-%d %H')
        file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
        #--- Extraer la data  --------
        url = "http://api.aviationstack.com/v1/flights?access_key="
        params = key_fly
        response = requests.get(url+params)
        if response:
                print('Success!')
        else:
                print('An error has occurred.')
        api_response = response.json()
        df_flights = pd.json_normalize(api_response, record_path=['data'])
        output_dir = Path(f'{dag_path}/raw_data/{file_date_path}')  ##busco la carpeta raw_data y almaceno
        output_dir.mkdir(parents=True, exist_ok=True)
        df_flights.to_csv(output_dir / f"{file_date_path}.csv".replace("/", "_"), index=False, mode='a')
    except ValueError as e:
        print("Formato datetime deberia ser %Y-%m-%d %H", e)
        raise e

# funcion de transformacion de datos
def transformar_data(exec_date, ti):
        print(f"Transformando la data para la fecha: {exec_date}")
        date = datetime.strptime(exec_date, '%Y-%m-%d %H')
        file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
        raw_file = f"{dag_path}/raw_data/{file_date_path}/{file_date_path.replace('/', '_')}.csv"
        df_flights = pd.read_csv(raw_file)
        # ------- Transformacion de la data ----------------
        # Eliminar variables con muchos nulos
        df = df_flights.drop(['aircraft', 'live', 'departure.gate', 'departure.delay', 'departure.actual', 'departure.estimated_runway', 'departure.actual_runway',
                       'arrival.gate', 'arrival.baggage', 'arrival.delay', 'arrival.actual', 'arrival.estimated_runway', 'arrival.actual_runway',
                       'flight.codeshared', 'flight.codeshared.airline_name', 'flight.codeshared.airline_iata', 'flight.codeshared.airline_icao', 'flight.codeshared.flight_number',
                       'flight.codeshared.flight_iata', 'flight.codeshared.flight_icao'], axis=1)
        # Renombrar columnas
        df=df.rename(columns={'departure.airport':'dep_airport','departure.timezone':'dep_timezone','departure.iata':'dep_iata','departure.icao':'dep_icao','departure.terminal':'dep_terminal',\
                          'departure.scheduled':'dep_scheduled','departure.estimated':'dep_estimated', 'arrival.airport':'arr_airport', 'arrival.timezone':'arr_timezone',\
                          'arrival.iata':'arr_iata', 'arrival.icao':'arr_icao','arrival.terminal':'arr_terminal', 'arrival.scheduled':'arr_scheduled', 'arrival.estimated':'arr_estimated',\
                          'airline.name':'airline_name', 'airline.iata':'airline_iata','airline.icao':'airline_icao', 'flight.number':'flight_number', 'flight.iata':'flight_iata',\
                          'flight.iata':'flight_iata', 'flight.icao':'flight_icao'})
        # si flight_date es null lo elimino
        df.drop(df[df.flight_date.isnull()].index, inplace = True)
        numero = int(df['flight_date'].count())
        print('Cantidad de vuelos descargados:', numero)
        ti.xcom_push(key='transform_data', value= numero)
        # convertir a formato fecha
        df["flight_date"] = pd.to_datetime(df["flight_date"], infer_datetime_format=True)
        df["dep_scheduled"] = pd.to_datetime(df["dep_scheduled"], infer_datetime_format=True)
        df["dep_estimated"] = pd.to_datetime(df["dep_estimated"], infer_datetime_format=True)
        df["arr_scheduled"] = pd.to_datetime(df["arr_scheduled"], infer_datetime_format=True)
        df["arr_estimated"] = pd.to_datetime(df["arr_estimated"], infer_datetime_format=True)
        # Calcular la duracion agendada del vuelo en minutos
        schedule = df.arr_scheduled - df.dep_scheduled
        df['duration_scheduled_min'] = schedule / timedelta(minutes=1)
        # Calcular la duracion estimada del vuelo en minutos
        estimated = df.arr_estimated - df.dep_estimated
        df['duration_estimated_min'] = estimated / timedelta(minutes=1)
        # cargar la data procesada
        output_dir = Path(f'{dag_path}/processed_data/{file_date_path}')
        output_dir.mkdir(parents=True, exist_ok=True)
        df.to_csv(output_dir / f"{file_date_path}.csv".replace("/", "_"), index=False, mode='a')

# funcion de carga de datos en base de datos
def cargar_data(exec_date):
    print(f"Cargando la data para la fecha: {exec_date}")
    date = datetime.strptime(exec_date, '%Y-%m-%d %H')
    file_date_path = f"{date.strftime('%Y-%m-%d')}/{date.hour}"
    PDW = key_red
    # Crear la conexion
    engine = create_engine(f'redshift+psycopg2://{redshift_conn["username"]}:{PDW}@{redshift_conn["host"]}:{redshift_conn["port"]}/{redshift_conn["database"]}')
    engine.execute('''
                CREATE TABLE IF NOT EXISTS realtime_flights_airflow_new (
                    flight_date DATE NOT NULL,
                    flight_status VARCHAR(20),
                    dep_airport VARCHAR(70),
                    dep_timezone VARCHAR(70),
                    dep_iata CHAR(10),
                    dep_icao CHAR(10),
                    dep_terminal CHAR(10),
                    dep_scheduled datetime,
                    dep_estimated datetime,
                    arr_airport VARCHAR(70),
                    arr_timezone VARCHAR(70),
                    arr_iata CHAR(10),
                    arr_icao CHAR(10),
                    arr_terminal CHAR(10),
                    arr_scheduled datetime,
                    arr_estimated datetime,
                    airline_name VARCHAR(70),
                    airline_iata CHAR(10),
                    airline_icao CHAR(10),
                    flight_number int,
                    flight_iata CHAR(10),
                    flight_icao CHAR(10),
                    duration_scheduled_min float,
                    duration_estimated_min float
                    );
             ''')
    #leer tabla creada
    processed_file = f"{dag_path}/processed_data/{file_date_path}/{file_date_path.replace('/', '_')}.csv"
    records = pd.read_csv(processed_file)
    # mandarla a la base de datos
    records.to_sql('realtime_flights_airflow_new', engine, index=False, if_exists='append')

# Envio de mensaje
def enviar(ti):
    try:
        x=smtplib.SMTP('smtp.gmail.com',587)
        x.starttls()
        x.login('auad03@gmail.com', key_mail)
        numero = int(ti.xcom_pull(key='transform_data', task_ids='transform_data'))
        subject='Nueva data vuelos en tiempo real'
        body_text='Se agregaron nuevos vuelos en tiempo real: '
        num_ = '{}'.format(numero)
        body_text_new = body_text + num_
        print(body_text_new)
        message='Subject: {}\n\n{}'.format(subject, body_text_new)
        x.sendmail('auad03@gmail.com','cauad85@gmail.com',message)
        print('Exito')
    except Exception as exception:
        print(exception)
        print('Failure')

# argumentos por defecto para el DAG
default_args = {
    'owner': 'CynthiaA',
    'start_date': datetime(2023,6,5),
    'retries':5,
    'retry_delay': timedelta(minutes=3)
}

flight_dag = DAG(
    dag_id='realtime_data',
    default_args=default_args,
    description='Agrega data de vuelvos en tiempo real',
    schedule_interval="@daily",
    catchup=False
)

# TAREAS
task_1 = PythonOperator(
    task_id='extract_data',
    python_callable=extraer_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_2 = PythonOperator(
    task_id='transform_data',
    python_callable=transformar_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_3 = PythonOperator(
    task_id='load_data',
    python_callable=cargar_data,
    op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

task_4 = PythonOperator(
    task_id='send_mail',
    python_callable=enviar,
    #op_args=["{{ ds }} {{ execution_date.hour }}"],
    dag=flight_dag,
)

# Orden de ejecucion de las tareas
task_1 >> task_2 >> task_3 >> task_4


#	pygame
import pygame
import random
import numpy as np
import time

COLOR_WHITE = (255, 255, 255)
COLOR_BLACK = (0, 0, 0)

# lalala
# window parameter
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
WINDOW_CAPTION = "Factory Simulator"
WINDOW_ICON = pygame.image.load("res\\img\\zaku.png")
simulator_window = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))
pygame.display.set_caption(WINDOW_CAPTION)
pygame.display.set_icon(WINDOW_ICON)

PRODUCER_WIDTH = 60
PRODUCER_HEIGHT = 60
CONSUMER_WIDTH = 36
CONSUMER_HEIGHT = 24

simulator_state = True

DAY_TIME = 600	# total work time
TIME_MAX1 = 60	# products finished in TIME_MAX1 will not be punished
TIME_MAX2 = 120	# products finished between TIME_MAX1 and TIME_MAX2 will be punished and no products is allowed to be finished after TIME_MAX2
PENALTY = 5	# the penalty of each product finished between TIME_MAX1 and TIME_MAX2
NUM_OF_ITEM = 4
START_TIME = time.time()	# lalala change later
generate_rate = 0.01	# lalala change later add a generate consumer function later

consumerINDEX = 0	# lalala

class Producer():
	index = -1
	producing = -1
	start_time = 0

	def __init__(self, index):
		self.index = index
		self.producing = -1
		temp = "This is producer %d, currently producing %d" % (self.index, self.producing)
		print(temp)

	def changeState(self, producing):
		if self.producing == -1:
			self.producing = producing
			if producing != -1:
				self.start_time = pygame.time.get_ticks()
			temp = "State of producer %d have been changed to produce item %d, start at self.start_time: %d" % (self.index, self.producing, self.start_time)
			print(temp)
			global profit
			profit -= 100# lalala read from file and add an if statement
			return True
		else:
			print("i am busy")
			return False

	# lalala thinking about a smarter update function
	def updateState(self):
		produceTime = 5	# lalala read from file later and add an if statement
		if self.producing != (-1) and (pygame.time.get_ticks() - self.start_time) > (produceTime * 1000):
			item_amount[self.producing] += 1
			print("an item %d finished" % self.producing)
			self.producing = -1

# lalala thinking about a smarter update function
def updateProducer():
	for i in range(0,num_of_producer):
		producers[i].updateState()

class Consumer():
	index = 0
	requirement = 0	# lalala u know what u should do
	chosen = False
	start_time = 0
	punished = False

	def __init__(self, requirement, start_time):
		global consumerINDEX
		super(Consumer, self).__init__()
		self.index = consumerINDEX
		consumerINDEX += 1
		self.requirement = requirement
		self.start_time = start_time
		global num_of_consumer
		num_of_consumer += 1

	def setChosen(self, chosen):
		self.chosen = chosen
	def setPunished(self):
		self.punished = True
	def isPunished(self):
		return self.punished
	def isChosen(self):
		return self.chosen
	def getRequirement(self):
		return self.requirement
	def getIndex(self):
		return self.index
	def getStartTime(self):
		return self.start_time

# lalala rewrite!
def generateConsumer():
	global consumers, num_of_consumer
	requirement = random.randint(1,3)
	consumers = np.append(consumers, Consumer(requirement, pygame.time.get_ticks()))

# lalala rewrite!
def updateConsumer():
	global consumers, num_of_consumer, item_amount, credit, profit
	for i in range(0,num_of_consumer):
		if consumers[i].isPunished():
			if pygame.time.get_ticks() - consumers[i].getStartTime() >= (TIME_MAX2 * 1000):
				print("lalala exit la")
		else:
			if pygame.time.get_ticks() - consumers[i].getStartTime() >= (TIME_MAX1 * 1000):
				credit -= 5
				consumers[i].setPunished()
				print("consumer %d is angry now" %(i))
		if consumers[i].isChosen():
			if item_amount[1] >= consumers[i].getRequirement():
				item_amount[1] -= consumers[i].getRequirement()
				profit += 500
				num_of_consumer -= 1
				consumers = np.delete(consumers, i)
				break

def load_textures():
	global producer_texture
	producer_texture = pygame.image.load("res\\img\\dinosaur.jpg")
	producer_texture = pygame.transform.scale(producer_texture, (PRODUCER_WIDTH, PRODUCER_HEIGHT))

	# lalala show the requirement of each consumer, show different texture when a consumer is selected
	global consumer_texture
	consumer_texture = pygame.image.load("res\\img\\pink_ghost.png")
	consumer_texture = pygame.transform.scale(consumer_texture, (CONSUMER_WIDTH, CONSUMER_HEIGHT))

# initialize the simulator
def init_simulator():
	global credit, profit, num_of_producer, num_of_consumer, item_name, item_amount
	credit = 100
	profit = 0
	num_of_producer = 5	# lalala read from file later and can be changed by reinforcement learning
	num_of_consumer = 0
	item_name = np.array(["ITEM A", "ITEM B", "ITEM C", "ITEM D"])	# lalala read from xml later
	item_amount = np.zeros(NUM_OF_ITEM)	# lalala i forget what i wanna to write

	pygame.init()
	simulator_window.fill(COLOR_WHITE)
	pygame.display.update()

# start simulate a day work: generate consumers and start time flies
def start_simulator():

	# lalala add a start button
	# lalala reset pygame.time or set a start time
	pygame.display.update()

def display_lalala():
	# lalala
	font_text = pygame.font.SysFont("Arial", 15)
	# show number of items
	# lalala use something like array
	for i in range(0,NUM_OF_ITEM):
		text_item = item_name[i] + ": {:.0f}".format(item_amount[i])
		surface_item = font_text.render(text_item, True, COLOR_BLACK)
		simulator_window.blit(surface_item, ((5 + (int)(i / 2)) * WINDOW_WIDTH / 8, 20 + 30 * (i % 2)))

	# text_items = np.array(["ITEM A: %d" % item_amount[0], "ITEM B: %d" % item_amount[1], "ITEM C: %d" % item_amount[2], "ITEM D: %d" % item_amount[3]])
	# surface_itemA = font_text.render(text_items[0], True, COLOR_BLACK)
	# surface_itemB = font_text.render(text_items[1], True, COLOR_BLACK)
	# surface_itemC = font_text.render(text_items[2], True, COLOR_BLACK)
	# surface_itemD = font_text.render(text_items[3], True, COLOR_BLACK)
	# simulator_window.blit(surface_itemA, (5 * WINDOW_WIDTH / 8, 20))
	# simulator_window.blit(surface_itemB, (5 * WINDOW_WIDTH / 8, 50))
	# simulator_window.blit(surface_itemC, (6 * WINDOW_WIDTH / 8, 20))
	# simulator_window.blit(surface_itemD, (6 * WINDOW_WIDTH / 8, 50))

	# credit and profit
	# lalala add something like a bar
	text_credit = font_text.render("Credit: {}".format(credit), True, COLOR_BLACK)
	text_profit = font_text.render("Profit: {}".format(profit), True, COLOR_BLACK)
	simulator_window.blit(text_credit, (7 * WINDOW_WIDTH / 8, 20))
	simulator_window.blit(text_profit, (7 * WINDOW_WIDTH / 8, 50))
	# create a timer on the top middle of the window
	# lalala maybe add a clock
	font_timer = pygame.font.SysFont("Times New Roman", 30)
	timer = "{:.0f}".format(pygame.time.get_ticks() / 1000)
	text_timer = font_timer.render(timer, True, COLOR_BLACK)
	simulator_window.blit(text_timer, (WINDOW_WIDTH / 2, 20))

def display_producer():
	# lalala timer
	# lalala change those parameters to global value maybe
	gap = 100
	offset_x = 50
	offset_y = 100
	text_offset = 65
	# lalala add a if statement to differentiate (not)working producer by changing texture
	for i in range(0,num_of_producer):
		simulator_window.blit(producer_texture, (i % 3 * gap + offset_x, (int)(i / 3) * gap + offset_y))
		font_text = pygame.font.SysFont("Arial", 15)
		text_producer_name = font_text.render("Producer {}".format(i), True, COLOR_BLACK)
		simulator_window.blit(text_producer_name, (i % 3 * gap + offset_x, (int)(i / 3) * gap + offset_y + text_offset))

def display_consumer():
	# lalala requirement
	# lalala change those parameters to global value maybe
	global consumers
	gap = 60
	offset_x = 50
	offset_y = 100
	text_offset = 30
	for i in range(0,num_of_consumer):
		simulator_window.blit(consumer_texture, (i % 5 * gap + offset_x + WINDOW_WIDTH / 2, (int)(i / 5) * gap + offset_y))
		font_text = pygame.font.SysFont("Arial", 10)
		text_consumer_name = font_text.render("Consumer {}".format(consumers[i].getIndex()), True, COLOR_BLACK)
		simulator_window.blit(text_consumer_name, (i % 5 * gap + offset_x + WINDOW_WIDTH / 2, (int)(i / 5) * gap + offset_y + text_offset))

def update_simulator():

	simulator_window.fill(COLOR_WHITE)

	display_lalala()
	display_producer()
	display_consumer()

	for event in pygame.event.get():
		# finish if x clicked
		if event.type == pygame.QUIT:
			simulator_state = False
			pygame.quit()

		if event.type == pygame.MOUSEBUTTONUP:
			mouse_pos = pygame.mouse.get_pos()

			# check if a producer is clicked
			gap = 100
			offset_x = 50
			offset_y = 100
			text_offset = 65
			for i in range(0,num_of_producer):
				if mouse_pos[0] > (i % 3 * gap + offset_x) and mouse_pos[0] < (i % 3 * gap + offset_x + PRODUCER_WIDTH):
					if mouse_pos[1] > ((int)(i / 3) * gap + offset_y) and mouse_pos[1] < ((int)(i / 3) * gap + offset_y + PRODUCER_HEIGHT):
						pause = True
						while pause:
							for event in pygame.event.get():
								# lalala add a full screen panel
								if event.type == pygame.MOUSEBUTTONUP:
									producers[i].changeState(1)
									pause = False

			# check if a consumer is clicked
			gap = 60
			offset_x = 50
			offset_y = 100
			text_offset = 30
			for i in range(0,num_of_consumer):
				if mouse_pos[0] > (i % 5 * gap + offset_x + WINDOW_WIDTH / 2) and mouse_pos[0] < (i % 5 * gap + offset_x + WINDOW_WIDTH / 2 + CONSUMER_WIDTH):
					if mouse_pos[1] > ((int)(i / 5) * gap + offset_y) and mouse_pos[1] < ((int)(i / 5) * gap + offset_y + CONSUMER_HEIGHT):
						consumers[i].setChosen(True)

	pygame.display.update()

def end_simulator():
	pygame.quit()

if __name__ == "__main__":
	load_textures()
	init_simulator()
	start_simulator()	# lalala: add a start button before start and add a if statement
	global producers, consumers
	producers = np.empty(shape = [num_of_producer], dtype = Producer)
	consumers = np.empty(shape = [num_of_consumer], dtype = Consumer)
	for i in range(0,num_of_producer):
		producers[i] = Producer(i)
	while simulator_state and (pygame.time.get_ticks() / 1000 < DAY_TIME):
		# lalala change!
		if random.random() < generate_rate:
			generateConsumer()

		updateProducer()	# lalala thinking about a smarter update function
		updateConsumer()
		update_simulator()
	end_simulator()


#!/usr/bin/env python3
"""
compute sizes of all connected components.
sort and display.
"""

from timeit import timeit
import time
from sys import argv

from geo.point import Point

def load_instance(filename):
    """
    loads .pts file.
    returns distance limit and points.
    """
    with open(filename, "r") as instance_file:
        lines = iter(instance_file)
        distance = float(next(lines))
        points = [Point([float(f) for f in l.split(",")]) for l in lines]

    return distance, points

def print_components_sizes(distance, points):
    """
    affichage des tailles triees de chaque composante
    """

    def grid_index(point, d):
        """return l'indice de la grille en commençant en haut à gauche puis sur la droite"""
        x,y = point.coordinates
        x_index = int(x / d)
        y_index = int(y / d)
        return x_index, y_index

    def find_composantes(points, d):
        grid = {}
        composantes = []
        component_id = 0
        for point in points:
            x_index, y_index = grid_index(point, d)
            if (x_index, y_index) in grid:
                component_id = grid[(x_index, y_index)]
            else:
                component_id = len(composantes)
                composantes.append([point])
                grid[(x_index, y_index)] = component_id
            for dx in [-1, 0, 1]:
                for dy in [-1, 0, 1]:
                    if dx == 0 and dy == 0:
                        continue
                    x_neighbour, y_neighbour = x_index + dx, y_index + dy
                    if (x_neighbour, y_neighbour) in grid:
                        neighbour_id = grid[(x_neighbour, y_neighbour)]
                        if component_id != neighbour_id:
                            if len(composantes[component_id]) < len(composantes[neighbour_id]):
                                component_id, neighbour_id = neighbour_id, component_id
                            composantes[component_id].extend(composantes[neighbour_id])
                            for neighbour in composantes[neighbour_id]:
                                grid[grid_index(neighbour, d)] = component_id
                            composantes[neighbour_id] = []
        return [c for c in composantes if c]

    return find_composantes(points, distance)

def main():
    """
    ne pas modifier: on charge une instance et on affiche les tailles
    """
    for instance in argv[1:]:
        distance, points = load_instance(instance)
        resultat = print_components_sizes(distance, points)
        print(resultat)
        bon_result = [len(elem) for elem in resultat]
        bon_result = sorted(bon_result, reverse=True)
        print(bon_result)

start = time.time()
main()
end = time.time()
duree = end - start
print(duree)


#!/usr/bin/env python
# coding=utf-8

import operations
from Queue import Queue
import numpy as np
class GradientDescentOptimizer(object):
    def __init__(self, learning_rate):
        self._learing_rate = learning_rate

    def minimize(self, loss):
        learning_rate = self._learing_rate
        class MinimizationOp(operations.Op):
            def forward(self):
                #add forwad
                loss.forward()
                grad_map = compute_grad(loss)
                for var in self.graph.trainable_variables:
                    grad = grad_map[var]
                    var.output_value -= learning_rate * grad

        return MinimizationOp()

def compute_grad(target_op):
    grad_table = {}

    #BFS for redundant computation
    queue = Queue()
    queue.put(target_op)

    visited = set()
    visited.add(target_op)

    while not queue.empty():
        node = queue.get()
        output_nodes_grads = []
        for output_node in node.output_nodes:
            if len(output_node.input_nodes) > 1:
                idx = output_node.input_nodes.index(node)
                output_nodes_grads.append(grad_table[output_node][idx])
            else:
                output_nodes_grads.append(grad_table[output_node])
        grad_table[node] = node.grad(output_nodes_grads)
        for input_node in node.input_nodes:
            if input_node not in visited:
                queue.put(input_node)
                visited.add(input_node)

    return grad_table


def solution(n):
    answer = [char for char in str(n)]
    answer = sorted(answer,reverse=True)
    answer = ''.join(answer)
    answer = int(answer)
#     return int(''.join(sorted([char for char in str(n)],reverse=True)))
    return answer

print(solution(118372))

## OUTPUT : 873211


import tensorflow as tf
import numpy as np

class Transformer():

    def __init__(self, image_shape, sess=None, batch_size=1, learning_rate=1e-3,
                 hsv=True):

        self.image_shape = image_shape
        shape = np.concatenate([np.array([batch_size]), image_shape])
        if sess:
            self.sess = sess
        else:
            self.sess = tf.Session()

        # Set up placeholder for templates and input images
        self.templates = tf.placeholder(tf.float32, shape=shape,
                                        name="transformer_templates")
        self.inputs = tf.placeholder(tf.float32, shape=shape,
                                     name="transformer_inputs")

        # Set initialized value for transformation matrix
        b = np.zeros([batch_size, 2, 3], dtype=np.float32)
        b[:, 0, 0] = 1
        b[:, 1, 1] = 1
        matrix_init = tf.constant(b, dtype=tf.float32)

        # Create transformation matrix variable
        with tf.variable_scope("Transformer", reuse=tf.AUTO_REUSE):
            # Extra variable to calibrate brightness
            # zeros = np.zeros([batch_size, 1, 1, 1], dtype=np.float32)
            # offset_init = tf.constant(zeros, tf.float32)
            # self.offset = tf.get_variable("offset", dtype=tf.float32,
            #                               initializer=offset_init,
            #                               trainable=True)
            # inputs = self.inputs + self.offset

            transform_matrix = tf.get_variable("transform_matrix",
                                               dtype=tf.float32,
                                               initializer=matrix_init,
                                               trainable=True)
            # Transform inputs using the matrix
            # self.transformed = self._transform(
            #     transform_matrix, self.inputs, image_shape)
            # self.transformed = self._transform(
            #     transform_matrix, inputs, image_shape)
            self.transformed = self._transform(
                transform_matrix, self.inputs, image_shape[:-1])

            # MSE between the transformed image and the template
            if hsv:
                # dist = self._hsv_dist(self.transformed, self.templates)
                # self.loss = tf.reduce_sum(dist) / batch_size
                # transformed_hsv = tf.image.rgb_to_hsv(self.transformed)
                # templates_hsv = tf.image.rgb_to_hsv(self.templates)
                # transformed_hsv = tf.image.rgb_to_yuv(self.transformed)
                # templates_hsv = tf.image.rgb_to_yuv(self.templates)
                # dist = self._hsv_dist(transformed_hsv, templates_hsv)
                # self.loss = tf.reduce_sum(dist) / batch_size
                self.loss = tf.reduce_sum(
                    tf.square(self.transformed - self.templates)) / batch_size
            else:
                self.loss = tf.reduce_sum(
                    tf.square(self.transformed - self.templates)) / batch_size
                # self.loss = tf.reduce_sum(
                #     tf.abs(self.transformed - self.templates)) / batch_size

            # Set up optimizer
            optimizer = tf.train.AdamOptimizer(learning_rate)
            # self.update_step = optimizer.minimize(
            #     self.loss, var_list=[transform_matrix, self.offset])
            self.update_step = optimizer.minimize(
                self.loss, var_list=[transform_matrix])
            # var_list = [x for x in tf.global_variables()
            #             if "Transformer" in x.name]
            var_list = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                         scope="Transformer")
            self.init = tf.variables_initializer(var_list=var_list)

    def _repeat(self, x, n_repeats):
        with tf.variable_scope('_repeat'):
            rep = tf.transpose(
                tf.expand_dims(tf.ones(shape=tf.stack([n_repeats, ])), 1), [1, 0])
            rep = tf.cast(rep, 'int32')
            x = tf.matmul(tf.reshape(x, (-1, 1)), rep)
            return tf.reshape(x, [-1])

    def _interpolate(self, im, x, y, out_size):
        with tf.variable_scope('_interpolate'):
            # constants
            num_batch = tf.shape(im)[0]
            height = tf.shape(im)[1]
            width = tf.shape(im)[2]
            channels = tf.shape(im)[3]

            x = tf.cast(x, 'float32')
            y = tf.cast(y, 'float32')
            height_f = tf.cast(height, 'float32')
            width_f = tf.cast(width, 'float32')
            out_height = out_size[0]
            out_width = out_size[1]
            zero = tf.zeros([], dtype='int32')
            max_y = tf.cast(tf.shape(im)[1] - 1, 'int32')
            max_x = tf.cast(tf.shape(im)[2] - 1, 'int32')

            # scale indices from [-1, 1] to [0, width/height]
            x = (x + 1.0)*(width_f) / 2.0
            y = (y + 1.0)*(height_f) / 2.0

            # do sampling
            x0 = tf.cast(tf.floor(x), 'int32')
            x1 = x0 + 1
            y0 = tf.cast(tf.floor(y), 'int32')
            y1 = y0 + 1

            x0 = tf.clip_by_value(x0, zero, max_x)
            x1 = tf.clip_by_value(x1, zero, max_x)
            y0 = tf.clip_by_value(y0, zero, max_y)
            y1 = tf.clip_by_value(y1, zero, max_y)
            dim2 = width
            dim1 = width*height
            base = self._repeat(tf.range(num_batch)*dim1, out_height*out_width)
            base_y0 = base + y0*dim2
            base_y1 = base + y1*dim2
            idx_a = base_y0 + x0
            idx_b = base_y1 + x0
            idx_c = base_y0 + x1
            idx_d = base_y1 + x1

            # use indices to lookup pixels in the flat image and restore
            # channels dim
            im_flat = tf.reshape(im, tf.stack([-1, channels]))
            im_flat = tf.cast(im_flat, 'float32')
            Ia = tf.gather(im_flat, idx_a)
            Ib = tf.gather(im_flat, idx_b)
            Ic = tf.gather(im_flat, idx_c)
            Id = tf.gather(im_flat, idx_d)

            # and finally calculate interpolated values
            x0_f = tf.cast(x0, 'float32')
            x1_f = tf.cast(x1, 'float32')
            y0_f = tf.cast(y0, 'float32')
            y1_f = tf.cast(y1, 'float32')
            wa = tf.expand_dims(((x1_f-x) * (y1_f-y)), 1)
            wb = tf.expand_dims(((x1_f-x) * (y-y0_f)), 1)
            wc = tf.expand_dims(((x-x0_f) * (y1_f-y)), 1)
            wd = tf.expand_dims(((x-x0_f) * (y-y0_f)), 1)
            output = tf.add_n([wa*Ia, wb*Ib, wc*Ic, wd*Id])
            return output

    def _meshgrid(self, height, width):
        with tf.variable_scope('_meshgrid'):
            # This should be equivalent to:
            #  x_t, y_t = np.meshgrid(np.linspace(-1, 1, width),
            #                         np.linspace(-1, 1, height))
            #  ones = np.ones(np.prod(x_t.shape))
            #  grid = np.vstack([x_t.flatten(), y_t.flatten(), ones])
            x_t = tf.matmul(tf.ones(shape=tf.stack([height, 1])),
                            tf.transpose(tf.expand_dims(tf.linspace(-1.0, 1.0, width), 1), [1, 0]))
            y_t = tf.matmul(tf.expand_dims(tf.linspace(-1.0, 1.0, height), 1),
                            tf.ones(shape=tf.stack([1, width])))

            x_t_flat = tf.reshape(x_t, (1, -1))
            y_t_flat = tf.reshape(y_t, (1, -1))

            ones = tf.ones_like(x_t_flat)
            grid = tf.concat(axis=0, values=[x_t_flat, y_t_flat, ones])
            return grid

    def _transform(self, theta, input_dim, out_size):
        with tf.variable_scope('_transform'):
            num_batch = tf.shape(input_dim)[0]
            height = tf.shape(input_dim)[1]
            width = tf.shape(input_dim)[2]
            num_channels = tf.shape(input_dim)[3]
            theta = tf.reshape(theta, (-1, 2, 3))
            theta = tf.cast(theta, 'float32')

            # grid of (x_t, y_t, 1), eq (1) in ref [1]
            height_f = tf.cast(height, 'float32')
            width_f = tf.cast(width, 'float32')
            out_height = out_size[0]
            out_width = out_size[1]
            grid = self._meshgrid(out_height, out_width)
            grid = tf.expand_dims(grid, 0)
            grid = tf.reshape(grid, [-1])
            grid = tf.tile(grid, tf.stack([num_batch]))
            grid = tf.reshape(grid, tf.stack([num_batch, 3, -1]))

            # Transform A x (x_t, y_t, 1)^T -> (x_s, y_s)
            T_g = tf.matmul(theta, grid)
            x_s = tf.slice(T_g, [0, 0, 0], [-1, 1, -1])
            y_s = tf.slice(T_g, [0, 1, 0], [-1, 1, -1])
            x_s_flat = tf.reshape(x_s, [-1])
            y_s_flat = tf.reshape(y_s, [-1])

            input_transformed = self._interpolate(
                input_dim, x_s_flat, y_s_flat,
                out_size)

            output = tf.reshape(
                input_transformed, tf.stack([num_batch, out_height, out_width, num_channels]))
            return output

    def transform(self, inputs, templates, n_steps=50):
        """
        Uses a gradient-descent optimizer to try to match inputs to templates.
        Returns transformed input images.
        Shape is (None, height, width, channels).

        :param inputs: Numpy array of input images
        :param templates: Numy array of templates to match inputs to
        :param n_steps: (optional) Number of steps to take in the optimization
        """

        self.sess.run(self.init)
        feed_dict = {self.templates: templates, self.inputs: inputs}

        for step in range(n_steps):
            _, loss = self.sess.run([self.update_step, self.loss],
                                    feed_dict=feed_dict)
            # loss = self.sess.run(self.loss, feed_dict=feed_dict)
            if step % 10 == 0:
                print("step: {} - loss: {:.4f}".format(step, loss))

        return self.sess.run(self.transformed, feed_dict=feed_dict)


from vkbottle import Keyboard, KeyboardButtonColor, Callback
from . import days_of_the_week

Days = days_of_the_week.Days
KEYBOARD_SCHEDULE = (
        Keyboard(one_time=True)
        .add(Callback("Понедельник", {"cmd": "get_schedule", "day": Days.MONDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .add(Callback("Вторник", {"cmd": "get_schedule", "day": Days.TUESDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .add(Callback("Среда", {"cmd": "get_schedule", "day": Days.WEDNESDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .row()
        .add(Callback("Четверг", {"cmd": "get_schedule", "day": Days.THURSDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .add(Callback("Пятница", {"cmd": "get_schedule", "day": Days.FRIDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .add(Callback("Суббота", {"cmd": "get_schedule", "day": Days.SATURDAY.value}), color=KeyboardButtonColor.PRIMARY)
        .get_json()
)


import unittest
from unittest.mock import patch
from huma_sdk._services._aliases import _Aliases

class TestFetchAliasesUnitCase(unittest.TestCase):
    def setUp(self):
        self.keyword_parameters = dict(page=1, limit=50, sort_by=-1, order_by="", search_by="", search_for="")
        self.aggregated_keyword_parameters = dict(limit=50, sort_by=-1, order_by="", search_by="", search_for="", is_batch_pages=True, max_page_count=5)

    def create_expected_response_payload(self):
        return {
            "aliases": [{
                "type": "",
                "scope": "",
                "rule_name": "",
                "rule_type": "",
            }]
        }

    def assert_result(self, aliases_payload, expected_response):
        self.assertEqual(aliases_payload, expected_response)

    @patch.object(_Aliases, '_make_request')
    def test_fetch_aliases_success(self, mock_make_request):
        expected_response = self.create_expected_response_payload()
        mock_make_request.return_value = expected_response
        client = _Aliases()
        aliases_payload = client.fetch_aliases(**self.keyword_parameters)
        self.assert_result(aliases_payload, expected_response)

    @patch.object(_Aliases, '_make_request')
    def test_fetch_aggregated_aliases_success(self, mock_make_request):
        expected_response = self.create_expected_response_payload()
        mock_make_request.return_value = expected_response
        client = _Aliases()
        aliases_payload = client.fetch_aliases(**self.aggregated_keyword_parameters)
        self.assert_result(aliases_payload, expected_response)

if __name__ == '__main__':
    import nose2
    nose2.discover()


from unittest import mock

import pytest
from airflow.exceptions import AirflowSkipException

from maintenance.flickr_audit_sub_provider_workflow import (
    FlickrSubProviderAuditor,
    audit_flickr_sub_providers,
)

auditor = FlickrSubProviderAuditor()

@pytest.mark.parametrize(
    "response_json, expected_institutions",
    (
        (None, None),
        ({"foo": "bar"}, []),
        ({"institutions": {}}, []),
        ({"institutions": {"institution": [{"foo": "bar"}]}}, [{"foo": "bar"}]),
    ),
)
def test_get_institutions(response_json, expected_institutions):
    requester = auditor.requester
    with mock.patch.object(requester, "get_response_json", return_value=response_json):
        assert auditor.get_institutions() == expected_institutions

@pytest.mark.parametrize(
    "response_json, expected_total_count",
    (
        (None, 0),
        ({}, 0),
        ({"photos": {}}, 0),
        ({"photos": {"total": 0}}, 0),
        # 1 record for each license, 8 total records
        ({"photos": {"total": 1}}, 8),
    ),
)
def test_check_for_licensed_images(response_json, expected_total_count):
    requester = auditor.requester
    with mock.patch.object(requester, "get_response_json", return_value=response_json):
        assert auditor.get_cc_image_count("name", "nsid") == expected_total_count

def test_get_new_institutions():
    mock_already_configured_institutions = [
        "24662369@N07",  # Matches 'Already configured' institution
        "35067687@N04",  # Additional test value
    ]
    mock_nsids_to_skip = [
        "61270229@N05",
    ]

    mock_institutions_from_api = [
        # Institutions that should be skipped
        # No name
        {"nsid": "150408343@N02"},
        {"name": {}, "nsid": "150408343@N02"},
        # No nsid
        {"name": {"_content": "Missing NSID"}},
        # Nsid in skip list
        {"name": {"_content": "Skipped NSID"}, "nsid": "61270229@N05"},
        # Already configured in sub-providers
        {"name": {"_content": "Already configured"}, "nsid": "24662369@N07"},
        # This one is mocked to return no CC-licensed images
        {"name": {"_content": "No CC images"}, "nsid": "138361426@N08"},
        # This one is mocked to return only a small number of CC-licensed images
        {"name": {"_content": "Not enough CC images"}, "nsid": "142575440@N02"},
        # Institutions that should be marked for consideration
        # This one is mocked to return CC-licensed_images
        {"name": {"_content": "Institution to consider"}, "nsid": "35128489@N07"},
    ]

    def mock_get_cc_image_count(name, nsid):
        # Mock counts for a few institutions such that they are skipped
        if name == "No CC images":
            return 0  # No cc-licensed images
        if name == "Not enough CC images":
            return 1  # Less than the minimum required number of images

        # All others have enough cc-licensed images
        return 1000

    with (
        mock.patch.object(
            auditor, "get_institutions", return_value=mock_institutions_from_api
        ),
        mock.patch.object(auditor, "get_cc_image_count", new=mock_get_cc_image_count),
    ):
        auditor.current_institutions = mock_already_configured_institutions
        auditor.nsids_to_skip = mock_nsids_to_skip

        actual_institutions = auditor.get_new_institutions_with_cc_licensed_images()
        assert actual_institutions == [
            ("Institution to consider", "35128489@N07", 1000)
        ]

@pytest.mark.parametrize(
    "potential_sub_providers, message",
    (
        # No suggested sub-providers
        pytest.param(
            [],
            "",
            marks=pytest.mark.raises(exception=AirflowSkipException),
        ),
        (
            [("NavyMedicine", "61270229@N05", 1000)],
            "NavyMedicine: 61270229@N05 _(1000 cc-licensed images)_",
        ),
        (
            [
                ("NavyMedicine", "61270229@N05", 1000),
                ("East Riding Archives", "138361426@N08", 2000),
            ],
            "NavyMedicine: 61270229@N05 _(1000 cc-licensed images)_\n"
            "East Riding Archives: 138361426@N08 _(2000 cc-licensed images)_",
        ),
    ),
)
def test_audit_flickr_sub_providers(potential_sub_providers, message):
    with mock.patch(
        "maintenance.flickr_audit_sub_provider_workflow.FlickrSubProviderAuditor.get_new_institutions_with_cc_licensed_images",
        return_value=potential_sub_providers,
    ):
        actual_message = audit_flickr_sub_providers()
        assert message in actual_message


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue 13 Apr 2021

@author: Przemyslaw Zielinski
"""

import sys, os
sys.path[0] = os.getcwd()

import torch
from math import pi
from matplotlib import pyplot as plt
from sf_nets.models.nets import CartToPolar
# from sf_nets.models import CoderNet

ctp = CartToPolar()

print("Testing:", ctp)

b = 10
r = 1.0
p = torch.linspace(0, pi, b)

x = torch.column_stack((r*torch.cos(p), r*torch.sin(p)))

print(x.shape)
# plt.scatter(*x.T)
# plt.show()

y = ctp(x)
print(y)
plt.scatter(*y.T)
plt.xlim([0, 2])
plt.show()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Dec  4 12:17:34 2017

@author: saintlyvi
"""
import pandas as pd
import numpy as np
from math import ceil, floor
from scipy import stats
import os

import colorlover as cl
import plotly.offline as offline
import plotly.graph_objs as go
import plotly as py
offline.init_notebook_mode(connected=True) #set for plotly offline plotting

import benchmark.bm0 as bm0
from support import image_dir

def plotAnswerIDCount(submodel):

    data = []
    yrs = list(range(1,16))
    clrs = ['Greens','RdPu','Blues','YlOrRd','Purples','Reds', 'Greys']
    i = 0

    #Get mean AnswerID count for number of years electrified
    for c in submodel['class'].unique():
        selectdata = submodel[submodel['class']==c][['YearsElectrified',
                         'AnswerID_count']].groupby('YearsElectrified').mean().applymap(
                         lambda x: ceil(x))
        t = selectdata.reindex(yrs, fill_value=0).reset_index()

        trace = go.Bar(
                x=yrs,
                y=t['AnswerID_count'],
                name=c,
                marker=dict(color=cl.flipper()['seq']['3'][clrs[i]][1])
                )
        data.append(trace)
        i+=1

    layout = go.Layout(
                barmode='stack',
                title = 'Number of AnswerIDs inferred for each customer class for 1 - 15+ years after electrification',
                xaxis = dict(title='Years Electrified',
                                tickvals = yrs),
                yaxis = dict(title='AnswerID count'),
                margin = dict(t=100,r=150,b=50,l=150))

    fig = go.Figure(data=data, layout=layout)

    return offline.iplot(fig, filename=os.path.join(image_dir,'answer_id_count'+'.png'))

def plotValidObsRatio(ohp, daytype):

    lenx = 15 * 12 * 24 # = years * months * hours

    d = ohp.loc[ohp['daytype']==daytype][['class', 'YearsElectrified', 'month', 'hour', 'valid_obs_ratio']]
    d['tix'] = 12*24*(d.YearsElectrified-1) + 24*(d.month-1) + d.hour
    z = d['valid_obs_ratio']*100
    x = d['tix']
    y = d['class']
    hovertext = list() #modify text box on hover
    for row in d.iterrows():
        hovertext.append(list())
        hovertext[-1].append(
                'Year: {}
month: {}
time: {}h00
valid: {}%'.format(
                        row[1]['YearsElectrified'], row[1]['month'],
                        row[1]['hour'], row[1]['valid_obs_ratio']*100))
    data = [go.Heatmap(z = z,
                       x = x,
                       y = y,
                       name = daytype,
                       zmin = 0,
                       zmax = 100,
                       text = hovertext,
                       hoverinfo ="text" ,
                       colorscale=[[0.0, 'rgb(165,0,38)'],
                                   [0.1111111111111111,'rgb(215,48,39)'],
                                   [0.2222222222222222,'rgb(244,109,67)'],
                                   [0.3333333333333333, 'rgb(253,174,97)'],
                                   [0.4444444444444444, 'rgb(254,224,144)'],
                                   [0.5555555555555556, 'rgb(224,243,248)'],
                                   [0.6666666666666666, 'rgb(171,217,233)'],
                                   [0.7777777777777778, 'rgb(116,173,209)'],
                                   [0.8888888888888888, 'rgb(69,117,180)'],
                                   [1.0, 'rgb(49,54,149)']]
                       )]

    layout = go.Layout(showlegend=False,
                       title='Percentage valid ' + daytype + ' observations for all inferred classes in data model',
                       margin = dict(t=150,r=150,b=50,l=150),
                       height = 400,
                       yaxis = dict(
                               type = 'category',
                               ticktext = d['class'],
                               tickwidth = 1.5),
                       xaxis = dict(
                               title = 'Years Electrified',
                               ticktext = list(range(1, 16)),
                               tickvals = np.arange(12*24/2, lenx+1, 12*24),
                               ),
                               )

    fig = go.Figure(data=data, layout=layout)

    return offline.iplot(fig, filename=os.path.join(image_dir,'valid_obs_ratio_'+daytype+'.png'))

def plotHourlyProfiles(customer_class, model_cat, daytype='Weekday', years_electrified=7,
                             model_dir=None, data=None):
    """
    This function plots the hourly load profile for a subset of a customer class for a specified year since electrification. The function requires either a data model or an expert model as input.

    """

    if model_cat == 'expert':
        if model_dir is None:
            df = bm0.bmHourlyProfiles()
        else:
            df = bm0.bmHourlyProfiles(model_dir)
        df.columns = ['YearsElectrified', 'mean_monthly_kw', 'month', 'daytype', 'hour',
                      'kw_mean', 'kw_std', 'class']
    elif model_cat == 'data':
        if data is None:
            return(print('Specify the observed hourly load profile dataframe to be used for this graphic.'))
        else:
            df = data[['class', 'YearsElectrified', 'month', 'daytype',
                         'hour', 'kw_mean', 'kw_std']]

    df = df[(df['daytype']==daytype) & (df['YearsElectrified']==years_electrified) & (df['class']==customer_class)]
    if df.empty:
        return(print('Cannot retrieve data for the given submodel parameters. Please specify a different submodel.'))
    else:
        maxdemand = df['kw_mean'].max()

    #generate plot data
    traces = []
    y_raw = df.loc[:, 'hour']
    y_raw = y_raw.reset_index(drop=True)
    months = np.flipud(df['month'].unique())
    count = 0
    for m in months:
        z_raw = df.loc[df['month'] == m, 'kw_mean']
        z_raw = z_raw.reset_index(drop=True)
        x = []
        y = []
        z = []
        for j in range(0, len(z_raw)):
            z.append([z_raw[j], z_raw[j]])
            y.append([y_raw[j], y_raw[j]])
            x.append([count, count+1])
        hovertext = list() #modify text box on hover
        for yi, yy in y:
            hovertext.append(list())
            hovertext[-1].append('{}h00
{:.3f} kW'.format(yy, z[yi][0]))

        traces.append(dict(
            z=z,
            x=x,
            y=y,
            name=m,
            showscale=False,
            type='surface',
            text = hovertext,
            hoverinfo="name+text"
        ))
        count += 1

    #set layout
    layout = go.Layout(
            title= daytype + ' hourly load profile for "' + customer_class + '" customers ' +
                    str(years_electrified) +' years after electrification',
            margin=go.Margin(t=50,r=50,b=50,l=50, pad=10),
            height= 700,
            scene=dict(
                xaxis=dict(
                        title = 'month',
                        type = 'category',
                        ticktext = months,
                        tickvals = np.arange(0.5, 12.5, 1),
                        tickwidth = 1.5,
                        ),
                yaxis=dict(
                        title = 'time of day',
                        tickvals = np.arange(0, 24, 2)),
                zaxis=dict(
                        title = 'demand (kW)',
                        tickvals = np.arange(0, ceil(maxdemand*10)/10, 0.1),
                        rangemode = "tozero")
                )
    )

    fig = { 'data':traces, 'layout':layout }

    return offline.iplot(fig, filename=os.path.join(image_dir,'annual_hourly_profiles'+'.png'))

def plotProfileSimilarity(merged_hp, customer_class, daytype):
    """
    daytype = one of [Weekday, Saturday, Sunday]
    """

    d = merged_hp.loc[(merged_hp['daytype']==daytype) & (merged_hp['class']==customer_class)][['YearsElectrified', 'month', 'hour', 'Mean [kVA]', 'kw_mean', 'kw_std']]
    d['tix'] = 12*24*(d.YearsElectrified-1) + 24*(d.month-1) + d.hour
    d['tixnames'] = d.apply(lambda xd: 'Year '+str(int(xd.YearsElectrified))+
        '
Month '+str(int(xd.month))+'
'+str(int(xd.hour))+'h00', axis=1)

    trace0 = go.Scatter(
        showlegend=False,
        opacity=0,
        x=d['tix'],
        y=list([0]*len(d)),
        mode='lines',
        name='data-model',
        line=dict(
            color='black',
            width=0.5),
        text=d['tixnames'],
        hoverinfo = 'text',
        hoverlabel = dict(
                bgcolor='white')
        )
    trace1 = go.Scatter(
            x=d['tix'],
            y=d['Mean [kVA]'],
            fill= None,
            mode='lines',
            name='benchmark mean',
            line=dict(
                    color='green'),
            hoverinfo='y'
            )
    trace2 = go.Scatter(
        x=d['tix'],
        y=d['kw_mean'],
        fill='tonexty',
        fillcolor='rgb(255, 204, 255)',
        mode='lines',
        name='data model mean',
        line=dict(
            color='purple'),
        hoverinfo='y'
            )
    trace3 = go.Scatter(
        x=d['tix'],
        y=d['kw_std'] + d['kw_mean'],
        mode='lines',
        name='data model std dev',
        line=dict(
            color='purple',
            dash = 'dot'),
        hoverinfo='none'
            )

    y4 = [(y>0)*y for y in d['kw_mean'] - d['kw_std']]
    trace4 = go.Scatter(
        x=d['tix'],
        y=y4,
        mode='lines',
        showlegend=False,
        line=dict(
            color='purple',
            dash = 'dot'),
        hoverinfo='none'
            )

    data = [trace0, trace1, trace2]#, trace3, trace4]

    layout = go.Layout(showlegend=True,
                title=daytype + ' load profile model similarity for ' + customer_class + ' customers ',
                margin = dict(t=150,r=150,b=50,l=150),
                height = 400,
                yaxis = dict(
                        title = 'mean hourly demand (kW)',
                        ticksuffix=' kW'),
                xaxis = dict(
                        title = 'time electrified (years)',
                        ticktext = list(range(1, 16)),
                        tickvals = np.arange(0, (15*12*24)+1, 12*24),
                        rangeslider=dict(),)
                        )
    fig = go.Figure(data=data, layout=layout)

    return offline.iplot(fig, filename=os.path.join(image_dir,'profile-similarity'+'.png'))

def plotDemandSimilarity(merged_ds):
    """
    daytype = one of [Weekday, Saturday, Sunday]
    """
    data = []
    trcs = len(merged_ds['class'].unique())
    clrs = ['Greens','RdPu','Blues','YlOrRd','Purples','Reds', 'Greys']

    #generate existing and new model traces for each customer subclass
    count=0
    for c in merged_ds['class'].unique():
        d = merged_ds.loc[(merged_ds['class']==c)][['YearsElectrified','Energy [kWh]','M_kw_mean','M_kw_std']]

        wx = 0.8/trcs
        ox = -wx*(count)
        slope, intercept, r_value, p_value, std_err = stats.linregress(d['YearsElectrified'].values, d['M_kw_mean'].values)
        line = slope*d['YearsElectrified'].values+intercept

        trace0 = go.Bar(
                x=d['YearsElectrified'].values,
                y=d['Energy [kWh]'].values,
                marker=dict(
                        color=cl.flipper()['seq']['3'][clrs[count]][-1]),
                name=c + ' benchmark',
                opacity=0.6,
                width = wx,
                offset = ox,
                )

        trace1 = go.Bar(
            x=d['YearsElectrified'].values,
            y=d['M_kw_mean'].values,
            name=c + ' data model',
            marker=dict(
                    color=cl.flipper()['seq']['3'][clrs[count]][1]),
            width = wx,
            offset = ox,
            )

        trace2 = go.Scatter(
                    x=d['YearsElectrified'].values,
                    y=line,
                    mode='lines',
                    line=dict(color=cl.flipper()['seq']['3'][clrs[count]][1],
                                     width=3),
                    name=c + ' data lin_reg'
            )

        data.append(trace1)
        data.append(trace2)
        data.append(trace0)
        count+=1

    layout = go.Layout(
                    title='Annual mean monthly demand model similarity',
                    xaxis = dict(title='time electrified (years)',
                        tickvals = list(range(1,16))),
                    yaxis = dict(title='annual mean monthly consumption (kWh)')
                    )
    fig = go.Figure(data=data, layout=layout)

    return offline.iplot(fig, filename=os.path.join(image_dir,'demand-similarity'+'.png'))

def multiplotDemandSimilarity(merged_ds):
    """
    daytype = one of [Weekday, Saturday, Sunday]
    """
    data = []
    lay = []
    clrs = ['Greens','RdPu','Blues','YlOrRd','Purples','Reds', 'Greys']

    #generate existing and new model traces for each customer subclass
    count=1
    for c in merged_ds['class'].unique():
        d = merged_ds.loc[(merged_ds['class']==c)][['YearsElectrified','Energy [kWh]','M_kw_mean','M_kw_std']]

        slope, intercept, r_value, p_value, std_err = stats.linregress(d['YearsElectrified'].values, d['M_kw_mean'].values)
        line = slope*d['YearsElectrified'].values+intercept

        trace0 = go.Bar(
                x=d['YearsElectrified'].values,
                y=d['Energy [kWh]'].values,
                xaxis='x'+str(count),
                yaxis='y'+str(count),
                marker=dict(
                        color=cl.flipper()['seq']['3'][clrs[count-1]][-1]),
                name=c + ' benchmark',
                )

        trace1 = go.Bar(
            x=d['YearsElectrified'].values,
            y=d['M_kw_mean'].values,
            name=c + ' data model',
            marker=dict(
                    color=cl.flipper()['seq']['3'][clrs[count-1]][1]),
            )

        trace2 = go.Scatter(
            x=d['YearsElectrified'].values,
            y=line,
            mode='lines',
            line=dict(color=cl.flipper()['seq']['3'][clrs[count-1]][1],
                             width=3),
            name=c + ' data lin_reg'
            )

        lay.append({'yaxis{}'.format(count): go.YAxis(type = 'linear',
                            title='annual mean monthly
 consumption (kWh)'),
                    'xaxis{}'.format(count): go.XAxis(title = 'time electrified (years)',
                            ticktext = list(range(0, d.YearsElectrified.max()+1)),
                            tickvals = np.arange(0, d.YearsElectrified.max()+1, 1))
                     })

        data.append(trace1)
        data.append(trace2)
        data.append(trace0)
        count+=1

    #create subplot graph objects
    rows = int(len(data)/3)
    fig = py.tools.make_subplots(rows=rows, cols=1, subplot_titles=list(merged_ds['class'].unique()), horizontal_spacing = 0.1, print_grid=False)

    for i in list(range(0,len(data))):
        r = floor(i/3)+1
        fig.append_trace(data[i],r,1)

    fig['layout'].update(
                title='Annual mean monthly demand model similarity')

    #update layout for all subplots
    for k in range(0,rows):
        fig['layout'].update(lay[k])

    return offline.iplot(fig, filename=os.path.join(image_dir,'multiplot-demand-similarity'+'.png'))

def plotMaxDemandSpread(md):

    table = pd.pivot_table(md, values='Unitsread_kw', index=['month','hour'],aggfunc='count')
    table.reset_index(inplace=True)

    data = [go.Heatmap(
        x=table['month'],
        y=table['hour'],
        z = table['Unitsread_kw'],
        colorscale=[[0.0, cl.flipper()['seq']['3']['Oranges'][0]],
                    [1.0, cl.flipper()['seq']['3']['Oranges'][-1]]]
        )]

    layout = go.Layout(
                title = 'Spread of occurence of maximum demand for all households',
                xaxis = dict(title='month',
                                tickvals = list(range(1,13))),
                yaxis = dict(title='hour',
                             tickvals = list(range(1,25)))
                )

    fig = go.Figure(data=data, layout=layout)

    return offline.iplot(fig, filename=os.path.join(image_dir,'max-demand-spread'+'.png'))

def plotMonthlyMaxDemand(md):

    data = []

    for c in md['class'].unique():
        d = md[md['class']==c]
        trace = dict(
            type = 'scatter',
            x=d['month'],
            y=d['Unitsread_kw'],
            mode = 'markers',
            name = c,
            marker = dict(size = d['Unitsread_kw']*3
            ))

        data.append(trace)

    return offline.iplot({'data': data}, filename=os.path.join(image_dir,'monthly-max-demand'+'.png'))

def plotHourlyMaxDemand(md):

    data = []

    for c in md['class'].unique():
        d = md[md['class']==c]
        trace = dict(
            type = 'scatter',
            x=d['hour'],
            y=d['Unitsread_kw'],
            mode = 'markers',
            name = c,
            marker = dict(size = d['Unitsread_kw']*3
            ))

        data.append(trace)

    return offline.iplot({'data': data}, filename=os.path.join(image_dir,'hourly-max-demand'+'.png'))


import numpy as np
from model_selection import train_test_split

class LinearModel:

    def __init__(self, learning_rate=None, batch_size=None):
        """
        Initialise linear regression model
        """
        self.w = None
        self.b = None
        self.learning_rate = learning_rate
        self.batch_size = batch_size
        self.X_train_mean = None
        self.X_train_std = None

    @property
    def coef_(self):
        """
        Get weight(coefficient) for this estimator
        """
        return self.w

    @property
    def intercept_(self):
        """
        Get bias(intercept) for this estimator
        """
        return self.b

    def normalise_train_data(self, X_train, y_train):
        X_train, X_val, y_train, y_val = train_test_split(X_train, y_train)

        self.X_train_mean = np.mean(X_train, axis=0)
        self.X_train_std = np.std(X_train, axis=0)

        X_train = (X_train - self.X_train_mean) / self.X_train_std
        X_val = (X_val - self.X_train_mean) / self.X_train_std

        return X_train, X_val, y_train, y_val

    def normalise_test_data(self, X_test, y_test):

        if self.X_train_mean is None:
            raise Exception("You need to fit train dataset with normalise option")

        X_test = (X_test - self.X_train_mean) / self.X_train_std
        return X_test, y_test


# -*- coding: utf-8 -*-
# __author__ = 'zengjing'

import web
import json
import types
import datetime
from mainapp.libs.signature import check_sig
from bson.objectid import ObjectId
from biocluster.config import Config
from mainapp.models.mongo.submit.denovo_rna.denovo_kegg_rich import DenovoKeggRich
from mainapp.models.mongo.meta import Meta
from mainapp.models.workflow import Workflow
from mainapp.controllers.project.denovo_controller import DenovoController

class KeggRichRegulate(DenovoController):
    """
    kegg富集、调控接口
    """
    def __init__(self):
        super(KeggRichRegulate, self).__init__(instant=False)

    @check_sig
    def POST(self):
        data = web.input()
        client = data.client if hasattr(data, 'client') else web.ctx.env.get('HTTP_CLIENT')
        #print data
        return_result = self.check_options(data)
        if return_result:
            info = {"success": False, "info": "+".json(return_result)}
            return json.dumps(info)
        my_param = {'analysis_type': data.analysis_type, "express_diff_id": data.express_diff_id,
                    "compare": data.compare, "submit_location": data.submit_location}
        if data.analysis_type in ["enrich", "both"]:
            my_param["correct"] = data.correct
            my_param["regulate"] = data.regulate
        params = json.dumps(my_param, sort_keys=True, separators=(',', ':'))
        name = data.compare.split(',')[0]
        compare_name = data.compare.split(',')[1]
        express_diff_info = Meta(db=self.mongodb).get_main_info(data.express_diff_id, "sg_denovo_express_diff")
        if not express_diff_info:
            info = {"success": False, "info": "express_diff_id不存在，请检查参数是否正确！"}
            return json.dumps(info)
        task_id = express_diff_info["task_id"]
        project_sn = express_diff_info["project_sn"]
        if data.analysis_type == "enrich":
            main_table_name = "KeggRich_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            kegg_enrich_id = DenovoKeggRich().add_kegg_rich(name=main_table_name, params=params, project_sn=project_sn, task_id=task_id)
            update_info = {str(kegg_enrich_id): "sg_denovo_kegg_enrich"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "kegg_enrich_id": str(kegg_enrich_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id,
                "all_list": data.express_diff_id,
                "correct": data.correct,
                "regulate": data.regulate
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)", "denovo.export_all_gene_list(all_list)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=kegg_enrich_id, collection_name="sg_denovo_kegg_enrich")
        if data.analysis_type == "regulate":
            main_table_name = "KeggRegulate_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            kegg_regulate_id = DenovoKeggRich().add_kegg_regulate(name=main_table_name, params=params, project_sn=project_sn,
                                                            task_id=task_id)
            update_info = {str(kegg_regulate_id): "sg_denovo_kegg_regulate"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "kegg_regulate_id": str(kegg_regulate_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=kegg_regulate_id, collection_name="sg_denovo_kegg_regulate")
        if data.analysis_type == "both":
            main_table_name = "KeggEnrichRegulate_" + str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
            sort_id = DenovoKeggRich().add_kegg_pval_sort(name=main_table_name, params=params,
                                                                  project_sn=project_sn,
                                                                  task_id=task_id)
            update_info = {str(sort_id): "sg_denovo_kegg_pvalue"}
            options = {
                "analysis_type": data.analysis_type,
                "update_info": json.dumps(update_info),
                "name": name,
                "compare_name": compare_name,
                "sort_id": str(sort_id),
                "kegg_table": data.express_diff_id,
                "diff_stat": data.express_diff_id,
                "all_list": data.express_diff_id,
                "correct": data.correct,
                "regulate": data.regulate
            }
            to_file = ["denovo.export_kegg_table(kegg_table)", "denovo.export_diff_express(diff_stat)",
                       "denovo.export_all_gene_list(all_list)"]
            self.set_sheet_data(name="denovo_rna.report.kegg_rich_regulate", options=options,
                                main_table_name=main_table_name, module_type="workflow", to_file=to_file,
                                main_id=sort_id, collection_name="sg_denovo_kegg_pvalue")
        task_info = super(KeggRichRegulate, self).POST()
        return json.dumps(task_info)

    def check_options(self, data):
        """
        检查网页端传来的参数是否正确
        """
        params_name = ["analysis_type", "express_diff_id", "compare", "submit_location"]
        success = []
        for name in params_name:
            if not hasattr(data, name):
                success.append("缺少参数：%" % name)
        express_diff_id = str(data.express_diff_id)
        if not isinstance(express_diff_id, ObjectId) and not isinstance(express_diff_id, types.StringType):
            success.append("传入的express_diff_id:%不是一个ObjectId对象或字符串类型!" % express_diff_id)
        analysis_type = data.analysis_type
        if analysis_type not in ["enrich", "regulate", "both"]:
            success.append("%分析不存在" % analysis_type)
        if analysis_type in ["enrich", "both"]:
            for name in ["correct", "regulate"]:
                if not hasattr(data, name):
                    success.append("缺少参数:%" % name)
            if data.regulate not in ["up", "down", "all"]:
                success.append("上下调选择应为up/down/all")
        return success


pins.touch_set_mode(TouchTarget.P1, TouchTargetMode.CAPACITIVE)
pins.touch_set_mode(TouchTarget.P2, TouchTargetMode.CAPACITIVE)

is_pin1 = input.pin_is_pressed(TouchPin.P1)
is_pin2 = input.pin_is_pressed(TouchPin.P2)

start = False
not_pressed = True
player1 = False
player2 = False
Tie = False
jenoha = True

def on_forever():
    console.log_value("x", player1)
    global start, player1, player2, Tie
    basic.pause(randint(3000, 10000))
    start = True
    basic.show_icon(IconNames.HEART)
    music.play_tone(Note.C, 1000)
    while jenoha == True:
        pass

def on_pin_pressed_p1():
    global player1
    player1 = True
input.on_pin_pressed(TouchPin.P1, on_pin_pressed_p1)

def on_pin_pressed_p2():
    global player2
    player2 = True
input.on_pin_pressed(TouchPin.P2, on_pin_pressed_p2)

basic.forever(on_forever)

def run_parallel():
    if player1 == True and start == True:
        basic.show_number(1)
        basic.pause(3000)
        control.reset()

    elif player2 == True and start == True:
        basic.show_number(2)
        basic.pause(3000)
        control.reset()

    elif player1 == True and player2 and start == True:
        basic.show_string("R")
        basic.pause(3000)
        control.reset()

    elif player1 == True and start == False:
        basic.show_string("B")
        basic.pause(3000)
        control.reset()

    elif player2 == True and start == False:
        basic.show_string("A")
        basic.pause(3000)
        control.reset()
control.in_background(run_parallel)


#!/usr/bin/python3
import os
import flask
import argparse
import sys
import PIL.Image
import werkzeug.utils

app = flask.Flask("Picture factory app", static_folder=None)
cache = "cache/"

@app.route("/upload", methods = ['GET', 'POST'])
def upload():
    if flask.request.method == 'POST':
        os.system("rm -r cache/")
        os.system("mkdir cache/")

        f = flask.request.files['file']
        fname = werkzeug.utils.secure_filename(f.filename)
        sfName = os.path.join(cache, fname)
        if not sfName.endswith(".ogg"):
            f.save(sfName + "_tmp")
            os.system("ffmpeg -i '{}' '{}.ogg'".format(sfName + "_tmp", sfName))
            sfName += ".ogg"
        else:
            f.save(sfName)

        os.system("./audio_splitter.py --silence-padding 500 --silence-vol -50 --target-dir chunks {}".format(sfName))
        os.system("rm static/segments.zip")
        os.system("zip -r static/segments.zip cache")
        return flask.redirect("/segments.zip")

    return flask.render_template("upload.html")

@app.route("/segments.zip")
def segments():
    return flask.send_from_directory("static", "segments.zip")

@app.before_first_request
def init():
    app.config['MAX_CONTENT_PATH'] = 32+1000*1000
    app.config['UPLOAD_FOLDER']    = cache
    app.config['UPLOAD_ENABLED']   = os.path.isfile("./upload.enable")

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Audio-Splitter',
                        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    # general parameters #
    parser.add_argument("-i", "--interface", default="127.0.0.1", help="Interface to listen on")
    parser.add_argument("-p", "--port",      default="5000",      help="Port to listen on")

    # startup #
    args = parser.parse_args()
    app.run(host=args.interface, port=args.port)


class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

a=[2,3,4,5]
head = llist=ListNode(1)
for item in a:
    llist.next=ListNode(item)
    llist=llist.next

class Solution(object):
    def reorderList(self, head):
        """
        :type head: ListNode
        :rtype: None Do not return anything, modify head in-place instead.
        """
        if head.next==None:
            return head

        curr=self.reorderList(head.next)
        head.next=curr

        while curr.next:
            curr=curr.next

        curr.next=head
        root=head=curr
        while curr.next!=head:
            curr=curr.next
        curr.next=None
        return root

b=Solution()
b.reorderList(head)
# 4, 5   -> 5,4       #1,5,2,4,3
# 3, 5,4 -> 4,3,5
# 2, 4,3,5 -> 5,2,3,4  || 5,2,4,3
# 1, 5,2,3,4 -> 1,5,2,4,3


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

class PNGWrongHeaderError(Exception):
    """Exception, that says the input file is probably not PNG file."""
    pass

class PNGNotImplementedError(Exception):
    """Exception, that says the PNG image has a structure we cannot process."""
    pass

class PngReader():
    """Class for reading PNG images."""

    def __init__(self, filepath):
        """PNG reader class initialization."""
        # RGB-data from image as a list of rows,
        #   each row contains pixels - triplets of color values
        self.rgb = []

        # save the data from the file
        with open(filepath, mode='rb') as f:
            self.binary = f.read()

        self._save()

    def _check_png(self):
        """Checks, if it is PNG, strip the header."""
        if (self.binary[:8] != b'\x89PNG\r\n\x1a\n'):
            raise PNGWrongHeaderError()
        self.binary = self.binary[8:]
        return self

    def _bytes_to_num(self,bytes):
        """Convert several bytes to one number."""
        n = 0
        for b in bytes:
            n = n*256 + b
        return n

    def _parse_png(self):
        """From raw binary data, get chunks and save them. Deletes raw data."""
        self._check_png()
        p = 0
        self.data = []
        while p < len(self.binary):
            l = self._bytes_to_num(self.binary[p:p+4])
            p += 4

            self.data += [{'head':self.binary[p:p+4], 'data':self.binary[p+4:p+l+4]}]

            p += l+8
        del self.binary
        return self

    def _get_size(self):
        """Reads image width and height from IHDR. Also checks, if this image is supported."""
        for chunk in self.data:
            if (chunk['head'] == b'IHDR'):
                ihdr = chunk['data']
                break
        self.width = self._bytes_to_num(ihdr[0:4]);
        self.height = self._bytes_to_num(ihdr[4:8]);
        # check if this is the right type of PNG
        if self._bytes_to_num(ihdr[8:9]) != 8 \
        or self._bytes_to_num(ihdr[9:10]) != 2 \
        or self._bytes_to_num(ihdr[10:11]) != 0 \
        or self._bytes_to_num(ihdr[11:12]) != 0 \
        or self._bytes_to_num(ihdr[12:13]) != 0:
            raise PNGNotImplementedError()
        return self;

    def _get_idat(self):
        """Gets IDAT and decompresses it."""
        idat = b''
        for chunk in self.data:
            if (chunk['head'] == b'IDAT'):
                idat += chunk['data']

        return zlib.decompress(idat)

    def _plus(self,a,b):
        """Add two pixels together."""
        return ((a[0]+b[0])%256,(a[1]+b[1])%256,(a[2]+b[2])%256)

    def _paeth_predictor(self,a,b,c):
        """Peath predicator from W3C spec."""
        # a = left, b = above, c = upper left
        res = tuple()
        for i in range(0,3):
            p = (a[i]+b[i]-c[i]) # initial estimate
            pa = abs(p-a[i]) # distances to a, b, c
            pb = abs(p-b[i])
            pc = abs(p-c[i])

            # return nearest of a,b,c,
            # breaking ties in order a,b,c.
            if (pa <= pb and pa <= pc):
                res += (a[i],)
            elif (pb <= pc):
                res += (b[i],)
            else:
                res += (c[i],)
        return res

    def _save(self):
        """Main class method. It saves pixels to 2D array."""
        self._parse_png()._get_size()
        idat = self._get_idat()

        self.rgb = []
        p = 0
        for row in range(0,self.height):
            png_filter = idat[p]
            p += 1
            line = []
            left_pixel = (0,0,0) # when no such thing is, this should be used
            upleft_pixel = (0,0,0) # when no such thing is, this should be used
            for column in range(0,self.width):
                pixel = (idat[p],idat[p+1],idat[p+2])
                p += 3
                # http://www.w3.org/TR/PNG-Filters.html
                if (png_filter == 0):
                    # None
                    left_pixel = pixel
                    line += [pixel]
                elif (png_filter == 1):
                    # Sub
                    left_pixel = self._plus(left_pixel,pixel)
                    line += [left_pixel]
                elif (png_filter == 2):
                    # Up
                    left_pixel = self._plus(pixel,self.rgb[len(self.rgb)-1][column])
                    line += [left_pixel]
                #elif (png_filter == 3):
                    # Average (not used)
                elif (png_filter == 4):
                    # Paeth
                    up_pixel = self.rgb[len(self.rgb)-1][column]
                    current = self._plus(pixel,self._paeth_predictor(left_pixel,up_pixel,upleft_pixel))
                    line += [current]
                    left_pixel = current
                    upleft_pixel = up_pixel
            self.rgb += [line]

        return self

#
# just for testing
#
if __name__ == '__main__':
    PngReader('test_data/sachovnice_paleta.png')


import argparse
import init_paths
import os
from concern import webcv2
import numpy as np
import cv2
import tqdm
from PIL import Image

from detectron2.utils.logger import setup_logger
from detectron2.utils.visualizer import Visualizer
from slender_det.config import get_cfg
from slender_det.data import MetadataCatalog, build_detection_train_loader

def setup(args):
    cfg = get_cfg()
    if args.config_file:
        cfg.merge_from_file(args.config_file)
    cfg.merge_from_list(args.opts)
    cfg.freeze()
    return cfg

def parse_args(in_args=None):
    parser = argparse.ArgumentParser(description="Visualize ground-truth data")
    parser.add_argument("--config-file", metavar="FILE", help="path to config file")
    parser.add_argument("--show", action="store_true", help="show output in a window")
    parser.add_argument("--speed", action="store_true", help="test speed of the loader")
    parser.add_argument(
        "opts",
        help="Modify config options using the command-line",
        default=None,
        nargs=argparse.REMAINDER,
    )
    return parser.parse_args(in_args)

if __name__ == "__main__":
    args = parse_args()
    setup_logger(name="fvcore")
    setup_logger(name="slender_det")
    logger = setup_logger()
    logger.info("Arguments: " + str(args))
    cfg = setup(args)

    metadata = MetadataCatalog.get(cfg.DATASETS.TRAIN[0])

    def output(vis, fname):
        if args.show:
            print(fname)
            webcv2.imshow("window", vis.get_image()[:, :, ::-1])
            webcv2.waitKey()

    train_data_loader = build_detection_train_loader(cfg)
    import ipdb; ipdb.set_trace()
    for batch in tqdm.tqdm(train_data_loader):
        if args.speed:
            continue
        for per_image in batch:
            # Pytorch tensor is in (C, H, W) format
            img = per_image["image"].permute(1, 2, 0)
            if cfg.INPUT.FORMAT == "BGR":
                img = img[:, :, [2, 1, 0]]
            else:
                img = np.asarray(Image.fromarray(img, mode=cfg.INPUT.FORMAT).convert("RGB"))

            visualizer = Visualizer(img, metadata=metadata, scale=1.0)
            target_fields = per_image["instances"].get_fields()
            labels = [metadata.thing_classes[i] for i in target_fields["gt_classes"]]
            vis = visualizer.overlay_instances(
                labels=labels,
                boxes=target_fields.get("gt_boxes", None),
                masks=target_fields.get("gt_masks", None),
                keypoints=target_fields.get("gt_keypoints", None),
            )
            output(vis, str(per_image["image_id"]) + ".jpg")


#!/usr/bin/env python3

# this script changes the DEBUG constant in `eggnog.h`
# so we can have it in production mode but test in debug mode

import sys

if len(sys.argv) != 2:
	print('usage: ./debug.py COMMAND')
	print("available commands: [debug, undebug]")
	sys.exit(1)

file = 'src/eggnog.h'

cmd = sys.argv[1]

fp = open(file, 'rt')
data = fp.read()

if cmd == 'debug':
	print('\nSetting DEBUG mode\n')
	data = data.replace('#define DEBUG 0', '#define DEBUG 1')
elif cmd == 'undebug':
	print('Turning off DEBUG mode')
	data = data.replace('#define DEBUG 1', '#define DEBUG 0')
else:
	sys.exit(1)

fp.close()
fp = open(file, 'wt')
fp.write(data)
fp.close()


import os
from operator import add, sub

def parse_input() -> list[list[str]]:
    parsed_input = []
    with open(
        os.path.dirname(os.path.abspath(__file__)) + '/input.txt',
        'r',
        encoding='utf-8') as f:
        for line in f:
            parsed_input.append(line.strip().split())
    return parsed_input

def cmp(a: int, b: int) -> int:
    return (a > b) - (a < b)

def move_rope(rope: list[list[int]], direction: str, magnitude: int):
    _directions = {
        'U': [0, 1],
        'R': [1, 0],
        'D': [0, -1],
        'L': [-1, 0]
    }

    tail_positions = []
    for _ in range(magnitude):
        rope[0] = list(map(add, rope[0], _directions[direction]))

        for knot in range(1, len(rope)):
            rope[knot] = follow_leader(rope[knot], rope[knot - 1])
        tail_positions.append(tuple(rope[-1]))
    return rope, tail_positions

def follow_leader(follower: list[int],
                  leader: list[int]) -> list[int]:
    _distance = list(map(sub, leader, follower))

    # Movement of a trailing knot only happens to prevent
    # a discontinuity --- any case where there would be
    # an empty space between the leading and following
    # knots (distance = 2)
    if any(abs(elem) > 1 for elem in _distance):
        # we can get slightly larger diagonal jumps
        # in longer chains that complicates things a
        # little bit
        _signs = [cmp(val, 0) for val in _distance]
        _distance = [
            val + (_signs[idx] * -1)
            if abs(val) > 1 else val
            for idx, val in enumerate(_distance)
        ]

        follower = list(map(add, follower, _distance))
    return follower

def simulate(num_knots, parsed_input):
    # Simulation with a single tail knot
    tail_history = [(0, 0)]
    # Elem 0 is the head, elem 1 is the first knot, and so on
    knot_positions = [[0, 0]  for _ in range(1 + num_knots)]

    for instruction in parsed_input:
        knot_positions, _tail_movement = move_rope(
            knot_positions,
            instruction[0],
            int(instruction[1])
        )
        tail_history = tail_history + _tail_movement
    return tail_history

def main():
    parsed_input = parse_input()

    tail_history = simulate(1, parsed_input)
    print(len(set(tail_history)))

    tail_history = simulate(9, parsed_input)
    print(len(set(tail_history)))

if __name__ == '__main__':
    main()


import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import Input, Dense, GlobalMaxPooling2D
from tensorflow.keras.models import Model

def build_model():
    input_layer = Input(shape=(120, 120, 3))
    vgg = VGG16(include_top=False)(input_layer)
    vgg.trainable = False
    f1 = GlobalMaxPooling2D()(vgg)
    class1 = Dense(2048, activation='relu')(f1)
    class2 = Dense(1, activation='sigmoid')(class1)

    f2 = GlobalMaxPooling2D()(vgg)
    regress1 = Dense(2048, activation='relu')(f2)
    regress2 = Dense(4, activation='sigmoid')(regress1)

    return Model(inputs=input_layer, outputs=[class2, regress2])

def localization_loss(y_true, yhat):
    delta_coord = tf.reduce_sum(tf.square(y_true[:, :2] - yhat[:, :2]))

    h_true = y_true[:, 3] - y_true[:, 1]
    w_true = y_true[:, 2] - y_true[:, 0]

    h_pred = yhat[:, 3] - yhat[:, 1]
    w_pred = yhat[:, 2] - yhat[:, 0]

    delta_size = tf.reduce_sum(
        tf.square(w_true - w_pred) + tf.square(h_true-h_pred))

    return delta_coord + delta_size

class FaceDetection(Model):
    def __init__(self, facetracker):
        super().__init__()
        self.model = facetracker

    def compile(self, opt, classloss, localizationloss):
        super().compile()
        self.closs = classloss
        self.lloss = localizationloss
        self.opt = opt

    def train_step(self, batch):
        X, y = batch

        with tf.GradientTape() as tape:
            classes, coords = self.model(X, training=True)

            batch_classloss = self.closs(y[0], classes)
            batch_localizationloss = self.lloss(
                tf.cast(y[1], tf.float32), coords)

            total_loss = batch_localizationloss+0.5*batch_classloss
            grad = tape.gradient(total_loss, self.model.trainable_variables)

        self.opt.apply_gradients(zip(grad, self.model.trainable_variables))

        return {"total_loss": total_loss, "class_loss": batch_classloss, "regress_loss": batch_localizationloss}

    def test_step(self, batch):
        X, y = batch

        classes, coords = self.model(X, training=False)
        batch_classloss = self.closs(y[0], classes)
        batch_localizationloss = self.lloss(tf.cast(y[1], tf.float32), coords)
        total_loss = batch_localizationloss+0.5*batch_classloss

        return {"total_loss": total_loss, "class_loss": batch_classloss, "regress_loss": batch_localizationloss}

    def call(self, X):
        return self.model(X)