import sys
import json
import pandas as pd
import yfinance as yf
import pandas_ta as ta
from backtestEngine import Strategy, Engine
import _lib

strategy_dandd = []

def read_json_file(file_path):
    with open(file_path, 'r') as f:
        return json.load(f)

def write_json_file(file_path, data):
    with open(file_path, 'w') as f:
        json.dump(data, f)

def compare_operations(a, b, operation, data, idx):
    try:
        val_a = data.loc[idx, a]
        val_b = data.loc[idx, b]
    except KeyError as e:
        print(f"KeyError: {e}")
        print("Columns in data:")
        print(data.columns)
        print(f"a = {a}")
        print(f"b = {b}")
        return False

    operations = {
        'gt': val_a > val_b,
        'lt': val_a < val_b,
        'gte': val_a >= val_b,
        'lte': val_a <= val_b,
        'eq': val_a == val_b,
        'ne': val_a != val_b,
        'ca': _lib.crossover(data, a, b, idx),
        'cb': _lib.crossbelow(data, a, b, idx),
    }
    return operations.get(operation, False)

class SMACrossover(Strategy):
    def on_bar(self):
        if self.current_idx != 0:
            for index, i in enumerate(strategy_dandd):
                if 'SubFilter' in i:
                    if compare_operations(i['A'], i['B'], i['Operation'], self.data, self.current_idx) and compare_operations(i['subFilter']['A'], i['B'], i['subFilter']['Operation'], self.data, self.current_idx):
                        self.process_strategy(i)
                else:
                    if compare_operations(i['A'], i['B'], i['Operation'], self.data, self.current_idx):
                        self.process_strategy(i)

    def process_strategy(self, strategy):
        if self.position_size == 0:
            if strategy['Action'] == 'Long_Entry':
                order_size = self.cash / self.close
                self.buy_limit('AAPL', size=order_size, limit_price=self.close)
        elif strategy['Action'] == 'Long_Exit':
            if compare_operations(strategy['A'], strategy['B'], strategy['Operation'], self.data, self.current_idx):
                self.sell_limit('AAPL', size=self.position_size, limit_price=self.close)

def create_indicator(data, indicator, attr, close, variables):
    return getattr(ta, attr)(data[close], int(variables))

def main():
    input_file_path = sys.argv[1]
    output_file_path = sys.argv[2]

    input_data = read_json_file(input_file_path)
    jsondata = input_data
    data = yf.Ticker('AAPL').history(start='2012-12-01', end='2022-12-31', interval='1d')
    e = Engine(initial_cash=100000)

    process_json_data(data, jsondata)
    e.add_data(data)
    e.add_strategy(SMACrossover())
    stats = e.run()
    print(e.portfolio_bh)
    result_data = prepare_result_data(stats)
    write_json_file(output_file_path, {"result": result_data})

def process_json_data(data, jsondata):

    lastFilterIndex = 0

    for indx, i in enumerate(jsondata):

        strategy = {}
        subStrategy = {}

        if (i['type'] == 'filter'):
            lastFilterIndex = indx
            strategy['Operation'] = i['Operation']
            strategy['Action'] = i['Action']
            if (i['Operand']['OperandType'] == 'indicator'):
                indicator = i['Operand']['Indicators']['Attribute']+"_INDX"+str(indx)+str(i['Operand']['Indicators']['Variables'][0])+i['Operand']['Indicators']['Timeframe']
                data[indicator] = getattr(ta, i['Operand']['Indicators']['Attribute'])(data['Close'], int(i['Operand']['Indicators']['Variables'][0]))
                strategy['A'] = indicator
            if (i['OperandB']['OperandType'] == 'indicator'):
                indicator = i['OperandB']['Indicators']['Attribute']+"_INDX"+str(indx)+str(i['OperandB']['Indicators']['Variables'][0])+i['OperandB']['Indicators']['Timeframe']
                # data = resample(data, i['OperandB']['Indicators']['Timeframe'], indicator, i['Operand']['Indicators']['Attribute'], 'Close', int(i['Operand']['Indicators']['Variables'][0]))
                data[indicator] = getattr(ta, i['OperandB']['Indicators']['Attribute'])(data['Close'], int(i['OperandB']['Indicators']['Variables'][0]))
                print(i['OperandB']['Indicators']['Attribute']+"_INDX"+str(indx)+str(i['OperandB']['Indicators']['Variables'][0])+i['OperandB']['Indicators']['Timeframe'])
                strategy['B'] = indicator

            if (i['Operand']['OperandType'] == 'StockAttribute'):
                indicator = (i['Operand']['StockAttribute']['Indicators'])
                print(indicator)
                strategy['A'] = indicator

            if (i['OperandB']['OperandType'] == 'StockAttribute'):
                indicator = (i['OperandB']['StockAttribute']['Indicators'])
                print(indicator)
                strategy['B'] = indicator

            if (i['Operand']['OperandType'] == 'Constant'):
                indicator = (str(i['Operand']['Constant'])+"_INDX"+str(indx))
                strategy['A'] = indicator
                data[indicator] = i['Operand']['Constant']

            if (i['OperandB']['OperandType'] == 'Constant'):
                indicator = (str(i['OperandB']['Constant'])+"_INDX"+str(indx))
                strategy['B'] = indicator
                data[indicator] = i['OperandB']['Constant']
            strategy_dandd.append(strategy)

        elif (i['type'] == 'sub-filter'):

            for jindx, j in enumerate(jsondata):

                subStrategy['Operation'] = j['Operation']

                if (j['Operand']['OperandType'] == 'indicator'):
                    indicator = j['Operand']['Indicators']['Attribute']+"_INDX"+str(jindx)+str(j['Operand']['Indicators']['Variables'][0])+j['Operand']['Indicators']['Timeframe']
                    data[indicator] = getattr(ta, j['Operand']['Indicators']['Attribute'])(data['Close'], int(j['Operand']['Indicators']['Variables'][0]))
                    subStrategy['A'] = indicator
                if (j['OperandB']['OperandType'] == 'indicator'):
                    indicator = j['OperandB']['Indicators']['Attribute']+"_INDX"+str(jindx)+str(j['OperandB']['Indicators']['Variables'][0])+j['OperandB']['Indicators']['Timeframe']
                    # data = resample(data, i['OperandB']['Indicators']['Timeframe'], indicator, i['Operand']['Indicators']['Attribute'], 'Close', int(i['Operand']['Indicators']['Variables'][0]))
                    data[indicator] = getattr(ta, j['OperandB']['Indicators']['Attribute'])(data['Close'], int(i['OperandB']['Indicators']['Variables'][0]))
                    print(j['OperandB']['Indicators']['Attribute']+"_INDX"+str(jindx)+str(j['OperandB']['Indicators']['Variables'][0])+j['OperandB']['Indicators']['Timeframe'])
                    subStrategy['B'] = indicator

                if (j['Operand']['OperandType'] == 'StockAttribute'):
                    indicator = (j['Operand']['StockAttribute']['Indicators'])
                    print(indicator)
                    subStrategy['A'] = indicator

                if (j['OperandB']['OperandType'] == 'StockAttribute'):
                    indicator = (j['OperandB']['StockAttribute']['Indicators'])
                    print(indicator)
                    subStrategy['B'] = indicator

                if (i['Operand']['OperandType'] == 'Constant'):
                    indicator = (str(j['Operand']['Constant'])+"_INDX"+str(jindx))
                    subStrategy['A'] = indicator
                    data[indicator] = j['Operand']['Constant']

                if (i['OperandB']['OperandType'] == 'Constant'):
                    indicator = (str(j['OperandB']['Constant'])+"_INDX"+str(jindx))
                    subStrategy['B'] = indicator
                    data[indicator] = j['OperandB']['Constant']

                strategy_dandd[lastFilterIndex]['subFilter'] = subStrategy

    return strategy

def prepare_result_data(stats):
    print(stats)

if __name__ == "__main__":
    main()


import boto3
import csv
import json

s3 = boto3.client('s3')
dynamodb = boto3.client('dynamodb')

def handler(event, context):
    # Get the object from the event then download it to Lambda tmp space
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    # IMPORTANT:
    if '.csv' not in key:
        return 'Not a csv that needs processing'
    if '.psv' in key:
        return 'An already processed logfile'
    s3.download_file(bucket, key, '/tmp/' + key)
    psv_name = 'processed_' + key[0:-4] + '.psv'
    # Open the file, process it, and upload a psv
    with open('/tmp/' + key, 'r') as infile, \
         open('/tmp/' + psv_name, 'w') as outfile:
        reader = csv.DictReader(infile)
        writer = csv.DictWriter(outfile, reader.fieldnames, delimiter='|')
        writer.writeheader()
        writer.writerows(reader)
    s3.upload_file('/tmp/' + psv_name, bucket, psv_name)
    # Use DynamoDB atomic counters to tally visits in csv
    with open('/tmp/' + key, 'r') as infile:
        first_line = infile.readline()
        for row in infile:
            ddb_empId = row.strip().split(',')[0]
            ddb_empName = row.strip().split(',')[1]
            ddb_empSalary = row.strip().split(',')[2]
            response = dynamodb.update_item(
                    TableName='EmployeeSalary',
                    Key={
                        'EmpID': {'N': ddb_empId},
                        'EmpName': {'S': ddb_empName},
                    },
                    UpdateExpression='ADD EmpSalary :empSalary',
                    ExpressionAttributeValues={
                        ':empSalary': {'N': ddb_empSalary}
                    },
                    ReturnValues="UPDATED_NEW"
            )
            print(response)


from django.http import HttpResponse
from django.shortcuts import render
# def index(request):
#     return HttpResponse("
Hello World
")
#
# def about(request):
#     return HttpResponse("
This is the about page
")

def index(request):
    # params = {'name':'Harry', 'place': 'Earth'}
    return render(request,"index.html")
    #return HttpResponse("Home")

def analyze(request):
    djtext = request.POST.get('text', 'default')
    removepunc = request.POST.get('removepunc', 'off')
    fullcaps = request.POST.get('fullcaps', 'off')
    newlineremover = request.POST.get('newlineremover', 'off')
    extraspaceremover = request.POST.get('extraspaceremover', 'off')
    charcount = request.POST.get('Charcount', 'off')
    # print(removepunc)
    # print(djtext)
    # analyzetext = djtext
    punctuations = '''!()-[]{};:'"\,<>./?@#$%^&*_~'''
    analyzed = ""
    if removepunc == 'on':
        for char in djtext:
            if char not in punctuations:
                analyzed = analyzed + char
        djtext = analyzed
    if fullcaps == 'on':
        analyzed = ""
        for char in djtext:
            analyzed = analyzed+char.upper()
        djtext=analyzed
    if newlineremover == 'on':
        analyzed = ""
        for char in djtext:
            if char != '\n' and char != '\r':
                analyzed = analyzed + char
        djtext=analyzed
    if extraspaceremover == 'on':
        analyzed = ""
        for index,char in enumerate(djtext):
            if djtext[index] == " " and djtext[index+1] == " ":
                pass
            else:
                analyzed = analyzed + char
        djtext=analyzed
    if charcount == 'on':
        count = 0
        analyzed = ""
        for char in djtext:
                count= count+1
        return HttpResponse("Character count = "+str(count))
    if removepunc=='off' and fullcaps=='off' and newlineremover == 'off' and extraspaceremover=='off' and charcount=='off':
        return HttpResponse("Error!")

    params = {'purpose':'Remove punctuation', 'analyzed_text': analyzed}
    return render(request, "analyze.html", params)

# def capfirst(request):
#     return HttpResponse("Capitalize first")
#
# def newlineremove(request):
#     return HttpResponse("New Line remover")
#
# def spaceremove(request):
#     return HttpResponse("Space remover")

# def charcount(request):
#     return HttpResponse("Character count")


import unittest
import requests
import os, sys, json
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)

class getAutoStartServiceWatchedListTest(unittest.TestCase):
    ''' 获取自启动服务信息信息 '''

    def setUp(self):
        self.base_url = "http://139.196.104.13:8082/mics/call"

    def tearDown(self):
        print(self.result)

    def test_getAutoStartServiceWatchedList(self):
        payload = {"method":"getAutoStartServiceWatchedList","params":"{'service_type':'http'}","service":"topmics-admin-mics","timeout":30000,"waitReply":True}
        # data = json.dumps(payload)
        r = requests.post(self.base_url, data=payload)
        self.result = r.text
        # self.assertEqual(self.result['status_code'], 200)
        # self.assertEqual(self.result['message'], 'parameter error')

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


import coc
import nextcord

from nextcord.ext import commands
from cogs.war import to_time
from cogs.utils.constants import clans
from datetime import datetime
from config import settings, emojis

def breakdown(members, process=None):
    res = {}
    for m in members:
        th = m.town_hall if m.town_hall > 9 else 9
        if th not in res:
            res[th] = 0
        val = 1 if process is None else process(m)
        res[th] += val
    return "/".join(f"{res.get(th, 0)}" for th in range(13, 8, -1))

superscriptNumbers = u"⁰¹²³⁴⁵⁶⁷⁸⁹"

def sup(c):
    if ord('0') <= ord(c) <= ord('9'):
        return superscriptNumbers[ord(c) - ord('0')]
    else:
        return c

def th_super(s):
    s = str(s)
    ret = u""
    for c in s:
        ret += sup(c)
    return ret

def member_display(member):
    return f"{member.map_position}. {member.name}{th_super(member.town_hall)}"

class Cwl(commands.Cog):
    """War bot commands and setup"""
    def __init__(self, bot):
        self.bot = bot
        # self.bot.coc.add_events(self.on_roster_change)

    def cog_unload(self):
        self.bot.coc.remove_events(self.on_roster_change)

    @commands.group(name="cwl", invoke_without_command=True)
    async def cwl(self, ctx, clan_name: str = "oak"):
        """CWL War Command
        Provides information on Clan War Leagues
        """
        if ctx.invoked_subcommand is not None:
            return

        if "oak" in clan_name.lower():
            clan_tag = clans['Reddit Oak']
        else:
            clan_tag = clans['Reddit Quercus']
        now = datetime.utcnow()
        war = await self.bot.coc.get_current_war(clan_tag)
        if not war.is_cwl:
            return await ctx.send(f"It appears that {war.clan} is not currently involved in CWL.  Please use "
                                  f"`/war` commands instead.")
        embed = nextcord.Embed(title="CWL Status", color=nextcord.Color.dark_blue())
        blank = emojis['other']['gap']
        group = await self.bot.coc.get_league_group(clan_tag)
        end_content = ""
        async for war in group.get_wars_for_clan(clan_tag):
            if war.state == "warEnded":
                prefix = war.status.title()
                end_content += (f"{prefix} - {war.clan} ({war.clan.stars}) vs "
                                f"{war.opponent} ({war.opponent.stars})\n")
            elif war.state == "inWar":
                # check for prior content and add embed if needed
                if end_content:
                    embed.add_field(name="Previous Rounds", value=end_content, inline=False)
                embed.add_field(name=f"{war.clan.name} vs {war.opponent.name}",
                                value=f"War ends in {to_time(war.end_time.seconds_until)}.",
                                inline=False)
                embed.add_field(name=war.clan.name,
                                value=f"{war.clan.stars} of {war.clan.max_stars} Stars\n"
                                      f"{war.clan.destruction:.1f}% Destruction",
                                inline=True)
                embed.add_field(name=war.opponent.name,
                                value=f"{war.opponent.stars} of {war.clan.max_stars} Stars\n"
                                      f"{war.opponent.destruction:.1f}% Destruction",
                                inline=True)
                embed.add_field(name=blank, value=blank, inline=True)
            elif war.state == "preparation":
                embed.add_field(name=f"Next Round vs {war.opponent.name}",
                                value=f"{breakdown(war.opponent.members)}\n"
                                      f"{to_time(war.start_time.seconds_until)} until war starts.")
        embed.set_thumbnail(url="https://vignette.wikia.nocookie.net/clashofclans/images/9/97/LeagueMedal.png")
        await ctx.send(embed=embed)

    @cwl.command(name="roster")
    async def cwl_roster(self, ctx, clan_name: str = "oak"):
        """Responds with the upcoming enemy's roster so that you can plan your roster.

        **Example:**
        /cwl roster"""
        if "oak" in clan_name.lower():
            clan_tag = clans['Reddit Oak']
        else:
            clan_tag = clans['Reddit Quercus']
        war = await self.bot.coc.get_current_war(clan_tag, cwl_round=coc.WarRound.current_preparation)
        await ctx.send(f"**{war.opponent.name} Roster:**\n{breakdown(war.opponent.members)}")

    @coc.WarEvents.members(clans['Reddit Oak'])
    async def on_roster_change(self, old_war, new_war):
        if new_war.type != "cwl":
            return
        self.bot.logger.info("Roster change detected in CWL")
        member_list = []
        for member in new_war.opponent.members:
            member.map_position = new_war.members.index(member) + 1
            member_list.append(member_display(member))
        elder_channel = self.bot.get_channel(settings['oak_channels']['elder_chat'])
        old_breakdown = breakdown(old_war.members)
        new_breakdown = breakdown(new_war.members)
        if old_breakdown != new_breakdown:
            content = (f"**CWL Roster Change for {new_war.opponent.name}**\n"
                       f"Old Breakdown: {old_breakdown}\n"
                       f"New Breakdown: {new_breakdown}")
            await elder_channel.send(content)
            await elder_channel.send("\n".join(member_list))

def setup(bot):
    bot.add_cog(Cwl(bot))


import json
import os
import pandas as pd
from os.path import exists
from jsonParser import readFromJson, writeToJson

def convertToTeamName(teams_df,id):

    team = teams_df.loc[teams_df["id"] == id]
    return team["name"].values[0]

dirname = os.path.dirname(__file__)
years = ["2021-22", "2022-23"]
players = []

excluded_elements_columns = [
     "cost_change_event",
     "cost_change_event_fall",
     "cost_change_start",
     "cost_change_start_fall",
     "special"
    ]

for year in years:
    players = []

    path = os.path.join(dirname, f"./data/{year}/Elements")
    general_data = readFromJson(f"./data/{year}/general.json")
    elements_df = pd.DataFrame(general_data['elements'])
    teams_df = pd.DataFrame(general_data['teams'])

    elements_subset_df = elements_df.loc[:, ~elements_df.columns.isin(excluded_elements_columns)]

    for filename in os.listdir(path):
        f = os.path.join(path,filename)
        if os.path.isfile(f) and filename.endswith(".json"):
            data = readFromJson(f)
            history = data["history"]
            #Find item from elements
            if len(history) > 0:
                element = elements_subset_df.loc[elements_subset_df["id"] ==  history[0]["element"]]
                element.fillna("", inplace=True)
                team = convertToTeamName(teams_df,element.team.values[0])

                outputName = str(element.code.values[0])
                outputFile = os.path.join(dirname, f"output/{outputName}.json")
                playerElement = (element.to_dict(orient = "records")[0])
                playerElement["season"] = year
                playerElement["team"] = convertToTeamName(teams_df, playerElement["team"] )
                playerElement["history"] = history

                for pe in playerElement["history"]:
                    pe["opponent_team"] = convertToTeamName(teams_df, pe["opponent_team"])

                file_exists = os.path.exists(os.path.join(dirname, f"output/{outputName}.json"))
                data = {}
                if file_exists:
                    with open(outputFile, 'r') as json_file:
                        print("Exists")
                        data = json.load(json_file)
                        data["team"] = team
                        data["seasons"].append(playerElement)
                else:
                    data =  {
                        "id": str(element.code.values[0]),
                        "name": str(element.first_name.values[0]) + " " + str(element.second_name.values[0]),
                        "type": "player",
                        "team": team,
                        "seasons": []
                    }
                    data["seasons"].append(playerElement)
                    print("Do not Exists")

                with open(outputFile, 'w') as json_file:
                    json.dump(data,json_file)


from isx_preprocessing.path_parcers.raw import (
    OFLFirstIsxMouseDir, IsxRootParserOFLFirst
)
from isx_preprocessing.path_parcers.output import (
    OutputMouseDirOFLFirst, OutputRootParserOFLFirst
)
from isx_preprocessing.exporting import IsxExporter
from typing import Optional, Sequence
from pathlib import Path
from tqdm import tqdm

SOURCE_DIR = Path(r"F:\Raw OFL")
DEST_DIR = Path(r"F:\OFL\ofl-first")
ON_EXISTS = "skip"

TRACE_FILENAME = "traces.csv"
PROPS_FILENAME = "props.csv"
TIFF_SUBDIR = "tiff"
TIFF_FILENAME = "tiff.tif"

def get_mouse_dir(
    source: OFLFirstIsxMouseDir, target_dirs: Sequence[OutputMouseDirOFLFirst]
) -> Optional[OutputMouseDirOFLFirst]:

    for target in target_dirs:
        if source.mouse_name == target.mouse_name:
            return target
    return None

def main():
    source_mouse_dirs = IsxRootParserOFLFirst.from_root_dir(
        SOURCE_DIR,
    ).mouse_dirs
    target_mouse_dirs = OutputRootParserOFLFirst.from_root_dir(
        DEST_DIR,
    ).mouse_dirs

    isx_exporter = IsxExporter(
        trace_filename=TRACE_FILENAME,
        props_filename=PROPS_FILENAME,
        tiff_subdir=TIFF_SUBDIR,
        tiff_filename=TIFF_FILENAME,
        on_exists=ON_EXISTS,
    )
    print(len(source_mouse_dirs))
    print(len(target_mouse_dirs))

    for source_mouse_dir in tqdm(source_mouse_dirs):
        target_mouse_dir = get_mouse_dir(source_mouse_dir, target_mouse_dirs)

        source_sessions = source_mouse_dir.day_dirs[1:]
        tartget_sessions = target_mouse_dir.day_dirs[1:]
        for source_session_dir, target_session_dir in zip(
            source_sessions, tartget_sessions
        ):
            isx_exporter(
                cellset_file=source_session_dir.cnmfe_cellset,
                output_dir=target_session_dir.session_dir,
            )

if __name__ == "__main__":
    main()


import sqlite3
from collections import defaultdict
import pickle
from pathlib import Path

def pair_id_to_image_ids(pair_id):
    image_id2 = pair_id % 2147483647
    image_id1 = (pair_id - image_id2) // 2147483647
    return image_id1, image_id2

def name_to_number(name):
    return int(name[:-len('.png')])

def extract_graph(db_loc):
    conn = sqlite3.connect(str(db_loc))
    #  print(db_loc)
    image_id_to_name = {}
    matches = []

    with conn:
        for idx, name in conn.execute("SELECT image_id, name FROM images;"):
            image_id_to_name[idx] = name

    with conn:
        for x in conn.execute("SELECT pair_id FROM inlier_matches;"):
            i, j = pair_id_to_image_ids(x[0])
            matches.append((i, j))

    graph = defaultdict(set)
    for i, j in matches:
        graph[i].add(j)
        graph[j].add(i)

    loop_closures = defaultdict(set)
    for a, b in matches:
        a_n = name_to_number(image_id_to_name[a])
        b_n = name_to_number(image_id_to_name[b])
        distance = abs(a_n - b_n)
        if distance > 150:
            loop_closures[a].add(b)
            loop_closures[b].add(a)

    return graph, loop_closures, image_id_to_name

def kvs_map(f, d):
    '''
    f: 'a -> 'b
    d: dictionary<'a, Set<'a>>
    returns: dictionary<'b, Set<'b>>
    '''
    r = {}
    for k, xs in d.items():
        r[f(k)] = set(f(x) for x in xs)
    return r

data_loc = Path('/local/sdd/nm583/kitti/dataset/')
total_graph = {}
total_loop_closure_graph = {}

train_seqs = range(0, 7)
test_seqs = range(7, 10)
train_paths = []
test_paths = []

for seq_n in range(11):
    seq_n_string = str(seq_n).zfill(2)
    sequence_loc = data_loc / 'sequences' / seq_n_string
    db_loc = sequence_loc / 'colmap/database.db'
    image_loc = sequence_loc / 'image_2'
    graph, loop_closures, image_id_to_name = extract_graph(db_loc)
    full_path = lambda x: image_loc / image_id_to_name[x]
    graph = kvs_map(full_path, graph)
    loop_closures = kvs_map(full_path, loop_closures)
    total_graph = {**graph, **total_graph}
    total_loop_closure_graph = {**loop_closures, **total_loop_closure_graph}
    if seq_n in train_seqs:
        train_paths += list(graph.keys())
    else:
        test_paths += list(graph.keys())
    print("{}: ({}, {}),".format(seq_n, len(graph), len(loop_closures)))

train_paths = sorted(train_paths)
test_paths = sorted(test_paths)

extracted_data_loc = Path('/local/sdd/nm583/extracted_kitti_data')

with (extracted_data_loc / 'graph.pickle').open('wb') as f:
    pickle.dump(total_graph, f)

with (extracted_data_loc / 'loop_closure_graph.pickle').open('wb') as f:
    pickle.dump(total_loop_closure_graph, f)

with (extracted_data_loc / 'train_paths.txt').open('w') as f:
    for path in train_paths:
        print(path, file=f)

with (extracted_data_loc / 'test_paths.txt').open('w') as f:
    for path in test_paths:
        print(path, file=f)


import requests

class GetIPAddressError(Exception):
    pass

class SomeClass(object):
    def __init__(self, name):
        self.name = name
        self.session = None

    def add_numbers(self, a, b):
        for k, v in {'a': a, 'b': b}.items():
            if isinstance(v, (int, float)):
                continue

            raise TypeError('expected {} to be {} or {} but was {}'.format(
                k, type(1), type(1.337), type(v)
            ))

        return 'Hi {}, {} + {} = {}'.format(
            self.name, a, b, a + b
        )

    def get_ip_address(self):
        if self.session is None:
            self.session = requests.Session()

        response = self.session.get('http://ifconfig.co/json')
        if response.status_code not in [200, 201]:
            raise GetIPAddressError('expected status code of 200 or 201, instead got {}'.format(
                response.status_code
            ))

        return response.json().get('ip')


import pygame
from pygame.locals import *
import sys
import random
import time

# Initialize Pygame
pygame.init()

# Set up the window
window_width = 800
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption('Snake Game')

# Set up the colors
black = (0, 0, 0)
white = (255, 255, 255)

# Set up the font
font = pygame.font.Font(None, 32)

# Function to display the main screen
def main_screen():
    username = ''
    class_name = ''
    username_input_active = False
    class_input_active = False

    cursor_blink_timer = 0
    cursor_visible = True

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_BACKSPACE:
                    if username_input_active and len(username) > 0:
                        username = username[:-1]
                    elif class_input_active and len(class_name) > 0:
                        class_name = class_name[:-1]
                elif event.key == K_TAB:
                    if username_input_active and len(username) > 0:
                        username += '\t'
                    elif class_input_active and len(class_name) > 0:
                        class_name += '\t'
                elif event.key == K_RETURN:
                    if len(username) > 0:
                        return username, class_name
                else:
                    if username_input_active:
                        username += event.unicode
                    elif class_input_active:
                        class_name += event.unicode
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    username_input_active = pygame.Rect(window_width // 2 + 5, window_height // 2 - 95, 200, 30).collidepoint(event.pos)
                    class_input_active = pygame.Rect(window_width // 2 + 5, window_height // 2 + 5, 200, 30).collidepoint(event.pos)
                    start_button = pygame.Rect(window_width // 2 - 75, window_height // 2 + 150, 150, 50)
                    if start_button.collidepoint(event.pos):
                        start_game()
                else:
                    username_input_active = False
                    class_input_active = False

        draw_main_screen(username, class_name, username_input_active, class_input_active, cursor_visible)

        # Toggle cursor visibility every 0.5 seconds
        cursor_blink_timer += 1
        if cursor_blink_timer >= 700:
            cursor_visible = not cursor_visible
            cursor_blink_timer = 0

# Function to draw the main screen
def draw_main_screen(username, class_name, username_input_active, class_input_active, cursor_visible):
    window.fill(black)

    # Render the text
    username_text = font.render('Username:', True, white)
    class_text = font.render('Class:', True, white)
    username_input = font.render(username, True, white)
    class_input = font.render(class_name, True, white)
    prompt_text = font.render('Press Enter to Start', True, white)

    # Display the text on the screen
    window.blit(username_text, (window_width // 2 - 100, window_height // 2 - 100))
    window.blit(class_text, (window_width // 2 - 100, window_height // 2))
    pygame.draw.rect(window, white, (window_width // 2 + 100, window_height // 2 - 100, 200, 30), 2)
    pygame.draw.rect(window, white, (window_width // 2 + 100, window_height // 2 + 5, 200, 30), 2)
    window.blit(username_input, (window_width // 2 + 105, window_height // 2 - 95))
    window.blit(class_input, (window_width // 2 + 105, window_height // 2 + 5))
    window.blit(prompt_text, (window_width // 2 - 150, window_height // 2 + 100))

    # Draw the cursor in the active input box
    if username_input_active and cursor_visible:
        cursor_pos_x = window_width // 2 + 105 + username_input.get_width()
        pygame.draw.line(window, white, (cursor_pos_x, window_height // 2 - 95), (cursor_pos_x, window_height // 2 - 75), 2)
    elif class_input_active and cursor_visible:
        cursor_pos_x = window_width // 2 + 105 + class_input.get_width()
        pygame.draw.line(window, white, (cursor_pos_x, window_height // 2 + 5), (cursor_pos_x, window_height // 2 + 30), 2)

    # Draw the start game button
    start_button = pygame.Rect(window_width // 2 - 75, window_height // 2 + 150, 150, 50)
    pygame.draw.rect(window, white, start_button)
    start_text = font.render('Start Game', True, black)
    window.blit(start_text, (window_width // 2 - 60, window_height // 2 + 165))

    pygame.display.update()

# Function to start the game
def start_game():
    game_loop()

# Set the width and height of the game window
width, height = 640, 480
window = pygame.display.set_mode((width, height))

# Set the colors
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
blue = pygame.Color(0, 0, 255)
green = pygame.Color(0, 255, 0)
yellow = pygame.Color(255, 255, 0)
orange = pygame.Color(255, 165, 0)
head = pygame.Color(152, 238, 204)  # color for snake head

# Set the initial position of the snake
snake_pos = [100, 50]
snake_body = [[100, 50], [90, 50], [80, 50]]

# Set the initial position of the food
food_pos = [random.randrange(1, width // 10) * 10, random.randrange(1, height // 10) * 10]
food_spawn = True

# Set the initial direction of the snake
direction = 'RIGHT'
change_to = direction

# Set the game clock
clock = pygame.time.Clock()

# Set the initial score
score = 0

# Initialize the slow food position variables
slow_food_pos = [-10, -10]  # Initialize outside the visible area
fast_food_pos = [-10, -10]  # Initialize outside the visible area
bound_food_pos = [-10, -10]  # Initialize outside the visible area
slow_food_spawn = False
fast_food_spawn = False
bound_food_spawn = False
isFast = False
speed_spawn_timer = 60.0  # Time in seconds for slow food to spawn
bound_spawn_timer = 90.0  # Time in seconds for bound food to spawn
last_slow_food_spawn = time.time()
last_fast_food_spawn = time.time()
last_bound_food_spawn = time.time()
slow_timer = time.time()
fast_timer = time.time()
bound_timer = time.time()
game_start = time.time()

# Game over function
def game_over():
    font = pygame.font.SysFont('Arial', 30)
    text = font.render('Game Over!', True, red)
    game_over_rect = text.get_rect()
    game_over_rect.midtop = (width // 2, height // 4)
    window.blit(text, game_over_rect)
    pygame.display.flip()
    pygame.time.wait(2000)
    pygame.quit()
    quit()

# User screen for choosing snake color
def choose_color():
    chosen = False
    color = blue  # Default color

    color_palette = [blue, red, green, yellow]  # Add more color options here

    while not chosen:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_1:
                    color = color_palette[0]
                    chosen = True
                elif event.key == pygame.K_2:
                    color = color_palette[1]
                    chosen = True
                elif event.key == pygame.K_3:
                    color = color_palette[2]
                    chosen = True
                elif event.key == pygame.K_4:
                    color = color_palette[3]
                    chosen = True

        # Background
        window.fill(black)

        # Render text
        font = pygame.font.SysFont('Arial', 30)
        text = font.render('Choose Snake Color:', True, white)
        window.blit(text, (width // 2 - 150, height // 2 - 50))

        text = font.render('1. Blue', True, color_palette[0])
        window.blit(text, (width // 2 - 50, height // 2))

        text = font.render('2. Red', True, color_palette[1])
        window.blit(text, (width // 2 - 50, height // 2 + 50))

        text = font.render('3. Green', True, color_palette[2])
        window.blit(text, (width // 2 - 50, height // 2 + 100))

        text = font.render('4. Yellow', True, color_palette[3])
        window.blit(text, (width // 2 - 50, height // 2 + 150))

        pygame.display.update()

    return color

# Get the chosen snake color

def game_loop():
    snake_color = choose_color()
    # Set the width and height of the game window
    width, height = 640, 480
    window = pygame.display.set_mode((width, height))

    # Set the colors
    black = pygame.Color(0, 0, 0)
    white = pygame.Color(255, 255, 255)
    red = pygame.Color(255, 0, 0)
    blue = pygame.Color(0, 0, 255)
    green = pygame.Color(0, 255, 0)
    yellow = pygame.Color(255, 255, 0)
    orange = pygame.Color(255, 165, 0)
    head = pygame.Color(152, 238, 204)  # color for snake head

    # Set the initial position of the snake
    snake_pos = [100, 50]
    snake_body = [[100, 50], [90, 50], [80, 50]]

    # Set the initial position of the food
    food_pos = [random.randrange(1, width // 10) * 10, random.randrange(1, height // 10) * 10]
    food_spawn = True

    # Set the initial direction of the snake
    direction = 'RIGHT'
    change_to = direction

    # Set the game clock
    clock = pygame.time.Clock()

    # Set the initial score
    score = 0

    # Initialize the slow food position variables
    slow_food_pos = [-10, -10]  # Initialize outside the visible area
    fast_food_pos = [-10, -10]  # Initialize outside the visible area
    bound_food_pos = [-10, -10]  # Initialize outside the visible area
    slow_food_spawn = False
    fast_food_spawn = False
    bound_food_spawn = False
    isFast = False
    speed_spawn_timer = 60.0  # Time in seconds for slow food to spawn
    bound_spawn_timer = 90.0  # Time in seconds for bound food to spawn
    last_slow_food_spawn = time.time()
    last_fast_food_spawn = time.time()
    last_bound_food_spawn = time.time()
    slow_timer = time.time()
    fast_timer = time.time()
    bound_timer = time.time()
    game_start = time.time()

    score = 0
    # Main game loop
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT or event.key == ord('d'):
                    change_to = 'RIGHT'
                if event.key == pygame.K_LEFT or event.key == ord('a'):
                    change_to = 'LEFT'
                if event.key == pygame.K_UP or event.key == ord('w'):
                    change_to = 'UP'
                if event.key == pygame.K_DOWN or event.key == ord('s'):
                    change_to = 'DOWN'

        # Validate the direction
        if change_to == 'RIGHT' and direction != 'LEFT':
            direction = 'RIGHT'
        if change_to == 'LEFT' and direction != 'RIGHT':
            direction = 'LEFT'
        if change_to == 'UP' and direction != 'DOWN':
            direction = 'UP'
        if change_to == 'DOWN' and direction != 'UP':
            direction = 'DOWN'

        # Update the snake position
        if direction == 'RIGHT':
            snake_pos[0] = (snake_pos[0] + 10) % width
        if direction == 'LEFT':
            snake_pos[0] = (snake_pos[0] - 10 + width) % width
        if direction == 'UP':
            snake_pos[1] = (snake_pos[1] - 10 + height) % height
        if direction == 'DOWN':
            snake_pos[1] = (snake_pos[1] + 10) % height

        # Snake body mechanism
        snake_body.insert(0, list(snake_pos))
        if snake_pos[0] == food_pos[0] and snake_pos[1] == food_pos[1]:
            score += 1
            food_spawn = False
        else:
            snake_body.pop()

        # Spawn food if not present
        if not food_spawn:
            food_pos = [random.randrange(1, width // 10) * 10, random.randrange(1, height // 10) * 10]
            food_spawn = True

        # Spawn slow food every minute
        current_time = time.time()
        if slow_food_spawn and current_time - last_slow_food_spawn > 3:
            if time.time() < bound_timer:
                slow_food_pos = [(random.randrange(2, (width // 10) - 10) * 10),
                                 (random.randrange(2, (height // 10) - 10) * 10)]
            else:
                slow_food_pos = [random.randrange(0, width // 10) * 10, random.randrange(0, height // 10) * 10]
            last_slow_food_spawn = current_time
            slow_food_spawn = True

        current_time = time.time()
        if not slow_food_spawn and current_time - last_slow_food_spawn > speed_spawn_timer:
            if time.time() < bound_timer:
                slow_food_pos = [(random.randrange(2, (width // 10) - 10) * 10), (random.randrange(2, (height // 10)-10) * 10)]
            else:
                slow_food_pos = [random.randrange(0, width // 10) * 10, random.randrange(0, height // 10) * 10]
            last_slow_food_spawn = current_time
            slow_food_spawn = True

        # Spawn fast food every minute

        current_time = time.time()
        if current_time - last_fast_food_spawn > speed_spawn_timer:
            if time.time() < bound_timer:
                fast_food_pos = [(random.randrange(2, (width // 10) - 10) * 10), (random.randrange(2, (height // 10)-10) * 10)]
            else:
                fast_food_pos = [random.randrange(0, width // 10) * 10, random.randrange(0, height // 10) * 10]
            last_fast_food_spawn = current_time
            fast_food_spawn = True

        # Spawn bound food every minute
        current_time = time.time()
        if current_time - last_bound_food_spawn > bound_spawn_timer:
            bound_food_pos = [(random.randrange(2, (width // 10) - 10) * 10), (random.randrange(2, (height // 10)-10) * 10)]
            last_bound_food_spawn = current_time
            bound_food_spawn = True

        # Background
        window.fill(black)

        # Draw the snake
        for i, pos in enumerate(snake_body):
            if i == 0:
                # Draw the head of the snake in brown color
                pygame.draw.rect(window, head, pygame.Rect(pos[0], pos[1], 10, 10))
            else:
                # Draw the rest of the body in the chosen color
                pygame.draw.rect(window, snake_color, pygame.Rect(pos[0], pos[1], 10, 10))

        # Draw the regular food
        pygame.draw.rect(window, white, pygame.Rect(food_pos[0], food_pos[1], 10, 10))

        # Draw the slow food if spawned
        if slow_food_spawn:
            pygame.draw.rect(window, green, pygame.Rect(slow_food_pos[0], slow_food_pos[1], 10, 10))

        if fast_food_spawn:
            pygame.draw.rect(window,orange, pygame.Rect(fast_food_pos[0], fast_food_pos[1], 10, 10))

        if bound_food_spawn:
            pygame.draw.rect(window, red, pygame.Rect(bound_food_pos[0], bound_food_pos[1], 10, 10))

        # Check if the snake eats the slow food
        if snake_pos[0] == slow_food_pos[0] and snake_pos[1] == slow_food_pos[1]:
            score += 3
            slow_food_spawn = False
            last_slow_food_spawn = time.time()
            slow_timer = time.time() + 30  # Slow timer for 30 seconds

        # Check if the snake eats the fast food
        if snake_pos[0] == fast_food_pos[0] and snake_pos[1] == fast_food_pos[1]:
            fast_food_spawn = False
            last_fast_food_spawn = time.time()
            fast_timer = time.time() + 30  # fast timer for 30 seconds

        # Check if the snake eats the boundary food
        if snake_pos[0] == bound_food_pos[0] and snake_pos[1] == bound_food_pos[1]:
            bound_food_spawn = False
            last_bound_food_spawn = time.time()
            bound_timer = time.time() + 30  # fast timer for 30 seconds

        if time.time() < bound_timer and (snake_pos[0] == (width-10) or snake_pos[0] == 10 or snake_pos[1] == (height-10) or snake_pos[1] == 10):
            game_over()

        # Game Over conditions
        for block in snake_body[1:]:
            if snake_pos[0] == block[0] and snake_pos[1] == block[1]:
                game_over()

        # Score
        font = pygame.font.SysFont('Arial', 20)
        score_text = font.render(f'Score: {score}', True, white)
        window.blit(score_text, (10, 10))

        # Refresh the game screen
        pygame.display.update()

        if time.time() < bound_timer:
            margin_rect = pygame.Rect(0, 0, width, height)
            pygame.draw.rect(window, red, margin_rect, 10)
            pygame.display.flip()

        # Check if slow mode is active and update the clock tick rate
        if fast_timer < slow_timer:
            if time.time() < slow_timer:
                clock.tick(12)  # Slow mode tick rate of 10
            else:
                clock.tick(18)  # Regular tick rate
        else:
            if time.time() < fast_timer:
                clock.tick(40)
            else:
                clock.tick(clock.tick(18))  # Regular tick rate

game_loop()


import re
from tqdm import tqdm
import argparse

pat_zh = '[\u4e00-\u9fa5]+'
pat_en = '[a-zA-Z]+'

def remove_char(str, idx):
    front = str[:idx]  # up to but not including n
    back = str[idx + 1:]  # n+1 till the end of string
    return front + back

punc_arr = ',，、：:.。*&)）]】》>%！!?"”'
punc_arr_left = '(（[【《<“'

def rm_blank_punc(text):

    if text.count(' ') > 0:
        for str in punc_arr:
            bstr = ' ' + str
            text = text.replace(bstr, str)

    if text.count(' ') > 0:
        for str in punc_arr_left:
            bstr = str + ' '
            text = text.replace(bstr, str)

    return text

def rm_blank_sp(text):
    text = text.replace('\t', ' ')
    text = re.subn('\s{2,}', ' ', text)[0]
    return text.strip()

def en_detok(sent):
    sent = sent.replace(" 's", "'s").replace(" 've", "'ve").replace(" 'm", "'m").replace(" 't", "'t")
    sent = rm_blank_punc(sent)
    sent = rm_blank_sp(sent)
    return sent

def zh_detok(text):
    text = text.strip()
    index = 0
    while 1:
        index = text.find(' ', index)
        # print('\n', index )
        if index == -1: break

        l_char = text[index - 1]
        # print('l_char : ', l_char)
        if re.match(pat_zh, l_char) != None:
            text = remove_char(text, index)
            continue

        if index + 1 <= len(text):
            r_char = text[index + 1]
            # print('r_char : ', r_char)
            if re.match(pat_zh, r_char) != None:
                text = remove_char(text, index)
                continue

        index += 1

    if len(re.findall(pat_en, text)) > 1: text = en_detok(text)
    # print(text)
    text = rm_blank_punc(text)
    text = rm_blank_sp(text)
    return text

if __name__ == '__main__':
    # revise from https://blog.csdn.net/lovechris00/article/details/127436252
    parser = argparse.ArgumentParser(description='which dataset')
    parser.add_argument('--input', type=str)
    parser.add_argument('--output', type=str)
    args = parser.parse_args()

    input_file = args.input
    output_file = args.output
    with open(input_file, "r", encoding="utf-8") as w:
        lines = [x.strip() for x in w.readlines()]

    detokenize_results = []
    for item in tqdm(lines):
        detokenize_results.append(zh_detok(item))

    print(lines[0])
    print(detokenize_results[0])
    with open(output_file, "w", encoding="utf-8") as f:
        for line in detokenize_results:
            f.write(line + "\n")


import os
import sys
import pickle
import random
import datetime
import argparse
import numpy as np
import matplotlib.pyplot as plt
from scipy import misc

from PIL import Image

def predict(image, SRCNN, epoch, mode='compare'):
    scale = 3.0
    input_size = 33
    label_size = 21
    pad = int((input_size - label_size) / 2)

    w, h, c = image.shape
    w -= int(w % scale)
    h -= int(h % scale)
    image = image[0:w, 0:h, :]

    scaled = misc.imresize(image, 1.0/scale, 'bicubic')
    scaled = misc.imresize(scaled, scale/1.0, 'bicubic')/255.0
    newimg = np.zeros(scaled.shape)

    for i in range(0, h - input_size + 1, label_size):
        for j in range(0, w - input_size + 1, label_size):
            sub_img_y = np.expand_dims(scaled[j : j + input_size, i : i + input_size, 0],axis=-1)
            prediction = np.squeeze(SRCNN.predict(np.expand_dims(sub_img_y, axis=0)))
            prediction[prediction > 1.0] = 1.0
            newimg[j + pad : j + pad + label_size, i + pad : i + pad + label_size, 0] = prediction
    newimg[...,1:] = scaled[...,1:]
    newimg = newimg[pad : w - w % input_size, pad : h - h % input_size,:]

    if(mode == 'compare'):
        height = int(1.2*h)
        width = int(1.2*w)
        image = pad_img(ycbcr2rgb(image*255.0), [width,height])
        scaled = pad_img(ycbcr2rgb(scaled*255.0), [width,height])
        newimg = pad_img(ycbcr2rgb(newimg*255.0), [width,height])
        saveimg = np.hstack((image,scaled,newimg))
        # plt.subplot(131)
        # plt.imshow(image/255.0)
        # plt.subplot(132)
        # plt.imshow(scaled/255.0)
        # plt.subplot(133)
        # plt.imshow(newimg/255.0)
        # plt.show()

        array2image(saveimg).save('../TrainResult/Round{}.png'.format(epoch+1))
        return None
    else:
        return newimg

def pad_img(img, img_size):
    img_h,img_w=img.shape[0], img.shape[1]
    target_h,target_w=img_size[0],img_size[1]

    if len(img.shape)==3:
        d=img.shape[2]
        padded=np.zeros((target_h, target_w,d))
    elif len(img.shape)==2:
        padded=np.zeros((target_h, target_w))

    padded[(target_h-img_h)//2:(target_h-img_h)//2+img_h,(target_w-img_w)//2:(target_w-img_w)//2+img_w,...]=img

    return padded

def array2image(arr):
    if(np.max(arr)<=1):
        image = Image.fromarray((arr*255).astype(np.uint8))
    else:
        image = Image.fromarray((arr).astype(np.uint8))

    return image

def showFLAGS(FLAGS):
    for i in vars(FLAGS):
        if len(i) < 8:
            print(i + '\t\t------------  ' + str(vars(FLAGS)[i]))
        else:
            print(i + '\t------------  ' + str(vars(FLAGS)[i]))
    print()

def progressbar(progress, total, length=40):
    total = total - 1
    num = int(progress/total*length)
    sys.stdout.write('#' * num + '_' * (length - num) )
    sys.stdout.write(':{:.2f}%'.format(progress/total*100)+ '\r')
    if progress == total:
        sys.stdout.write('\n\n')
    sys.stdout.flush()

def checkpath(path):
    try:
        os.makedirs(path)
        # print('creat ' + path)
    except OSError:
        pass

def log(text):
    """
    log status with time label
    """
    print()
    nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    line1 = '='*10 + '  ' + nowTime + '  '+ '='*10
    length = len(line1)
    leftnum = int((length - 4 - len(text))/2)
    rightnum = length - 4 - len(text) - leftnum
    line2 = '*'*leftnum + ' '*2 + text  + ' '*2 + '*'*rightnum
    print(line1)
    print(line2)
    print('='*len(line1))

def all_files_under(path, extension=None, append_path=True, sort=True):
    if append_path:
        if extension is None:
            filenames = [os.path.join(path, fname) for fname in os.listdir(path)]
        else:
            filenames = [os.path.join(path, fname) for fname in os.listdir(path) if fname.endswith(extension)]
    else:
        if extension is None:
            filenames = [os.path.basename(fname) for fname in os.listdir(path)]
        else:
            filenames = [os.path.basename(fname) for fname in os.listdir(path) if fname.endswith(extension)]

    if sort:
        filenames = sorted(filenames)

    return filenames

mat = np.array(
    [[ 65.481, 128.553, 24.966 ],
     [-37.797, -74.203, 112.0  ],
     [  112.0, -93.786, -18.214]])
mat_inv = np.linalg.inv(mat)
offset = np.array([16, 128, 128])

def rgb2ycbcr(rgb_img):
    ycbcr_img = np.zeros(rgb_img.shape)
    for x in range(rgb_img.shape[0]):
        for y in range(rgb_img.shape[1]):
            ycbcr_img[x, y, :] = np.round(np.dot(mat, rgb_img[x, y, :] * 1.0 / 255) + offset)
    return ycbcr_img
def ycbcr2rgb(ycbcr_img):
    rgb_img = np.zeros(ycbcr_img.shape, dtype=np.uint8)
    for x in range(ycbcr_img.shape[0]):
        for y in range(ycbcr_img.shape[1]):
            [r, g, b] = ycbcr_img[x,y,:]
            rgb_img[x, y, :] = np.maximum(0, np.minimum(255, np.round(np.dot(mat_inv, ycbcr_img[x, y, :] - offset) * 255.0)))
    return rgb_img


from itertools import combinations

def solution1(nums): # 방법1 : combinations 사용
    cnt = 0
    for cb in combinations(nums, 3): # 원소 3개로 구성된 리스트의 모든 조합
        s = sum(cb)
        if isPrime(s):
            cnt += 1
    return cnt

def solution2(nums): # 방법2 : 반복문 사용
    sum = 0
    cnt = 0
    nums_len = len(nums)

    for i in range(nums_len - 2):
        for j in range(i+1, nums_len - 1):
            for k in range(j+1, nums_len):
                sum = nums[i] + nums[j] + nums[k]
                if isPrime(sum):
                    cnt += 1
    return cnt

def isPrime(num): # 소수 판별
    for divisor in range(2, num // 2 + 1):
        if num % divisor == 0:
            return False
    return True

print(solution1([1,2,3,4])) # 테스트코드


ANSIBLE_METADATA = {
    'metadata_version': '0.1',
    'status': ['preview'],
    'supported_by': 'community'
}

DOCUMENTATION = '''
---
module: contrail

short_description: Interact with Juniper Contrail via REST API

version_added: "2.9"

description:
    - "Interact with Juniper Contrail via REST API"

options:
    name:
        description:
            - Resource name
        required: true
        type: 'str'
    type:
        description:
            - Resource type (e.g. virtual-network)
        required: true
        type: str
    state:
        description:
            - Expected resource state
        required: true
        choices:
            - present
            - absent
            - query
        type: str
    domain:
        description:
            - Domain name (e.g. default-domain)
        required: true
        type: str
    project:
        description:
            - Project name (e.g. vCenter)
        required: true
        type: str
    definition:
        description:
            - Resource definition (REST API payload)
        required: false
        type: dict

author:
    - Jean-Philippe Clipffel (@jpclipffel)
'''

EXAMPLES = '''
# Pass in a message
- name: Get a resource
  contrail:
    type: virtual-network
    domain: default-domain
    project: vCenter
    name: VPCB1
'''

RETURN = '''
msg:
    description: Action status
    type: str
    returned: always
api:
    description: Contrail API request and response
    type: complex
    returned: always
'''

import json

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection

class Result:
    '''Generic Contrail API result.

    Any request made to the API (i.e. using `send_request`) **should** returns a :class:`Result` instance.
    '''
    def __init__(self, changed=False, failed=False, msg="", method="", path="", request={}, response={}, status_code=-1):
        self.changed = changed
        self.failed = failed
        self.msg = msg
        # ---
        self.method = method
        self.path = path
        self.request = request
        self.response = response
        self.status_code = status_code

    def to_dict(self):
        '''Transforms the :class:`Result` to a `dict` object suitable for Ansible.
        '''
        return {
            "changed": self.changed,
            "failed": self.failed,
            "msg": self.msg,
            "api": {
                "method": self.method,
                "path": self.path,
                "request": self.request,
                "response": self.response,
                "status_code": self.status_code
            }
        }

class ContrailError(Exception):
    '''Generic Contrail API error.

    This exception simply wraps a :class:`Result`.
    '''
    def __init__(self, result):
        self.result = result

class Resource:
    '''Generic Contrail resource interface.

    One **can't** use a :class:`Resource` directly: a derivied class, such as
    :class:`VirtualNetwork` must be used instead.
    '''

    # Resource properties, overide by :class:`Resource`'s derived classes.
    type = ""           # string; The resource type name (e.g. 'virtual-network')
    path_get = ""       # string; API path to 'GET' the resource
    path_put = ""       # string; API path to 'PUT' to the resource
    path_post = ""      # string; API path to 'POST' to the resource
    parent_type = ""    # string; Resource parent type name (e.g. 'project')

    def __init__(self, contrail, name, project, domain):
        '''Initializes the instance.

        :param Contrail contrail: :class:`Contrail` instance
        :param str name: Resource name (== display name)
        :param str project: Resource project name
        :param domain: Resource domain name
        '''
        self.contrail = contrail
        self.name = name
        self.project = project
        self.domain = domain
        # ---
        self._uuid = None
        self._definition = None

    @property
    def uuid(self):
        '''Returns the resource UUID or `None` if the resource does not exists.

        :rtype: str, None
        :raise: ContrailError
        '''
        method, path = "POST", "/fqname-to-id"
        request, content, status_code = {}, {}, -1
        # ---
        try:
            if not self._uuid:
                request = {"type": self.type, "fq_name": [self.domain, self.project, self.name]}
                status_code, content = self.contrail.connection.send_request(method, path, request)
                if status_code in [200, ] and "uuid" in content:
                    self._uuid = content["uuid"]
            return self._uuid
        except Exception as error:
            raise ContrailError(Result(
                failed=True, msg='Exception: {0}'.format(str(error)),
                method=method, path=path, request=request, response=content, status_code=status_code))

    @property
    def definition(self):
        '''Returns the resource definition or `{}` (an empty :class:`dict`) if resource does not exists.

        :rtype: dict
        :raise: ContrailError
        '''
        method, path = "GET", "/{0}/{1}".format(self.path_get, self.uuid)
        request, content, status_code = {}, {}, -1
        # ---
        try:
            if not self._definition:
                status_code, content = self.contrail.connection.send_request(method, path)
                if status_code in [200, ]:
                    self._definition = content
            return self._definition
        except Exception as error:
            raise ContrailError(Result(
                failed=True, msg='Exception: {0}'.format(str(error)),
                method=method, path=path, request=request, response=content, status_code=status_code))

    @property
    def exists(self):
        '''Returns `True` is the resource exists (i.e. has an UUID), `False` otherwise.

        :rtype: Bool
        '''
        if self.uuid:
            return True
        return None

    def apply(self, definition):
        '''Creates or update the resource.

        If the resource already exists, a 'PUT' call is performed.
        If the resource doesn't exists, a 'POST' call is performed.

        :param dict definition: Resource definition (API payload)
        :rtype: Result
        :raise: ContrailError
        '''
        method, path = "", ""
        _definition, content, status_code = {}, {}, -1
        # ---
        try:
            _definition = {self.type: {
                "parent_type": self.parent_type,
                "fq_name": [ self.domain, self.project, self.name ]
            }}
            _definition[self.type].update(definition)
            # ---
            if self.exists:
                method, path = "PUT", "/{0}/{1}".format(self.path_put, self.uuid)
            else:
                method, path = "POST", "/{0}".format(self.path_post)
            # ---
            status_code, content = self.contrail.connection.send_request(method, path, _definition)
            # ---
            if status_code in [200, ]:
                return Result(
                    changed=True, msg="Resource updated",
                    method=method, path=path, request=_definition, response=content, status_code=status_code)
            else:
                raise ContrailError(Result(
                    failed=True, msg="Failed to update resource",
                    method=method, path=path, request=_definition, response=content, status_code=status_code))
        except ContrailError as error:
            raise error
        except Exception as error:
            raise ContrailError(Result())

    def delete(self):
        '''Deletes the resource.

        If the resource exists, a 'DELETE' call is performed.
        If the resource doesn't exists, nothing is done.

        :rtype: Result
        :raise: ContrailError
        '''
        method, path = "DELETE", "/{0}/{1}".format(self.path_put, self.uuid)
        _definition, status_code = {}, -1
        # ---
        try:
            if self.exists:
                msg = "Resource deleted"
                status_code, _ = self.contrail.connection.send_request(method, path)
            else:
                msg = "Resource does not exists"
            return Result(
                changed=False, msg=msg,
                method=method, path=path, status_code=status_code)
        except ContrailError as error:
            raise error
        except Exception as error:
            raise ContrailError(Result(
                failed=True, msg='Exception: {0}'.format(str(error)),
                method=method, path=path, status_code=status_code))

class VirtualNetwork(Resource):
    '''Contrail API object 'virtual-network'
    '''
    type = "virtual-network"
    path_get = "virtual-network"
    path_put = "virtual-network"
    path_post = "virtual-networks"
    parent_type = "project"

class Contrail:
    '''Interfaces with Contrail API (high-level functions).

    :attr resources_map: Mapping between resources type name and classes.
    '''

    resources_map = {
        "virtual-network": VirtualNetwork
    }

    def __init__(self, module, connection):
        '''Initializes instance.

        :param object module: Ansible module instance
        :param object connection: Ansible connection plugin interface
        '''
        self.module = module
        self.connection = connection

    def resource(self, type, name, project, domain):
        '''Returns the requested resource.

        :param str type: Resource type name (e.g. 'virtual-network')
        :param str name: Resource name
        :param str project: Resource project
        :param str domain: Resource domain

        :return: A new resource instance
        :rtype: Resource
        :raise: ContrailError
        '''
        if not type in self.resources_map:
            raise ContrailError(Result(False, "failure", "Unknown resource type: {0}".format(type)))
        return self.resources_map[type](self, name, project, domain)

    def state_query(self, type, name, project, domain):
        '''Query a resource.

        :param str type: Resource type name (e.g. 'virtual-network')
        :param str name: Resource name
        :param str project: Resource project
        :param str domain: Resource domain

        :return: A new resource instance
        :rtype: Result
        :raise: ContrailError
        '''
        resource = self.resource(type, name, project, domain)
        if resource.exists:
            return Result(msg="Resource queried", response=resource.definition)
        else:
            return Result(failed=True, msg="Resource does not exists")

    def state_present(self, type, name, project, domain, definition):
        '''Creates or updates a resource.

        :param str type: Resource type name (e.g. 'virtual-network')
        :param str name: Resource name
        :param str project: Resource project
        :param str domain: Resource domain
        :param definition: Resource definition (API payload)

        :return: A new resource instance
        :rtype: Result
        :raise: ContrailError
        '''
        try:
            resource = self.resource(type, name, project, domain)
            return resource.apply(definition)
        except ContrailError as error:
            raise error

    def state_absent(self, type, name, project, domain):
        '''Removes a resource.

        :param str type: Resource type name (e.g. 'virtual-network')
        :param str name: Resource name
        :param str project: Resource project
        :param str domain: Resource domain

        :return: A new resource instance
        :rtype: Result
        :raise: ContrailError
        '''
        try:
            resource = self.resource(type, name, project, domain)
            return resource.delete()
        except ContrailError as error:
            raise error

def run_module():
    '''Ansible module entry point.
    '''
    # Ansible module arguments
    module_args = dict(
        name=dict(type=str, required=True),
        type=dict(type="str", required=True),
        state=dict(type="str", required=True),
        domain=dict(type="str", required=True),
        project=dict(type="str", required=True),
        definition=dict(type="dict", required=False, default={}))
    # Initializes module, connection and API helper
    module = AnsibleModule(argument_spec=module_args, supports_check_mode=False)
    connection = Connection(module._socket_path)
    contrail = Contrail(module, connection)
    # Wraps module parameters
    resource_state = module.params["state"]
    resource_name = module.params["name"]
    resource_type = module.params["type"]
    resource_domain = module.params["domain"]
    resource_project = module.params["project"]
    resource_definition = module.params["definition"]
    # Run module
    try:
        # Run module in 'query' mode (gather info)
        if resource_state in ["query", "status", ]:
            result = contrail.state_query(resource_type, resource_name, resource_project, resource_domain)
        # Run module in 'present' mode (may create or update resource(s))
        elif resource_state in ["present", ]:
            result = contrail.state_present(resource_type, resource_name, resource_project, resource_domain, resource_definition)
        # Run module in 'absent' mode (may deletes resource(s))
        elif resource_state in ["absent", ]:
            result = contrail.state_absent(resource_type, resource_name, resource_project, resource_domain)
        # Invalid state
        else:
            result = Result(failed=True, msg="Invalid module state: {0}".format(resource_state))
    except ContrailError as error:
        result = error.result
    # Exit
    if result.failed:
        module.fail_json(**result.to_dict())
    else:
        module.exit_json(**result.to_dict())

def main():
    run_module()

if __name__ == '__main__':
    main()


from config import TESTS_FOLDER
from extract_goodreader import parse_args, process_text

def test_process_text():
    """
    Tests the processing of a GoodReader export.
    """

    test_args = ["--first", 0]
    args = parse_args(test_args)

    given_fn = TESTS_FOLDER / "goodreader-given.txt"
    with open(given_fn) as given_fd:
        given = given_fd.read()

    result = process_text(args, given)
    # print(f"{result=}")

    with open(TESTS_FOLDER / "goodreader-result.txt", "w") as result_fd:
        result_fd.write(result)
    with open(TESTS_FOLDER / "goodreader-expected.txt") as expected_fd:
        expected = expected_fd.read()
    # print(f"{expected=}")
    assert result == expected

if __name__ == "__main__":
    test_process_text()