import os
from change_directory import directory
import re
import datetime
import pandas as pd
import numpy as np

class straddle_prepare:
    def __init__(self , current_day_options, tradinghour, d, delta_t, maturity_T):
        self.maturity_T = maturity_T
        self.d = d
        self.tradinghour = tradinghour
        self.currentDate = np.datetime64(d).astype(datetime.date)
        self.current_day_options = current_day_options
        self.project_dir = directory()
        self.dailyTradeTime = datetime.datetime.combine(self.currentDate, self.tradinghour)
        self.delayTradeTime = self.dailyTradeTime + datetime.timedelta(minutes=delta_t)
        self.previousTradeTime = self.dailyTradeTime - datetime.timedelta(minutes=delta_t)

    def get_maturity(self):
        date_distance = self.maturity_T
        current_day_options_by_mtr = self.current_day_options.groupby('Maturity')
        mtr_list = []
        for mtr in current_day_options_by_mtr.groups:
            mtr_list.append(mtr)
        mtr_list = sorted(mtr_list)
        secondMtrIndex = len(mtr_list) + 1
        for mtr_count in range(0, len(mtr_list)):
            if mtr_list[mtr_count] - self.currentDate > datetime.timedelta(days=date_distance):
                secondMtrIndex = mtr_count
                break
        if secondMtrIndex > len(mtr_list):
            firstMtr, secondMtr = 0, 0

        else:
            firstMtr = mtr_list[secondMtrIndex - 1]
            secondMtr = mtr_list[secondMtrIndex]
        return firstMtr, secondMtr

    def get_weight(self, firstMtr, secondMtr):
        first_ttm = (datetime.datetime.combine(firstMtr, datetime.time(8, 0, 0))
                     - self.dailyTradeTime).total_seconds() / (365 * 24 * 60 * 60)

        second_ttm = (datetime.datetime.combine(secondMtr, datetime.time(8, 0, 0))
                      - self.dailyTradeTime).total_seconds() / (365 * 24 * 60 * 60)
        # Linear weight:
        first_weight = ((self.maturity_T / 365) - second_ttm) / (first_ttm - second_ttm)
        second_weight = 1 - first_weight

        return first_weight,second_weight

    def get_ATM_strike(self, firstMtr, secondMtr, perp_underlying):
        mtr_options = self.current_day_options.groupby('Maturity')
        first_mtr_options = mtr_options.get_group(firstMtr)
        second_mtr_options = mtr_options.get_group(secondMtr)

        first_mtr_strikes = first_mtr_options['Strike']
        second_mtr_strikes = second_mtr_options['Strike']

        # Option files with certain maturity, strikes ready.
        common_strikes = list(set(first_mtr_strikes).intersection(second_mtr_strikes))
        ATM_strike = common_strikes[0]
        strike_diff = abs(ATM_strike - perp_underlying)
        for x in common_strikes:
            if abs(x - perp_underlying) < strike_diff:
                ATM_strike = x
                strike_diff = abs(x - perp_underlying)
        return ATM_strike

    def get_around_ATM_strike(self,strike_list, ATM_strike, around_number):
        max_list = [x for x in strike_list if x >ATM_strike]
        min_list = [x for x in strike_list if x <ATM_strike]
        max_list.sort()
        min_list.sort(reverse=True)
        final_list=max_list[0:around_number]
        final_list.append(ATM_strike)
        final_list.extend(min_list[0:around_number])
        return final_list

    def get_perp_price(self):
        perpListDir = self.project_dir.data_download(type='perpetual')
        perpDir = perpListDir+str(self.d).replace("-", "")+'_PERPETUAL.csv'
        perpFile = pd.read_csv(filepath_or_buffer=perpDir)
        perpTime = perpFile['Time']
        perpPrice = perpFile['Price']
        perpStartingTime = datetime.datetime.combine(self.currentDate, datetime.time(0, 0, 0))
        perp_count = 0
        for t in range(0, len(perpTime)):
            if perpStartingTime + datetime.timedelta(seconds=perpTime[t]) >= self.previousTradeTime:
                perp_count = t
                p_price = perpPrice[perp_count]
                while p_price == 0:
                    perp_count += 1
                    p_price = perpPrice[perp_count]
                break
        perp_underlying = perpPrice[perp_count]
        return perp_underlying

    def change_maturity(self,mtr):
        month_list = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
        mtr = re.split('([A-Z]+)', mtr)
        month = month_list.index(mtr[1]) + 1
        maturity = datetime.date(int(mtr[2]) + 2000, month, int(mtr[0]))
        return maturity

    def get_future_price(self):
        future_list_dir = self.project_dir.data_download(type = 'future')
        future_list = os.listdir(future_list_dir)
        current_day_future = []
        current_day_future_mtr = []
        for i in future_list:
            future_list_str = i.split('_')
            if future_list_str[0]  == str(self.d).replace("-", ""):
                current_day_future.append(i)
                mtr = self.change_maturity(future_list_str[1].split('.')[0])
                current_day_future_mtr.append(mtr)
        current_future_price = pd.Series(index= current_day_future_mtr)
        for future_count in range(len(current_day_future)):
            future_file = pd.read_csv(filepath_or_buffer= future_list_dir + current_day_future[future_count])
            future_time = future_file['Time']
            future_price = future_file['Price']
            future_startingtime = datetime.datetime.combine(self.currentDate, datetime.time(0, 0, 0))
            t_count = 0
            for t in range(0,len(future_time)):
                if future_startingtime + datetime.timedelta(seconds=future_time[t]) >= self.previousTradeTime:
                    t_count = t
                    f_price = future_price[t_count]
                    while f_price == 0:
                        t_count += 1
                        f_price = future_price[t_count]
                    break
            current_future_price[current_day_future_mtr[future_count]] = future_price[t_count]
        return current_future_price

    def outer_interpolation(self,mtr1,mtr2,price1,price2,t_mtr):
        t_price = price2 + (price2 - price1) * (t_mtr - mtr2) / (mtr2 - mtr1)
        return t_price

    def calculate_ttm(self,mtr):
        ttm = (datetime.datetime.combine(mtr, datetime.time(8, 0, 0)) - self.dailyTradeTime).total_seconds() / (
                        365 * 24 * 60 * 60)
        return ttm

    def get_bid_ask_price(self, strike, maturity, file):
        # if strike ==0, search by file , else search by strike and maturity.
        d_bid, d_ask = [], []
        if strike != 0 or maturity != 0:
            mtr_options = self.current_day_options.groupby('Maturity')
            first_mtr_options = mtr_options.get_group(maturity)
            first_options = first_mtr_options.groupby('Strike').get_group(strike)
            first_options = first_options.sort_values(by='CallPut')
            file = first_options['File']
        for f in file:
            optionListDir = self.project_dir.data_download(type='option')
            data_1_dir = optionListDir + f
            data_1 = pd.read_csv(filepath_or_buffer=data_1_dir)
            data_1_time = data_1['Time']
            data_1_bid = data_1['Bid_1_Price']
            data_1_ask = data_1['Ask_1_Price']
            option_count = 0
            for t_count in range(0, len(data_1_time)):
                if data_1_time[t_count] == '0':
                    break
                t = datetime.datetime.strptime(data_1_time[t_count], "%Y/%m/%d-%H:%M:%S.%f")
                if t_count < 5 and t > self.delayTradeTime:
                    continue
                if t <= self.previousTradeTime:
                    option_count = t_count
                else:
                    break
            b_price = data_1_bid[option_count]
            a_price = data_1_ask[option_count]

            if b_price == 0:
                for t_count in range(option_count, len(data_1_time)):
                    if data_1_time[t_count] == '0':
                        break
                    t = datetime.datetime.strptime(data_1_time[t_count], "%Y/%m/%d-%H:%M:%S.%f")
                    if data_1_bid[t_count] != 0 and t <= self.delayTradeTime:
                        b_price = data_1_bid[t_count]
                        break
            if a_price == 0:
                for t_count in range(option_count, len(data_1_time)):
                    if data_1_time[t_count] == '0':
                        break
                    t = datetime.datetime.strptime(data_1_time[t_count], "%Y/%m/%d-%H:%M:%S.%f")
                    if data_1_ask[t_count] != 0 and t <= self.delayTradeTime:
                        a_price = data_1_ask[t_count]
                        break
            start_t = datetime.datetime.strptime(data_1_time[option_count], "%Y/%m/%d-%H:%M:%S.%f")
            if option_count == 0 and (start_t < self.previousTradeTime or start_t > self.delayTradeTime):
                b_price = 0
                a_price = 0
            if b_price == 0 or a_price == 0:
                print('@ ', self.delayTradeTime, ': ', f, '>>>Not Available!')
            d_bid.append(b_price)
            d_ask.append(a_price)
        return d_bid,d_ask

    def get_mid_price(self, bid_price, ask_price):
        if bid_price == 0 or ask_price == 0:
            mid_price = 0
        else:
            mid_price = (bid_price+ask_price)/2
        return mid_price

    def get_signal_pos(self, net_pos, new_delta, past_delta, change_contract):
        new_net_pos = net_pos
        signal = "hold"
        if net_pos == 0 and new_delta > 0.1:
            new_net_pos = 1
            signal = "long"
        elif net_pos == 1 and change_contract :
            if past_delta < 0:
                new_net_pos = 0
                signal = 'clean'
                if new_delta > 0.1:
                    new_net_pos = 1
                    signal = 'clean_long'
        elif net_pos == 1 and not change_contract:
            new_net_pos = 0
            signal = 'clean'
            if new_delta > 0.1:
                new_net_pos = 1
                signal = 'clean_long'
        return new_net_pos, signal

    def get_hedge_signal(self, past_delta, change_contract):
        if abs(past_delta) > 0.2 or not change_contract :
            signal = 'clean_short'
        else:
            signal = 'hold'
        return signal

    def calculate_cash(self, daily_1_bid, daily_1_ask, daily_2_bid, daily_2_ask, w1, w2, buy_or_sell):
        # if buy_or_sell=0 means buy
        if buy_or_sell == 0:
            cash = - (w1*(sum(daily_1_bid)+sum(daily_1_ask))/2+w2*(sum(daily_2_bid)+sum(daily_2_ask))/2)
        else:
            cash = (w1 * (sum(daily_1_bid) + sum(daily_1_ask)) / 2 + w2 * (sum(daily_2_bid) + sum(daily_2_ask)) / 2)
        return cash

    def get_all_options_info(self):
        firstMtr, secondMtr = self.get_maturity()
        first_weight, second_weight = self.get_weight(firstMtr, secondMtr)
        ATM_strike = self.get_ATM_strike(firstMtr,secondMtr,self.get_perp_price())
        return [first_weight, second_weight, ATM_strike, firstMtr, secondMtr]

class option_data:
    def __init__(self):
        self.project_dir = directory()

    def get_perp_date_list(self):
        perpListDir = self.project_dir.data_download(type='perpetual')
        perpList = os.listdir(perpListDir)
        dateList = []
        for f in perpList:
            f_date = re.split('_', f)
            date = datetime.datetime.strptime(f_date[0], "%Y%m%d").date()
            dateList.append(date)
        return dateList

    def get_option_df(self):
        month_list = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
        option_listdir = self.project_dir.data_download(type='option')
        option_list = os.listdir(option_listdir)

        option_date_list, option_maturity_list, option_strike_list, option_call_put_list, option_maturity_month_list \
            = [], [], [], [], []
        for f in option_list:
            f_date = re.split('_', f)
            date = datetime.datetime.strptime(f_date[0], "%Y%m%d").date()
            option_date_list.append(date)
            mtr = re.split('([A-Z]+)', f_date[1])
            month = month_list.index(mtr[1]) + 1
            maturity = datetime.date(int(mtr[2]) + 2000, month, int(mtr[0]))
            strike = int(f_date[2])
            call_put = re.split('([C,P])', f_date[3])[1]
            option_maturity_list.append(maturity)
            option_maturity_month_list.append(maturity.month)
            option_strike_list.append(strike)
            option_call_put_list.append(call_put)
        option_file = {'Date': option_date_list, 'Maturity': option_maturity_list,
                       'MaturityMonth': option_maturity_month_list, 'Strike': option_strike_list,
                       'CallPut': option_call_put_list, 'File': option_list}
        option_file_df = pd.DataFrame(option_file)
        return option_file_df

    def calculate_return(self, daily1_sell_price, daily2_sell_price, pre_daily1_buy_price, pre_daily2_buy_price, w1, w2):
        daily_return = w1 * (daily1_sell_price-pre_daily1_buy_price)+w2*(daily2_sell_price-pre_daily2_buy_price)
        return daily_return

    def trade_cost(self, bid_price, ask_price, quantity, buy_or_sell):
        # buy_or_sell =0 means buy
        if buy_or_sell == 0:
            cost = (sum(ask_price) - (sum(bid_price)+sum(ask_price))/2)*quantity
        else:
            cost = ((sum(bid_price)+sum(ask_price))/2 - sum(bid_price))*quantity
        return cost


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

n = num = int(input('请输入一个数字：'))
list = []  # 存放质因数

for j in range(int(num / 2) + 1):  # 判断次数仅需该数字的一半多1次
    for i in range(2, n):
        t = n % i  # i不能是n本身
        if t == 0:  # 若能整除
            list.append(i)  # 则表示i是质因数
            n =int(n / i)   # 除以质因数后的n重新进入判断，注意应用两个除号，使n保持整数
            break  # 找到1个质因数后马上break，防止非质数却可以整除的数字进入质因数列表

if len(list) == 0:  # 若一个质因数也没有
    print('该数字没有任何质因数。')
else:  # 若至少有一个质因数
    list.append(n)  # 此时n已被某个质因数整除过，最后一个n也是其中一个质因数
    list.sort()  # 排下序
    print('%d=%d' % (num, list[0]), end='')
    for i in range(1, len(list)):
        print('*%d' % list[i], end='')


import glob, os
import numpy as np
import matplotlib
import datetime
#matplotlib.use('Agg')
import matplotlib.pyplot as plt

os.chdir("./")

for file in glob.glob("*.data"):
    with open(file) as inp:
        currentData = list(zip(*(line.split('\t') for line in inp)))
        timestamp = np.array([datetime.datetime.strptime(timestamp_string, '%H:%M:%S.%f') for timestamp_string in currentData[0]])
        #print(timestamp)
        volt = np.array([float(numeric_string) for numeric_string in currentData[1]])
        #print(volt)
        current = np.array([float(numeric_string) for numeric_string in currentData[2]])
        voltmeter = np.array([float(numeric_string) for numeric_string in currentData[3]])
        plt.plot(volt, timestamp, color='b', label='volt')
        plt.plot(current, timestamp, color='r', label='current')
        plt.plot(voltmeter, timestamp, color='g', label='volt/meter')
        plt.title(os.path.splitext(file)[0])
        plt.legend()
        #plt.show()
        plt.savefig(os.path.splitext(file)[0]+".png", bbox_inches='tight')
        plt.close()


import heapq
import sys
cnt = int(input())
heap=[]
for _ in range(cnt):
    n = int(sys.stdin.readline())
    if n!=0:
        heapq.heappush(heap, n)
    else:
        if not heap:
            print(0)
        else:
            print(heapq.heappop(heap))


"""
Max & Bouke Data Processing script
Based on Chao old script

Tip: 'SHIFT + ALT + F' --> Format JSON
"""

from __future__ import division
import json
import math
import csv
import os
from scipy.spatial import distance
import numpy as np
from numpy import trapz
from scipy.integrate import simps
import matplotlib.pyplot as plt

def line(p1,p2):
	A = (p1[1] - p2[1])
	B = (p2[0] - p1[0])
	C = (p1[0]*p2[1] - p2[0]*p1[1])
	return A,B,-C

def intersection(L1, L2):
	D  = L1[0]*L2[1] - L1[1]*L2[0]
	Dx = L1[2]*L2[1] - L1[1]*L2[2]
	Dy = L1[0]*L2[2] - L1[2]*L2[0]
	if D != 0:
		x = Dx / D
		y = Dy / D
		return x,y
	else:
		return False

def find_nearest(array, value):
	idx = (np.abs(array-value)).argmin()
	if array[idx] - value == 0:
		return ([idx])
	elif array[idx] - value < 0:
		return ([idx, idx+1])
	else:
		return ([idx-1, idx])

def get_second(s, ftr = [3600,60,1]):
	return sum([a*b for a,b in zip(ftr, map(float, s.split(':')))])

def get_parameters(m=""):# m for naming keys
	# for parameters below, only include trials with more than 10 points (at least 5 unique points) and when there was no touch_up in the middle of the trial (participant did not realse finger)
	if len(df_choice[i]["coor"+m]) > 0:
		#recode time into 101 time bins and coor to [0,0] at start and [1,1] at end
		timestamp = []
		temp_time = []
		coor_ab = []
		for j in d["time"+m]:
			temp_time.append(j)
		timestamp = np.linspace(temp_time[0], temp_time[-1], num=101)
		d["timestamp"] = timestamp
		start = [d["coor"+m][0][0], d["coor"+m][0][1]]
		end = [d["coor"+m][-1][0], d["coor"+m][-1][1]]
		for c in range(len(d["timestamp"])):
			idx = find_nearest(d["time"+m], d["timestamp"][c])
			if (len(idx) == 1) or (d["time"+m][idx[1]] - d["time"+m][idx[0]] == 0):

				if (end[0] - start[0]) == 0 or (end[1] - start[1]) == 0:
					end[0] = 1
					end[1] = 1
					print("x_dif: ", start[1] -end[1], "y_dif: ", start[1] -end[1], "x_y_end: ", end, "x_y_start: ", start)
					coor = [1,1]
				else:
					coor = [(d["coor"+m][idx[0]][0] - start[0]) / (end[0] - start[0]), (d["coor"+m][idx[0]][1] - start[1]) / (end[1] - start[1])]
			else:
				prop = (d["timestamp"][c] - d["time"+m][idx[0]]) / (d["time"+m][idx[1]] - d["time"+m][idx[0]])
				x_temp = d["coor"+m][idx[0]][0] + (d["coor"+m][idx[1]][0] - d["coor"+m][idx[0]][0]) * prop
				y_temp = d["coor"+m][idx[0]][1] + (d["coor"+m][idx[1]][1] - d["coor"+m][idx[0]][1]) * prop
				coor = [(x_temp - start[0]) / (end[0] - start[0]), (y_temp - start[1]) / (end[1] - start[1])]
			coor_ab.append(coor)
		d["coor_ab"+m] = coor_ab

		# separate x and y values
		if d["coor"+m] != []:
			for j in d["coor"+m]:
				d["coor_x"+m].append(j[0])
				d["coor_y"+m].append(j[1])
			for j in d["coor_ab"+m]:
				d["coor_x_ab"+m].append(j[0])
				d["coor_y_ab"+m].append(j[1])
				if d["resp"] != "":
					if d["resp"] == d["stim"][0]:
						d["coor_x_ab_direction"+m].append(-j[0])
					else:
						d["coor_x_ab_direction"+m].append(j[0])
				else:
					d["coor_x_ab_direction"+m].append(j[0])
				d["coor_y_ab_direction"+m].append(j[1])

		# max deviation
		deviation = []
		R = []
		L1 = line(d["coor_ab"+m][-1], d["coor_ab"+m][0])
		x1, y1 = d["coor_ab"+m][-1]
		x2, y2 = d["coor_ab"+m][0]
		k1 = (y1 - y2) / (x1 - x2)
		for j in d["coor_ab"+m]:
			x0, y0 = j
			k2 = -k1
			b2 = y0 - k2 * x0
			L2 = line([x0, y0], [0, b2])
			r = intersection(L1, L2)
			R.append(r)
			dst = distance.euclidean(j ,r)
			if r != False:
				#only calculate the bulge ones
				if r[1] > y0:
					dst = dst * (-1)
			deviation.append(dst)
		MD = max(deviation)
		idx_MD = deviation.index(MD)
		d["MD"+m] = MD
		d["y_MD"+m] = d["coor_ab"+m][idx_MD][1]
		d["intersection_point"] = R[idx_MD]

		# min_distance (minimum distance to the unchosen option)
		dst_to_unchosen = []
		for j in d["coor_ab"+m]:
			target = [-1, 1]
			dst = distance.euclidean(j, target)
			dst_to_unchosen.append(dst)
		min_distance = min(dst_to_unchosen)
		d["min_distance"+m] = min_distance

		# number of choice commitments
		AOI = []
		L1_L = line([-1, 0], [0, 1])
		L1_R = line([1, 0], [0, 1])
		k_L = -1
		k_R = 1
		for j in d["coor_ab"+m]:
			x0, y0 = j
			if x0 > 0:
				b2 =  y0 - k_R * x0
				L2 = line(j, [0, b2])
				r = intersection(L1_R, L2)
				#print(r)
				if r != False:
					if r[1] < y0:
						AOI.append(1)
					else:
						AOI.append(0)
				else:
					AOI.append(0)
			elif x0 < 0:
				b2 = y0 - k_L * x0
				L2 = line(j, [0, b2])
				r = intersection(L1_L, L2)
				#print(r)
				if r != False:
					if r[1] < y0:
						AOI.append(-1)
					else:
						AOI.append(0)
				else:
					AOI.append(0)
			else:
				AOI.append(0)
		count = 0
		for j in range(len(AOI)-1):
			count += abs(AOI[j+1] - AOI[j])
		commitment = (count + 1) / 2
		d["commitment"+m] = commitment

		# complexity on x-direction and y-direction
		seq_x = [d["coor"+m][0][0]]
		seq_y = [d["coor"+m][0][1]]
		delta_x = []
		delta_y = []
		for j in range(len(d['coor'+m])-1):
			delta_x.append(d['coor'+m][j+1][0] - d['coor'+m][j][0])
			delta_y.append(d['coor'+m][j+1][1] - d['coor'+m][j][1])
		for j in range(len(delta_x)-1):
			if delta_x[j] == 0:
				k = j - 1
				while k >= 0:
					if delta_x[k] != 0:
						if delta_x[k] > 0:
							delta_x[j] = 0.0001
						elif delta_x[k] < 0:
							delta_x[j] = -0.0001
						break
					k -= 1
			if delta_y[j] == 0:
				k = j - 1
				while k >= 0:
					if delta_y[k] != 0:
						if delta_y[k] > 0:
							delta_y[j] = 0.0001
						elif delta_y[k] < 0:
							delta_y[j] = -0.0001
						break
					k -= 1
		for j in range(len(delta_x)-1):
			product_x = delta_x[j] * delta_x[j+1]
			product_y = delta_y[j] * delta_y[j+1]
			if product_x < 0:
				seq_x.append(d['coor'+m][j+1][0])
			if product_y < 0:
				seq_y.append(d['coor'+m][j+1][1])
		seq_x.append(d['coor'+m][-1][0])
		seq_y.append(d['coor'+m][-1][1])
		distance_x = []
		distance_y = []
		for j in range(len(seq_x)-1):
			distance_x.append(seq_x[j+1] - seq_x[j])
		for k in range(len(seq_y)-1):
			distance_y.append(seq_y[k+1] - seq_y[k])
		d['x_flip'+m] = len(distance_x) - 1
		d['y_flip'+m] = len(distance_y) - 1
		d['distance_x'+m] = distance_x
		d['distance_y'+m] = distance_y

		#velocity relative location/ms & acceleration relative location/(ms*ms)
		velocity = []
		acceleration = []
		abs_acce = []
		v_time = []
		acce_time = []
		for j in range(len(d['coor_ab'+m])-1):
			v = distance.euclidean(d['coor_ab'+m][j],d['coor_ab'+m][j+1])/(abs(d['timestamp'][j]-d['timestamp'][j+1])*1000)
			v_time.append(d['timestamp'][j+1]*1000)
			velocity.append(v)

		for n in range(len(velocity)-1):
			acce = (velocity[n+1]-velocity[n])/((d['timestamp'][n+2]-d['timestamp'][n+1])*1000)
			acce_time.append(d['timestamp'][n+2]*1000)
			acceleration.append(acce)

		max_velocity = max(velocity)
		d['max_velocity'+m] = max_velocity
		for j in acceleration:
			abs_acce.append(abs(j))
		max_acceleration = max(abs_acce)
		d['max_acceleration'+m] = max_acceleration

		# AUC
		dx = d['timestamp'][1] - d['timestamp'][0]
		y_coors = []
		x_coors = []
		for j in range(len(d['coor_ab'+m])):
			ycoord = d['coor_ab'+m][j][0]
			x_coors.append(ycoord)
			ycoord = d['coor_ab'+m][j][1]
			y_coors.append(ycoord)
		d['AUC'+m] = trapz(y_coors, x_coors)

		# instaneous movement angles
		d["IMA"+m] = []
		for j in range(len(d['coor_ab'+m])-1):
			x_change = d['coor_x_ab_direction'+m][j+1] - d['coor_x_ab_direction'+m][j]
			y_change = d['coor_y_ab_direction'+m][j+1] - d['coor_y_ab_direction'+m][j]
			if x_change != 0 or y_change != 0:
				IMA_temp = math.atan2(x_change, y_change) * 180 / math.pi
				if abs(IMA_temp) > 90:
					if IMA_temp < 0:
						IMA_temp += 180
					else:
						IMA_temp -= 180
				IMA_current = abs(IMA_temp) * np.sign(x_change)
			else:
				IMA_current = -1
			d["IMA"+m].append(IMA_current)

		# angles from the origin (as computed in Sullivan (2015)'s)
		d["angle"+m] = []
		for j in range(len(d['coor_ab'+m])):
			angle_temp = math.atan2(d["coor_x_ab_direction"+m][j], d["coor_y_ab_direction"+m][j]) * 180 / math.pi
			if abs(angle_temp) > 90:
				if angle_temp < 0:
					angle_temp += 180
				else:
					angle_temp -= 180
			angle_current = abs(angle_temp) * np.sign(d["coor_x_ab_direction"+m][j])
			d["angle"+m].append(angle_current)

	else: # empty placeholders
		d["coor_ab"+m] = []
		d["MD"+m] = -1
		d["y_MD"+m] = -1
		d["commitment"+m] = -1
		d["min_distance"+m] = -1
		d["x_flip"+m] = -1
		d["y_flip"+m] = -1
		d["distance_x"+m] = []
		d["distance_y"+m] = []
		d["max_velocity"+m] = -1
		d["max_acceleration"+m] = -1
		d["AUC"+m] = -1
		d["IMA"+m] = []
		d["angle"+m] = []

food_list = ["Sushi", "Chips", "Banana", "Pear", "Radish", "Bell pepper", "Donuts", "Mars", "French fries", "KinderBueno"]

abs_path = "C:\\Users\\bouke\\Documents\\GitHub\\DataAnalysis\\"
par_path = abs_path + "Participant\\"
## save data as CSV file
f = csv.writer(open(abs_path + "data_merged.csv", "w"), delimiter=";")

f.writerow(["ppn", "condition", "age", "gender", "length", "weight", "hand", "diet", "diet_text", "allergies", "allergies_text", "goal_health", "hunger", "vegan",
		"tsc1", "tsc2", "tsc3", "tsc4", "tsc5", "tsc6", "tsc7", "tsc8", "tsc9", "tsc10", "tsc11", "tsc12", "tsc13",
		"trial_NO", "trial_block",
		#"nudging_direction",
		"recommendation",
		"stim", "stim_L", "stim_R", "health_L","taste_L","health_R","taste_R", "choice", "direction",
		"AUC", "MD", "y_MD", "commitment", "min_distance", "max_velocity", "max_acceleration", "x_flip", "distance_x", "y_flip", "distance_y", "RT", "drag_time", "hold_time", "angle", "IMA",
		"coor_x", "coor_y", "coor_x_ab", "coor_y_ab", "coor_x_ab_direction", "coor_y_ab_direction", "AUC2", "MD2", "y_MD2", "commitment2", "min_distance2", "max_velocity2", "max_acceleration2", "x_flip2", "distance_x2", "y_flip2", "distance_y2",
		"drag_time2", "hold_time2", "angle2", "IMA2", "coor_x2", "coor_y2", "coor_x_ab2", "coor_y_ab2", "coor_x_ab_direction2", "coor_y_ab_direction2", "events"])

## load data
os.chdir(par_path)

for folder in os.listdir(par_path): # go through participants/folders, folder = pXX (ex. p01)
	print(folder) # folder = participant
	#if folder != "p16":
	#	continue
	os.chdir(par_path + folder)

	if os.path.isdir(par_path + folder + '\\plots\\') == False: # make plot folder if none
		os.makedirs(par_path + folder + '\\plots\\')

	with open(folder+"_rating.json") as json_data: # Rating
		df_rating = json.load(json_data)

	with open(folder+"_survey.json") as json_data: # Survey
		df_survey = json.load(json_data)

	with open(folder+"_choice_up.json") as json_data: # Base
		df_choice_base = json.load(json_data)

	with open(folder+"_choice_up_B.json") as json_data: # Text
		df_choice_text = json.load(json_data)

	with open(folder+"_choice_up_A.json") as json_data: # Cursor
		df_choice_cursor = json.load(json_data)

	# dict creates dictionary
	df_choice = dict(df_choice_base, **df_choice_text) # some variables in mouse session are overrided by the same variables in touch session (logout, login, instruction and practice?)
	df_choice = dict(df_choice, **df_choice_cursor)
	#print(df_choice)

	condition = 0 # UPDATE

	## extract MT parameters based on the event-tracking
	for i in df_choice.keys():

		if not i.find("trial_") != -1: # if no trial go back and continue loop, filters for practice, instruction, logout and login
			continue

		# Then i = trial_Baseline/Cursor/Text_XX (ex. trial_Baseline_47)

		d = df_choice[i] # d is 1 trial, also make d if it does not exist
		trial_no = int(i[i.rfind("_")+1:]) # get trial number after "trial_"

		# if d["time2"] != []: # check if time2
		for k in range(len(d["time2"])):
			d["time2"][k] = get_second(d["time2"][k])  # convert to seconds

		# RT (time between screens)
		#if d["leave_time"] != "": # check if leave time
		# if trial_no != 0:

		d["RT"] = get_second(d["leave_time"]) - get_second(df_choice[i[0:i.rfind("_")+1]+str(trial_no)]["leave_time"])

		# else: # for instruction trials
		# 	if i.find("mouse") != -1:
		# 		d["RT"] = get_second(d["leave_time"]) - get_second(df_choice_mouse["instruction_trial"]["leave_time"])
		# 	else:
		# 		d["RT"] = get_second(d["leave_time"]) - get_second(df_choice_touch["instruction_trial"]["leave_time"])
		#else:
		#	d["RT"] = -1

		# run the get_parameters function to extract parameters based on both tracking methods
		d["coor_x"] = []
		d["coor_y"] = []
		d["coor_x_ab"] = []
		d["coor_y_ab"] = []
		d["coor_x_ab_direction"] = []
		d["coor_y_ab_direction"] = []
		d["coor_x2"] = []
		d["coor_y2"] = []
		d["coor_x_ab2"] = []
		d["coor_y_ab2"] = []
		d["coor_x_ab_direction2"] = []
		d["coor_y_ab_direction2"] = []
		get_parameters(m="")
		get_parameters(m="2")

		## additional variables
		# choice direction
		# if d["resp"] != "": # check if response
		if d["resp"] == d["stim"][0]: # if food number == left food number
			d["direction"] = "Left"
		else:
			d["direction"] = "Right"
		#else:
		#	d["direction"] = ""

		if "recommendation" in d:
			# recode nudging direction
			if d["recommendation"] == 0:
				d["recommendation"] = "Left"
			elif d["recommendation"] == 1:
				d["recommendation"] = "Right"
		else:
			d["recommendation"] = ""

		# other choice variables
		d["taste_L"] = -1
		d["health_L"] = -1
		d["taste_R"]  = -1
		d["health_R"] = -1
		if d["stim"] != "":
			index_L = d["stim"][0]
			index_R = d["stim"][1]
			if index_L != "f":
				d["stim_L"] = food_list[int(index_L)]
			else:
				d["stim_L"] = "Filler"
			if index_R != "f":
				d["stim_R"] = food_list[int(index_R)]
			else:
				d["stim_L"] = "Filler"
			if d["direction"] == "Left":
				d["choice"] = d["stim_L"]
			else:
				d["choice"] = d["stim_R"]

			# ratings
			for j in df_rating.keys():
				if j.find("rating") != -1:
					e = df_rating[j]
					if e["stim"] == str(index_L):
						d["taste_L"] = int(e["ratingT"])
						d["health_L"] = int(e["ratingH"])
					if e["stim"] == str(index_R):
						d["taste_R"] = int(e["ratingT"])
						d["health_R"] = int(e["ratingH"])
		else:
			d["stim_L"] = ""
			d["stim_R"] = ""
			d["choice"] = ""

		trial_block = i[i.find("_")+1:i.rfind("_")]

		# dragging time
		#if d["time"] != []: # check if time
		d["drag_time"] = d['time'][-1] - d['time'][0]
		d["hold_time"] = d["time"][1] - d["time"][0]
		d["drag_time2"] = d["time2"][-1] - d["time2"][0]

		for k in range(1, len(d["coor2"])):
			if d["coor2"][k][0] != d["coor2"][k-1][0] or d["coor2"][k][1] != d["coor2"][k-1][1]:
				break

		d["hold_time2"] = d["time2"][k] - d["time2"][0]

		# else:
		# 	d["drag_time"] = -1
		# 	d["hold_time"] = -1
		# 	d["drag_time2"] = -1
		# 	d["hold_time2"] = -1

		## write data
		f.writerow([folder, condition, df_survey["survey1"]["age"], df_survey["survey1"]["gender"], df_survey["survey1"]["length"], df_survey["survey1"]["weight"], df_survey["survey1"]["hand"],
			df_survey["survey2"]["diet"], df_survey["survey2"]["dietText"], df_survey["survey2"]["allergies"], df_survey["survey2"]["allergiesText"],
			df_survey["survey3"]["health"], df_survey["survey3"]["hunger"], df_survey["survey3"]["vegan"],
			df_survey["tsc1"]["Q1"], df_survey["tsc1"]["Q2"], df_survey["tsc1"]["Q3"], df_survey["tsc1"]["Q4"],
			df_survey["tsc2"]["Q1"], df_survey["tsc2"]["Q2"], df_survey["tsc2"]["Q3"], df_survey["tsc2"]["Q4"],
			df_survey["tsc3"]["Q1"], df_survey["tsc3"]["Q2"], df_survey["tsc3"]["Q3"], df_survey["tsc3"]["Q4"],
			df_survey["tsc4"]["Q1"],
			trial_no, trial_block,
			#d["nudge"], d["nudgeDirection"],
			d["recommendation"],
			d["stim"], d["stim_L"], d["stim_R"], d["health_L"], d["taste_L"], d["health_R"], d["taste_R"], d["choice"], d["direction"],
			d["AUC"], d["MD"], d["y_MD"], d["commitment"], d["min_distance"], d["max_velocity"], d["max_acceleration"], d["x_flip"], d["distance_x"], d["y_flip"], d["distance_y"], d["RT"], d["drag_time"], d["hold_time"], d["angle"], d["IMA"],
			d["coor_x"], d["coor_y"], d["coor_x_ab"], d["coor_y_ab"], d["coor_x_ab_direction"], d["coor_y_ab_direction"], d["AUC2"], d["MD2"], d["y_MD2"], d["commitment2"], d["min_distance2"], d["max_velocity2"], d["max_acceleration2"], d["x_flip2"], d["distance_x2"], d["y_flip2"],
			d["distance_y2"], d["drag_time2"], d["hold_time2"], d["angle2"], d["IMA2"], d["coor_x2"], d["coor_y2"], d["coor_x_ab2"], d["coor_y_ab2"], d["coor_x_ab_direction2"], d["coor_y_ab_direction2"], d["events"]])

		## make the plots
		plt.scatter(d['coor_x'], d['coor_y'], color="b")
		plt.scatter(d['coor_x_ab'], d['coor_y_ab'], color='r')
		plt.scatter(d['coor_x2'], d['coor_y2'], color="b", marker='+')
		plt.scatter(d['coor_x_ab2'], d['coor_y_ab2'], color='r', marker='+')

		plt.text(0.7, 0.15, s='AUC = '+str(round(d["AUC"], 2))+"/"+str(round(d["AUC2"], 2)))
		plt.text(0.7, 0.1, s='MD = '+str(round(d["MD"], 2))+"/"+str(round(d["MD2"], 2)))
		plt.text(0.7, 0.05, s='x-flip = '+str(round(d["x_flip"], 1))+"/"+str(round(d["x_flip2"], 1)))
		plt.text(0.7, 0, s='drag_time = '+str(round(d["drag_time"], 2))+"/"+str(round(d["drag_time2"], 2)))
		plt.text(0.7, -0.05, s='commitment = '+str(round(d["commitment"], 1))+"/"+str(round(d["commitment2"], 1)))
		plt.text(0.7, -0.1, s='min_distance = '+str(round(d["min_distance"], 2))+"/"+str(round(d["min_distance2"], 2)))

		plt.savefig(par_path + folder + '\\plots\\' + i +".png")
		plt.close()


import os
from aws_cdk import (
    Duration,
    CfnTag,
    Stack,
    CustomResource,
    CfnParameter,
    CfnCondition,
    Fn,
    Aws,
    aws_cloud9 as cloud9,
    aws_ssm as ssm,
    aws_lambda as lambda_,
    aws_iam as iam,
)
from constructs import Construct

class MainStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        c9 = cloud9.CfnEnvironmentEC2(self,'MyCfnEnvironmentEC2',
            instance_type='m4.large',
            automatic_stop_time_minutes=120,
            image_id='ubuntu-18.04-x86_64',
            name='Demo SOAFEE AWS IoT Fleetwise',
            description='Demo SOAFEE AWS IoT Fleetwise',
            repositories=[
                cloud9.CfnEnvironmentEC2.RepositoryProperty(
                    path_component='/demo-soafee-aws-iotfleetwise',
                    repository_url='https://github.com/aws-samples/demo-soafee-aws-iotfleetwise.git')],
            tags=[CfnTag(key='SSMBootstrap', value='Active')]
        )

        lambda_role = iam.Role(self, 'LambdaRole',
            assumed_by =iam.ServicePrincipal('lambda.amazonaws.com'),
            managed_policies=[
                iam.ManagedPolicy.from_aws_managed_policy_name('service-role/AWSLambdaBasicExecutionRole'),
                iam.ManagedPolicy.from_aws_managed_policy_name('AdministratorAccess')
            ]
        )

        with open(os.path.join(os.path.dirname(__file__), 'lambda.py'), encoding='utf8') as fp:
            handler_code = fp.read()

        on_event_fn = lambda_.Function(self, 'SetInstanceProfileLambda',
            code=lambda_.InlineCode(handler_code),
            handler='index.on_event',
            timeout=Duration.seconds(300),
            runtime=lambda_.Runtime.PYTHON_3_9,
            role=lambda_role
        )

        c9_role = iam.Role(self, 'C9Role',
            assumed_by =iam.ServicePrincipal('ec2.amazonaws.com'),
            managed_policies=[
                iam.ManagedPolicy.from_aws_managed_policy_name('AdministratorAccess')
            ]
        )

        c9_instance_profile = iam.CfnInstanceProfile(self, 'C9InstanceProfile',
            roles=[c9_role.role_name]
        )

        CustomResource(self, 'SetInstanceProfileResource',
            service_token=on_event_fn.function_arn,
            properties={
                'InstanceProfileArn': c9_instance_profile.attr_arn,
                'InstanceProfileName': c9_instance_profile.ref
            }
        )


from fenics import *
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt

def vertex_normal(mesh, boundary_parts, i):
    """Calculates the normal in a given vertex of the mesh."""
    ver = Vertex(mesh, i)
    n = Point(0.0, 0.0)
    div = 0.0
    for fac in entities(ver, mesh.geometry().dim()-1):
        f = Facet(mesh, fac.index())
        if f.exterior()==True:
            n+=f.normal()
            div+=1
    n/=div
    return n

def grad2n(nx, ny, u, un):
    """returns the functions representing the x and y component of gard(u).grad(u).n"""
    Vn = u.function_space()
    mesh = Vn.mesh()
    Wn = FunctionSpace(mesh, 'CG', 1)

    grad_nu_x =inner(un, nx)
    grad_nu_y = inner(un, ny)

    grad_nu_x = project(grad_nu_x, Wn)
    grad_nu_y = project(grad_nu_y, Wn)

    gnux = Function(Wn, grad_nu_x.vector())
    gnuy = Function(Wn, grad_nu_y.vector())
    return gnux, gnuy

def compute_normal_field(omega, mf):
    """Computes a vector field whose elements are the normals at each point."""
    #Boundary Mesh
    gamma = BoundaryMesh(omega, "exterior")
    mapa = gamma.entity_map(0)

    V = FunctionSpace(gamma, "CG", 1)
    N = VectorFunctionSpace(gamma, "CG", 1)
    normal_field = Function(N)

    normal_x = Function(V)
    normal_y = Function(V)

    for ver in entities(gamma, 0):
        i = mapa[ver.index()]

        point = vertex_normal(omega, mf, i)
        normal_x.vector()[ver.index()] = -1.0*point[0]
        normal_y.vector()[ver.index()] = -1.0*point[1]

    (x, y) = TestFunctions(N)
    solve(inner(normal_field[0], x)*dx + inner(normal_field[1], y)*dx - inner(normal_x, x)*dx -inner(normal_y, y)*dx == 0, normal_field)

    #Dirichlet Boundary must be initialized by Function in Vector Space over Omega (only on Gamma fails)
    V_vec = VectorFunctionSpace(omega, "CG", 1)
    normal_fieldV = Function(V_vec)
    for ver in entities(gamma, 0):
        i = mapa[ver.index()]
        normal_fieldV.vector()[i] = normal_field.vector()[ver.index()]
        normal_fieldV.vector()[i+omega.num_vertices()] = normal_field.vector()[ver.index()+gamma.num_vertices()]

    deform = TrialFunction(V_vec)
    v = TestFunction(V_vec)
    a = 0.01*inner(nabla_grad(deform), nabla_grad(v))*dx + 0.01*inner(deform,v)*ds(4)
    L = inner(Constant((0.0,0.0)),v)*dx
    bc1 = DirichletBC(V_vec, normal_fieldV, mf, 15)     #Obstacle
    bc2 = DirichletBC(V_vec, Constant((0,0)), mf, 13)    #outflow
    bc3 = DirichletBC(V_vec, Constant((0,0)), mf,14)    #noslip
    bc4 = DirichletBC(V_vec, Constant((0,0)), mf, 12)    #inflow
    bc = [bc1, bc2, bc3, bc4]
    deform = Function(V_vec)
    solve(a==L, deform, bcs=bc)
    return deform

def mesh_surface(mesh):
	"""Calculates surface of a mesh."""
	Wu = FunctionSpace(mesh, 'CG', 1)
	e = Expression('1.0', degree=1)
	unity = interpolate(e, Wu)
	surface = unity*dx
	surface = assemble(surface)
	return surface


import numpy as np

def linear_regression_gradient_descent(X, y, learning_rate=0.01, num_iterations=1000):
    # Initialize parameters (slope and intercept)
    m, n = X.shape
    theta = np.zeros((n, 1))
    history = {'loss': [], 'theta': []}

    for iteration in range(num_iterations):
        # Calculate predictions
        predictions = np.dot(X, theta)

        # Calculate errors
        errors = predictions - y

        # Update parameters using gradient descent
        gradient = np.dot(X.T, errors) / m
        theta -= learning_rate * gradient

        # Calculate Mean Squared Error (MSE)
        mse = np.mean(errors**2)
        history['loss'].append(mse)
        history['theta'].append(theta.copy())

    return theta, history

# Generate sample data
np.random.seed(0)
X = np.random.rand(100, 1) * 10
y = 2 * X + 1 + np.random.randn(100, 1) * 2

# Add bias term to X
X_b = np.c_[np.ones((X.shape[0], 1)), X]

# Perform linear regression using gradient descent
theta, history = linear_regression_gradient_descent(X_b, y)

# Calculate R-squared (R²)
y_pred = X_b.dot(theta)
sst = np.sum((y - np.mean(y))**2)
ssr = np.sum((y - y_pred)**2)
r2 = 1 - (ssr / sst)

print(f"Estimated coefficients (slope and intercept): {theta.ravel()}")
print(f"R-squared (R²): {r2:.2f}")


def collect(collection: list, item: str):
    if item not in collection:
        collection.append(item)

    return collection

def drop(collection: list, item: str):
    if item in collection:
        collection.remove(item)

    return collection

def combine_items(collection: list, old_item: str, new_item: str):
    index = collection.index(old_item)
    collection.insert(index + 1, new_item)

def renew(collection: list, item: str):
    if item in collection:
        index = collection.index(item)
        catch_item = collection.pop(index)
        collection.append(catch_item)
    return collection

collecting_items = [item for item in input().split(", ")]

command = input()

while not command == "Craft!":
    cmd, cmd_item = command.split(" - ")

    if cmd == "Collect":
        collect(collecting_items, cmd_item)
    elif cmd == "Drop":
        drop(collecting_items, cmd_item)
    elif cmd == "Combine Items":
        old, new = cmd_item.split(":")
        if old in collecting_items:
            combine_items(collecting_items, old, new)
    elif cmd == "Renew":
        renew(collecting_items, cmd_item)

    command = input()

print(", ".join(collecting_items))

SoftUni/Python homework/fundamentals/5. List advanced/11. inventory.py


# import numpy as np
# import pandas as pd
# import seaborn as sns
# import matplotlib.pyplot as plt
# sns.set_theme()

# E_of_alpha = pd.read_csv("../csv/E_of_alpha.csv", engine="pyarrow", names= ["E_of_alpha"])

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import set_plot_style
sns.set_theme()
set_plot_style.main()
from scipy.optimize import curve_fit

E_of_alpha = pd.read_csv("../csv/E_of_alpha.csv", engine="pyarrow", names= ["E_of_alpha"])

Variance_vec = pd.read_csv("../csv/variance_alpha.csv", engine="pyarrow", names= ["variance"])

alpha_max = 0.25; alpha_min=0.05

def polynomial(x, a, b, c):
    return a * x**2 + b * x + c

E_of_alpha= E_of_alpha.values.astype(float)
Variance_vec = Variance_vec.values.astype(float)

alpha_step = (alpha_max-alpha_min)/len(E_of_alpha[0])

alpha_vec = np.arange(1,len(E_of_alpha[0])+1)* alpha_step + alpha_min

fig_task3, ax_task3 = plt.subplots(1,1)

upper_bound = E_of_alpha[0]+np.sqrt(Variance_vec[0]/(1e7))
lower_bound = E_of_alpha[0]-np.sqrt(Variance_vec[0]/(1e7))
fs = 15

ax_task3.plot(alpha_vec, E_of_alpha[0], label = "Average energy", color='r', linewidth=2)
#ax_task3.errorbar(alpha_vec, E_of_alpha[0], yerr = np.sqrt(Variance_vec[0]/1e6), color = 'r')
ax_task3.fill_between(alpha_vec,lower_bound,upper_bound, label=r"$\pm\sigma$", alpha=0.5)

params, covariance = curve_fit(polynomial, alpha_vec, E_of_alpha[0])

alpha_vals = np.linspace(alpha_min, alpha_max, 50)

ax_task3.legend(fontsize = fs)
ax_task3.set_title(r"Averag local energy as function of parameter $\alpha$", fontsize=fs)
ax_task3.set_xlabel(r"$\alpha$", fontsize = fs+4)
ax_task3.set_ylabel(r"Energy [$E_h$]", fontsize = fs)
opt_e_ind = np.argmin(E_of_alpha[0])
opt_alpha = alpha_vec[opt_e_ind]
min_E =np.min(E_of_alpha[0])

#ax_task3.plot(alpha_vals, polynomial(alpha_vals, *params), linestyle=':',linewidth=4, label=f'Curve fit, \n y = {params[0]:.2} x^2 + {params[1]:.2} x + {params[2]:.2}')

st =r"Optimal $\alpha =$" +f"{opt_alpha:.4f}" + r" with $\langle E_L\rangle$= "+ f"{min_E:.4f}"

ax_task3.scatter(opt_alpha, min_E, color='k',label = st, marker ="+", s =300)

plt.tight_layout()

ax_task3.legend(fontsize = fs-2)
fig_task3.savefig("plots_python/task3/E_of_alpha.png")

print((Variance_vec[0]))
print(alpha_vec.shape)

opt_e_ind = np.argmin(E_of_alpha[0])

opt_alpha = alpha_vec[opt_e_ind]

print("optimal alpha= ", opt_alpha)
print("with energy", np.min(E_of_alpha[0]))

fig_hist, ax_hist = plt.subplots(1,1)


"""
Knight's Problem divide and conquer algorithm
"""
from classDef import *
from baseCases import *
import math

def lookUp(n,m, mode):
	'''
	takes a dimensions (n,m) and returns a solveBoardd matrix of the same size
	returns nxm matrix
	'''
	# print("lookUp: ", n, m,mode)
	if not((n,m) in base_cases.keys()):
		print("Solution not found")
		return None
	else:
		if (mode=='c'):
			data = base_cases[(n,m)][0]
		elif (mode=='s'):
			data = base_cases[(n,m)][1]
		elif (mode=='d'):
			data = base_cases[(n,m)][2]
		else:
			print("mode is undefined")
			return None
		#print(data)
		start=(-1,-1)
		end=(0,0)
		for i in range(0,n):
			for j in range(0,m):
				if (data[i][j] == 1):
					start=(i,j)
					pass
				elif (data[i][j]==(n*m)):
					end=(i,j)
					pass

		return (Board(n,m,start,end,data))

def solveBoard(n,m):
	'''
	takes dimensions (n, m) and returns a knight's tour on a board of size n*m
	returns: matrix
	'''
	#CASE1
	if ((n<=10) and (m<=10)):
		temp = lookUp(n,m,'s')
		if (temp==None):
			print("Solution not found.")
			return None
		else:
			return temp
	#CASE2
	elif ((n==3) and (m>10)):
		k = ((m-7)%4) + 7
		#print(k)
		aux_matrix=lookUp(3,4,'s')
		if (aux_matrix==None):
			print("Solution not found")
			return None
		else:
			for i in range(1,(m-k)/4):
				temp = lookUp(3,4,'s')
				aux_matrix.two_link(temp)
			temp2 = solveBoard(3,k)
			if (temp2==None):
				print("solution not found")
				return None
			else:
				temp2.two_link(aux_matrix)
				return temp2
	#CASE3
	elif ((n==4) and (m>10)):
		k = ((m-6)%5) + 6
		aux_matrix=lookUp(4,5,'d')
		#print(aux_matrix)
		if(aux_matrix==None):
			print("Solution not found")
			return None
		else:
			for i in range(1,(m-k)/5):
				temp = lookUp(4,5,'d')
				aux_matrix.two_link(temp)
			# print("k", k)
			# print(aux_matrix)
			# print(aux_matrix.forward_links)
			# print(aux_matrix.backward_links)
			# print(aux_matrix.rows,aux_matrix.cols)
			temp2=solveBoard(4,k)
			#print(temp2)
			if (temp2==None):
				print("solution not found")
				return None
			else:
				#print(temp2)
				# print(temp2.startPos)
				#print(temp2.endPos)
				temp2.two_link(aux_matrix)
				return temp2
	#CASE4
	elif ((5<=n<=10) and (m>10)):
		m1 = int(math.floor(m/4)*2)+(m%2)
		m2 = m-m1
		# print(m1,m2)
		temp1 = solveBoard(n,m1)
		temp2 = solveBoard(n,m2)
		if ((temp1==None) or (temp2==None)):
			print("solution not found")
			return None
		else:
			temp1.two_link(temp2)
			if (temp1==None):
				print("solution not found")
				return None
			else:
				return temp1
	#CASE5
	elif ((n>10) and (m>10)):
		n2 = int(math.floor(n/4)*2)+(n%2)
		n1 = n-n2
		m2 = int(math.floor(m/4)*2)+(m%2)
		m1 = m-m2
		first_quad = solveBoard(n1,m1)
		second_quad = solveBoard(n1,m2)
		third_quad = solveBoard(n2,m1)
		fourth_quad = solveBoard(n2,m2)

		if ((first_quad==None) or (second_quad==None) or (third_quad==None) or (fourth_quad==None)):
			print("solution not found")
			return None

		# print(first_quad)data[i][j]
		# print('ss')
		first_quad.quad_link(second_quad,third_quad,fourth_quad)
		return first_quad

sol = solveBoard(16,16)
print(sol)
print(sol.forward_links)
print(sol.backward_links)

#c = lookUp(3,4,'s')
# print(c)
# c.transpose()
# print(c)
# print(sol.startPos, sol.endPos)
# print(sol.forward_links)
# print(sol.backward_links)
# print(sol.backward_links)
# temp = lookUp(4,5,'s')
# print(temp)
# print(temp.endPos)
# if __name__ == "__main__":

# 	n = int(input("Enter value of n: "))
# 	m = int(input("Enter value of m: "))

# 	solution  = solveBoard(n,m)
# 	print (solution)


from flask import Blueprint
from flask import Response, json, request

from infrastructure import DB
from model import Restaurant

restaurant = Blueprint('restaurant', __name__)

@restaurant.route('/restaurants', methods=['GET'])
def all_restaurants():
    print(DB)
    rests = [{'name': rest.name, 'stars': rest.stars, 'id': rest.id} for rest in DB['restaurant']]
    data = json.dumps(rests)
    return Response(data, status=200)

@restaurant.route('/restaurants', methods=['POST'])
def restaurants_create():
    data = request.json
    print(data)
    DB['restaurant'].append(Restaurant("ABC", 5))
    return Response(status=200)


# This decodes and encode affine ciphers
# Created by Nicholas Lueth

import math
import string

def dc(ct):
    return_list = []
    for i in ct:
        return_list.append(letters_to_nums[i])
    return return_list

alphabet = string.ascii_letters[:26].upper()
letters_to_nums = {}
nums_to_letters = {}
for i, char in enumerate(alphabet):
    letters_to_nums[char] = i
for i, char in enumerate(alphabet):
    nums_to_letters[str(i)] = char

print(f"Letters2Num = {letters_to_nums}\nNum2Letters = {nums_to_letters}")
preText = "OPAMKNYIBYTXYPOBYNYTTYLCITTXYYVHMPTXOCEYCCIGYICHOGOTCTXYAGOBYAMKIVKEZYLAMKSONNVYYHNITYLMVZGHHX"

text = dc(preText)
a = 17
b = 8
mod = 26
print(text)

def encrypt():
    new_str = ""
    for i in range(len(text)):
        try:
            new_str += nums_to_letters[str((a * text[i] + b) % mod)]
        except KeyError:
            new_str += nums_to_letters[str(((a * text[i] + b) % mod) + 26)]
    print(new_str)

def decrypt():
    new_str = ""
    for i in range(len(text)):
        new_str += nums_to_letters[str((inverse(a, mod) * (text[i] - b)) % mod)]
    return new_str

def inverse(num, modular):
    # Set the variables
    gcd = math.gcd(num, modular)
    # Answer is a counter that increments with every failed iteration
    answer = 0

    if num % 2 == 0 and modular % 2 == 0:
        print("There is no modular inverse!")
        exit(0)

    while True:
        # If the remainder of num * answer / mod is the gcd then the answer is the modular inverse
        if (num * answer) % modular == gcd:
            break
        # If the the remainder isn't the gcd then increment the answer and try again
        else:
            answer += 1
    return answer

print(decrypt())


def Vid_s ():
    import random as rnd
    import pyautogui as pg
    import time

    time.sleep(2)

    vids = 1
    pg.click(55,632)
    while vids <= 42:
        vid_X = rnd.randrange(200, 950)
        vid_Y = rnd.randrange(120, 505)
        vids = vids + 1
        time.sleep(0.2)
        pg.doubleClick(vid_X, vid_Y)
        pg.typewrite(["left","left"])


import sys, os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

from keras import applications
from keras.layers import *
from keras.models import Model
from keras.models import Sequential

from nyoka import KerasToPmml
from nyoka import PMML44 as pml
from nyoka.Base64 import FloatBase64
import unittest
import requests
import json
from requests.auth import HTTPBasicAuth
from adapaUtilities import AdapaUtility
from dataUtilities import DataUtility

from keras.applications.mobilenet import preprocess_input
from keras.preprocessing import image
from keras.preprocessing.image import img_to_array
import numpy as np
import pandas as pd

class TestCases(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        print("******* Unit Test for Keras *******")
        self.adapa_utility = AdapaUtility()
        self.data_utility = DataUtility()

    def test_01_image_classifier_with_image_as_input(self):
        model = applications.MobileNet(weights='imagenet', include_top=False,input_shape = (224, 224,3))
        activType='sigmoid'
        x = model.output
        x = Flatten()(x)
        x = Dense(1024, activation="relu")(x)
        predictions = Dense(2, activation=activType)(x)
        model_final = Model(inputs =model.input, outputs = predictions,name='predictions')

        cnn_pmml = KerasToPmml(model_final,model_name="MobileNetImage",description="Demo",\
            copyright="Internal User",dataSet='image',predictedClasses=['dogs','cats'])
        cnn_pmml.export(open('2classMBNet.pmml', "w"), 0)

        img = image.load_img('nyoka/tests/resizedCat.png')
        img = img_to_array(img)
        img = preprocess_input(img)
        imgtf = np.expand_dims(img, axis=0)
        model_pred=model_final.predict(imgtf)
        model_preds = {'dogs':model_pred[0][0],'cats':model_pred[0][1]}

        model_name  = self.adapa_utility.upload_to_zserver('2classMBNet.pmml')

        predictions, probabilities = self.adapa_utility.score_in_zserver(model_name, 'nyoka/tests/resizedCat.png',True)

        self.assertEqual(abs(probabilities['cats'] - model_preds['cats']) < 0.00001, True)
        self.assertEqual(abs(probabilities['dogs'] - model_preds['dogs']) < 0.00001, True)

    def test_02_image_classifier_with_base64string_as_input(self):
        model = applications.MobileNet(weights='imagenet', include_top=False,input_shape = (224, 224,3))
        activType='sigmoid'
        x = model.output
        x = Flatten()(x)
        x = Dense(1024, activation="relu")(x)
        predictions = Dense(2, activation=activType)(x)
        model_final = Model(inputs =model.input, outputs = predictions,name='predictions')

        cnn_pmml = KerasToPmml(model_final,model_name="MobileNetBase64",description="Demo",\
            copyright="Internal User",dataSet='imageBase64',predictedClasses=['dogs','cats'])
        cnn_pmml.export(open('2classMBNetBase64.pmml', "w"), 0)

        img = image.load_img('nyoka/tests/resizedCat.png')
        img = img_to_array(img)
        img = preprocess_input(img)
        imgtf = np.expand_dims(img, axis=0)

        base64string = "data:float32;base64," + FloatBase64.from_floatArray(img.flatten(),12)
        base64string = base64string.replace("\n", "")
        csvContent = "imageBase64\n\"" + base64string + "\""
        text_file = open("input.csv", "w")
        text_file.write(csvContent)
        text_file.close()

        model_pred=model_final.predict(imgtf)
        model_preds = {'dogs':model_pred[0][0],'cats':model_pred[0][1]}

        model_name  = self.adapa_utility.upload_to_zserver('2classMBNetBase64.pmml')

        predictions, probabilities = self.adapa_utility.score_in_zserver(model_name, 'input.csv',True)

        self.assertEqual(abs(probabilities['cats'] - model_preds['cats']) < 0.00001, True)
        self.assertEqual(abs(probabilities['dogs'] - model_preds['dogs']) < 0.00001, True)

    # def test_03_SimpleDNN(self):
    #     X_train, X_test, y_train, columns, target_name, test_file = self.data_utility.get_data_for_regression()
    #     model = Sequential()
    #     model.add(Dense(13, input_dim=3, kernel_initializer='normal', activation='relu'))
    #     model.add(Dense(23))
    #     model.add(Dense(1, kernel_initializer='normal'))
    #     model.compile(loss='mean_squared_error', optimizer='adam')
    #     model.fit(X_train, y_train, epochs=1000, verbose=0)
    #     pmmlObj=KerasToPmml(model, model_name='Sequential', description="Demo", copyright="Internal User",\
    #         dataSet="inputBase64")
    #     pmmlObj.export(open('sequentialModel.pmml','w'),0)

    #     base64string = "data:float32;base64," + FloatBase64.from_floatArray(np.array(X_test).flatten(),12)
    #     base64string = base64string.replace("\n", "")
    #     csvContent = "inputBase64\n\"" + base64string + "\""
    #     text_file = open(test_file, "w")
    #     text_file.write(csvContent)
    #     text_file.close()

    #     model_pred = model.predict(X_test)
    #     model_name  = self.adapa_utility.upload_to_zserver('sequentialModel.pmml')

    #     predictions, probabilities = self.adapa_utility.score_in_zserver(model_name, test_file,True)

    #     print(model_pred)
    #     print(predictions)
    #     print(probabilities)

    @classmethod
    def tearDownClass(self):
        print("\n******* Finished *******\n")

if __name__ == '__main__':
    unittest.main(warnings='ignore')


import json

from gps import *
import time
import openrouteservice as ors
import constants

gpsd = gps(mode=WATCH_ENABLE | WATCH_NEWSTYLE)
currentLat = 0.0
currentLon = 0.0

client = ors.Client(key=constants.api_key)

def get_current_address():
    while True:
        report = gpsd.next()  #
        if report['class'] == 'TPV':
            currentLat = getattr(report, 'lat', 0.0)
            currentLon = getattr(report, 'lon', 0.0)
            # print(currentLat, "\t", currentLon)
            coordinate = [currentLon, currentLat]
            reverse = client.pelias_reverse(
                point=coordinate,
                validate=True,
            )
            # print(reverse["features"][0]["properties"]["name"])
            if currentLat != 0 or currentLon != 0: return (reverse["features"][0]["properties"]["name"]);

def get_current_coordinate():
    while True:
        report = gpsd.next()  #
        if report['class'] == 'TPV':
            currentLat = getattr(report, 'lat', 0.0)
            currentLon = getattr(report, 'lon', 0.0)
            # print(currentLat, "\t", currentLon)
            coordinate = [currentLon, currentLat]
            if currentLat != 0 or currentLon != 0: return coordinate


from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='sys_mon'),
    path('sdp/', views.sdp, name='sdp'),
    path('fdp/', views.fdp, name='fdp'),
    path('efs/', views.efs, name='efs'),
    path('etc/', views.etc, name='etc'),
    path('rcom/', views.rcom, name='rcom'),
    path('drf/', views.drf, name='drf'),
    path('sdr/', views.sdr, name='sdr'),
    path('app/', views.app, name='app'),
    path('nms/', views.nms, name='nms'),
    path('was/', views.was, name='was'),
    path('log/', views.log, name='log'),
    path('test/', views.test, name='test'),

]


import numpy as np
from scipy.ndimage import gaussian_filter

from config import *

class PeopleDynamics:

    def __init__(self, grid):
        self.people = 0
        self.walls = 0
        self.people = 0
        self.grid = grid
        self.ng = 0
        self.i = 0

    def update_people_dynamics(self):
        self.matrix = np.copy(self.grid.matrix)

        self.walls = self.grid.get_attribute("walls")
        self.fire = self.grid.fire_map()
        self.people = self.grid.get_attribute("people")

        self.move_people()
        return self.matrix

    def move_people(self):
        people_list = self.calculate_people_movement()
        self.execute_people_movement(people_list)

    def execute_people_movement(self, people_list):
        for (r, c, v) in people_list:
            self.matrix[r, c, indices["people"]] = v

    def calculate_people_movement(self):
        # nice_grid = self.nice_grid()
        # self.grid.ng = nice_grid
        # if evacuation_alg == 'dijkstra':
        self.i += 1
        self.grid.make_dijkstra()
        people_list = []
        for i in range(self.matrix.shape[0]):
            for j in range(self.matrix.shape[1]):
                people_in_cell = self.people[i, j]
                while people_in_cell > 0:
                    if self.i % 3 == 0:
                        movement = self.move_people_in_cell(i, j)
                    else:
                        movement = (i, j, 1)
                    # movement = self.move_with_nice_grid(i, j, nice_grid)
                    people_list.append(movement)
                    people_in_cell -= 1
                self.matrix[i, j, indices["people"]] = 0
        return people_list

    def move_with_nice_grid(self, i, j, nice_grid):
        nice_grid[i, j] = -5
        grid_part = nice_grid[max(i - 1, 0):min(i + 2, self.matrix.shape[0]),
                    max(j - 1, 0):min(j + 2, self.matrix.shape[1])]
        mx = np.argmax(grid_part, axis=0)[0]
        my = np.argmax(grid_part, axis=1)[0]
        movement = (
                self.grid.bound(mx + i, 0, self.matrix.shape[0] - 1),
                self.grid.bound(my + j, 0, self.matrix.shape[1] - 1), 1)
        return movement

    def nice_grid(self):
        num_rows = self.matrix.shape[0]
        num_cols = self.matrix.shape[1]
        nice_grid = -2 * np.ones((num_rows, num_cols))
        wall_grid = -2 * np.ones((num_rows, num_cols))
        wall_grid[self.grid.get_attribute("walls") == wall_categories[no_walls_symbol]] = 0
        wall_grid[self.grid.get_attribute("walls") == wall_categories[exit_symbol]] = 0

        wall_grid = gaussian_filter(wall_grid, sigma=1, mode='nearest', order=0)

        fire_grid = 0 * np.ones((num_rows, num_cols))
        fire_grid -= 25 * self.grid.get_attribute("fire")
        fire_grid = gaussian_filter(fire_grid, sigma=5, mode='nearest', order=0)

        exit_grid = 0 * np.ones((num_rows, num_cols))
        exit_grid[self.grid.get_attribute("walls") == wall_categories[exit_symbol]] = 25
        exit_grid = gaussian_filter(exit_grid, sigma=5, mode='nearest', order=0)

        # nice_grid[self.grid.get_attribute("walls") == wall_categories[exit_symbol]] = 100
        nice_grid = wall_grid + fire_grid + exit_grid  # + gaussian_filter(nice_grid, sigma=16, mode='nearest', order=0)
        nice_grid -= np.min(nice_grid)
        nice_grid /= np.max(nice_grid)
        return nice_grid

    def move_people_in_cell(self, i, j):
        if (self.grid.get_attribute("walls", i, j) == wall_categories[exit_symbol]):
            return (i, j, 1)
        if evacuation_alg == 'magnetic':
            (n1, n2) = self.grid.get_attraction_neighbor_magnetic(i, j)
        else:
            (n1, n2) = self.grid.get_attraction_neighbor_dijkstra(i, j)
        if self.forbidden_cell(n1, n2):
            (n1, n2) = self.grid.get_attraction_neighbor_dijkstra(i, j)
        return n1, n2, 1

    def forbidden_cell(self, i, j):
        if self.walls[i, j] != wall_categories[no_walls_symbol] and self.walls[i, j] != wall_categories[exit_symbol]:
            return True
        if self.fire[i, j] == 1:
            return True
        return False


import xmltodict
from pathlib import Path

from bpmn_tools.notation      import Definitions
from bpmn_tools.collaboration import Collaboration, Participant
from bpmn_tools.flow          import Process, Start, End, Task
from bpmn_tools.flow          import Flow, FlowNodeRef, Lane, LaneSet
from bpmn_tools.diagrams      import Diagram, Plane

from bpmn_tools.layout        import simple

from bpmn_tools.util import compare

def compare_with_roundtrip(obj1, expected):
  # obj -> xml
  d1 = obj1.as_dict(with_tag=True)
  print("*" * 20, "round 1" , "*" * 20)
  compare(d1, expected)

  # xml -> obj

  obj2 = Definitions.from_dict(d1)

  d2 = obj2.as_dict(with_tag=True)
  print("*" * 20, "round 2" , "*" * 20)
  compare(d2, expected)

  return obj2

def test_flow_node_ref():
  a = Task("Some task")
  r1 = FlowNodeRef(a)

  assert r1.ref  == a
  assert r1.text == a.id

  r2 = compare_with_roundtrip(r1, { "bpmn:flowNodeRef" : a.id })

  assert r2.ref  is None
  assert r2.text == a.id

def test_lane():
  activities = [
    Start(id="start"),
    Task('Say "Hello!"', id="hello"),
    End(id="end")
  ]

  l1 = Lane("some lane", id="testlane").extend(activities)

  compare_with_roundtrip(l1, {
    "bpmn:lane": {
      "@id": "testlane",
      "@name": "some lane",
      "bpmn:flowNodeRef": [
        "start",
        "hello",
        "end"
      ]
    }
  })

def test_laneset():
  l1 = Lane("lane 1", id="lane1").append(Task("task 1", id="task1"))
  l2 = Lane("lane 2", id="lane2").append(Task("task 2", id="task2"))
  ls = LaneSet(id="laneset").extend([l1, l2])

  assert len(ls) == 2

  compare_with_roundtrip(ls,{
    "bpmn:laneSet": {
      "@id": "laneset",
      "bpmn:lane": [
        {
          "@id": "lane1",
          "@name": "lane 1",
          "bpmn:flowNodeRef": "task1"
        },
        {
          "@id": "lane2",
          "@name": "lane 2",
          "bpmn:flowNodeRef": "task2"
        }
      ]
    }
  })

def test_process_with_default_laneset():
  l1 = Lane("lane 1", id="lane1").append(Task("task 1", id="task1"))
  l2 = Lane("lane 2", id="lane2").append(Task("task 2", id="task2"))
  ls = LaneSet(id="laneset").extend([l1, l2])

  process = Process(id="process").append(ls)

  compare_with_roundtrip(process, {
    "bpmn:process": {
      "@id": "process",
      "bpmn:task": [
        {
          "@id": "task1",
          "@name": "task 1"
        },
        {
          "@id": "task2",
          "@name": "task 2"
        }
      ],
      "bpmn:laneSet": {
        "@id": "laneset",
        "bpmn:lane": [
          {
            "@id": "lane1",
            "@name": "lane 1",
            "bpmn:flowNodeRef": "task1"
          },
          {
            "@id": "lane2",
            "@name": "lane 2",
            "bpmn:flowNodeRef": "task2"
          }
        ]
      }
    }
  })

def test_diagram_with_lane():
  with open(Path(__file__).resolve().parent / "hello-lanes.bpmn") as fp:
    expected = xmltodict.parse(fp.read())

  activities_lane1 = [
    Start(id="start"),
    Task('Say "Hello!"', id="hello"),
    End(id="end")
  ]

  activities_lane2 = [
    Task('Hear "Hello!"', id="hear")
  ]

  lane2 = Lane("lane 2", id="lane2").extend(activities_lane2)

  process_lane1 = Process(id="process1").extend(activities_lane1).extend([
    Flow(source=activities_lane1[0], target=activities_lane1[1]),
    Flow(source=activities_lane1[1], target=activities_lane1[2])
  ])

  process_lane2 = Process(id="process2").append(lane2)

  collaboration = Collaboration(id="collaboration").extend([
    Participant("participant1", process_lane1, id="participant1"),
    Participant("participant2", process_lane2, id="participant2")
  ])

  definitions = Definitions(id="definitions").extend([
    process_lane1,
    process_lane2,
    collaboration
  ])

  definitions.append(
    Diagram(
      id="diagram",
      plane=Plane(id="plane", element=collaboration)
    )
  )

  simple.layout(definitions)

  compare(definitions.as_dict(with_tag=True), expected)

def test_process_of_element_in_lane():
  """
    tests if a task in a lane's process is actually the process
  """
  task = Task("task")
  process = Process().append(task)
  assert task.process == process

  task = Task("task")
  lane = Lane("lane").append(task)
  process = Process().append(lane)
  assert task.process == process


from __future__ import print_function
from flask import Flask, redirect, url_for, session, request, jsonify, render_template, flash, Markup
from flask_oauthlib.client import OAuth

from github import Github

import os
import pprint
import sys
import traceback
import base64
import markdown

class GithubOAuthVarsNotDefined(Exception):
	'''raise this if the necessary environmental vars are not defined'''

# Check if environmental variables are set
if (os.getenv('GITHUB_CLIENT_ID') == None or\
os.getenv('GITHUB_CLIENT_SECRET') == None or\
os.getenv('APP_SECRET_KEY') == None or\
os.getenv('GITHUB_ORG') == None):
	raise GithubOAuthVarsNotDefined('''
		Please define environment variables:
			GITHUB_CLIENT_ID
			GITHUB_CLIENT_SECRET
			GITHUB_ORG
			APP_SECRET_KEY
		''')

# Create Flask app
app = Flask(__name__)

# Assign APP_SECRET_KEY for using Sessions
app.secret_key = os.getenv('APP_SECRET_KEY')

# Creat OAuth object for OAuth calls
oauth = OAuth(app)

# Connect to GitHub
github = oauth.remote_app(
    'github',
    consumer_key=os.getenv('GITHUB_CLIENT_ID'),
    consumer_secret=os.getenv('GITHUB_CLIENT_SECRET'),
    request_token_params={'scope': 'read:org, repo'},
    base_url='https://api.github.com/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url='https://github.com/login/oauth/access_token',
    authorize_url='https://github.com/login/oauth/authorize'
)

@app.context_processor
def inject_logged_in():
    return dict(logged_in=logged_in())

@app.context_processor
def inject_github_org():
    return dict(github_org=os.getenv('GITHUB_ORG'))

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/login')
def login():
    return github.authorize(callback=url_for('authorized', _external=True, _scheme='https'))

@app.route('/logout')
def logout():
    session.clear()
    flash('You were logged out')
    return redirect(url_for('home'))

@app.route('/login/authorized')
def authorized():
    resp = github.authorized_response()

	# No response from GitHub, deny login
    if resp is None:
        session.clear()
        login_error_message = 'Access denied: reason=%s error=%s full=%s' % (
            request.args['error'],
            request.args['error_description'],
            pprint.pformat(request.args)
        )
        flash(login_error_message, 'error')
        return redirect(url_for('home'))

	# Try getting access token from response
    try:
        session['github_token'] = (resp['access_token'], '')
        session['user_data']=github.get('user').data
        github_userid = session['user_data']['login']
        org_name = os.getenv('GITHUB_ORG')

	# Throw exception if access token is not given or there is trouble with using the token
    except Exception as e:
        session.clear()
        message = 'Unable to login: ' + str(type(e)) + str(e)
        flash(message,'error')
        return redirect(url_for('home'))

	# Try using token to get user information
    try:
        g = Github(resp['access_token'])
        org = g.get_organization(org_name)
        named_user = g.get_user(github_userid)
        isMember = org.has_in_members(named_user)

	# Throw exception if token cannot get information
    except Exception as e:
        message = 'Unable to connect to Github with accessToken: ' + resp['access_token'] + " exception info: " + str(type(e)) + str(e)
        session.clear()
        flash(message,'error')
        return redirect(url_for('home'))

	# Check if user is member of given GITHUB_ORG
    if not isMember:
        session.clear() # Must clear session before adding flash message
        message = 'Unable to login: ' + github_userid + ' is not a member of ' + org_name + \
          '

Logout of github as user:  ' + github_userid + \
          '
'
        flash(Markup(message),'error')

    else:
        flash('You were successfully logged in')

    return redirect(url_for('home'))

@app.route('/feedback')
def renderFeedback():
    if not logged_in():
        flash('You must be logged in to do that', 'error')
        return redirect(url_for('home'))
    user_feedback = []
    g = Github(get_github_oauth_token()[0])
    repos = g.get_organization(os.getenv('GITHUB_ORG')).get_repos()
    named_user = g.get_user(session['user_data']['login'])
    for repo in repos:
        if (repo.name[0:8].upper() == 'FEEDBACK'):
            if (repo.has_in_collaborators(named_user)):
                user_feedback.append(Markup(markdown.markdown(bytes.decode(base64.b64decode(repo.get_contents('README.md').content)))))
    return render_template('feedback.html',list_feedback=user_feedback)

@github.tokengetter
def get_github_oauth_token():
    return session.get('github_token')

# Checks if token is in session, which means that the user is logged in
def logged_in():
    return 'github_token' in session

if __name__ == '__main__':
    app.run()


from sys import stdin
from collections import deque

input = stdin.readline
n, m = map(int,input().split())

board = [list(input().strip()) for _ in range(n)]
q = deque()
visited_r = [[0]*m for _ in range(n)]
visited_b = [[0]*m for _ in range(n)]

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def init():
    rx,ry,bx,by = [0]*4
    for i in range(n):
        for j in range(m):
            if board[i][j] == 'R':
                rx, ry = i,j
            elif board[i][j] == 'B':
                bx, by = i,j
    q.append((rx,ry,bx,by,1))
    visited_r[rx][ry] = 1
    visited_b[bx][by] = 1

def move(x,y,dx,dy):
    count = 0
    while board[x+dx][y+dy] != '#' and board[x][y] != 'O':
        x += dx
        y += dy
        count += 1
    return x,y,count

def bfs():
    init()
    while q:
        rx,ry,bx,by,depth = q.popleft()
        if depth > 10:
            break
        for i in range(4): #4방향 돌리기
            nrx, nry, count_r = move(rx, ry, dx[i], dy[i])
            nbx, nby, count_b = move(bx, by, dx[i], dy[i])
            if board[nbx][nby] == 'O':
                continue
            if board[nrx][nry] == 'O':
                return print(depth)
            if nrx == nbx and nry == nby:
                if count_r>count_b:
                    nrx -= dx[i]
                    nry -= dy[i]
                else:
                    nbx -= dx[i]
                    nby -= dy[i]
            if not visited_r[nrx][nry] or not visited_b[nbx][nby]:
                q.append((nrx,nry,nbx,nby,depth+1))
                visited_r[nrx][nry] = 1
                visited_b[nbx][nby] = 1
    return print(-1)

bfs()


"""
Exponential Decay Example

"""
import numpy as np
from scipy.stats.distributions import uniform  # type: ignore

from mud.base import SpatioTemporalProblem

def exp_decay_1D(
    u_0=0.75,
    time_range=[0, 4.0],
    domain=[0, 1],
    num_samples=10000,
    lambda_true=0.5,
    t_start=0.0,
    sampling_freq=100.0,
    std_dev=0.05,
):
    def u_t_lambda_1(t, l1):
        return u_0 * np.exp(-np.outer(l1, t))

    # Build initial samples
    initial = uniform(loc=domain[0], scale=domain[1] - domain[0])

    exp_decay = SpatioTemporalProblem()
    exp_decay.domain = domain
    exp_decay.times = np.arange(t_start, time_range[1], 1 / sampling_freq)
    exp_decay.sample_dist = "u"
    exp_decay.lam = initial.rvs(size=num_samples)
    exp_decay.data = u_t_lambda_1(exp_decay.times, exp_decay.lam)
    exp_decay.true_vals = u_t_lambda_1(exp_decay.times, lambda_true)[0]
    exp_decay.std_dev = std_dev

    return exp_decay

def exp_decay_2D(
    time_range=[0, 3.0],
    domain=np.array([[0.7, 0.8], [0.25, 0.75]]),
    num_samples=100,
    lambda_true=[0.75, 0.5],
    N=100,
    t_start=0.0,
    sampling_freq=10.0,
    std_dev=0.05,
):
    def u_t_lambda_2(t, l1, l2):
        return (l1 * np.exp(-np.outer(t, l2))).T

    # Build initial samples
    num_params = domain.shape[0]
    mn = np.min(domain, axis=1)
    mx = np.max(domain, axis=1)
    initial = uniform(loc=mn, scale=mx - mn)

    exp_decay = SpatioTemporalProblem()
    exp_decay.domain = domain
    exp_decay.times = np.arange(t_start, time_range[1], 1 / sampling_freq)[0:N]
    exp_decay.sample_dist = "u"
    exp_decay.lam = initial.rvs(size=(num_samples, num_params))
    exp_decay.data = u_t_lambda_2(
        exp_decay.times, exp_decay.lam[:, 0], exp_decay.lam[:, 1]
    )
    exp_decay.true_vals = u_t_lambda_2(exp_decay.times, lambda_true)[0]
    exp_decay.std_dev = std_dev

    return exp_decay


#!/usr/bin/env python3

import requests
import logging
import json
import argparse

class ConsulHelper():
    """
    A collection of consul api methods
    """

    def __init__(self, consul_url):
        self.consul_url = consul_url
        self.kv_url = '{}/v1/kv'.format(consul_url)
        self.ctlg_url = '{}/v1/catalog'.format(consul_url)

    def get_systemd_config(self, service_name):
        try:
            r = requests.get('{}/systemd/{}?raw'
                             .format(self.kv_url, service_name))
            if r.status_code == 200:
                data = r.text
                logger.info('{} systemd config available in consul'
                            .format(service_name))
                return data
            else:
                logger.error('{} service does not have consul '
                             'systemd key-value entry'
                             .format(service_name))
        except Exception as e:
            logger.error('Error connecting to {}: {}'.format(consul_url, e))

    def get_all_services(self):
        try:
            r = requests.get('{}/services'.format(self.ctlg_url))
            if r.status_code == 200:
                items = r.json()
                services = [item for item in items.keys()]
            else:
                logger.error('Error in getting data from consul')
        except Exception as e:
            logger.error('Error connecting to {}: {}'.format(consul_url, e))

        return services

    def get_nodes_per_service(self, service_name):
        svc_node_map = {}
        try:
            r = requests.get('{}/service/{}'
                             .format(self.ctlg_url, service_name))
            if r.status_code == 200:
                items = r.json()
                nodes = [item.get('Node') for item in items]
                svc_node_map.update({service_name: nodes})
            else:
                logger.error('Error in getting data from consul')

        except Exception as e:
            logger.error('Unable to connect to {}: {}'.format(consul_url, e))

        return svc_node_map

    def get_systemd_status_per_node(self, service_name):
        status_map = {}
        try:
            r = requests.get('{}/service/{}'
                             .format(self.ctlg_url, service_name))
            items = r.json()
            if items:
                status_items = []
                for item in items:
                    node = item.get('Node')
                    inv_svc_name = service_name.replace(' ', '_')
                    svc_key = 'systemd_{}'.format(inv_svc_name)
                    try:
                        status = item.get('ServiceMeta')['systemd']
                        if status:
                            # Convert string to boolean for consistency
                            if status.lower() == 'true':
                                status = True
                            elif status.lower() == 'false':
                                status = False
                            logger.info('{} systemd defined on {}'
                                        .format(service_name, node))
                            status_items.append({node: {svc_key: status}})
                        else:
                            logger.warning('{} systemd key is null on {}'
                                           .format(service_name, node))
                            status_items.append({node: {svc_key: False}})
                    except KeyError:
                        logger.warning('{} service json file on {} '
                                       'does not have systemd key'
                                       .format(service_name, node))
                        status_items.append({node: {svc_key: False}})
                status_map.update({service_name: status_items})
            else:
                logger.error('{} service does not exist in consul'
                             .format(service_name))
        except Exception as e:
            logger.error('Error connecting to {}: {}'.format(consul_url, e))

        return status_map

    def get_all_nodes(self):
        try:
            r = requests.get('{}/nodes'.format(self.ctlg_url))
            if r.status_code == 200:
                items = r.json()
                nodes = [node.get('Node') for node in items]
            else:
                logger.warning('Error in getting data from consul')
        except Exception as e:
            logger.error('Error connecting to {}: {}'.format(consul_url, e))

        return nodes

class SystemdConfigCheck():
    def __init__(self, systemd_config, svc_name):
        self.systemd_config = systemd_config
        self.svc_name = svc_name
        self.reqd_params = ['User',
                            'ExecStart',
                            'ExecStop',
                            'After']

    def get_params(self):
        lines = self.systemd_config.split()
        results = {}
        for item in self.reqd_params:
            check = [i for i in lines if i.startswith(item)]
            if len(check) == 0:
                results.update({item: ''})
            else:
                v = check[0].split('=')
                results.update({v[0]: v[1]})
        return results

    def check_root_user(self):
        r = self.get_params()
        if r.get('User') == 'root':
            logger.warning('{} config check failed - root user defined'
                           .format(self.svc_name))
            return False
        else:
            logger.info('{} config check passed - non-root user defined'
                        .format(self.svc_name))
            return True

    def check_params(self):
        r = self.get_params()
        test_results = []
        for k, v in r.items():
            if v:
                logger.info('{} config check passed - {} param defined'
                            .format(self.svc_name, k))
                test_results.append(True)
            else:
                logger.warning('{} config check failed - {} param not defined'
                               .format(self.svc_name, k))
                test_results.append(False)

        if all(test_results):
            return True
        else:
            return False

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--list', action='store_true')
    parser.add_argument('--host', help='Provide hostname')
    args = parser.parse_args()
    ch = ConsulHelper(consul_url)
    all_services = ch.get_all_services()
    nodes = ch.get_all_nodes()
    hostvars = {}
    hostvarlist = []
    inventory = {}

    # Systemd and ansible inventory file creation tasks
    for svc_name in all_services:
        svc_data = ch.get_systemd_config(svc_name)
        node_per_svc = ch.get_nodes_per_service(svc_name)
        # Replace service names with spaces with _
        inv_svc_name = svc_name.replace(' ', '_')
        inventory[inv_svc_name] = {'hosts': node_per_svc[svc_name]}

        if svc_data:
            systemd_check = SystemdConfigCheck(svc_data, svc_name)
            check_root = systemd_check.check_root_user()
            check_params = systemd_check.check_params()

            if check_root and check_params:
                inventory[inv_svc_name]['vars'] = {'systemd_conf_check_{}'
                                                   .format(inv_svc_name): True}
            else:
                logger.warning('{} config overall checks failed'
                               .format(svc_name))
                inventory[inv_svc_name]['vars'] = {'systemd_conf_check_{}'
                                                   .format(inv_svc_name):
                                                   False}
        else:
            inventory[inv_svc_name]['vars'] = {'systemd_conf_check_{}'
                                               .format(inv_svc_name): False}

        status_map = ch.get_systemd_status_per_node(svc_name)
        values = status_map.get(svc_name)

        for v in values:
            hostvarlist.append(v)

    for n in nodes:
        tmp = {}
        items = [i.get(n) for i in hostvarlist if i.get(n)]
        for item in items:
            tmp.update(item)
        hostvars[n] = tmp

    inventory['_meta'] = {'hostvars': hostvars}

    if args.list:
        print(json.dumps(inventory, indent=2))
    elif args.host:
        print(json.dumps(hostvars.get(args.host, {})))

if __name__ == "__main__":
    logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
                        level=logging.INFO)
    logger = logging.getLogger(__name__)
    consul_url = 'http://pi-1:8500'

    main()


##############################################################################
#                             AVIS SOFTWARE                                  #
#                     (Productos de Software Libre)                          #
#                                                                            #
##############################################################################
#
#  **************************************************************************
#  * El software libre no es una cuestion economica sino una cuestion etica *
#  **************************************************************************
#
# Avis Software es marca registrada.4
#
# Este programa es software libre; puede redistribuirlo o modificarlo bajo los
# terminos de la Licencia Publica General de GNU tal como se publica por la
# Free Software Foundation; ya sea la version 3 de la Licencia, o (a su
# eleccion) cualquier version posterior.
#
# Este programa se distribuye con la esperanza de que le sea util, pero SIN
# NINGUNA GARANTIA; sin incluso la garantia implicita de MERCANTILIDAD o
# IDONEIDAD PARA UN PROPOSITO PARTICULAR.
#
# Vea la Licencia Publica General GNU para mas detalles.
#
# Deberia haber recibido una copia de la Licencia Publica General de GNU
# junto con este programa, si no es asi, escriba a la Free Software Foundation,
# Inc, 59 Temple Place - Suite 330, Boston, MA 02111-1307, EE.UU.
#
##############################################################################
# ARCHIVO             : action.py
# AUTOR               : Norman Ruiz.
# COLABORADORES       : No aplica.
# VERSION             : 1.00 estable.
# FECHA DE CREACION   : 14/12/2022.
# ULTIMA ACTUALIZACION: 14/12/2022.
# LICENCIA            : GPL (General Public License) - Version 3.
#=============================================================================
# SISTEMA OPERATIVO   : Linux NT-9992031 4.4.0-19041-Microsoft #1237-Microsoft Sat Sep 11 14:32:00 PST 2021 x86_64 GNU/Linux.
# IDE                 : VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Oct 01 2021 01:51:08)
# COMPILADOR          : Python 3.9.2
# LICENCIA            : GPL (General Public License) - Version 3.
#=============================================================================
# DEDICATORIA: A mi hija Micaela Ruiz que me re aguanta.
#=============================================================================
# DESCRIPCION:
#             Este archivo incluye la definicion del modulo action.
#
#             Las funciones action se encargan de organizar la persistencoa
#             de los datos.
#
#-------------------------------------------------------------------------------
# ARCHIVO DE CABECERA: No aplica
#
# FUNCIONES DEFINIDAS:
#==============================================================================|
#     NOMBRE     |  TIPO  |                    ACCION                          |
#================+========+====================================================|
# Verificar_archivo() | void | Verifica si el archivo de log del dia existe y  |
#                             de no ser asi lo genera.                         |
#----------------+--------+----------------------------------------------------|
# Escribir_log   |  void  | Escribe una linea con un mensaje en el rachivo     |
#                           de logs.                                           |
#================+========+====================================================|
#
#-------------------------------------------------------------------------------
# MODIFICACIONES DE LA VERSION 0.01 estable (05/05/2022)
# AUTOR DE LA MODIFICACION: Norman Ruiz.
# * Ejemplo de historial de modificaciones.
#
#-------------------------------------------------------------------------------
#
#///////////////////////////////////////////////////////////////////////////////

#*****************************************************************************
#                             INCLUSIONES ESTANDAR
#=============================================================================
import files_bot.logger as log
import files_bot.conection as data_conection
from threading import Thread

#*****************************************************************************
#                             INCLUSIONES PARA WINDOWS
#=============================================================================

# Sin especificar

#*****************************************************************************
#                             INCLUSIONES PARA LINUX
#=============================================================================

# Sin especificar

#*****************************************************************************
#               ESPACIO DE NOMBRES DE LA LIBRERIA
#=============================================================================

# Sin especificar

#***************************************************************************
#                        FUNCIONES PARA LINUX
#===========================================================================
# FUNCION   : bool verificar_archivo()
# ACCION    : Verifica si el archivo de log del dia existe y
#             de no ser asi lo genera.
# PARAMETROS: void, no recibe nada.
# DEVUELVE  : void, no devuelve nada.
#---------------------------------------------------------------------------
def persistir_datos(config, loteRegistros):
    estado = True
    ubicacion = "LaposTecno"
    insert = config["parametros"]["conexiones"][ubicacion]["insert"]
    update = config["parametros"]["conexiones"][ubicacion]["update"]
    delete = config["parametros"]["conexiones"][ubicacion]["delete"]
    threads = []
    thread = 0
    count = 0
    max_threads = int(config["parametros"]["bot"]["hilos"])
    threadsregistros = {}

    try:
        mensaje = "Anexanado lote de datos..."
        print("  " + mensaje)
        log.Escribir_log(mensaje)

        registros = len(loteRegistros)
        if (registros % max_threads != 0):
            registros += max_threads

        registros_threds = registros // max_threads

        for terminal, campos in loteRegistros.items():
            threadsregistros[terminal] = list(campos)
            count += 1
            if (count == registros_threds):
                thread += 1
                conexion = data_conection.Conectar(config, ubicacion)
                threads.append(Thread(target=Impactar_cambio, args=(conexion, ubicacion, insert, update, delete, dict(threadsregistros), thread)))
                count = 0
                threadsregistros.clear()

        conexion = data_conection.Conectar(config, ubicacion)
        threads.append(Thread(target=Impactar_cambio, args=(conexion, ubicacion, insert, update, delete, dict(threadsregistros), thread)))
        count = 0
        threadsregistros.clear()

        for thread in threads:
            thread.start()

        for thread in threads:
            thread.join()

        mensaje = "Subproceso finalizado..."
        print(" ", mensaje)
        log.Escribir_log(mensaje)
        mensaje = " " + "-" * 128
        print(mensaje)
        log.Escribir_log(mensaje, False)

    except Exception as excepcion:
        estado = False
        mensaje = "ERROR - Anexanado lote de datos: " + str(excepcion)
        print(" ", mensaje)
        log.Escribir_log(mensaje)
        mensaje = " " + "-" * 128
        print(mensaje)
        log.Escribir_log(mensaje, False)
        mensaje = "WARNING!!! - Subproceso interrumpido..."
        print(" ", mensaje)
        log.Escribir_log(mensaje)

    finally:
        return estado

#---------------------------------------------------------------------------
# FUNCION   : void Impactar_cambio(objeto_conexion, string, string, string, dict)
# ACCION    : Inserta y/o actualiza el nuevo lote de terminales en el proceso de migracion.
# PARAMETROS: objeto_conexion, la conecion contra la base de datos
#             string, la ubicacion  a la que apunta la conexion
#             string, la nonquery para los insert
#             string, la nonquery para los update
#             dict, el lote de terminales a impactar
# DEVUELVE  : void, no devuelve nada.
#---------------------------------------------------------------------------
def Impactar_cambio(conexion, ubicacion, insertAux, updateAux, deleteAux, sublote, thread):
    estado = True
    try:
        for terminal, campos in sublote.items():
            if campos[0] == 'c':
                insert = insertAux.replace('?1', str("'" + terminal + "'")).replace('?2', 'NULL' if campos[1][0] is None else str("'" + campos[1][0] + "'")).replace('?3', 'NULL' if campos[1][1] is None else str("'" + campos[1][1] + "'")).replace('?4', 'NULL' if campos[1][2] is None else str("'" + campos[1][2] + "'")).replace('?5', 'NULL' if campos[1][3] is None else str("'" + campos[1][3] + "'")).replace('?6', 'NULL' if campos[1][4] is None else str("'" + campos[1][4] + "'")).replace('?7', 'NULL' if campos[1][5] is None else str("'" + campos[1][5] + "'")).replace('?8', 'NULL' if campos[1][6] is None else str("'" + campos[1][6] + "'")).replace('?9', 'NULL' if campos[1][7] is None else str("'" + campos[1][7] + "'")).replace('?0', 'NULL' if campos[1][8] is None else str("'" + campos[1][8][:-3] + "'"))
                data_conection.Insertar_nuevos(conexion, insert, thread)
            elif campos[0] == 'u':
                update = updateAux.replace('?0', str("'" + terminal + "'")).replace('?1', 'NULL' if campos[1][0] is None else str("'" + campos[1][0] + "'")).replace('?2', 'NULL' if campos[1][1] is None else str("'" + campos[1][1] + "'")).replace('?3', 'NULL' if campos[1][2] is None else str("'" + campos[1][2] + "'")).replace('?4', 'NULL' if campos[1][3] is None else str("'" + campos[1][3] + "'")).replace('?5', 'NULL' if campos[1][4] is None else str("'" + campos[1][4] + "'")).replace('?6', 'NULL' if campos[1][5] is None else str("'" + campos[1][5] + "'")).replace('?7', 'NULL' if campos[1][6] is None else str("'" + campos[1][6] + "'")).replace('?8', 'NULL' if campos[1][7] is None else str("'" + campos[1][7] + "'")).replace('?9', 'NULL' if campos[1][8] is None else str("'" + campos[1][8][:-3] + "'"))
                data_conection.Actualizar_existentes(conexion, update, thread)
            elif campos[0] == 'd':
                delete = deleteAux.replace('?1', str("'" + terminal + "'"))
                data_conection.Eliminar_existentes(conexion, delete, thread)

    except Exception as excepcion:
        estado = False
        mensaje = "ERROR - Impactando cambio: " + str(excepcion)
        print(" ", mensaje)
        log.Escribir_log(mensaje)
        mensaje = " " + "-" * 128
        print(mensaje)
        log.Escribir_log(mensaje, False)
        mensaje = "WARNING!!! - Subproceso interrumpido..."
        print(" ", mensaje)
        log.Escribir_log(mensaje)

    finally:
        data_conection.Desconectar(conexion, ubicacion)
        return estado

#---------------------------------------------------------------------------
# FUNCION   : void Impactar_cambio(objeto_conexion, string, string, string, dict)
# ACCION    : Inserta y/o actualiza el nuevo lote de terminales en el proceso de migracion.
# PARAMETROS: objeto_conexion, la conecion contra la base de datos
#             string, la ubicacion  a la que apunta la conexion
#             string, la nonquery para los insert
#             string, la nonquery para los update
#             dict, el lote de terminales a impactar
# DEVUELVE  : void, no devuelve nada.
#---------------------------------------------------------------------------
def generar_historial(config):
    estado = True
    conexion = None
    ubicacion = "LaposTecno"
    consulta = config["parametros"]["conexiones"][ubicacion]["sp"]
    try:
        mensaje = "Generando historial..."
        print("  " + mensaje)
        log.Escribir_log(mensaje)

        conexion = data_conection.Conectar(config, ubicacion)
        estado = data_conection.Ejecutar_sp(conexion, ubicacion, consulta)
        data_conection.Desconectar(conexion, ubicacion)

        mensaje = "Subproceso finalizado..."
        print(" ", mensaje)
        log.Escribir_log(mensaje)

    except Exception as excepcion:
        estado = False
        mensaje = "ERROR - Generando historial: " + str(excepcion)
        print(" ", mensaje)
        log.Escribir_log(mensaje)
        mensaje = " " + "-" * 128
        print(mensaje)
        log.Escribir_log(mensaje, False)
        data_conection.Desconectar(conexion, ubicacion)
        mensaje = "WARNING!!! - Subproceso interrumpido..."
        print(" ", mensaje)
        log.Escribir_log(mensaje)

    finally:
        return estado
#***************************************************************************
#                        FUNCIONES PARA WINDOWS
#===========================================================================
# FUNCION   :
# ACCION    :
# PARAMETROS:
# DEVUELVE  :
#---------------------------------------------------------------------------

# Sin especificar

#=============================================================================
#                            FIN DE ARCHIVO
##############################################################################