from load_data import Data
import time
from collections import defaultdict
from model import *
from torch.optim.lr_scheduler import ExponentialLR
import argparse

class Experiment:
    def __init__(self, model_name, learning_rate=0.001, ent_vec_dim=200, rel_vec_dim=200,
                 num_iterations=100, batch_size=128, decay_rate=0., cuda = False, device=0,
                 input_dropout=0.3, hidden_dropout=0., hidden_dropout1=0.4, hidden_dropout2=0.5,
                 feature_map_dropout=0., in_channels=1, out_channels=32, filt_h=3, filt_w=3,
                 label_smoothing=0.):
        self.model_name = model_name
        self.learning_rate = learning_rate
        self.ent_vec_dim = ent_vec_dim
        self.rel_vec_dim = rel_vec_dim
        self.num_iterations = num_iterations
        self.batch_size = batch_size
        self.decay_rate = decay_rate
        self.label_smoothing = label_smoothing
        self.cuda = cuda
        self.device = device
        self.kwargs = {"input_dropout": input_dropout, "hidden_dropout": hidden_dropout,
                       "hidden_dropout1": hidden_dropout1, "hidden_dropout2": hidden_dropout2,
                       "feature_map_dropout": feature_map_dropout, "in_channels": in_channels,
                       "out_channels": out_channels, "filt_h": filt_h, "filt_w": filt_w}

    def get_data_idxs(self, data):
        # 把三元组中的实体和关系都转换为id
        data_idxs = [(self.entity_idxs[data[i][0]], self.relation_idxs[data[i][1]], self.entity_idxs[data[i][2]])
                     for i in range(len(data))]
        return data_idxs

    def get_er_vocab(self, data):
        # entity-relation词典，记录该头实体+关系对应的尾实体有哪些（可以用于filter-setting或者负采样）
        er_vocab = defaultdict(list)
        for triple in data:
            er_vocab[(triple[0], triple[1])].append(triple[2])
        return er_vocab

    def get_batch(self, er_vocab, er_vocab_pairs, idx):
        # 拿到1个batch_size个(头,关系)，对应拿到(尾)。由于reverse，就不存在head_batch和tail_batch的问题
        batch = er_vocab_pairs[idx:idx + self.batch_size]
        targets = np.zeros((len(batch), len(d.entities)))
        for idx, pair in enumerate(batch):
            targets[idx, er_vocab[pair]] = 1.  # 把该条(头,关系)的所有尾实体在target中标1
        targets = torch.FloatTensor(targets)
        if self.cuda:
            targets = targets.to(self.device)
        return np.array(batch), targets

    def evaluate(self, model, data):
        hits = []
        ranks = []
        for i in range(10):
            hits.append([])

        test_data_idxs = self.get_data_idxs(data)
        # print("待验证数据集三元组数(reverse): %d" % len(test_data_idxs))
        er_vocab = self.get_er_vocab(self.get_data_idxs(d.data))  # 数据集全部三元组的(头,关系)->尾 字典

        for i in range(0, len(test_data_idxs), self.batch_size):    # step = batch_size
            data_batch, _ = self.get_batch(er_vocab, test_data_idxs, i)  # data_batch是三元组
            e1_idx = torch.tensor(data_batch[:, 0])
            r_idx = torch.tensor(data_batch[:, 1])
            e2_idx = torch.tensor(data_batch[:, 2])
            if self.cuda:
                e1_idx = e1_idx.to(self.device)
                r_idx = r_idx.to(self.device)
                e2_idx = e2_idx.to(self.device)
            predictions = model.forward(e1_idx, r_idx)

            for j in range(data_batch.shape[0]):  # 针对data_batch的每一条三元组
                filt = er_vocab[(data_batch[j][0], data_batch[j][1])]
                target_value = predictions[j, e2_idx[j]].item()
                predictions[j, filt] = 0.0  # filter-setting，先把所有存在的尾置0，再将真尾设回预测值，避免其他存在尾的影响
                predictions[j, e2_idx[j]] = target_value

            sort_values, sort_idxs = torch.sort(predictions, dim=1, descending=True)  # sort_idxs是预测分值从高到低的实体id

            sort_idxs = sort_idxs.cpu().numpy()
            for j in range(data_batch.shape[0]):
                rank = np.where(sort_idxs[j] == e2_idx[j].item())[0][0]  # rank是真尾的sort序号
                ranks.append(rank + 1)  # 实际位次要+1

                for hits_level in range(10):
                    if rank <= hits_level:
                        hits[hits_level].append(1.0)
                    else:
                        hits[hits_level].append(0.0)

        print('MR:{:.6f}, MRR:{:.6f}'.format(np.mean(ranks), np.mean(1. / np.array(ranks))))
        print('Hits@1:{:.6f}, Hits@3:{:.6f}, Hit@10:{:.6f}'.format(np.mean(hits[0]), np.mean(hits[2]), np.mean(hits[9])))

    def train_and_eval(self):
        self.entity_idxs = {d.entities[i]: i for i in range(len(d.entities))}  # entity2id
        self.relation_idxs = {d.relations[i]: i for i in range(len(d.relations))}  # relation2id

        train_data_idxs = self.get_data_idxs(d.train_data)  # 把train_triples中的实体和关系都转换成id了，reverse过所以double了
        print("训练集三元组数(reverse): %d" % len(train_data_idxs))

        if model_name.lower() == "hype":
            model = HypE(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)
        elif model_name.lower() == "hyper":
            model = HypER(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)
        elif model_name.lower() == "distmult":
            model = DistMult(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)
        elif model_name.lower() == "conve":
            model = ConvE(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)
        elif model_name.lower() == "complex":
            model = ComplEx(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)
        elif model_name.lower() == "tucker":
            model = TuckER(d, self.ent_vec_dim, self.rel_vec_dim, self.device, **self.kwargs)

        if self.cuda:
            model.to(self.device)
        model.init()
        opt = torch.optim.Adam(model.parameters(), lr=self.learning_rate)
        # opt = torch.optim.Adagrad(model.parameters(), lr=self.learning_rate)

        if self.decay_rate:
            scheduler = ExponentialLR(opt, self.decay_rate)

        er_vocab = self.get_er_vocab(train_data_idxs)
        er_vocab_pairs = list(er_vocab.keys())  # 训练集里的(头,关系)

        print("开始训练...")
        for it in range(1, self.num_iterations + 1):
            start_train = time.time()
            model.train()
            losses = []
            np.random.shuffle(er_vocab_pairs)
            for j in range(0, len(er_vocab_pairs), self.batch_size):
                data_batch, targets = self.get_batch(er_vocab, er_vocab_pairs, j)  # data_batch是(头,关系), target把尾标1
                opt.zero_grad()
                e1_idx = torch.tensor(data_batch[:, 0])
                r_idx = torch.tensor(data_batch[:, 1])
                if self.cuda:
                    e1_idx = e1_idx.to(self.device)
                    r_idx = r_idx.to(self.device)
                predictions = model.forward(e1_idx, r_idx)  # 大小是[batch_size, num_entity]
                if self.label_smoothing:
                    targets = ((1.0 - self.label_smoothing) * targets) + (1.0 / targets.size(1))
                loss = model.loss(predictions, targets)
                loss.backward()
                opt.step()
                losses.append(loss.item())
            if self.decay_rate:
                scheduler.step()
            print("Epoch " + str(it) + ", time:" + str("%.2f" % (time.time() - start_train)) +
                  ", loss:" + str("%.8f" % np.mean(losses)))
            model.eval()
            with torch.no_grad():
                # print("验证集结果:", end='')
                # self.evaluate(model, d.valid_data)
                # print("训练集结果:", end='')
                # self.evaluate(model, d.train_data)
                if not it % 2:
                    print("测试集结果: ", end='')
                    start_test = time.time()
                    self.evaluate(model, d.test_data)
                    print("test time:" + str("%.2f" % (time.time() - start_test)))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--model_name', type=str, default="ConvE", help='TuckER, HypER, HypE, ConvE, DistMult or ComplEx')
    # FB15k, FB15k-237, WN18 or WN18RR
    parser.add_argument("--dataset", type=str, default="WN18RR", help="数据集")
    parser.add_argument("--cuda", type=bool, default=True, help="use cuda (GPU)")
    parser.add_argument("--device", type=int, default=2)

    args = parser.parse_args()
    model_name = args.model_name
    print("模型: " + model_name)
    data_dir = "../data/%s/" % args.dataset     # 拼接形成数据集路径
    torch.backends.cudnn.deterministic = True
    seed = 20
    np.random.seed(seed)
    torch.manual_seed(seed)
    if torch.cuda.is_available:
        torch.cuda.manual_seed_all(seed)  # 消除模型训练的随机性，使结果可复现

    # 获取数据，reverse -> (t, r^-1, h)
    d = Data(data_dir=data_dir, reverse=True)     # valid和train也都读进来了，有txt文件就可以
    experiment = Experiment(model_name, num_iterations=200, batch_size=128, learning_rate=0.005,
                            decay_rate=1.0, ent_vec_dim=200, rel_vec_dim=200, cuda=args.cuda, device=args.device,
                            input_dropout=0.2, hidden_dropout=0.3, hidden_dropout1=0.45, hidden_dropout2=0.5,
                            feature_map_dropout=0.2, in_channels=1, out_channels=32, filt_h=1, filt_w=9,
                            label_smoothing=0.1)
    experiment.train_and_eval()


import pygame
from pygame import mixer

import numpy as np

from visualization.transition import Transition
from visualization.button import Button
from visualization.game import deck

from gym_environments.blackjack_env import BlackjackEnv

from agents.player_agent import Player
from agents.dealer_agent import Dealer
from agents.rl_agent import QLearningAgent

#declare other classes
transition_player = Transition()
dealer_bust_img = transition_player.images['dealer_bust']
player_bust_img = transition_player.images['player_bust']
robot_bust_img = transition_player.images['robot_bust']
dealer_turn_img = transition_player.images['dealer_turn']
dealer_wins_img = transition_player.images['dealer_wins']
player_wins_img = transition_player.images['player_wins']
robot_win_img = transition_player.images['robot_win']

env = BlackjackEnv()
observation = env.reset()

def main():
    initial_cards, player_sum, dealer_sum, ace = deck._deal_initial_cards()

    #declare agents
    dealer = Dealer(dealer_sum, initial_cards[2])
    player = Player(player_sum, [initial_cards[0], initial_cards[1]], ace)
    robot = QLearningAgent(env)

    pygame.init()
    mixer.init()
    robot.train(num_episodes=400000)
    screen = pygame.display.set_mode((640, 480), pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.HWACCEL)

    screen_width = screen.get_width()
    screen_height = screen.get_height()
    pygame.display.set_caption('blackjack')
    pygame.display.set_icon(deck.cardBacks[1])

    #COLOR PALLATE
    DARK_BLUE = (43, 65, 98)
    BLUE_GREY = (56, 95, 113)
    OFF_WHITE = (245, 240, 246)
    LIGHT_BROWN = (215, 179, 119)
    DARK_BROWN = (143, 117, 79)

    running = True

    #BUTTONS
    def hit():
        player._move('hit')
        click.play()
    def stay():
        player._move('stay')
        click.play()
    def replay():
        global observation
        initial_cards, player_sum, dealer_sum, ace = deck._deal_initial_cards()

        player._reset(player_sum, [initial_cards[0], initial_cards[1]], ace)
        dealer._reset(dealer_sum, initial_cards[2])
        observation = env.reset()

        shuffle.play()
    buttons = []
    button_width = 100
    button_height = 40
    big_button_width = 400
    big_button_height = 100
    hit_button_x = ((screen_width - button_width) // 2) - button_width // 2 - 10
    hit_button_y = (screen_height - button_height) // 2
    stay_button_x = ((screen_width - button_width) // 2) + button_width // 2 + 10
    stay_button_y = (screen_height - button_height) // 2
    replay_button_x = screen_width // 2 - big_button_width // 2
    replay_button_y = screen_width // 2 - big_button_height - 10
    hit_button = Button(hit_button_x, hit_button_y, button_width, button_height, "hit", hit)
    stay_button = Button(stay_button_x, stay_button_y, button_width, button_height, "stay", stay)
    replay_button = Button(replay_button_x, replay_button_y, big_button_width, big_button_height, 'replay', replay)
    buttons.extend([hit_button, stay_button, replay_button])

    #TILE
    pattern_image = pygame.image.load("public/pattern.png")
    pattern_image = pygame.transform.scale(pattern_image, (pattern_image.get_width() / 6, pattern_image.get_height() / 6))
    pattern_width, pattern_height = pattern_image.get_size()

    #SOUND EFFECTS
    click = pygame.mixer.Sound('public/sounds/click_high.wav')
    shuffle = pygame.mixer.Sound('public/sounds/shuffle.mp3')
    pygame.mixer.music.load('public/sounds/ipanema.mp3')

    click.set_volume(1.8)
    shuffle.set_volume(1.8)
    pygame.mixer.music.set_volume(0.5)

    pygame.mixer.music.play(-1)

    #button visibility decider

    replay() #this is to cause the first game from playing itself
    while (running):
        dealer_cards = dealer.cards
        player_cards = player.cards
        robot_cards = env.cards

        # CARD VARIABLES
        padding = 10
        player_card_delay = 10 + (20 * (len(player_cards) - 1))
        dealer_card_delay = 10
        robot_card_delay = 10

        screen.fill(BLUE_GREY)
        for x in range(0, screen_width, pattern_width):
                for y in range(0, screen_height, pattern_height):
                    screen.blit(pattern_image, (x, y))

        #DEAL CARDS FOR DEALER & ROBOT?

        if (player.done):
            if (not env.round_done):
                global observation
                action = np.argmax(robot.q_table[observation])
                observation, _, _, _ = env.step(action, True)
        if (env.round_done):
            if (not dealer.stop):
                dealer._move('hit')

        # PYGAME EVENTS
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                print(robot_cards)
                running = False
            for button in buttons:
                button.handle_event(event)

        # SHOW BUTTONS
        for button in buttons:
            if (not player.done):
                if (buttons.index(button) == 2):
                    button.set_visibility(False)
                else:
                    button.set_visibility(True)
                    button.draw(screen)
            else:
                if (buttons.index(button) != 2):
                    button.set_visibility(False)
                else:
                    if (dealer.stop):
                        button.draw(screen)
                        button.set_visibility(True)
                        screen.blit(player_bust_img, (0, 0))

        # SHOW DEALER CARDS
        for card in dealer_cards:
            screen.blit(card, (dealer_card_delay, 10))
            dealer_card_delay += 20
        if (len(dealer_cards) < 2):
            screen.blit(deck.cardBacks[0], (dealer_card_delay, 10))

        # SHOW PLAYER CARDS
        for card in player_cards:
            screen.blit(card, (screen_width - player_card_delay - card.get_width(), screen_height - padding - card.get_height()))
            player_card_delay -= 20

        #SHOW ROBOT CARDS
        for card in robot_cards:
            screen.blit(card, (robot_card_delay, screen_height - padding - card.get_height()))
            robot_card_delay += 20
        pygame.display.flip()

if __name__ == "__main__":
    main()


import time
from ble_MIDI import *
from hub import *
import force_sensor

#Plug in Force Sensor to port C
#push force button to play a range of notes
#right button on hub disconnects

def done():
    return button.pressed(button.RIGHT)

def play_note(note):
    Piano.on(note, velocity['f'])
    time.sleep(.1)
    Piano.off(note)
    time.sleep(.1)

def start():
    try:
        while not done():
            fs = force_sensor.force(port.C)
            print(fs)

            note_range = 108 - 21  # Total number of notes in the range
            note_value = int((fs / 100) * note_range) + 21  # Map the force sensor value to the note range

            play_note(note_value)

    except:
        pass

    print('disconnect')
    midi.disconnect()

midi = MIDI_Player('emma')
midi.wait_for_connection()
Piano = MIDI_Instrument(midi, instruments['Acoustic Grand Piano'], channel=0)

start()


# -*- coding: utf-8 -*-
"""
Created on Fri Jun  4 23:47:23 2021

@author: John
"""

import sys
import pandas as pd
from sqlalchemy import create_engine

def load_data(messages_filepath, categories_filepath):
    """Function to load data returns a dataframe"""

    messages = pd.read_csv(messages_filepath)
    categories = pd.read_csv(categories_filepath)

    # merge datasets
    df = pd.merge(messages, categories, on="id")

    return df

def clean_data(df):
    """Function to clean text data"""

    categories = df["categories"].str.split(";", expand=True)

    # select the first row of the categories dataframe
    row = categories.iloc[[1]]

    # remove last 2 characters of catergory names
    category_colnames = [category_name.split('-')[0] for category_name in row.values[0]]

    # rename the columns of `categories`
    categories.columns = category_colnames

    for column in categories:
        # set each value to be the last character of the string
        categories[column] = categories[column].astype(str).str[-1:]

        # convert column from string to numeric
        #categories[column] = pd.to_numeric(categories[column], downcast="integer")
        categories[column] = categories[column].astype(int)

    categories.drop(categories[categories['related'] > 1].index, inplace = True)
    # drop the original categories column from `df`
    df.drop("categories", axis=1, inplace=True)

    # concatenate the original dataframe with the new `categories` dataframe
    df = pd.concat([df, categories],join='inner',axis=1)

    # drop duplicates
    df=df.drop_duplicates(subset=['message'])

    return df

def save_data(df, database_filename):
    """save dataframe as sql database file"""
    engine = create_engine('sqlite:///' + database_filename)
    df.to_sql('DisasterResponse', engine, index=False,if_exists='replace')

def main():
    """Function to call all sub functions  to process and clean data."""

    if len(sys.argv) == 4:

        messages_filepath, categories_filepath, database_filepath = sys.argv[1:]

        print('Loading data...\n    MESSAGES: {}\n    CATEGORIES: {}'
              .format(messages_filepath, categories_filepath))
        df = load_data(messages_filepath, categories_filepath)

        print('Cleaning data...')
        df = clean_data(df)

        print('Saving data...\n    DATABASE: {}'.format(database_filepath))
        save_data(df, database_filepath)

        print('Cleaned data saved to database!')

    else:
        print('Please provide the filepaths of the messages and categories '\
              'datasets as the first and second argument respectively, as '\
              'well as the filepath of the database to save the cleaned data '\
              'to as the third argument. \n\nExample: python process_data.py '\
              'disaster_messages.csv disaster_categories.csv '\
              'DisasterResponse.db')

if __name__ == '__main__':
    main()


"zarr companion: benchmark Zarr companion file for band access"

import random

import zarr

from .utils import parse_args
from .benchmark_abc import BenchmarkABC, Verbosity

class ZarrCompanionBenchmark(BenchmarkABC, re_str=r'.*profile\.zarr'):
    "benchmark for profile converted to zarr"

    def __init__(self, path: str) -> None:
        self.file = path

    def task(self) -> None:
        z = zarr.open(self.file, mode='r')

        # Y,X,C Zarr dataset
        profile = z['0']

        y = random.randrange(profile.shape[0])
        x = random.randrange(profile.shape[1])

        band = profile[y, x, :]  # load it
        sum(band)  # do something with it

    def info(self, verbosity: Verbosity) -> str:
        info = f'Zarr Companion: {self.file}'

        if verbosity == Verbosity.VERBOSE:
            data = zarr.open(self.file, mode='r')['0']
            zarr_info = str(data.info)[:-1].split('\n')
            zarr_info = [item.split(':') for item in zarr_info]
            zarr_info = {l.strip(): r.strip() for (l, r) in zarr_info}

            info += (f'\n\tshape = {data.shape}, chunks = {data.chunks}, '
                     f'compressor = {data.compressor}, filters = {data.filters}')
            info += (f'\n\torder = {data.order}, size (mem) = {zarr_info["No. bytes"]}'
                     f', size (disk) {zarr_info["No. bytes stored"]}')

        return info

def _main():

    args = parse_args()

    for file in args.files:
        ZarrCompanionBenchmark(file).bench(
            Verbosity.VERBOSE, enable_gc=args.gc, number=args.number, repeat=args.repeat)

if __name__ == "__main__":
    _main()

"""
ZarrCompanionBenchmark (duration averaged on 1000 iterations, repeated 3 times.)
results: [2.404e-04, 2.301e-04, 2.302e-04]: 2.301e-04 s to 2.404e-04 s, 2.336e-04 s ± 5.912e-06 s
Zarr Companion: files/z-series/profile.zarr
        shape = (167, 439, 5), chunks = (84, 439, 5), compressor = None, filters = None
        order = C, size (mem) = 366565 (358.0K), size (disk) 369004 (360.4K)

ZarrCompanionBenchmark (duration averaged on 1000 iterations, repeated 3 times.)
results: [3.583e-04, 3.521e-04, 3.527e-04]: 3.521e-04 s to 3.583e-04 s, 3.544e-04 s ± 3.372e-06 s
Zarr Companion: files/test-channel-image/profile.zarr
        shape = (512, 512, 31), chunks = (128, 128, 16), compressor = None, filters = None
        order = C, size (mem) = 16252928 (15.5M), size (disk) 16777463 (16.0M)
"""


import os
import sys
import subprocess
from Bio import SeqIO
import multiprocessing

external_wrappers_dir = '/'.join(
    os.path.dirname(os.path.realpath(__file__)).split('/')[:-1] + ['external_wrappers']) + '/'

def run_nanopolish_variants(data):
    workspace, window, cmd = data
    stdout_file_1 = workspace + window.replace(':', '_') + '.log'
    stderr_file_1 = workspace + window.replace(':', '_') + '.err'
    stdout_handle_1 = open(stdout_file_1, 'w')
    stderr_handle_1 = open(stderr_file_1, 'w')
    proc = subprocess.Popen(cmd, stdout=stdout_handle_1, stderr=stderr_handle_1)
    proc.wait()
    stdout_handle_1.close();
    stderr_handle_1.close();

class Assembly():
    def __init__(self, assembly_fasta, sample_name, logObject, contig_fasta=None, assembly_graph=None):
        self.assembly_fasta = os.path.abspath(assembly_fasta)
        self.sample_name = sample_name
        self.logFile = logObject
        self.contig_fasta = contig_fasta
        self.assembly_graph = assembly_graph

    def filter_contigs_by_size(self, working_dir, size_filter=0, change_reference=True):
        """ Filter assembly contigs by size threshold. """
        try:
            working_dir = os.path.abspath(working_dir) + '/'
            assert(os.path.isdir(working_dir))
            self.logFile.info('-'*70)
            self.logFile.info("Filtering assembly %s for contigs shorter than %d." % (self.assembly_fasta, size_filter))
            resulting_assembly = working_dir + self.sample_name + '.filtered.fasta'
            assembly_handle = open(resulting_assembly, 'w')
            with open(self.assembly_fasta) as oaf:
                for rec in SeqIO.parse(oaf, 'fasta'):
                    if len(str(rec.seq)) >= size_filter:
                        assembly_handle.write('>' + rec.description + '\n' + str(rec.seq) + '\n')
            assembly_handle.close()
            assert(os.path.isfile(resulting_assembly))
            self.logFile.info("Successfully filtered assembly. Resulting assembly file can be found at: %s" % resulting_assembly)
            if change_reference:
                self.assembly_fasta = resulting_assembly
                self.assembly_graph = None
                self.contig_fasta = None
            return resulting_assembly
        except RuntimeError as e:
            self.logFile.error("Something went wrong when filtering assembly for short contigs. Raising exception ..." % e)
            raise RuntimeError

    def detect_adapters(self, working_dir, options='-r -e -f Directive -v --no_protection --adaptorsdb', cores=1):
        """ Use GAEMR to detect adapters in assembly. Returns commands for guinan analysis and adapter removal. """
        try:
            working_dir = os.path.abspath(working_dir) + '/'
            assert(os.path.isdir(working_dir) and os.path.isfile(self.contig_fasta))
            gaemr_version_info = open(external_wrappers_dir + "run_contamination_screen.txt").readlines()[0]
            self.logFile.info('-'*70)
            self.logFile.info("Screening for adapters with GAEMR version %s" % gaemr_version_info)
            result_txt = working_dir + self.sample_name + '.screen.out'
            gaemr_cmd = ['/bin/bash', external_wrappers_dir + 'run_contamination_screen.sh', '-t', str(cores), options, '-o',
                        result_txt, '-i', self.contig_fasta]
            self.logFile.info("Executing the command: %s" % ' '.join(gaemr_cmd))
            stdout_file = working_dir + self.sample_name + ".contamination_screen.log"
            stderr_file = working_dir + self.sample_name + ".contamination_screen.err"
            stdout_handle = open(result_txt, 'w'); stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(gaemr_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close(); stderr_handle.close()
            commands_result_file = working_dir + self.sample_name + '.screen.out.directives.txt'
            assert(os.path.isfile(result_txt) and os.path.isfile(commands_result_file))
            self.logFile.info("GAEMR adapter detection finished successfully!")
            return commands_result_file
        except RuntimeError as e:
            self.logFile.error("GAEMR adapter detection was not able to be run properly! Error message: %s. Raising exception ..." % e)
            raise RuntimeError

    def remove_adapters(self, command_file, working_dir, options='--sort_by_length --rename', change_reference=True):
        #  Use guinan suite to remove adapters in assembly.
        try:
            working_dir = os.path.abspath(working_dir) + '/'
            assert(os.path.isdir(working_dir) and os.path.isfile(command_file) and os.path.isfile(self.contig_fasta) and os.path.isfile(self.assembly_graph))
            guinan_version_info = open(external_wrappers_dir + "modify_assembly.txt").readlines()[0]
            self.logFile.info('-'*70)
            self.logFile.info("Removing adapters with guinan version %s" % guinan_version_info)
            result_header = working_dir +  self.sample_name + '.adapter-free'
            guinan_cmd = ['/bin/bash', external_wrappers_dir + 'modify_assembly.sh', options, '--agp', self.assembly_graph,
                          '--command_file', command_file, '--output_header', result_header, self.contig_fasta]
            self.logFile.info("Executing the command: %s" % ' '.join(guinan_cmd))
            stdout_file = working_dir + self.sample_name + ".contamination_screen.log"
            stderr_file = working_dir + self.sample_name + ".contamination_screen.err"
            stdout_handle = open(stdout_file, 'w'); stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(guinan_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close(); stderr_handle.close()
            # TODO: improve checksafe
            result_file = result_header + '.scaffolds.fasta'
            assert(os.path.isfile(result_file))
            self.logFile.info("Successfully filtered out any adapters with guianan, filtered assembly can be found at: %s" % result_file)
            if change_reference:
                self.assembly_fasta = result_file
                self.assembly_graph = None
                self.contig_fasta = None
            self.logFile.info("guinan adapter removal finished successfully!")
            return result_file
        except RuntimeError as e:
            self.logFile.error("guinan adapter removal was not able to be run properly! Error message: %s. Raising exception ..." % e)
            raise RuntimeError

    def run_mlst(self, working_dir):
        """ Performing mlst on assembly. """
        try:
            working_dir = os.path.abspath(working_dir) + '/'
            assert(os.path.isdir(working_dir))
            mlst_version_info = open(external_wrappers_dir + "mlst.txt").readlines()[0]
            self.logFile.info('-'*70)
            self.logFile.info("Performing MLST of %s" % mlst_version_info)
            result_txt = working_dir + self.sample_name + '.txt'
            mlst_cmd = ['/bin/bash', external_wrappers_dir + 'mlst.sh', self.assembly_fasta]
            self.logFile.info("Executing the command: %s" % ' '.join(mlst_cmd))
            stderr_file = working_dir + self.sample_name + ".mlst.err"
            stdout_handle = open(result_txt, 'w'); stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(mlst_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close(); stderr_handle.close()
            # TODO: improve checksafe
            assert(os.path.isfile(result_txt) and os.path.getsize(result_txt) > 100)
            self.logFile.info("mlst finished successfully!")
        except RuntimeError as e:
            self.logFile.error("mlst was not able to be run properly! Error message: %s. Raising exception ..." % e)
            raise RuntimeError

    def run_gaemr_formatter(self, working_dir, options='-g 1 -c 100 -r', reference_change=True):
        try:
            assert (os.path.isfile(self.assembly_fasta))
            workspace = os.path.abspath(working_dir) + '/'

            gaemr_version = open(external_wrappers_dir + 'make_standard_assembly_files.txt').readlines()[0]
            self.logFile.info("-" * 70)
            self.logFile.info("Formatting assemblies with GAEMR for QC and Vesper2, using %s" % gaemr_version)

            output_results = workspace + '/' + self.sample_name

            gaemr_cmd = ["sh", external_wrappers_dir + "make_standard_assembly_files.sh", options, '-S', self.assembly_fasta,
                         '-o', output_results]

            self.logFile.info("Executing the command: %s" % ' '.join(gaemr_cmd))
            stdout_file = workspace + "gaemr_formatting.log"
            stderr_file = workspace + "gaemr_formatting.err"
            stdout_handle = open(stdout_file, 'w')
            stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(gaemr_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close();
            stderr_handle.close()

            resulting_graph = output_results + '.agp'
            resulting_contig = output_results + '.contigs.fasta'
            resulting_scaffold = output_results + '.scaffolds.fasta'

            assert (os.path.isfile(resulting_graph) and os.path.isfile(resulting_contig) and os.path.isfile(resulting_scaffold))
            self.logFile.info("Results are available at %s" % workspace)

            if reference_change:
                self.assembly_fasta = resulting_scaffold
                self.contig_fasta = resulting_contig
                self.assembly_graph = resulting_graph
            return ([resulting_scaffold, resulting_contig, resulting_graph])
        except RuntimeError as e:
            self.logFile.error("Unable to run GAEMR formatting of assembly for QC. Raising exception ..." % e)
            raise RuntimeError

    def run_gaemr_qc(self, read_list, working_dir, options='--force --analyze_rna', cores=1):
        try:
            assert (os.path.isfile(self.assembly_fasta) and os.path.isfile(self.contig_fasta) and os.path.isfile(self.assembly_graph))
            workspace = os.path.abspath(working_dir) + '/'

            gaemr_version = open(external_wrappers_dir + 'gaemr.txt').readlines()[0]
            self.logFile.info("-" * 70)
            self.logFile.info("Running GAEMR for QC, using %s" % gaemr_version)

            os.chdir(workspace)

            gaemr_cmd = ["sh", external_wrappers_dir + "gaemr.sh", options, '-t', str(cores), '-a',
                         self.assembly_graph, '-c', self.contig_fasta, '-s', self.assembly_fasta, '--read_list=' + read_list]

            self.logFile.info("Executing the command: %s" % ' '.join(gaemr_cmd))
            stdout_file = workspace + "gaemr_qc.log"
            stderr_file = workspace + "gaemr_qc.err"
            stdout_handle = open(stdout_file, 'w')
            stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(gaemr_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close();
            stderr_handle.close()

            # Check GAEMR QC ran successfully
            assert(os.path.isdir(workspace + '/gaemr/'))
            result_files = ['assembly.basic_assembly_stats.table.txt', 'assembly.blast_hit_taxonomy.table.txt',
                            'assembly.contig_detail.table.txt', 'assembly.gap_analysis.table.txt',
                            'assembly.gap_ss_analysis.table.txt', 'assembly.scaffold_detail.table.txt',
                            'assembly.scaffolds.bam_phys_cvg_stats.table.txt',
                            'assembly.scaffolds.bam_seq_cvg_stats.table.txt',
                            'assembly.scaffolds.simple_bam_stats.table.txt', 'fragment.scaffolds.insert_size.table.txt']
            for f in result_files:
                fpath = workspace + '/gaemr/table/' + f
                assert(fpath)
                with open(fpath) as ofp:
                    file_line_count = len(ofp.readlines())
                    assert(file_line_count > 2)

            self.logFile.info("Results are available at %s" % workspace + '/gaemr/')
            return
        except RuntimeError as e:
            self.logFile.error("Unable to run GAEMR for QC. Raising exception ..." % e)
            raise RuntimeError

    def run_gaemr_qc_ont(self, read_list, working_dir, options='--force --analyze_rna', cores=1):
        try:
            assert (os.path.isfile(self.assembly_fasta) and os.path.isfile(self.contig_fasta) and os.path.isfile(self.assembly_graph))
            workspace = os.path.abspath(working_dir) + '/'

            gaemr_version = open(external_wrappers_dir + 'gaemr_ont.txt').readlines()[0]
            self.logFile.info("-" * 70)
            self.logFile.info("Running GAEMR for QC, using %s" % gaemr_version)

            os.chdir(workspace)

            gaemr_cmd = ["sh", external_wrappers_dir + "gaemr_ont.sh", options, '-t', str(cores), '-a',
                         self.assembly_graph, '-c', self.contig_fasta, '-s', self.assembly_fasta, '--read_list=' + read_list]

            self.logFile.info("Executing the command: %s" % ' '.join(gaemr_cmd))
            stdout_file = workspace + "gaemr_qc.log"
            stderr_file = workspace + "gaemr_qc.err"
            stdout_handle = open(stdout_file, 'w')
            stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(gaemr_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close();
            stderr_handle.close()

            # Check GAEMR QC ran successfully
            assert(os.path.isdir(workspace + '/gaemr/'))
            result_files = ['assembly.basic_assembly_stats.table.txt', 'assembly.blast_hit_taxonomy.table.txt',
                            'assembly.contig_detail.table.txt', 'assembly.gap_analysis.table.txt',
                            'assembly.gap_ss_analysis.table.txt', 'assembly.scaffold_detail.table.txt',
                            'assembly.scaffolds.bam_phys_cvg_stats.table.txt',
                            'assembly.scaffolds.bam_seq_cvg_stats.table.txt',
                            'assembly.scaffolds.simple_bam_stats.table.txt', 'fragment.scaffolds.insert_size.table.txt']
            for f in result_files:
                fpath = workspace + '/gaemr/table/' + f
                assert(fpath)
                with open(fpath) as ofp:
                    file_line_count = len(ofp.readlines())
                    assert(file_line_count > 2)

            self.logFile.info("Results are available at %s" % workspace + '/gaemr/')
            return
        except RuntimeError as e:
            self.logFile.error("Unable to run GAEMR for QC. Raising exception ..." % e)
            raise RuntimeError

    def run_pilon(self, working_dir, nanopore_bam=None, illumina_bam=None, options='', cores=1, reference_change=False):
        try:
            assert (os.path.isfile(illumina_bam) or os.path.isfile(nanopore_bam))
            workspace = os.path.abspath(working_dir) + '/'
            assert (os.path.isdir(working_dir))
            pilon_version = open(external_wrappers_dir + 'pilon.txt').readlines()[0]
            self.logFile.info("-" * 70)
            self.logFile.info("Running pilon for illumina and/or nanopore to refine assembly, using version %s" % pilon_version)

            result_assembly = workspace + self.sample_name + '.fasta'
            result_changes = workspace + self.sample_name + '.changes'
            pilon_cmd = ["/bin/bash", external_wrappers_dir + "pilon.sh", options, '--genome', self.assembly_fasta, '--changes',
                         '--threads', str(cores), '--output', self.sample_name, '--outdir', workspace]
            if nanopore_bam:
                pilon_cmd += ['--nanopore', nanopore_bam]
            if illumina_bam:
                pilon_cmd += ['--frags', illumina_bam]

            self.logFile.info("Executing the command: %s" % ' '.join(pilon_cmd))
            stdout_file = workspace + 'pilon.log'
            stderr_file = workspace + "pilon.err"
            stdout_handle = open(stdout_file, 'w')
            stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(pilon_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close();
            stderr_handle.close()

            assert (os.path.isfile(result_assembly))
            self.logFile.info("Results are available at %s" % result_assembly)

            if reference_change:
                self.assembly_fasta = result_assembly

            return [result_assembly, result_changes]
        except RuntimeError as e:
            self.logFile.error("Unable to run Pilon. Raising exception ..." % e)
            raise RuntimeError

    def run_nanopolish(self, nanopore_fastq, nanopore_bam, working_dir, nanopolish_variants_options='', cores=8, reference_change=True):
        try:
            workspace = os.path.abspath(working_dir) + '/'
            assert (os.path.isfile(nanopore_fastq) and os.path.isfile(nanopore_bam) and os.path.isdir(working_dir))

            workspace_vcf_dir = working_dir + 'vcfs/'
            workspace_log_dir = working_dir + 'logs/'

            os.system('mkdir %s' % workspace_vcf_dir)
            os.system('mkdir %s' % workspace_log_dir)
            nanopolish_version = open(external_wrappers_dir + 'nanopolish.txt').readlines()[0]
            self.logFile.info("-" * 70)
            self.logFile.info("Running nanopolish to refine assembly, using version %s" % nanopolish_version)
            result_assembly = workspace + self.sample_name + '.fasta'

            # run polishing.
            nanopolish_variants_cmd_1 = ["/bin/bash", external_wrappers_dir + "nanopolish_makerange.sh",
                                               self.assembly_fasta]

            self.logFile.info("Executing the command: %s" % ' '.join(nanopolish_variants_cmd_1))
            stdout_file_1 = workspace + 'nanopolish_variants_1.log'
            stderr_file_1 = workspace + 'nanopolish_variants_1.err'
            stdout_handle_1 = open(stdout_file_1, 'w')
            stderr_handle_1 = open(stderr_file_1, 'w')
            proc1 = subprocess.Popen(nanopolish_variants_cmd_1, stdout=stdout_handle_1, stderr=stderr_handle_1)
            proc1.wait()
            stdout_handle_1.close(); stderr_handle_1.close();

            cmds = []
            with open(stdout_file_1) as osf1:
                for line in osf1:
                    line = line.strip()
                    nanopolish_cmd = ['/bin/bash', external_wrappers_dir + "nanopolish.sh", "variants", "--consensus",
                                      nanopolish_variants_options,
                                      '-g', self.assembly_fasta, "-o",
                                      workspace_vcf_dir + 'polished.' + line.replace(':', '_') + '.vcf', '-w', line,
                                      '-r', nanopore_fastq, '-b', nanopore_bam, '-t', '2', '--min-candidate-frequency',
                                      '0.1']
                    self.logFile.info("Will be executing the command: %s" % ' '.join(nanopolish_cmd))
                    cmds.append([workspace_log_dir, line, nanopolish_cmd])

            p = multiprocessing.Pool(int(cores/2))
            try:
                p.map(run_nanopolish_variants, cmds)
            except:
                self.logFile.error("Problem with running nanopolish variants --consensus. Raising exception ...")
                p.close()
                raise RuntimeError
            else:
                p.close()

            vcflist_file = workspace + 'vcfs.list'
            vcflist_handle = open(vcflist_file, 'w')
            for f in os.listdir(workspace_vcf_dir):
                vcflist_handle.write(workspace_vcf_dir + f + '\n')
            vcflist_handle.close()

            # combine results across windows and convert to FASTA format.
            nanopolish_vcf2fasta_cmd = ["/bin/bash", external_wrappers_dir + "nanopolish.sh", "vcf2fasta",
                                        "--skip-checks", '-g', self.assembly_fasta, '-f', vcflist_file]
            self.logFile.info("-" * 70)
            self.logFile.info("Executing the command: %s" % ' '.join(nanopolish_vcf2fasta_cmd))
            stderr_file = workspace + 'nanopolish_vcf2fasta.err'
            stdout_handle = open(result_assembly, 'w')
            stderr_handle = open(stderr_file, 'w')
            proc = subprocess.Popen(nanopolish_vcf2fasta_cmd, stdout=stdout_handle, stderr=stderr_handle)
            proc.wait()
            stdout_handle.close(); stderr_handle.close()

            assert (os.path.isfile(result_assembly) and os.path.getsize(result_assembly) > 100)
            self.logFile.info("Polished assembly available at %s" % result_assembly)

            if reference_change:
                self.assembly_fasta = result_assembly
            return result_assembly
        except RuntimeError as e:
            self.logFile.error("Unable to run Nanopolish. Raising exception ..." % e)
            raise RuntimeError


from typing import Any
import time
from functools import wraps

class StopwatchMaker(object):
    """
    Wrapper class that makes timing functions easier.
    If wrapped the function will be timed unless you pass in the keyword 'timed = False'.
    You can set the loading message with keyword 'loading_msg = ...' and end message with keyword 'end_msg = ...'.
    """

    def __init__(self, f):
        self._f = f

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        timed: bool = True
        loading_msg: str = None
        end_msg: str = None

        if "timed" in kwds:
            timed = kwds.pop("timed")
        if "loading_msg" in kwds:
            loading_msg = kwds.pop("loading_msg")
        if "end_msg" in kwds:
            end_msg = kwds.pop("end_msg")

        if not timed:
            return self._f(*args, **kwds)

        if loading_msg:
            print(loading_msg)

        timer = time.time()
        ret = self._f(*args, **kwds)
        timer = time.time() - timer

        if end_msg:
            print(end_msg, end='')
        print(timer)
        return ret

class StopwatchMessageMaker:
    def __init__(self, loading_msg = None, end_msg = None) -> None:
        self._loading_msg = loading_msg
        self._end_msg = end_msg

    def __call__(self, f) -> any:
        lm = self._loading_msg
        em = self._end_msg

        class Stopwatch:
            def __init__(self, f) -> None:
                self._f = f

            def __call__(self, *args: Any, **kwds: Any) -> Any:

                if lm:
                    print(lm)

                timer = time.time()
                ret = self._f(*args, **kwds)  #check if you are acessing the right function
                timer = time.time() - timer

                if em:
                    print(em, end='')
                print(timer)
                return ret

        return Stopwatch(f)

# def stopwatch_factory(loading_msg: str = None, end_msg: str = None):
#     def timer(func, *params):
#         if loading_msg: print(loading_msg)

#         timer = time.time()
#         try:
#             ret = func(*params) if params and func else func() if func else None
#         except BaseException as e:
#             raise
#         timer = time.time() - timer

#         if end_msg: print(end_msg, end="")
#         print(f'{timer:^4}')
#         return ret

#     return timer

# @staticmethod
#     def timed(func: callable = lambda *args: None, *params,  loading_msg: str = None, end_msg: str = None) -> any:
#         """Prints out a loading_msg and calls the passed func with given params.
#         After the execution of given function prints out the end_msg followed by the time it took func to complete."""

#         if loading_msg: print(loading_msg)

#         timer = time.time()
#         try:
#             ret = func(*params) if params and func else func() if func else None
#         except BaseException as e:
#             raise
#         timer = time.time() - timer

#         if end_msg: print(end_msg, end="")
#         print(f'{timer:^4}')
#         return ret


from django.shortcuts import render, redirect, get_object_or_404
from .models import Phone

def index(request):
    return redirect('catalog')

def show_catalog(request):
    template = 'catalog.html'
    object = Phone.objects.all()
    sort = request.GET.get('sort', 1)
    if sort == 'name':
        object = Phone.objects.order_by('name')
        context = {'phones': object}
    elif sort == 'max_price':
        object = Phone.objects.order_by('-price')
        context = {'phones': object}
    elif sort == 'min_price':
        object = Phone.objects.order_by('price')
        context = {'phones': object}
    else:
        context = {'phones': object}
    return render(request, template, context)

def show_product(request, slug):
    post = get_object_or_404(Phone, slug=slug)
    template = 'product.html'
    context = {'phone': post}
    return render(request, template, context)


# -*- coding: utf-8 -*-
"""
Created on Fri Jul 21 00:48:27 2017

@author: DataScience
"""

# -*- coding: utf-8 -*-
"""
Created on Thu Jul 20 18:17:59 2017

@author: DataScience
"""

#生成上证50支股票，流动股东变化间隔的分布图

import cPickle as cp
import datetime as dt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

shares = cp.load(open('shares.pkl'))
#res = pd.DataFrame()
res = []

for stock in list(shares.keys()):
    Holder_list = shares[stock]['holder_liqname']
    Time_list = shares[stock]['time']

    index = 0
    change_index = []

    for i in Holder_list:
        if index == 0:
            index += 1
            continue
        elif (i == Holder_list[index-1]) :
            index += 1
            continue
        else:
            change_index.append(index)
            index += 1

    changeT_list = []

    index = 0
    for j in Time_list:
        if index in change_index or index == 0:
            changeT_list.append(dt.datetime.strptime(j,"%Y-%m-%d").date())

        index += 1

    series = pd.Series(changeT_list)
    dif = series.diff()
    res_tmp = (dif[1:] / np.timedelta64(1, 'D')).astype(int)
   # res = pd.concat([res,res_tmp],axis = 1)
    res= res + list(res_tmp)
#==============================================================================
# res.columns = list(shares.keys())
# res.to_csv('SH50_liq_change.csv')
#==============================================================================
plt.hist(res,bins=40, histtype="stepfilled", color="#CD4F39")
plt.title('SH50_liq',fontsize=30 )
plt.xlabel('Gap',fontsize=20)
plt.ylabel('Num',fontsize=20)


#coding=utf-8
from django.conf.urls.defaults import *
#from view import current_datetime,hello,hours_ahead,template_datetime,dir_datetime,html_datetime,current_url_view_good,display_meta,model_meta,search_form
from book_sql import book_list
from linshi import Thanks,cs_disange,method_splitter,some_page_get,some_page_post,wcs_s
#from view import search,contact,setEmail,thanks

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
#admin.autodiscover()

urlpatterns = patterns('view',
                       ('^$','hello'),
                       ('^current_time/$','current_datetime'),
                       ('^current_time(\d{1,2})/$','hours_ahead'),
                       ('^template_datetime/$','template_datetime'),
                       ('^html_datetime/$','html_datetime'),
                       ('^dir_datetime/$','dir_datetime'),
                       ('^book_list/$',book_list),
                       (r'^admin/',include(admin.site.urls)),
                       ('^page/$','current_url_view_good'),
                       ('^meta/$','display_meta'),
                       ('^model_meta','model_meta'),
                       (r'^search-form/$','search_form'),
                       ('^search/$','search'),
                       ('^contact/$','contact'),
                       ('^setEmail/$','setEmail'),
                       ('^thanks/$','thanks'),
                       ('^linshi/(?P<thanks>\w+)/$',Thanks), #命名组传递参数
                       ('^(?P<thanks>xiao\w+)/$',cs_disange,{'name':'No Thanks.html'}), #使用第三个参数
                       ('^(?P<thanks>[^xiao]\w+)/$',cs_disange,{'name':'thanks.html'}), #使用第三个参数
                       ('^@@/$',cs_disange,{'name':'No Thanks.html','thanks':'suru cuowu'}),#伪造捕捉的URLconf值
                       ('^@somepage/$',method_splitter,{'GET':some_page_get,'POST':some_page_post}),
                       #('^wcs_s/$',wcs_s),
                       #('^current_time/',include('wcs_s'))

)


# hello_world.py
from datetime import timedelta
from airflow import DAG
from airflow.utils.dates import days_ago
from airflow.operators.bash import BashOperator
from airflow.operators.python import PythonOperator
from airflow.operators.python_operator import PythonVirtualenvOperator

with DAG(
    dag_id="train_infer", # DAG의 식별자용 아이디입니다.
    description="train model and get inference", # DAG에 대해 설명합니다.
    start_date=days_ago(7), # DAG 정의 기준 2일 전부터 시작합니다.
    schedule_interval="0 0 * * *", # 매일 06:00에 실행합니다.
    tags=["model"],
) as dag:

    t0 = BashOperator(
    task_id="credential",
    bash_command='export GOOGLE_APPLICATION_CREDENTIALS="/opt/ml/wine/airflow/deep-theorem-391805-8dd50cc51ba5.json"',
    dag=dag,
    )

    t1 = BashOperator(
    task_id="preprocess",
    bash_command="python /opt/ml/wine/code/data/prepare_data.py",
    dag=dag,
    )

    t2 = BashOperator(
    task_id="train",
    bash_command="python /opt/ml/wine/Recbole/train.py --model_name DCN",
    dag=dag,
    )

    t3 = BashOperator(
    task_id="inference",
    bash_command="python /opt/ml/wine/Recbole/inference.py",
    dag=dag,
    )
    # 테스크 순서를 정합니다.
    # t1 실행 후 t2를 실행합니다.
    t0 >> t1 >> t2 >> t3


from django.http import Http404
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm
from django.contrib.auth.decorators import login_required
from blog.models import Post
from .models import User
import datetime

# Create your views here.
def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Your account has been created. You can now login')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

@login_required
def profile(request, username):
    # current_user = request.user
    try:
        current_user_id = User.objects.get(username=username)
    except User.DoesNotExist:
        raise Http404("User Does Not Exist")
    profile_context = {
        "user_posts": Post.objects.filter(author=current_user_id),
        "queried_user": User.objects.get(username=username)
    }
    return render(request, 'users/profile.html', profile_context)

@login_required
def specific_blog(request, username, title):
    try:
        current_user_id = User.objects.get(username=username)
        post = Post.objects.get(title=title, author=current_user_id)
    except User.DoesNotExist:
        raise Http404("User Does Not Exist")
    context = {
            "user_post": post
        }
    return render(request, 'users/userblog.html', context)

@login_required
def addPost(request):
    if request.method == 'POST':
        if 'data' in request.POST:
            blog_title = request.POST['title']
            blog_data = request.POST['data']
            current_user = request.user
            # print(current_user)
            # print(type(current_user))
            # print(current_user.id)
            object = Post.objects.create(title=blog_title, content=blog_data, date_posted=datetime.datetime.now(), author=current_user)
            object.save()
            print("This Works and object saved!!!")
    context = {
        'message': 'Your Post has been Added !!! ',
        'posts': Post.objects.all(),
        'user': request.user
    }
    return render(request, 'blog/home.html', context)


from django.contrib import admin
from django.urls import path
from api import views
from django.conf.urls.static import static
from django.conf import settings
from rest_framework_jwt.views import obtain_jwt_token
from knox import views as knox_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.UserRegistration.as_view()),
    path('books/',views.ShopList.as_view()),
    path('books/<int:pk>/',views.ShopDetail.as_view()),
    path('addproduct/',views.ProductList.as_view()),
    path('viewproduct/<int:pk>/',views.ProductDetail.as_view()),
    path('viewproductdetails/<int:pk>/<int:productID>/',views.ProductDetailView.as_view()),
    path('cart/',views.AddToCart.as_view()),
    path('cartview/<int:pk>/',views.CartView.as_view()),
    path('cartviewss/<int:pk>/',views.updateQuantity.as_view()),
    path('register/', views.RegisterAPI.as_view(), name='register'),
    path('login', views.LoginAPI.as_view(), name='login'),
    path('logout', knox_views.LogoutView.as_view(), name='logout'),
    path('logoutall/', knox_views.LogoutAllView.as_view(), name='logoutall'),

]

if settings.DEBUG is True:
    urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)


class Solution:
    def checkStraightLine(self, coordinates: List[List[int]]) -> bool:
        c, n = coordinates, len(coordinates)
        slopex = c[1][0]-c[0][0]
        slopey = c[1][1]-c[0][1]

        for i in range(n):
            dx = c[i][0]-c[0][0]
            dy = c[i][1]-c[0][1]
            if slopex * dy != slopey * dx:
                return False

        return True


import os
import sys
import time
import serial
import logging

LOG = logging.getLogger(__name__)

# unless an explicit RADIORA_BRIDGE_TTY is specified to use, this searches by default across
# a set of common TTYs to find a RadioRA Classic RS232 module
DEFAULT_RADIORA_BRIDGE_TTY_TO_SEARCH = [
    '/dev/tty.usbserial-A501SGSU',
    '/dev/tty.usbserial-A501SGSV',
    '/dev/tty.usbserial-A501SGSW',
    '/dev/tty.usbserial-A501SGSX',
    '/dev/tty.usbserial-A501SGSY',
    '/dev/tty.usbserial-A501SGSZ',
    '/dev/tty.usbserial-A501SGT0',
    '/dev/tty.usbserial-A501SGT1',
    '/dev/tty.usbserial-A501SGT2',
    '/dev/tty.usbserial-A501SGT3',
    '/dev/ttyS0',         # Raspberry Pi mini UART GPIO
#    '/dev/ttyAMA0',       # Raspberry Pi GPIO pins 14/15 (pre-Bluetooth RPi 3)
    '/dev/serial0',       # RPi 3 serial port alias 1
    '/dev/serial1',       # RPi 3 serial port alias 2
    '/dev/tty.usbserial', # typical MacOS USB serial adapter
    '/dev/ttyUSB0',       # Linux USB serial 1
    '/dev/ttyUSB1'        # Linux USB serial 2
]

class RadioRASerial:

    def __init__(self):
        self.version = None
        self.tty_timeout = int(os.environ['RADIORA_BRIDGE_TTY_TIMEOUT']) if 'RADIORA_BRIDGE_TTY_TIMEOUT' in os.environ else 1
        ttys_to_search = DEFAULT_RADIORA_BRIDGE_TTY_TO_SEARCH

        # NOTE: RADIORA_BRIDGE_TTY environment variable overrides the default search paths
        if 'RADIORA_BRIDGE_TTY' in os.environ:
            tty_config = os.environ['RADIORA_BRIDGE_TTY']
            logging.info(">> RadioRA Classic device search paths overridden by env variable RADIORA_BRIDGE_TTY=" + tty_config)
            ttys_to_search = tty_config.split(',')

        self.__discover_radiora_serial__(ttys_to_search)

    def __discover_radiora_serial__(self, ttys_to_search):
        LOG.info(">> Discovering RadioRA device on serial interfaces: {}".format(', '.join(ttys_to_search)))
        for tty in ttys_to_search:
            try:
                if not os.path.exists(tty):
                    logging.info(">> Serial device {} does not exist, ignoring".format(tty))
                    continue

                LOG.warning('>> Testing tty {}'.format(tty))
                self.tty = tty
                self.serial = serial.Serial(tty,
                                            baudrate=9600, # 9600 baud is required by RA-RS232
                                            parity=serial.PARITY_NONE,
                                            stopbits=serial.STOPBITS_ONE,
                                            bytesize=serial.EIGHTBITS,
                                            dsrdtr=True, rtscts=True,
                                            timeout=self.tty_timeout)
                self.writeCommand('VERI')
                response = self.readData()

                # response = REV,M<Master Revision>,S<Slave Revision>, e.g. REV,M3.14,S1.01
                if ((response != None) and response.startswith('REV,')):
                    self.version = response.lstrip('REV,').rstrip('!')
                    LOG.warning('>> Found Lutron RadioRA Classic at {} (version={})'.format(self.tty, self.version))
                    break

                self.serial.close()
                self.serial = None
                self.tty = None

            except:
                LOG.error('Unexpected error: %s', sys.exc_info()[0])
                self.version = None

        if self.version == None:
            LOG.fatal("No RadioRA RS232 devices discovered at {}".format(', '.join(ttys_to_search)))
            raise RuntimeError("No RadioRA RS232 devices discovered at {}".format(', '.join(ttys_to_search)))

    def __repr__(self):
        return '<RadioRA Classic RS232: tty={}; version={}>'.format(self.tty, self.version)

    def _readline(self):
        eol = b'\r'
        line = bytearray()
        while True:
            c = self.serial.read(1)
            if c:
                if c == eol:
                    #line += '|'
                    break
                line += c
            else:
               break
        return bytes(line).decode('utf-8')

    def writeCommand(self, command):
        LOG.info('>> Serial write to {}: {}'.format(self.tty, command))
        self.serial.reset_input_buffer()
        self.serial.write((command + "\r\n").encode('utf-8'))

    # not the most efficient reading one byte at a time, but it is way faster than
    # waiting for a 1 or 2 second timeout on every read. This could be improved in future.
    def readData(self):
        start = time.time()
        result = self._readline()
        while self.serial.in_waiting:
            result = result + self._readline()
        end = time.time()

        LOG.info('>> Serial read ({1:.0f} ms): {0}'.format(result, 1000 * (end-start)))
        return result


import socket
from select import *
import sys
from time import sleep
import bluetooth
import json
import SensorDeliverer as sd
import ActuatorManager as am

frontstr = "Client >> "

if __name__ == "__main__":
    file_path = 'config.json'
    with open(file_path, "r") as fj:
        fd = json.load(fj)
        HOST = fd['SERVER_IP']
        PORT_SENSOR = fd['SERVER_PORT_SENSOR']
        PORT_ACTUATOR = fd['SERVER_PORT_ACTUATOR']
        BT_ADDR = fd['BT_ADDR']
        BT_PORT = fd['BT_PORT']
        SYSTEM_ID = fd['SYSTEM_ID']

    print("System ID : ", SYSTEM_ID)
    print("System ID Type : ", type(SYSTEM_ID))
    print("Server Host Sensor : ", HOST, " | Port : ", PORT_SENSOR)
    print("Server Host Actuator : ", HOST, " | Port : ", PORT_ACTUATOR)
    print("Bluetooth Address : ", BT_ADDR, "Port : ", BT_PORT)

    loop = True

    while loop:
        # Bluetooth Socket
        try :
            print(frontstr, "Bluetooth connecting ... ", end="")
            bt_socket=bluetooth.BluetoothSocket(bluetooth.RFCOMM)
            bt_socket.connect((BT_ADDR,BT_PORT))
            print("Success!!")

            sensor = sd.SensorDeliverer(bt_socket, HOST, PORT_SENSOR, SYSTEM_ID)
            actuator = am.ActuatorManager(bt_socket, HOST, PORT_ACTUATOR, SYSTEM_ID)

            sensor.start()
            actuator.start()

            sensor.join()
            actuator.join()
        except KeyboardInterrupt:
            print(frontstr, "ClientAgent is stopped.")
        except Exception as e :
            print(frontstr, "Error is occured : ", e)

        bt_socket.close()
        print(frontstr, "Bluetooth socket closed.")
        print(frontstr, "Sleep 5 sec for next connection.")
        sleep(5)


import numpy as np
import torch
from flask import Flask, jsonify, request

from transformers import DistilBertTokenizer, DistilBertForSequenceClassification
from pydantic import BaseModel
from statistics import mode
import logging

app = Flask(__name__)

# class EntityIn(BaseModel):
#     texts : list

# class EntityOut(BaseModel):
#     label : str

@app.route("/",methods=['GET'])
def test():
    return jsonify({"Hello" : "World"})

def get_model():
    tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
    model = DistilBertForSequenceClassification.from_pretrained('prakhars/instagram_caption_classifier')
    return tokenizer, model

label_dict= {
14: 'Travel',
 0: 'Art and Culture',
 9: 'Music',
 4: 'Entertainment',
 10: 'Parenting',
 8: 'Health and Fitness',
 13: 'Sports',
 6: 'Food',
 2: 'Beauty, Fashion and Lifestyle',
 1: 'Automotive',
 11: 'Pets',
 5: 'Finance',
 12: 'Photography',
 3: 'DIY',
 7: 'Gaming'
 }

tokenizer, model = get_model()

@app.route('/predict/',methods=['POST'])

def read_root():

    try:
        texts = request.json['texts']
        encodings = tokenizer(texts, return_tensors="pt", padding=True, truncation=True)
        outputs = model(**encodings)
        predictions = outputs.logits.argmax(-1)
        out_codes = predictions.tolist()
        out_labels = {'labels':[]}
        most_common_label = {}
        for code in out_codes:
            out_labels['labels'].append(label_dict[code])
    except Exception as e:
        logging.error("Exception occured", exc_info=True)

    try :
        most_common_label['label'] = mode(out_labels['labels'])
    except:
        most_common_label['label'] = out_labels['labels'][0]

    return jsonify(most_common_label)

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


from PyQt5 import QtCore, QtGui, QtWidgets
import orderPage, askLogout
import sqlite3

class Ui_homePage(object):

    def askLogout(self):
        self.askLogoutDialog = QtWidgets.QDialog()
        self.askLogoutUi = askLogout.Ui_askLogoutDialog()
        self.askLogoutUi.setupUi(self.askLogoutDialog)
        self.askLogoutDialog.show()

    def getEmail(self,userid):
        _translate = QtCore.QCoreApplication.translate
        connDB = sqlite3.connect('washaDB/users.db')
        curDB = connDB.cursor()
        curDB.execute("SELECT * FROM users WHERE userID=:userID",
                    {'userID':userid})
        DBList = curDB.fetchall()
        DBTup = DBList[0]
        self.email = DBTup[1]
        self.profileButton.setText(_translate("homePage", self.email))

    def openOrders(self):
        self.orderWindow = QtWidgets.QMainWindow()
        self.orderUi = orderPage.Ui_orderWindow()
        self.orderUi.setupUi(self.orderWindow)
        self.orderWindow.show()
        self.orderUi.userID = self.userID
        self.orderUi.addressToTxtBox()

    def setupUi(self, homePage):
        self.userID = 0
        self.email = ''
        homePage.setObjectName("homePage")
        homePage.resize(362, 528)
        homePage.setMinimumSize(QtCore.QSize(362, 528))
        homePage.setMaximumSize(QtCore.QSize(362, 528))
        self.centralwidget = QtWidgets.QWidget(homePage)
        self.centralwidget.setObjectName("centralwidget")
        self.newOrderButton = QtWidgets.QPushButton(self.centralwidget, clicked= lambda: self.openOrders())
        self.newOrderButton.setGeometry(QtCore.QRect(50, 250, 271, 41))
        self.newOrderButton.setAutoDefault(False)
        self.newOrderButton.setDefault(False)
        self.newOrderButton.setFlat(False)
        self.newOrderButton.setObjectName("newOrderButton")
        self.showOrdersButton = QtWidgets.QPushButton(self.centralwidget)
        self.showOrdersButton.setGeometry(QtCore.QRect(50, 310, 271, 41))
        self.showOrdersButton.setObjectName("showOrdersButton")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(50, 130, 271, 71))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold")
        font.setPointSize(56)
        self.label.setFont(font)
        self.label.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.profileButton = QtWidgets.QCommandLinkButton(self.centralwidget)
        self.profileButton.setGeometry(QtCore.QRect(10, 450, 228, 41))
        self.profileButton.setObjectName("profileButton")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget, clicked = lambda: self.askLogout())
        self.pushButton.setGeometry(QtCore.QRect(236, 450, 111, 41))
        self.pushButton.setObjectName("pushButton")
        homePage.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(homePage)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 362, 21))
        self.menubar.setObjectName("menubar")
        self.menuAbout = QtWidgets.QMenu(self.menubar)
        self.menuAbout.setObjectName("menuAbout")
        homePage.setMenuBar(self.menubar)
        self.actionAbout = QtWidgets.QAction(homePage)
        self.actionAbout.setObjectName("actionAbout")
        self.menuAbout.addAction(self.actionAbout)
        self.menubar.addAction(self.menuAbout.menuAction())

        self.retranslateUi(homePage)
        QtCore.QMetaObject.connectSlotsByName(homePage)

    def retranslateUi(self, homePage):
        _translate = QtCore.QCoreApplication.translate
        homePage.setWindowTitle(_translate("homePage", "Home Page"))
        homePage.setWindowIcon(QtGui.QIcon("icon.png"))
        self.newOrderButton.setText(_translate("homePage", "NEW ORDER"))
        self.showOrdersButton.setText(_translate("homePage", "SHOW ORDERS"))
        self.label.setText(_translate("homePage", "OLS"))
        self.profileButton.setText(_translate("homePage", "example@email.com"))
        self.pushButton.setText(_translate("homePage", "LOGOUT"))
        self.menuAbout.setTitle(_translate("homePage", "Info"))
        self.actionAbout.setText(_translate("homePage", "About"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    homePage = QtWidgets.QMainWindow()
    ui = Ui_homePage()
    ui.setupUi(homePage)
    homePage.show()
    sys.exit(app.exec_())


import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
from regex_search import searchExclude

def returnWeather(url="https://weather.theage.com.au/local-forecast/vic/melbourne"):
    '''
    Retrieves the weather from our specified url
    '''
    html = urlopen(url)
    soup = BeautifulSoup(html, 'html.parser')
    weather = soup.find('div', attrs={'class':'ff_current_temp'})
    weather = str(weather)
    weather = searchExclude('a-z=_"<> / \n °', weather) # strips all unnessacary characters so we can just get the numbers
    x=""
    for i in weather: # puts the string back together
        x+= i
    weather = x
    return weather


import time

num = int(input("Enter a large number: "))

def is_prime(num):
    end = num//2
    for i in range(2, int(end + 1)) :
        if num % i == 0: return False
    return True

def prime_factorize(num):
    ts = time.time()
    if is_prime(num):
        return (1, num)

    prime_facts = []
    fact_pairs = []

    for i in range(2, ((num//2) + 1)) :
        if i not in prime_facts:
            if is_prime(i) and num%i == 0 :
                prime_facts.append(i)

                if is_prime(num/i):
                    fact_pairs.append((i, int(num/i)))
                    prime_facts.append(num/i)
    print(f"runtime{ts-time.time()}")
    return fact_pairs

print(prime_factorize(num))


import json
import csv
import numpy as np

## mapping.json contains mapping of district name to id
with open('mapping.json') as json_data:
    mapping = json.load(json_data)

## common function to find top 5 hotspot/coldspot depending upon which metric you choose i.e weekly, monthy or overall and for the method state/neighbor
def neighbors_creation(file_name, outfile_name):

    ## metric_dict contains zscore for the districts for the metric you provided
    ## metric is week, month or overall number
    metric_dict = dict()
    for dist in mapping.values():
        metric_dict[dist]=dict()
    data = open(file_name, 'r')
    metric_list = set()
    for line in data:
        line = line.split(',')
        metric_list.add(int(line[1]))
        ## for metric num(week number or month number or overall num)
        metric_dict[int(line[0])][int(line[1])] = list()
        ## storing mean
        metric_dict[int(line[0])][int(line[1])].append((line[2]))
        ## storing s.d.
        metric_dict[int(line[0])][int(line[1])].append((line[3]))
    data.close()
    metric_list=list(metric_list)
    metric_list.sort()

    f=open(outfile_name,'a')

    ## for a metric number(week number or month number or overall) and for neighbors
    for metric_num in metric_list:

        zscore_neighbor_list=list()
        idx_list1=list()

        ## for all districts
        for idx in mapping.values():
            zscore = metric_dict[idx][metric_num]

            ## getting the zscore values if it is not nan and appending it to zscore_neighbor_list
            if zscore[0]!='nan':
                zscore_neighbor_list.append(float(zscore[0]))
                ## idx_list1 contains the district ids for the appended zscore value
                idx_list1.append(idx)

        zscore_neighbor_list = np.array(zscore_neighbor_list)

        ## sorting the neighbor zscore values and getting the top and lowest 5 values
        neighbor_ind_hot = np.array(np.argpartition(zscore_neighbor_list,-5)[-5:])
        neighbor_ind_cold = np.array(np.argpartition(zscore_neighbor_list,5)[:5])

        ## getting the district ids of the top and lowest 5 zscore values
        neighbor_ind_hot = neighbor_ind_hot[np.argsort(zscore_neighbor_list[neighbor_ind_hot])]
        neighbor_ind_cold = neighbor_ind_cold[np.argsort(zscore_neighbor_list[neighbor_ind_cold])]

        idx_list1 = np.array(idx_list1)

        f.write(str(metric_num)+",neighborhood,hot,"+str(idx_list1[neighbor_ind_hot][4])+","+str(idx_list1[neighbor_ind_hot][3])+","+str(idx_list1[neighbor_ind_hot][2])+","+str(idx_list1[neighbor_ind_hot][1])+","+str(idx_list1[neighbor_ind_hot][0])+"\n")
        f.write(str(metric_num)+",neighborhood,cold,"+str(idx_list1[neighbor_ind_cold][4])+","+str(idx_list1[neighbor_ind_cold][3])+","+str(idx_list1[neighbor_ind_cold][2])+","+str(idx_list1[neighbor_ind_cold][1])+","+str(idx_list1[neighbor_ind_cold][0])+"\n")

    ## for a metric number(week number or month number or overall) and state wise
    for metric_num in metric_list:

        zscore_state_list=list()
        idx_list2=list()

        ## for all districts
        for idx in mapping.values():
            zscore = metric_dict[idx][metric_num]

            ## getting the zscore values if it is not nan and appending it to zscore_state_list
            if zscore[1]!='nan':
                zscore_state_list.append(float(zscore[1]))
                ## idx_list2 contains the district ids for the appended zscore value
                idx_list2.append(idx)

        zscore_state_list = np.array(zscore_state_list)

        ## sorting the state zscore values and getting the top and lowest 5 values
        state_ind_hot = np.array(np.argpartition(zscore_state_list,-5)[-5:])
        state_ind_cold = np.array(np.argpartition(zscore_state_list,5)[:5])

        ## getting the district ids of the top and lowest 5 zscore values
        state_ind_hot = state_ind_hot[np.argsort(zscore_state_list[state_ind_hot])]
        state_ind_cold = state_ind_cold[np.argsort(zscore_state_list[state_ind_cold])]

        idx_list2 = np.array(idx_list2)

        f.write(str(metric_num)+",state,hot,"+str(idx_list2[state_ind_hot][4])+","+str(idx_list2[state_ind_hot][3])+","+str(idx_list2[state_ind_hot][2])+","+str(idx_list2[state_ind_hot][1])+","+str(idx_list2[state_ind_hot][0])+"\n")
        f.write(str(metric_num)+",state,cold,"+str(idx_list2[state_ind_cold][4])+","+str(idx_list2[state_ind_cold][3])+","+str(idx_list2[state_ind_cold][2])+","+str(idx_list2[state_ind_cold][1])+","+str(idx_list2[state_ind_cold][0])+"\n")

    f.close()

neighbors_creation('zscore-week.csv','top-week.csv')
neighbors_creation('zscore-month.csv','top-month.csv')
neighbors_creation('zscore-overall.csv','top-overall.csv')

print("Top 5 hot/cold spot file generated")


#!/usr/bin/python3

import sys, json

def treatKey(obj, path, key):
    objKey = obj[key]
    objKeyType = type(objKey)
    value = objKey if (not objKeyType is dict and not objKeyType is list) else ''
    # used to be a print
    return (path + '/' + key, value)

def _finditem(obj, key, path = ''):
    objType = type(obj)
    results = []
    if objType is dict:
        keys = obj.keys()
        if key == '':
            for keyTmp in keys:
                results += [treatKey(obj, path, keyTmp)]
        elif key in keys:
            results += [treatKey(obj, path, key)]
        for keyTmp in keys:
            res = _finditem(obj[keyTmp], key, path + '/' + keyTmp)
            if res != []:
                results += res
    elif objType is list:
        objLen = len(obj)
        for objIndex in range(objLen):
            objEl = obj[objIndex]
            res = _finditem(objEl, key, path + '/' + str(objIndex))
            if res != []:
                results += res
    return results

filePath = sys.argv[1]
key = sys.argv[2] if len(sys.argv) >= 3 else ''
# `ytVariableName` could be for instance 'ytInitialPlayerResponse'
ytVariableName = sys.argv[3] if len(sys.argv) >= 4 else 'ytInitialData'

# if not found from key could search by value
# that way could find easily shortest path to get the value as sometimes the value is repeated multiple times

with open(filePath) as f:
    isJSON = f.read(1) == '{'

if not isJSON:
    with open(filePath) as f:
        content = f.read()
    newContent = '{' + content.split(ytVariableName + ' = {')[1].split('};')[0] + '}'
    with open(filePath, 'w') as f:
        f.write(newContent)

with open(filePath) as f:
    data = json.load(f)

with open(filePath, 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii = False, indent = 4)

pathValues = _finditem(data, key)
for path, value in pathValues:
    print(path, value)
    path = path[1:]
    path = path.replace('/', "']['")
    pathParts = path.split("][")
    pathPartsLen = len(pathParts)
    for pathPartsIndex in range(pathPartsLen):
        pathPart = pathParts[pathPartsIndex][1:-1]
        if pathPart.isdigit():
            pathParts[pathPartsIndex] = pathPart
    path = "][".join(pathParts)
    newPath = "['" + path + "']"
    print(newPath, value)


# pyright: reportMissingImports=false

import sys
from typing import Literal, TypeGuard
import fontforge
import psMat
import util
import properties as P
from datetime import datetime

if len(sys.argv) != 5:
    raise ValueError("Invalid argument")

def is_font_style(style: str) -> TypeGuard[Literal["Regular", "Bold", "Italic", "BoldItalic"]]:
    return style in ["Regular", "Bold", "Italic", "BoldItalic"]

FONT_EN_TTF = sys.argv[1]
FONT_JP_TTF = sys.argv[2]
if not is_font_style(sys.argv[3]):
    raise ValueError("Invalid font style")
else:
    FONT_STYLE = sys.argv[3]
BUILD_FILE = sys.argv[4]

def main() -> None:
    font = new_font()

    merge_en(font)
    merge_jp(font)

    if "Italic" in FONT_STYLE:
        make_italic(font)
        util.fix_all_glyph_points(font, round=True, addExtrema=True)
    else:
        util.fix_all_glyph_points(font, addExtrema=True)

    font.selection.all()
    font.autoHint()
    font.autoInstr()
    font.selection.none()

    util.font_into_file(font, BUILD_FILE)
    util.log("Generated:", BUILD_FILE)

def merge_en(font) -> None:
    en_font = fontforge.open(FONT_EN_TTF)
    en_font.encoding = P.ENCODING
    font.mergeFonts(en_font)
    en_font.close()
    util.log("Merged:", FONT_EN_TTF, "->", BUILD_FILE)

def merge_jp(font) -> None:
    jp_font = fontforge.open(FONT_JP_TTF)
    font.mergeFonts(jp_font)
    for glyph in jp_font.glyphs():
        unicode = glyph.unicode
        if unicode == -1:
            continue
        if glyph.altuni is not None:
            font[unicode].altuni = glyph.altuni
        font[unicode].unicode = unicode
    jp_font.close()
    util.log("Merged:", FONT_JP_TTF, "->", BUILD_FILE)

def make_italic(font) -> None:
    PI = 3.14159265358979323846
    rot_rad = -1 * P.ITALICANGLE * PI / 180
    transform_mat = psMat.skew(rot_rad)

    def selectMore(start, end=None):
        nonlocal font
        if end is None:
            font.selection.select(("more", "encoding"), start)
        else:
            font.selection.select(("more", "ranges", "encoding"), start, end)

    selectMore(0x21, 0x217f)
    selectMore(0x2460, 0x24ea)
    selectMore(0x2768, 0x277e)
    selectMore(0x27e6, 0x27eb)
    selectMore(0x2987, 0x2998)
    selectMore(0x2e18)
    selectMore(0x2e22, 0x2e2e)
    selectMore(0x2e8e, 0xffe5)
    selectMore(0x1f100)
    selectMore(0x20b9f, 0x2f920)
    # NOTE: After 0x110000, codepoint is defferent in Reguler and Bold.
    selectMore(".notdef", "uni301F.half")
    selectMore("acute.half", "zero.alt01")
    font.transform(transform_mat)
    font.selection.none()

def new_font():
    style_prop = P.STYLE_PROPERTY[FONT_STYLE]
    font = fontforge.font()
    font.ascent = P.ASCENT
    font.descent = P.DESCENT
    font.italicangle = P.ITALICANGLE if "Italic" in FONT_STYLE else 0
    font.upos = P.UNDERLINE_POS
    font.uwidth = P.UNDERLINE_HEIGHT
    font.familyname = P.FAMILY
    font.copyright = P.COPYRIGHT
    font.encoding = P.ENCODING
    font.fontname = P.FAMILY + "-" + FONT_STYLE
    font.fullname = P.FAMILY + " " + FONT_STYLE
    font.version = P.VERSION
    font.appendSFNTName(
        "English (US)",
        "SubFamily",
        "".join([" " + c if c.isupper() else c for c in FONT_STYLE]).lstrip()
    )
    font.appendSFNTName(
        "English (US)",
        "UniqueID",
        "; ".join(
            [
                f"FontForge {fontforge.version()}",
                P.FAMILY + " " + FONT_STYLE,
                P.VERSION,
                datetime.today().strftime("%F"),
            ]
        ),
    )

    font.gasp_version = 1
    font.gasp = (
        (65535,
         ('gridfit', 'antialias', 'symmetric-smoothing', 'gridfit+smoothing')),
    )

    font.weight = style_prop["weight"]
    font.os2_weight = style_prop["os2_weight"]
    font.os2_width = 5  # Medium (100%)
    font.os2_stylemap = style_prop["os2_stylemap"]
    font.os2_vendor = "2357"  # Me
    font.os2_panose = (  # https://monotype.github.io/panose/pan1.htm
        2,                            # Family Kind = 2-Latin: Text and Display
        11,                           # Serif Style = Nomal Sans
        style_prop["panose_weight"],  # Weight
        9,                            # Proportion = 9-Monospaced
        3,                            # Contrast = 3-Very Low
        2,                            # Stroke Variation = 2-No Variation
        2,                            # Arm Style = 2-Straight Arms/Horizontal
        style_prop['panose_letterform'],  # Letterform
        2,                            # Midline = 2-Standard/Trimmed
        4,                            # X-height = 4-Constant/Large
    )

    # typoascent, typodescent is generic version for above.
    # the `_add` version is for setting offsets.
    font.os2_typoascent = P.ASCENT
    font.os2_typodescent = -P.DESCENT
    font.os2_typoascent_add = 0
    font.os2_typodescent_add = 0

    # winascentwindescent is typoascent/typodescent for Windows.
    font.os2_winascent = P.ASCENT
    font.os2_windescent = P.DESCENT
    font.os2_winascent_add = 0
    font.os2_windescent_add = 0

    # winascentwindescent is typoascent/typodescent for macOS.
    font.hhea_ascent = P.ASCENT
    font.hhea_descent = -P.DESCENT
    font.hhea_ascent_add = 0
    font.hhea_descent_add = 0

    # linegap is for gap between lines.  The `hhea_` version is for macOS.
    font.os2_typolinegap = 0
    font.hhea_linegap = 0

    return font

if __name__ == "__main__":
    main()