# -*- coding: utf-8 -*-
"""
Created on Sat Jul  4 00:01:31 2020

@author: SHIKHIN
"""
from __future__ import division
import praw
import datetime
from statistics import mean
import re
from pytz import timezone
import operator

tz = timezone('EST')
grade_types = {'PO01':1, 'FR02':2, 'AG03':3, 'G04':4, 'G06':6, 'VG08':8, 'VG10':10, 'F12':12, 'F15':15, 'VF20':20, 'VF25':25, 'VF35':35, 'VF30':30, 'XF40':40, 'XF45':45, 'AU50':50, 'AU53':53, 'AU55':55, 'AU58':58, 'MS60':60, 'MS61':61, 'MS62':62, 'MS63':63, 'MS64':64, 'MS65':65, 'MS66':66, 'MS67':67, 'MS68':68, 'MS69':69, 'MS70':70, 'PO':1, 'po':1, 'Poor':1, 'poor':1, 'FR':2, 'fr':2, 'AG':3, 'ag':3, 'G':4, 'g':4, 'Good':4, 'good':4, 'VG':8, 'vg':8, 'F':12, 'f':12, 'Fine':12, 'fine':12, 'VF':20, 'vf':20, 'XF':40, 'xf':40, 'AU':50, 'au':50, 'BU':60, 'bu':60, 'MS':60, 'ms':60, 'PF':60, 'pf':60}

alt_grade_types = ['PO', 'po', 'Poor', 'poor', 'FR', 'fr', 'AG', 'ag', 'G', 'g', 'Good', 'good', 'VG', 'vg', 'F', 'f', 'Fine', 'fine', 'VF', 'vf', 'XF', 'xf', 'au', 'AU','BU', 'bu', 'MS', 'ms', 'pf', 'PF']

numeric_grade_type = [1, 2, 3, 4, 6, 8, 10, 12, 15, 20, 25, 35, 30, 40, 45, 50, 53, 55, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 ]

desig_set1 = ['FS', 'FB', 'FH', 'FBL']
desig_set2 = ['PL', 'DMPL']
desig_set3 = ['CAM', 'DCAM']
desig_set4 = ['BR', 'RD', 'RB']
desig_set5 = ['toned', 'cleaned', 'polished', 'details', 'replated', 'corroded']
desig_set6 = ['+', '*']

reddit = praw.Reddit("bot", user_agent="bot user agent")

subreddit=reddit.subreddit('redditCoinGrading')

def search_avg_grade(avg):
    for key in grade_types:
        if(grade_types[key] == avg):
            return key
        elif(grade_types[key] >= avg):
            return key

grade_list = []             #contains grades of different comments

while(True):

    for submission in subreddit.new():

            desig_dict1 = {'FS':0, 'FB':0, 'FH':0, 'FBL':0}
            desig_dict2 = {'PL':0, 'DMPL':0}
            desig_dict3 = {'CAM':0, 'DCAM':0}
            desig_dict4 = {'BR':0, 'RD':0, 'RB':0}
            desig_dict5 = {'toned':0, 'cleaned':0, 'polished':0, 'details':0, 'replated':0, 'corroded':0}
            desig_dict6 = {'+':0, '*':0}

            converted_submission_dt = datetime.datetime.utcfromtimestamp(submission.created_utc)
            current_time_utc = datetime.datetime.utcnow()

            date_difference = current_time_utc - converted_submission_dt

            if(date_difference.days <= 7):
                bot_in_post = False                                 #flag if bot has commented on the post

                for comment in submission.comments:
                    if ((comment.author is not None) and (comment.author.name=="RCG_bot")):
                        bot_in_post = True
                        break

                if(bot_in_post==False):
                    mycomment = submission.reply("Hi, I’m the RCG bot (beta)!\n\nPlease read the rules how to have your grade counted.\n\nThank you, and happy collecting!\n\n ^(*I'm a bot and this action was performed automatically. Please [contact the moderators](https://www.reddit.com/message/compose/?to=/r/redditcoingrading) or [fill out this form](https://forms.gle/HtoDquWoqRAy9DWdA) if there is a bug*)")
                    mycomment.mod.distinguish(how='yes', sticky=True)

                numeric_grade = []
                designation = []

                for comment in submission.comments:

                    set1 = False
                    set2 = False
                    set3 = False
                    set4 = False
                    set5 = False
                    set6 = False

                for comment in submission.comments:
                    if (comment.score >= 0 and  comment.id and (comment.author is not None) and (comment.author.name!="RCG_bot")):            #use author name, improve bot using this functionality
                        curr_comment = comment.body
                        sub_str = re.findall(r'\[(.*?)\]', curr_comment)
                        if(sub_str):
                            number_metric = re.findall('[0-9]+', sub_str[0])

                            if(number_metric):
                                numeric_grade.append(int(number_metric[0]))
                            else:
                                for alt in alt_grade_types:
                                    if(alt in sub_str[0].lower()):                      #po and poor bug
                                        if((alt=='po' and 'poor' in sub_str[0].lower()) or (alt=='f' and 'fine' in sub_str[0].lower()) or (alt=='f' and 'vf' in sub_str[0].lower()) or (alt=='g' and 'vg' in sub_str[0].lower()) or (alt=='f' and 'xf' in sub_str[0].lower()) or (alt=='f' and 'pf' in sub_str[0].lower())):
                                            continue
                                        else:
                                            numeric_grade.append(grade_types[alt])

                        if(sub_str):
                            if(set1 is False):
                                for s in desig_set1:
                                    if(s.lower() in sub_str[0].lower()):
                                        if(not(s=='FB' and 'fbl' in sub_str[0].lower())):
                                            designation.append(s)
                                            desig_dict1[s] = desig_dict1[s] + 1
                                            set1 = True
                                            break

                            if(set2 is False):
                                for s in desig_set2:
                                    if(s.lower() in sub_str[0].lower()):
                                        if(not(s=='PL' and 'dmpl' in sub_str[0].lower())):
                                            designation.append(s)
                                            desig_dict2[s] = desig_dict2[s] + 1
                                            set2 = True
                                            break

                            if(set3 is False):
                                for s in desig_set3:
                                    if(s.lower() in sub_str[0].lower()):
                                        if(not(s=='CAM' and 'dcam' in sub_str[0].lower())):
                                            designation.append(s)
                                            desig_dict3[s] = desig_dict3[s] + 1
                                            set3 = True
                                            break

                            if(set4 is False):
                                for s in desig_set4:
                                    if(s.lower() in sub_str[0].lower()):
                                        designation.append(s)
                                        desig_dict4[s] = desig_dict4[s] + 1
                                        set4 = True
                                        break

                            if(set5 is False):
                                for s in desig_set5:
                                    if(s in sub_str[0].lower()):
                                        designation.append(s)
                                        desig_dict5[s] = desig_dict5[s] + 1
                                        set5 = True
                                        break

                            if(set6 is False):
                                for s in desig_set6:
                                    if(s in sub_str[0]):
                                        designation.append(s)
                                        desig_dict6[s] = desig_dict6[s] + 1
                                        set6 = True
                                        break

                        del sub_str[:]

                        desig_final = []

                        if(desig_dict1[max(desig_dict1.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict1.items(), key=operator.itemgetter(1))[0])

                        if(desig_dict2[max(desig_dict2.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict2.items(), key=operator.itemgetter(1))[0])

                        if(desig_dict3[max(desig_dict3.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict3.items(), key=operator.itemgetter(1))[0])

                        if(desig_dict4[max(desig_dict4.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict4.items(), key=operator.itemgetter(1))[0])

                        if(desig_dict5[max(desig_dict5.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict5.items(), key=operator.itemgetter(1))[0])

                        if(desig_dict6[max(desig_dict6.items(), key=operator.itemgetter(1))[0]]!=0):
                            desig_final.append(max(desig_dict6.items(), key=operator.itemgetter(1))[0])

                        print(desig_final)

                print(numeric_grade)

                for num in numeric_grade:
                    if(num not in numeric_grade_type):
                        numeric_grade.remove(num)

                if(numeric_grade):                             #control block which edits comment
                    average = mean(numeric_grade)
                    print(average)
                    final_avg = search_avg_grade(average)                 #finds the correspoding key in grade_types

                    listToStr = ' '.join([str(elem) for elem in desig_final])

                    edited_comment = "Hi, I’m the RCG bot (beta)!\n\n" + "This coin grades as follows: \n #" + final_avg + " " + listToStr + "\n\nPlease read the rules how to have your grade counted.\n\n " + "\n\n^(*Last updated*: *" + datetime.datetime.now(tz).strftime('%m/%d/%y %I:%M:%S %p') + " EST*) \n\n ^(*I'm a bot and this action was performed automatically. Please [contact the moderators](https://www.reddit.com/message/compose/?to=/r/redditcoingrading) or [fill out this form](https://forms.gle/HtoDquWoqRAy9DWdA) if there is a bug*)"

                    if(date_difference.days == 7):
                        edited_comment = edited_comment + "\n\n^(This post is more than 7 days old, and will no longer be updated.)"

                    for comment in submission.comments:
                        if (comment.author is not None and comment.author.name=="RCG_bot"):
                            reddit.validate_on_submit = True
                            reddit.comment(comment.id).edit(edited_comment)
                            break


from fastapi import APIRouter, Depends, Response, Request
from typing import List, Optional, Union
from authenticator import authenticator
from jwtdown_fastapi.authentication import Token
from queries.posts import Error, PostIn, PostOut, PostRepository
from queries.users import UserOut

class AccountToken(Token):
    account: UserOut

router = APIRouter()

@router.get("/api/protected", response_model=bool)
async def get_protected(
    account_data: dict = Depends(authenticator.get_current_account_data),
):
    print(account_data)
    return True

@router.get("/token", response_model=AccountToken | None)
async def get_token(
    request: Request,
    user: UserOut = Depends(authenticator.try_get_current_account_data),
) -> AccountToken | None:
    if authenticator.cookie_name in request.cookies:
        return {
            "access_token": request.cookies[authenticator.cookie_name],
            "type": "Bearer",
            "account": user,
        }

@router.post("/api/posts", response_model=Union[PostOut, Error])
def create_post(
    post: PostIn,
    response: Response,
    repo: PostRepository = Depends(),
    account_data: dict = Depends(authenticator.get_current_account_data),
):
    response = repo.create_post(post)
    if not response:
        response.status_code = 400
    else:
        return response

@router.delete("/api/posts/{post_id}", response_model=bool)
def delete_post(
    post_id: int,
    response: Response,
    repo: PostRepository = Depends(),
    account_data: dict = Depends(authenticator.get_current_account_data),
) -> bool:
    response = repo.delete(post_id)
    if not response:
        response.status_code = 400
    return response

@router.put("/api/posts/{post_id}", response_model=Union[PostOut, Error])
def update_post(
    post_id: int,
    post: PostIn,
    response: Response,
    repo: PostRepository = Depends(),
    account_data: dict = Depends(authenticator.get_current_account_data),
) -> Union[PostOut, Error]:
    response = repo.update_post(post_id, post)
    if not response:
        response.status_code = 400
    return response

@router.get("/api/posts", response_model=Union[List[PostOut], Error])
def get_all_posts(
    repo: PostRepository = Depends(),
    account_data: dict = Depends(authenticator.get_current_account_data),
):
    return repo.get_all_posts()

@router.get("/api/posts/{post_id}", response_model=Optional[PostOut])
def get_one_post(
    post_id: int,
    response: Response,
    repo: PostRepository = Depends(),
    account_data: dict = Depends(authenticator.get_current_account_data),
) -> PostOut:
    post = repo.get_one_post(post_id)
    if not post:
        response.status_code = 400
    return post


from products_mixin import ProductsMixin

'Module which is responsible for calculating an itemizations cost based on product information'

class CheckoutCartCalculator(ProductsMixin):
    'Class that calculates the cost totals for a list of items'

    def __init__(self, products = None):
        self.items = []
        self.products = products or {}

        self._validate_shape_of_products(products)

    def calculate_totals(self, items = None, sales_tax_rate = 0):
        'Calculate the subtotal, sales tax total, and total based on the items'

        self.items = items or []

        return {
            'subtotal': self._calculate_subtotal(),
            'sales_tax_rate': sales_tax_rate,
            'sales_tax_total': self._calculate_sales_tax_total(sales_tax_rate = sales_tax_rate),
            'total': self._calculate_total(sales_tax_rate = sales_tax_rate)
        }

    def _calculate_sales_tax_total(self, sales_tax_rate):
        return self._calculate_subtotal() * sales_tax_rate

    def _calculate_subtotal(self):
        return sum(
            [
                item['count'] * self.products[item['product_key']]['price']
                for item in self.items
            ]
        )

    def _calculate_total(self, sales_tax_rate):
        return (
            self._calculate_subtotal() +
            self._calculate_sales_tax_total(sales_tax_rate = sales_tax_rate)
        )


import random
tensuu = 0
counter = [1,2,3,4,5]
for number in counter:
    kbn = random.randrange(1,4)
    a = random.randrange(1,10)
    b = random.randrange(1,10)
    c = random.randrange(1,10)
    if a >= b >= c:
        x = a
        y = b
        z = c
    elif a >= c >= b:
        x = a
        y = c
        z = b
    elif  b >= a >= c:
        x = b
        y = a
        z = c
    elif b >= c >= a:
        x = b
        y = c
        z = a
    elif c >= a >= b:
        x = c
        y = a
        z = b
    else:
        x = c
        y = b
        z = a
    if kbn == 1:
        print(f"{number}もん目：{x} + {y} + {z} = ")
        ans = input()
        if int(ans) == x + y + z:
            print("せいかい！")
            tensuu += 1
        else:
            print("ざんねん。ちがうよ。")
            print(f"{x+y+z}だよ")
    elif kbn == 2:
        print(f"{number}もん目：{x} - {y} + {z} = ")
        ans = input()
        if int(ans) == x - y + z:
            print("せいかい！")
            tensuu += 1
        else:
            print("ざんねん。ちがうよ。")
            print(f"{x-y+z}だよ")
    elif kbn == 3:
        print(f"{number}もん目：{x} + {y} - {z} = ")
        ans = input()
        if int(ans) == x + y - z:
            print("せいかい！")
            tensuu += 1
        else:
            print("ざんねん。ちがうよ。")
            print(f"{x+y-z}だよ")
print()
print(f"{tensuu * 20}てんでした！")
if tensuu == 5:
    print("すごいね！！よくできました")
elif tensuu == 0:
    print("もっとがんばろう")
else:
    print("もうちょっと。がんばってね。")


from meta_strategies import double_oracle, fictitious_play, mrcp_solver, prd_solver, iterative_double_oracle
from meta_strategies import iterated_prd, iterative_double_oracle_player_selection, regret_controled_RD
from game_generator import Game_generator
from psro_trainer import PSRO_trainer
from utils import set_random_seed
from nash_solver.gambit_tools import load_pkl

from absl import app
from absl import flags
import os
import pickle
import datetime
import numpy as np
import pandas as pd
import sys
import functools
print = functools.partial(print, flush=True)

FLAGS = flags.FLAGS

flags.DEFINE_integer("num_rounds", 10, "The number of rounds starting with different.")
flags.DEFINE_integer("num_strategies", 100, "The number of rounds starting with different.")
flags.DEFINE_integer("num_iterations", 20, "The number of rounds starting with different.")
flags.DEFINE_string("game_type", "zero_sum", "Type of synthetic game.")
flags.DEFINE_integer("seed", None, "The seed to control randomness.")
flags.DEFINE_boolean("MRCP_deterministic", True, "mrcp should return a same value given the same empirical game")
flags.DEFINE_string("closed_method", "alter", "Method for handling closeness of the MRCP")

def psro(generator,
         game_type,
         num_rounds,
         seed,
         checkpoint_dir,
         num_iterations=20,
         closed_method="alter"):
    if game_type == "zero_sum":
        meta_games = generator.zero_sum_game()
    elif game_type == "general_sum":
        meta_games = generator.general_sum_game()
    elif game_type == "symmetric_zero_sum":
        meta_games = generator.symmetric_zero_sum_game()
    elif game_type == "kuhn":
        kuhn_meta_games = load_pkl("./MRCP/kuhn_meta_game.pkl")
        meta_games = kuhn_meta_games[0] # The first element of kuhn_meta_game.pkl is meta_games.
        generator.num_strategies = 64
    else:
        for pkl in os.listdir('efg_game'):
            print(pkl)
            if pkl.split('.pkl')[0] == game_type:
                with open('efg_game/'+pkl,'rb') as f:
                    meta_games = pickle.load(f)
        if not 'meta_games' in locals():
            raise ValueError

    # for example 1 in paper
    # meta_games = [np.array([[0,-0.1,-3],[0.1,0,2],[3,-2,0]]),np.array([[0,0.1,3],[-0.1,0,-2],[-3,2,0]])]
    # generator.num_strategies = 3
    # num_rounds = 1
    # num_iterations = 10
    init_strategies = np.random.randint(0, meta_games[0].shape[0], num_rounds)

    DO_trainer = PSRO_trainer(meta_games=meta_games,
                           num_strategies=generator.num_strategies,
                           num_rounds=num_rounds,
                           meta_method=double_oracle,
                           checkpoint_dir=checkpoint_dir,
                           num_iterations=num_iterations,
                           seed=seed,
                           init_strategies=init_strategies)

    FP_trainer = PSRO_trainer(meta_games=meta_games,
                           num_strategies=generator.num_strategies,
                           num_rounds=num_rounds,
                           meta_method=fictitious_play,
                           checkpoint_dir=checkpoint_dir,
                           num_iterations=num_iterations,
                           seed=seed,
                           init_strategies=init_strategies)

    PRD_trainer = PSRO_trainer(meta_games=meta_games,
                               num_strategies=generator.num_strategies,
                               num_rounds=num_rounds,
                               meta_method=prd_solver,
                               checkpoint_dir=checkpoint_dir,
                               num_iterations=num_iterations,
                               seed=seed,
                               init_strategies=init_strategies)

    CRD_trainer = PSRO_trainer(meta_games=meta_games,
                               num_strategies=generator.num_strategies,
                               num_rounds=num_rounds,
                               meta_method=regret_controled_RD,
                               checkpoint_dir=checkpoint_dir,
                               num_iterations=num_iterations,
                               seed=seed,
                               init_strategies=init_strategies)

    # IDO_trainer = PSRO_trainer(meta_games=meta_games,
    #                            num_strategies=generator.num_strategies,
    #                            num_rounds=num_rounds,
    #                            meta_method=iterative_double_oracle,
    #                            checkpoint_dir=checkpoint_dir,
    #                            num_iterations=num_iterations,
    #                            seed=seed,
    #                            init_strategies=init_strategies)
    #
    # IPRD_trainer = PSRO_trainer(meta_games=meta_games,
    #                             num_strategies=generator.num_strategies,
    #                             num_rounds=num_rounds,
    #                             meta_method=iterated_prd,
    #                             checkpoint_dir=checkpoint_dir,
    #                             num_iterations=num_iterations,
    #                             seed=seed,
    #                             init_strategies=init_strategies)

    # IDOS_trainer = PSRO_trainer(meta_games=meta_games,
    #                             num_strategies=generator.num_strategies,
    #                             num_rounds=num_rounds,
    #                             meta_method=iterative_double_oracle_player_selection,
    #                             checkpoint_dir=checkpoint_dir,
    #                             num_iterations=num_iterations,
    #                             seed=seed,
    #                             init_strategies=init_strategies)

    MRCP_trainer = PSRO_trainer(meta_games=meta_games,
                           num_strategies=generator.num_strategies,
                           num_rounds=num_rounds,
                           meta_method=mrcp_solver,
                           checkpoint_dir=checkpoint_dir,
                           num_iterations=num_iterations,
                           seed=seed,
                           init_strategies=init_strategies,
                           closed_method=closed_method)

    DO_trainer.loop()
    print("#####################################")
    print('DO looper finished looping')
    print("#####################################")
    if not os.path.exists(checkpoint_dir):
        os.makedirs(checkpoint_dir)
    with open(checkpoint_dir + game_type + '_meta_games.pkl','wb') as f:
        pickle.dump(meta_games, f)
    nashconv_names = ['nashconvs_'+str(t) for t in range(len(DO_trainer.neconvs))]
    mrconv_names = ['mrcpcons_'+str(t) for t in range(len(DO_trainer.mrconvs))]
    df = pd.DataFrame(np.transpose(DO_trainer.neconvs+DO_trainer.mrconvs),\
            columns=nashconv_names+mrconv_names)
    df.to_csv(checkpoint_dir+game_type+'_DO.csv',index=False)
    with open(checkpoint_dir + game_type + '_mrprofile_DO.pkl','wb') as f:
        pickle.dump(DO_trainer.mrprofiles, f)

    FP_trainer.loop()
    print("#####################################")
    print('FP looper finished looping')
    print("#####################################")
    df = pd.DataFrame(np.transpose(FP_trainer.neconvs+FP_trainer.mrconvs),\
            columns=nashconv_names+mrconv_names)
    df.to_csv(checkpoint_dir+game_type+'_FP.csv',index=False)
    with open(checkpoint_dir + game_type + '_mrprofile_FP.pkl','wb') as f:
        pickle.dump(FP_trainer.mrprofiles, f)

    # PRD_trainer.loop()
    # print("#####################################")
    # print('PRD looper finished looping')
    # print("#####################################")
    # df = pd.DataFrame(np.transpose(PRD_trainer.neconvs + PRD_trainer.mrconvs), \
    #                     columns=nashconv_names + mrconv_names)
    # df.to_csv(checkpoint_dir + game_type + '_PRD.csv', index=False)
    # with open(checkpoint_dir + game_type + '_mrprofile_PRD.pkl', 'wb') as f:
    #     pickle.dump(PRD_trainer.mrprofiles, f)

    CRD_trainer.loop()
    print("#####################################")
    print('CRD looper finished looping')
    print("#####################################")
    df = pd.DataFrame(np.transpose(CRD_trainer.neconvs + CRD_trainer.mrconvs), \
                      columns=nashconv_names + mrconv_names)
    df.to_csv(checkpoint_dir + game_type + '_CRD.csv', index=False)
    with open(checkpoint_dir + game_type + '_mrprofile_CRD.pkl', 'wb') as f:
        pickle.dump(CRD_trainer.mrprofiles, f)

    # IDO_trainer.loop()
    # print("#####################################")
    # print('IDO looper finished looping')
    # print("#####################################")
    # df = pd.DataFrame(np.transpose(IDO_trainer.neconvs + IDO_trainer.mrconvs), \
    #                     columns=nashconv_names + mrconv_names)
    # df.to_csv(checkpoint_dir + game_type + '_IDO.csv', index=False)
    # with open(checkpoint_dir + game_type + '_mrprofile_IDO.pkl', 'wb') as f:
    #     pickle.dump(IDO_trainer.mrprofiles, f)
    #
    # IPRD_trainer.loop()
    # print("#####################################")
    # print('IPRD looper finished looping')
    # print("#####################################")
    # df = pd.DataFrame(np.transpose(IPRD_trainer.neconvs + IPRD_trainer.mrconvs), \
    #                      columns=nashconv_names + mrconv_names)
    # df.to_csv(checkpoint_dir + game_type + '_IPRD.csv', index=False)
    # with open(checkpoint_dir + game_type + '_mrprofile_IPRD.pkl', 'wb') as f:
    #     pickle.dump(IPRD_trainer.mrprofiles, f)

    # IDOS_trainer.loop()
    # print("#####################################")
    # print('IDOS looper finished looping')
    # print("#####################################")
    # df = pd.DataFrame(np.transpose(IDOS_trainer.neconvs + IDOS_trainer.mrconvs), \
    #                     columns=nashconv_names + mrconv_names)
    # df.to_csv(checkpoint_dir + game_type + '_IDOS.csv', index=False)
    # with open(checkpoint_dir + game_type + '_mrprofile_IDOS.pkl', 'wb') as f:
    #     pickle.dump(IDOS_trainer.mrprofiles, f)

    # MRCP_trainer.loop()
    # print("#####################################")
    # print('MRCP looper finished looping')
    # print("#####################################")
    # df = pd.DataFrame(np.transpose(MRCP_trainer.neconvs+MRCP_trainer.mrconvs),\
    #         columns=nashconv_names+mrconv_names)
    # df.to_csv(checkpoint_dir+game_type+'_MRCP.csv',index=False)
    # with open(checkpoint_dir + game_type + '_mrprofile_MRCP.pkl','wb') as f:
    #     pickle.dump(DO_trainer.mrprofiles, f)

    print("The current game type is ", game_type)
    print("DO neco av:", np.mean(DO_trainer.neconvs, axis=0))
    print("DO mrcp av:", np.mean(DO_trainer.mrconvs, axis=0))
    print("FP fpco av:", np.mean(FP_trainer.nashconvs, axis=0))
    print("FP neco av:", np.mean(FP_trainer.neconvs, axis=0))
    print("FP mrcp av:", np.mean(FP_trainer.mrconvs, axis=0))
    # print("PRD prdco av:", np.mean(PRD_trainer.nashconvs, axis=0))
    # print("PRD neco av:", np.mean(PRD_trainer.neconvs, axis=0))
    # print("PRD mrcp av:", np.mean(PRD_trainer.mrconvs, axis=0))
    print("CRD CRDco av:", np.mean(CRD_trainer.nashconvs, axis=0))
    print("CRD neco av:", np.mean(CRD_trainer.neconvs, axis=0))
    print("CRD mrcp av:", np.mean(CRD_trainer.mrconvs, axis=0))
    # print("IDO IDOco av:", np.mean(IDO_trainer.nashconvs, axis=0))
    # print("IDO neco av:", np.mean(IDO_trainer.neconvs, axis=0))
    # print("IDO mrcp av:", np.mean(IDO_trainer.mrconvs, axis=0))
    # print("IPRD IDOco av:", np.mean(IDO_trainer.nashconvs, axis=0))
    # print("IDO neco av:", np.mean(IDO_trainer.neconvs, axis=0))
    # print("IDO mrcp av:", np.mean(IDO_trainer.mrconvs, axis=0))
    # print("IDOS IDOSco av:", np.mean(IDOS_trainer.nashconvs, axis=0))
    # print("IDOS neco av:", np.mean(IDOS_trainer.neconvs, axis=0))
    # print("IDOS mrcp av:", np.mean(IDOS_trainer.mrconvs, axis=0))
    # print("MR neco av:", np.mean(MRCP_trainer.neconvs, axis=0))
    # print("MR mrcp av:", np.mean(MRCP_trainer.mrconvs, axis=0))

    print("====================================================")

def main(argv):
    if len(argv) > 1:
        raise app.UsageError("Too many command-line arguments.")

    seed = set_random_seed(FLAGS.seed)
    if not FLAGS.MRCP_deterministic:
        seed = None # invalidate the seed so it does not get passed into psro_trainer

    # root_path = './' + FLAGS.game_type + "_se_" + '/'
    #
    # if not os.path.exists(root_path):
    #     os.makedirs(root_path)

    generator = Game_generator(FLAGS.num_strategies)
    checkpoint_dir = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')+'_se_'+ FLAGS.game_type + "_" + str(seed)
    checkpoint_dir = os.path.join(os.getcwd(), checkpoint_dir) + '/'

    if not os.path.exists(checkpoint_dir):
        os.makedirs(checkpoint_dir)
    sys.stdout = open(checkpoint_dir + '/stdout.txt', 'w+')

    # game_list = ["zero_sum", "general_sum"]

    psro(generator=generator,
         game_type=FLAGS.game_type,
         num_rounds=FLAGS.num_rounds,
         seed=seed,
         checkpoint_dir=checkpoint_dir,
         num_iterations=FLAGS.num_iterations,
         closed_method=FLAGS.closed_method)

if __name__ == "__main__":
  app.run(main)


import tensorflow as tf
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def softmax(x):
  return tf.exp(x)/tf.reduce_sum(tf.exp(x), 1)
  # softmax of the each row of matrix

x = tf.placeholder("float",[None,None])
# dynamic matrix
y = softmax(x)
# softmax of each row of matrix x
with tf.Session() as session:
	# input you nxn matrix here
	x_data = [[1, 2, 3],
			  [4, 5, 6],
			  [7, 8, 9]]
	result = session.run(y, feed_dict = {x : x_data})
	print(result);
	session.close()


import unittest
from modules.data.parameters import parseRawHyperparameterData
from modules.data.configData import ConfigData

from modules.data.experiment import ExperimentData, ExperimentType

class TestExperimentData(unittest.TestCase):
    params = parseRawHyperparameterData([{"name": "iparam", "default": "1", "min": "1", "max": "10", "step": "1", "type": "integer"}, {"name": "fparam", "default": "1.0", "min": "1.0", "max": "10.0", "step": "1.0", "type": "float"}, {"name": "sparam", "default": "Hi", "type": "string"}, {"name": "bparam", "default": True, "type": "bool"}])
    configs = {"config0": ConfigData(**{"data":{"key":"value"}})}
    optional = ["trialExtraFile", "scatterIndVar", "scatterDepVar", "startedAtEpochMillis", "finishedAtEpochMillis"]
    fields_with_default = {"file": "", "postProcess": False, "configs": {}, "totalExperimentRuns": 0, "experimentType": ExperimentType.UNKNOWN, "finished": False,"passes":0, "fails":0}

    exp_info = {'configs':configs,'trialExtraFile': 'Testing Data', 'description': 'Testing Data', 'file': 'experimentV3dpcllHWPrK1Kgbyzqb', 'creator': 'U0EmxpfuqWM2fSa1LKmpFiqLj0V2', 'finished': False, 'estimatedTotalTimeMinutes': 0, 'dumbTextArea': 'dummy = dummy\na = 100', 'verbose': True, 'scatterIndVar': 'iparam', 'scatterDepVar': 'fparam', 'timeout': 18000, 'workers': 1, 'keepLogs': True, 'hyperparameters': params, 'name': 'Testing Data', 'trialResult': 'Testing Data', 'totalExperimentRuns': 0, 'created': 1679705027850, 'scatter': True, 'expId': 'V3dpcllHWPrK1Kgbyzqb'}

    exp_info_has_all_optional = {'trialExtraFile': 'Testing Data', 'description': 'Testing Data', 'file': 'experimentV3dpcllHWPrK1Kgbyzqb', 'creator': 'U0EmxpfuqWM2fSa1LKmpFiqLj0V2', 'finished': False, 'estimatedTotalTimeMinutes': 0, 'dumbTextArea': 'dummy = dummy\na = 100', 'verbose': True, 'scatterIndVar': 'iparam', 'scatterDepVar': 'fparam', "startedAtEpochMillis": 0, "finishedAtEpochMillis": 0, 'timeout': 18000, 'workers': 1, 'keepLogs': True, 'hyperparameters': params, 'name': 'Testing Data', 'trialResult': 'Testing Data', 'totalExperimentRuns': 0, 'created': 1679705027850, 'scatter': True, 'expId': 'V3dpcllHWPrK1Kgbyzqb'}

    exp_info_has_all_default = {'trialExtraFile': 'Testing Data', 'description': 'Testing Data', 'file': 'experimentV3dpcllHWPrK1Kgbyzqb', 'creator': 'U0EmxpfuqWM2fSa1LKmpFiqLj0V2', 'finished': False, "experimentType": ExperimentType.PYTHON, 'estimatedTotalTimeMinutes': 0, 'dumbTextArea': 'dummy = dummy\na = 100', 'verbose': True, 'scatterIndVar': 'iparam', 'scatterDepVar': 'fparam', 'timeout': 18000, 'workers': 1, 'keepLogs': True, "configs": {}, 'hyperparameters': params, 'name': 'Testing Data', 'trialResult': 'Testing Data', 'totalExperimentRuns': 0, "passes": 0, "fails": 0, 'created': 1679705027850, 'scatter': True, "postProcess": True, 'expId': 'V3dpcllHWPrK1Kgbyzqb'}

    def test_creating_object_does_not_mutate_input_fields(self):
        experiment = ExperimentData(**self.exp_info)
        expDict = experiment.dict().copy()
        for key, value in expDict.items():
            if key in self.optional:
                if key in self.exp_info:
                    self.assertEqual(value, self.exp_info[key])
                else:
                    self.assertIsNone(value)
            elif key in self.fields_with_default:
                if key in self.exp_info:
                    self.assertEqual(value, self.exp_info[key])
                else:
                    self.assertEqual(value, self.fields_with_default[key])
            else:
                self.assertEqual(value, self.exp_info[key])

    def test_remove_optional_does_not_error(self):
        for field in self.optional:
            cloned_info = self.exp_info_has_all_optional.copy()
            del cloned_info[field]
            experiment = ExperimentData(**cloned_info)
            self.assertIsInstance(experiment, ExperimentData)
            self.assertEqual(experiment.dict()[field], None)

    def test_remove_default_does_not_error(self):
        for field, value in self.fields_with_default.items():
            cloned_info = self.exp_info_has_all_default.copy()
            del cloned_info[field]
            experiment = ExperimentData(**cloned_info)
            self.assertIsInstance(experiment, ExperimentData)
            self.assertEqual(experiment.dict()[field], value)

    def test_check_trialResult(self):
        cloned_info = self.exp_info.copy()
        del cloned_info['trialResult']
        with self.assertRaises(ValueError):
            ExperimentData(**cloned_info)

    def test_check_hyperparams(self):
        cloned_info = self.exp_info.copy()
        invalid_hyperparameters_dict = {"field": "value"}
        cloned_info['hyperparameters'] = invalid_hyperparameters_dict
        with self.assertRaises(ValueError):
            ExperimentData(**cloned_info)

    def test_check_configs(self):
        cloned_info = self.exp_info.copy()
        invalid_configs_dict = {"field": "value"}
        cloned_info['configs'] = invalid_configs_dict
        with self.assertRaises(ValueError):
            ExperimentData(**cloned_info)

        cloned_info = self.exp_info.copy()
        invalid_configs_dict = {1: "value"}
        cloned_info['configs'] = invalid_configs_dict
        with self.assertRaises(ValueError):
            ExperimentData(**cloned_info)

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


from anti_spoofing.data_utils import ASVDataset
from anti_spoofing.constants import *
import torch
import multiprocessing
from multiprocessing import Pool
from tqdm import tqdm
import numpy as np

from anti_spoofing.data_utils_short import ASVDatasetshort
from anti_spoofing.matlab.mat_loader import CQCCDataset
from preprocessing_tools.preprocessing import preprocess
import os
from torch.utils.data.dataloader import DataLoader

def preprocess_function(s, option=OPTION):
    return preprocess(s, option=option, bins=BINS, sr=16000, win_length=WIN_LEN, hop_length=HOP_LEN)

class PreprocessedASVDataset(torch.utils.data.Dataset):

    def __init__(self, dataset: ASVDataset, multi_proc=True, balanced=True, option=OPTION):
        self.len = len(dataset)
        self.balanced = balanced
        if option == "lfcc":
            self.X = torch.empty(self.len, 16000 * 3 // HOP_LEN - 1, BINS, dtype=torch.float32)
        else:
            self.X = torch.empty(self.len, 16000 * 3 // HOP_LEN + 1, BINS, dtype=torch.float32)
        self.t = torch.empty(self.len, dtype=torch.float32)
        self.data_idx_s = None
        self.data_idx_b = None
        self.option = option
        if dataset.metadata:
            self.meta = torch.empty(self.len, dtype=torch.int64)
        else:
            self.meta = None

        if multi_proc:
            # torch.multiprocessing.set_sharing_strategy('file_descriptor')

            with Pool(multiprocessing.cpu_count()) as pool:
                jobs = []

                for i in tqdm(range(self.len)):
                    if dataset.metadata:
                        x, t, meta = dataset[i]
                    else:
                        x, t = dataset[i]
                    jobs.append(pool.apply_async(preprocess_function, (x.astype(np.float32),
                                                                       self.option)))
                    self.t[i] = float(t)
                    if dataset.metadata:
                        self.meta[i] = int(meta)

                for i, job in tqdm(enumerate(jobs), total=self.len):
                    self.X[i] = torch.from_numpy(job.get(timeout=30))
        else:
            for i in tqdm(range(self.len)):
                if dataset.metadata:
                    x, t, meta = dataset[i]
                    self.meta[i] = int(meta)
                else:
                    x, t = dataset[i]
                self.X[i] = torch.from_numpy(preprocess_function(x.astype(np.float32), self.option))
                self.t[i] = float(t)

        self.set_balance(balanced)

    def __getitem__(self, index):
        if self.balanced:
            if index < self.len // 2:
                idx_s = self.data_idx_s[index]
                assert self.t[idx_s] < 0.5
                return self.get_data(idx_s)
            else:
                idx_b = self.data_idx_b[index % len(self.data_idx_b)]
                assert self.t[idx_b] > 0.5
                return self.get_data(idx_b)
        else:
            return self.get_data(index)

    def get_data(self, index):
        if self.meta is not None:
            return self.X[index], self.t[index], self.meta[index]
        else:
            return self.X[index], self.t[index]

    def __len__(self):
        return self.len

    def set_balance(self, value: bool):
        self.balanced = value
        if self.balanced:
            idxs = torch.arange(len(self.t))
            self.data_idx_s = idxs[self.t < 0.5]  # N
            self.data_idx_b = idxs[self.t > 0.5]  # n << N
            self.len = 2 * len(self.data_idx_s)
        else:
            self.len = len(self.t)

def load_data(batch_size=50, batch_size_test=1, length=3 * 16000, num_train=10000, num_test=10000, custom_path='./data',
              multi_proc=True, balanced=True, option=OPTION, metadata=False, include_eval=False, return_dataset=False,
              short=False):
    """
    loads the data and puts it in PyTorch DataLoader.

    If a data loader has not been saved already,
    a data loader is created, then saved for train and test sets.
    """

    type_train = "train_short" if short else "train"
    train_loader = load_single_data(batch_size=batch_size, length=length, num_data=num_train, data_type=type_train,
                                    custom_path=custom_path, multi_proc=multi_proc, balanced=balanced, option=option,
                                    metadata=metadata, return_dataset=return_dataset)
    dev_loader = load_single_data(batch_size=batch_size_test, length=length, num_data=num_test, data_type="dev",
                                  custom_path=custom_path, multi_proc=multi_proc, balanced=balanced, option=option,
                                  metadata=metadata)

    if include_eval:
        eval_loader = load_single_data(batch_size=batch_size_test, length=length, num_data=num_test, data_type="eval",
                                       custom_path=custom_path, multi_proc=multi_proc, balanced=balanced, option=option,
                                       metadata=metadata)
        return train_loader, dev_loader, eval_loader

    return train_loader, dev_loader

def load_data_cqcc(batch_size=50, batch_size_test=1, num_train=1000, num_test=1000, balanced=False):
    """
    loads the data and puts it in PyTorch DataLoader.
    Librispeech uses Index caching to access the data more rapidly.

    If a data loader has not been saved already,
    a data loader is created, then saved for train and test sets.
    """

    train_dataloader = load_single_data_cqcc(batch_size=batch_size, num_data=num_train,
                                             balanced=balanced, data_type="train")
    dev_dataloader = load_single_data_cqcc(batch_size=batch_size_test, num_data=num_test,
                                           balanced=balanced, data_type="test")

    return train_dataloader, dev_dataloader

def load_single_data(batch_size=50, length=4 * 16000, num_data=10000, data_type="train", custom_path="./data",
                     multi_proc=True, balanced=True, option=OPTION, metadata=False, return_dataset=False):
    is_train = data_type in ["train", "train_short"]

    local_dir = os.path.dirname(__file__)

    if os.path.exists(os.path.join(local_dir,
                                   "data/preprocessed/{}_{}_{}_{}_{}_{}.torch"
                                           .format(data_type, option, num_data, metadata, WIN_LEN, HOP_LEN))):
        data = torch.load(os.path.join(local_dir,
                                       "data/preprocessed/{}_{}_{}_{}_{}_{}.torch"
                                       .format(data_type, option, num_data, metadata, WIN_LEN, HOP_LEN)))
        data.set_balance(balanced and is_train)
        if return_dataset:
            return data
        dataloader = DataLoader(data, batch_size=batch_size, num_workers=4, shuffle=is_train, drop_last=is_train)
        return dataloader

    if not os.path.isdir(os.path.join(local_dir, 'data/preprocessed')):
        os.makedirs(os.path.join(local_dir, 'data/preprocessed'))

    if data_type == "train":
        data = ASVDataset(length=length, is_train=True, is_eval=False, nb_samples=num_data, random_samples=True,
                          metadata=metadata, custom_path=custom_path)
    elif data_type == "train_short":
        data = ASVDatasetshort(length=length, random_samples=True,
                               metadata=metadata, custom_path=custom_path)
    elif data_type == "dev":
        data = ASVDataset(length=length, is_train=False, is_eval=False, nb_samples=num_data, random_samples=True,
                          metadata=metadata, custom_path=custom_path)
    elif data_type == "eval":
        data = ASVDataset(length=length, is_train=False, is_eval=True, nb_samples=num_data, random_samples=True,
                          metadata=metadata, custom_path=custom_path)
    else:
        raise ValueError("data type {} not recognized".format(data_type))

    print("preprocessing_tools {} set".format(data_type))
    pp_data = PreprocessedASVDataset(data, multi_proc=multi_proc, balanced=is_train and balanced, option=option)
    torch.save(pp_data, os.path.join(local_dir,
                                     "data/preprocessed/{}_{}_{}_{}_{}_{}.torch"
                                     .format(data_type, option, num_data, metadata, WIN_LEN, HOP_LEN)))

    if return_dataset:
        return pp_data

    dataloader = DataLoader(pp_data, batch_size=batch_size, num_workers=4, shuffle=is_train, drop_last=is_train)

    return dataloader

def load_single_data_cqcc(batch_size=50, num_data=1000, balanced=False, data_type="train"):
    local_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "anti_spoofing")

    is_train = data_type == "train"

    if os.path.exists(
            os.path.join(local_dir, "data", "preprocessed", "{}_cqcc_{}_{}_{}_{}_{}"
                    .format(data_type, B, d, cf, ZsdD, balanced))):
        print("{} data found locally".format(data_type))
        cqcc_data = torch.load("./data/preprocessed/{}_cqcc_{}_{}_{}_{}_{}"
                               .format(data_type, B, d, cf, ZsdD, balanced))
        dataloader = torch.utils.data.DataLoader(cqcc_data, batch_size=batch_size,
                                                 num_workers=0, shuffle=is_train, drop_last=True)
        return dataloader

    if not os.path.isdir('./data/preprocessed'):
        local_dir = os.path.dirname(__file__)
        os.makedirs(os.path.join(local_dir, 'data/preprocessed'))

    print("loading {} .mat files to PyTorch...".format(data_type))

    cqcc_data_type = data_type if data_type == "train" else "dev"

    cqcc_data = CQCCDataset(params_id="{}_{}_{}_{}_{}".format(cqcc_data_type, B, d, cf, ZsdD),
                            n_files=num_data, balanced=is_train and balanced)

    torch.save(cqcc_data,
               os.path.join(local_dir, "data", "preprocessed", "{}_cqcc_{}_{}_{}_{}_{}"
                            .format(data_type, B, d, cf, ZsdD, balanced)))

    dataloader = torch.utils.data.DataLoader(cqcc_data, batch_size=batch_size,
                                             num_workers=0, shuffle=is_train, drop_last=True)

    return dataloader


import os
import copy
import re
import numpy as np
import urllib.request
import fasttext

class EmbeddingsDict(object):
    """Contains word embeddings"""

    def __init__(self, opt):
        self.opt = copy.deepcopy(opt)
        self.tok2emb = {}
        self.dim = 0
        self.load_items()

        self.fasttext_model = None
        if self.opt.get('fasttext_model') is not None:
            if not os.path.isfile(self.opt['fasttext_model']):
                emb_path = os.environ.get('EMBEDDINGS_URL')
                if not emb_path:
                    raise RuntimeError('No pretrained fasttext model provided')
                fname = os.path.basename(opt['fasttext_model'])
                try:
                    print('Trying to download a pretrained fasttext model'
                        ' from the repository')
                    url = urllib.parse.urljoin(emb_path, fname)
                    urllib.request.urlretrieve(url, opt['fasttext_model'])
                    print('Downloaded a fasttext model')
                except Exception as e:
                    raise RuntimeError('Looks like the `EMBEDDINGS_URL` variable'
                                    ' is set incorrectly', e)
            self.fasttext_model = fasttext.load_model(opt['fasttext_model'])
            if self.tok2emb and (self.fasttext_model.dim != self.dim):
                raise RuntimeError("Fasttext model and loaded embeddings have"
                                   " different dimension sizes.")
        else:
            print("No fasttext model provided: using loaded embeddings.")

    def add_items(self, tokens):
        if self.fasttext_model is not None:
            for token in tokens:
                if self.tok2emb.get(token) is None:
                    self.tok2emb[token] = self.fasttext_model[token]

    def __contains__(self, token):
        if self.fasttext_model and (token not in self.tok2emb):
            self.tok2emb[token] = self.fasttext_model[token]
        return token in self.tok2emb

    def __getitem__(self, token):
        if self.fasttext_model and (token not in self.tok2emb):
            self.tok2emb[token] = self.fasttext_model[token]
        return self.tok2emb.get(token, None)

    def encode(self, tokens):
        embs = [self.__getitem__(t) for t in tokens if self.__contains__(t)]
        if embs:
            return np.mean(embs, axis=0)
        return np.zeros(self.dim, dtype=np.float32)

    def save_items(self, fname=None):
        if fname is None:
            if self.opt.get('embedding_file') is not None:
                fname = self.opt['embedding_file']
            elif self.opt.get('pretrained_model') is not None:
                fname += self.opt['pretrained_model'] + '.emb'
            elif self.opt.get('model_file') is not None:
                fname += self.opt['model_file'] + '.emb'
            else:
                print("Warning! no save file for embeddings provided.")
                return
        f = open(fname, 'w')
        string = '\n'.join([el[0] + ' ' + self.emb2str(el[1]) for el in self.tok2emb.items()])
        f.write(string)
        f.close()

    def emb2str(self, vec):
        string = ' '.join([str(el) for el in vec])
        return string

    def load_items(self):
        """Initialize embeddings from file."""
        fname = None
        if self.opt.get('embedding_file') is not None:
            fname = self.opt['embedding_file']
        elif self.opt.get('pretrained_model') is not None:
            fname = self.opt['pretrained_model']+'.emb'
        elif self.opt.get('model_file') is not None:
            fname = self.opt['model_file']+'.emb'

        if fname is None or not os.path.isfile(fname):
            print('There is no %s file provided. Initializing new dictionary.' % fname)
        else:
            print('Loading existing dictionary from %s.' % fname)
            with open(fname, 'r') as f:
                for ln in f:
                    values = re.split('[ \t]', ln.strip())
                    word = values[0]
                    embed = np.asarray(values[1:], dtype=np.float32)
                    self.tok2emb[word] = embed
                    if not self.dim:
                        self.dim = len(embed)


import sys
import logging
import time
from optparse import OptionParser

import sleekxmpp
from sleekxmpp.componentxmpp import ComponentXMPP
from sleekxmpp.stanza.roster import Roster
from sleekxmpp.xmlstream import ElementBase
from sleekxmpp.xmlstream.stanzabase import ET, registerStanzaPlugin

# Python versions before 3.0 do not use UTF-8 encoding
# by default. To ensure that Unicode is handled properly
# throughout SleekXMPP, we will set the default encoding
# ourselves to UTF-8.
if sys.version_info < (3, 0):
    reload(sys)
    sys.setdefaultencoding('utf8')

class Config(ElementBase):

    """
    In order to make loading and manipulating an XML config
    file easier, we will create a custom stanza object for
    our config XML file contents. See the documentation
    on stanza objects for more information on how to create
    and use stanza objects and stanza plugins.

    We will reuse the IQ roster query stanza to store roster
    information since it already exists.

    Example config XML:
      <config xmlns="sleekxmpp:config">
        <jid>component.localhost</jid>
        <secret>ssshh</secret>
        <server>localhost</server>
        <port>8888</port>

        <query xmlns="jabber:iq:roster">
          <item jid="user@example.com" subscription="both" />
        </query>
      </config>
    """

    name = "config"
    namespace = "sleekxmpp:config"
    interfaces = set(('jid', 'secret', 'server', 'port'))
    sub_interfaces = interfaces

registerStanzaPlugin(Config, Roster)

class ConfigComponent(ComponentXMPP):

    """
    A simple SleekXMPP component that uses an external XML
    file to store its configuration data. To make testing
    that the component works, it will also echo messages sent
    to it.
    """

    def __init__(self, config):
        """
        Create a ConfigComponent.

        Arguments:
            config      -- The XML contents of the config file.
            config_file -- The XML config file object itself.
        """
        ComponentXMPP.__init__(self, config['jid'],
                                     config['secret'],
                                     config['server'],
                                     config['port'])

        # Store the roster information.
        self.roster = config['roster']['items']

        # The session_start event will be triggered when
        # the component establishes its connection with the
        # server and the XML streams are ready for use. We
        # want to listen for this event so that we we can
        # broadcast any needed initial presence stanzas.
        self.add_event_handler("session_start", self.start)
        self.add_event_handler('presence_subscribe', self.subscribe)
        self.add_event_handler('presence_subscribed', self.subscribed)

        # The message event is triggered whenever a message
        # stanza is received. Be aware that that includes
        # MUC messages and error messages.
        self.add_event_handler("message", self.message)

        #self.auto_authorize = True
        #self.auto_subscribe = True

    def start(self, event):
        """
        Process the session_start event.

        The typical action for the session_start event in a component
        is to broadcast presence stanzas to all subscribers to the
        component. Note that the component does not have a roster
        provided by the XMPP server. In this case, we have possibly
        saved a roster in the component's configuration file.

        Since the component may use any number of JIDs, you should
        also include the JID that is sending the presence.

        Arguments:
            event -- An empty dictionary. The session_start
                     event does not provide any additional
                     data.
        """

        for jid in self.roster:
            if self.roster[jid]['subscription'] != 'none':
                self.sendPresence(pfrom=self.jid, pto=jid)

        #self._start_thread('chat_send', self.chat_send)

    def subscribe(self, presence):
        # If the subscription request is rejected.
        if not self.backend.allow_subscription(presence['from']):
            self.sendPresence(pto=presence['from'],
                              ptype='unsubscribed')
            return

        # If the subscription request is accepted.
        self.sendPresence(pto=presence['from'],
                          ptype='subscribed')

        # Save the fact that a subscription has been accepted, somehow. Here
        # we use a backend object that has a roster.
        self.backend.roster.subscribe(presence['from'])

        # If a bi-directional subscription does not exist, create one.
        if not self.backend.roster.sub_from(presence['from']):
            self.sendPresence(pto=presence['from'],
                              ptype='subscribe')

    def subscribed(self, presence):
        # Store the new subscription state, somehow. Here we use a backend object.
        self.backend.roster.subscribed(presence['from'])

        # Send a new presence update to the subscriber.
        self.sendPresence(pto=presence['from'])

    def message(self, msg):
        """
        Process incoming message stanzas. Be aware that this also
        includes MUC messages and error messages. It is usually
        a good idea to check the messages's type before processing
        or sending replies.

        Since a component may send messages from any number of JIDs,
        it is best to always include a from JID.

        Arguments:
            msg -- The received message stanza. See the documentation
                   for stanza objects and the Message stanza to see
                   how it may be used.
        """
        # The reply method will use the messages 'to' JID as the
        # outgoing reply's 'from' JID.
        #print(msg)
        msg.reply("Thanks for sending\n%(body)s" % msg).send()

    def chat_send(self):
        while True:
            self.send_message('user2@localhost', 'THIS IS A MESSAGE', 'chat', 'muc.localhost')
            time.sleep(5)

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
                        format='%(levelname)-8s %(message)s')

    # Load configuration data.
    config_file = open('config.xml', 'r+')
    config_data = "\n".join([line for line in config_file])
    config = Config(xml=ET.fromstring(config_data))
    config_file.close()

    # Setup the ConfigComponent and register plugins. Note that while plugins
    # may have interdependencies, the order in which you register them does
    # not matter.
    xmpp = ConfigComponent(config)
    xmpp.registerPlugin('xep_0030') # Service Discovery
    xmpp.registerPlugin('xep_0004') # Data Forms
    xmpp.registerPlugin('xep_0060') # PubSub
    xmpp.registerPlugin('xep_0199') # XMPP Ping

    # Connect to the XMPP server and start processing XMPP stanzas.
    if xmpp.connect():
        xmpp.process(threaded=False)
        print("Done")
    else:
        print("Unable to connect.")


from django.urls import path

from . import views

app_name = "clients"

urlpatterns = [
    path("", views.view_clients, name="view_clients"),
    path("fetch", views.fetch_clients, name="fetch_clients"),
    path("export", views.export_users_csv, name="export_users_csv"),
]


import argparse
import logging
from src.application.app_dash import AppDash
from src.application.app_ingestion import AppIngestion
from src.application.app_processing import AppProcessing

logger = logging.getLogger()
logger.setLevel(logging.INFO)

ch = logging.StreamHandler()
ch.setLevel(logging.INFO)

formatter = logging.Formatter('%(message)s')

ch.setFormatter(formatter)
logger.addHandler(ch)

APPS = {
    "ingestion": AppIngestion.run,
    "process": AppProcessing.run,
    "dash": AppDash.run
}

def main():
    parser = argparse.ArgumentParser(
        description='Painel de repositórios do GitHub.')
    parser.add_argument(
        "-p",
        dest="process",
        choices=['ingestion', 'process', 'dash'],
        type=str,
        help='Escolha entre uma das opições [ingestion, process, dash]')

    args = parser.parse_args()

    if args.process is not None:
        app_run = APPS.get(args.process)
        app_run()

if __name__ == '__main__':
    main()


# -*- coding: utf8 -*-
from random import randint
import binascii as ba
import re
#I wanted to experiment with jpegs and pngs
#So this it the first bit flipper I made, iterates through all bytes
#and flips it changes it to random value
def writeByte(x, f):
    #writes and converts byte to new picture
    f.write((int(x)).to_bytes(1,byteorder = 'big'))
    #f.write(bytes([int(x)])) #both of these will work

def allBytes(count):
    innerCount = 0
    index = 0
    while( count < len(data)):#iterate compltely through all bytes in image
        with open ("all//"+ str(count) + "  " + str(hex(count))+ ".jpg", "wb") as f:
            index = 0
            for x in data:#changes only new byte
                if(index == count ):
                    x = randint(0, 255)
                index += 1
                writeByte(x, f)
                innerCount += 1
        count += 1

##file = input("what is the file called? ")
##ext = input("what file extension has it? ")
file = "test"
ext = ".png"
with open(file+ext, "rb") as f:
    data = f.read()
count = 0
innerCount = 0
index = 0
print(len(data))
allBytes(count)
print("complete")


# https://programmers.co.kr/learn/courses/30/lessons/42578

def solution(clothes):
    answer = 1
    cloth_dict = dict()
    for e in clothes:
        if e[1] in cloth_dict:
            cloth_dict[e[1]].add(e[0])
        else:
            cloth_dict[e[1]] = {e[0]}
    # 공식: (첫번째자리의 경우의 수) * (두번째자리의 경우의 수...) - 1
    # 유도: 각 자리는 순서와 상관 없으니까 모두 곱하면 가능한 경우의 수가 나온다
    # 각 자리의 경우의 수는 (해당 부위의 옷 개수 + 1 <- 해당 부위를 입지 않은 경우)
    # 위의 식만으로는 모든 옷을 입지 않은 경우가 생김으로 모든 옷을 입지 않은 경우의 수를 제한다
    # 정의는 알고있다만 응용은 아직 많이 힘드네
    while cloth_dict:
        answer *= len(cloth_dict.popitem()[1]) + 1
    answer -= 1
    return answer


import os
import sys

import numpy as np

from catkit.config import CONFIG_INI
from catkit.interfaces.MotorController import MotorController

"""Implementation of the Newport motor controller interface."""

# Import XPS Q8 driver
try:
    library_path = os.environ.get('CATKIT_NEWPORT_LIB_PATH')
    if library_path:
        sys.path.append(library_path)
    import XPS_Q8_drivers
except Exception as error:
    XPS_Q8_drivers = error

class NewportMotorController(MotorController):

    instrument_lib = XPS_Q8_drivers

    OK_STATES = (7, 11, 12, 42)

    def __init__(self, *args, **kwargs):
        if isinstance(self.instrument_lib, BaseException):
            raise self.instrument_lib
        super().__init__(*args, **kwargs)

    def initialize(self, host, port, timeout=60, initialize_to_nominal=True, atol=0.001):
        """Creates an instance of the controller library and opens a connection."""

        self.host = host
        self.port = port
        self.timeout = timeout
        self.initialize_to_nominal = initialize_to_nominal
        self.atol = atol

    def _open(self):
        # Create an instance of the XPS controller.
        self.instrument = self.instrument_lib.XPS()

        # Connect to a socket on the controller server.
        socket_id = self.instrument.TCP_ConnectToServer(self.host, self.port, self.timeout)
        if socket_id == -1:
            raise Exception(f"Connection to XPS failed, check IP & Port (invalid socket '{socket_id}')")
        self.socket_id = socket_id

        # Initialize and move to nominal positions.
        if self.initialize_to_nominal:
            self.log.info(f"Initializing Newport XPS Motor Controller {self.config_id}...")
            motors = [s for s in CONFIG_INI.sections() if s.startswith('motor_')]
            for motor_name in motors:
                self.__move_to_nominal(motor_name)

        return self.instrument

    def _close(self):
        """Close dm connection safely."""
        try:
            self.instrument.TCP_CloseSocket(self.socket_id)
        finally:
            self.socket_id = None

    def absolute_move(self, motor_id, position):
        """
        Moves motor to specified position.  Skips if already in position (or close enough).
        :param motor_id: String to match in the config ini (ex: motor_FPM_X).
        :param position: Target position to move to.
        """
        group = CONFIG_INI.get(motor_id, "group_name")
        positioner = CONFIG_INI.get(motor_id, "positioner_name")
        self.__ensure_initialized(group)

        current_position = self.get_position(motor_id)
        if not np.isclose(current_position, position, atol=self.atol):
            # Move.
            self.log.info(f"Moving positioner '{positioner}' by '{position}'...")
            error_code, return_string = self.instrument.GroupMoveAbsolute(self.socket_id, positioner, [position])
            self.__raise_on_error(error_code, 'GroupMoveAbsolute')

    def relative_move(self, motor_id, distance):
        """
        Moves motor by the specified distance.
        :param motor_id: String to match in the config ini (ex: motor_FPM_X).
        :param distance: Distance to move motor, can be positive or negative.
        """
        group = CONFIG_INI.get(motor_id, "group_name")
        positioner = CONFIG_INI.get(motor_id, "positioner_name")
        self.__ensure_initialized(group)

        # Move.
        self.log.info(f"Moving positioner '{positioner}' by '{distance}'...")
        error_code, return_string = self.instrument.GroupMoveRelative(self.socket_id, positioner, [distance])
        self.__raise_on_error(error_code, 'GroupMoveRelative')

    def get_position(self, motor_id):
        """
        Get current position
        :param motor_id: String to match in the config ini (ex: motor_FPM_X).
        :return: Current position.
        """
        group = CONFIG_INI.get(motor_id, "group_name")
        positioner = CONFIG_INI.get(motor_id, "positioner_name")
        self.__ensure_initialized(group)

        error_code, current_position = self.instrument.GroupPositionCurrentGet(self.socket_id, positioner, 1)
        self.__raise_on_error(error_code, 'GroupPositionCurrentGet')
        return current_position

    def __ensure_initialized(self, group):
        error_code, current_status = self.instrument.GroupStatusGet(self.socket_id, group)
        self.__raise_on_error(error_code, 'GroupStatusGet')

        # Kill motor if it is not in a known good state.
        if current_status not in self.OK_STATES:
            error_code, return_string = self.instrument.GroupKill(self.socket_id, group)
            self.__raise_on_error(error_code, 'GroupKill')
            self.log.warning(f"Killed group '{group}' because it was not in state '{self.OK_STATES}'")

            # Update the status.
            error_code, current_status = self.instrument.GroupStatusGet(self.socket_id, group)
            self.__raise_on_error(error_code, 'GroupStatusGet')

        # Initialize from killed state.
        if current_status == 7:
            # Initialize the group
            error_code, return_string = self.instrument.GroupInitialize(self.socket_id, group)
            self.__raise_on_error(error_code, 'GroupInitialize')
            self.log.info(f"Initialized group '{group}'")

            # Update the status
            error_code, current_status = self.instrument.GroupStatusGet(self.socket_id, group)
            self.__raise_on_error(error_code, 'GroupStatusGet')

        # Home search
        if current_status == 42:
            error_code, return_string = self.instrument.GroupHomeSearch(self.socket_id, group)
            self.__raise_on_error(error_code, 'GroupHomeSearch')
            self.log.info(f"Homed group '{group}'")

    def __move_to_nominal(self, group_config_id):
        self.__ensure_initialized(CONFIG_INI.get(group_config_id, "group_name"))
        nominal = CONFIG_INI.getfloat(group_config_id, "nominal")
        self.absolute_move(group_config_id, nominal)

    # Migrated from Newport demo code, now raises exceptions and does logging elsewhere.
    def __raise_on_error(self, error_code, api_name):
        if error_code == 0:
            return

        if error_code == -2:
            raise Exception(f"{api_name}: TCP timeout")
        elif error_code == -108:
            raise Exception(f"{api_name}: The TCP/IP connection was closed by an administrator")
        else:
            error_code2, error_string = self.instrument.ErrorStringGet(self.socket_id, error_code)
            if error_code2 != 0:
                raise Exception(f"{api_name}: ERROR '{error_code}'")
            else:
                raise Exception(f"{api_name}: '{error_string}'")


# 1004. Given a binary array nums and an integer k,
# return the maximum number of consecutive 1's in the array if you can flip at most k 0's

def longestOnes(nums: list[int], k: int) -> int:
    left = flips = curlen = maxlen = 0
    # make an actual copy of array instead of a reference to same array (arr = nums)
    arr = nums.copy()
    for right in range(0, len(nums)):
        # increase current length of "consecutive ones" subarray each iteration
        curlen += 1
        # if this iteration encounters a zero
        if arr[right] == 0:
            # change zero to a one
            arr[right] = 1
            # increase amount of flips by one
            flips += 1
            # if flips exceed k
            if flips == k + 1:
                # move left window boundary until it passes a zero
                while nums[left] == 1:
                    # once nums[left] hits a zero, the loop will terminate
                    left += 1
                    # reduce current length by one
                    curlen -= 1
                # move left window boundary past zero
                left += 1
                # reduce current length by one
                curlen -= 1
                # reduce flips by one to return to max number of flips
                flips -= 1
        if curlen > maxlen:
            maxlen = curlen
    return maxlen

# k = 3
# nums = [0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]
# # Output: 10

# k = 2
# nums = [1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1]
# # Output: 7

k = 2
nums = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0]
# Output: 6

print(longestOnes(nums, k))


# coding=utf-8
import xlrd
import time
import os
from xlutils.copy import copy

dir_path = os.path.dirname(os.getcwd())

# excel 文件操作工具类
# xlrd 只能操作 .xls
# 若要操作.xlsx 需要openpyxl
#
class ExcelUtil:

    def __init__(self, excel_path=None, index=None):
        if excel_path == None:
            self.excel_path = os.path.abspath(dir_path + '/config/casedata.xls')
        else:
            self.excel_path = excel_path
        if index == None:
            index = 0
        self.data = xlrd.open_workbook(self.excel_path)
        self.table = self.data.sheets()[index]
        # [[],[]]

    # 获取excel数据，按照每行一个list，添加到一个大的list里面
    def get_data(self):
        result = []
        rows = self.get_lines()
        if rows != None:
            for i in range(rows):
                col = self.table.row_values(i)
                result.append(col)
            return result
        return None

    # 获取excel行数
    def get_lines(self):
        # 行数
        rows = self.table.nrows
        if rows >= 1:
            return rows
        return None

    # 获取单元格的数据
    def get_col_value(self, row, col):
        # print
        if self.get_lines() > row:
            data = self.table.cell(row, col).value
            return data
        return None

    # 写入数据
    def write_value(self, row, value):
        read_value = xlrd.open_workbook(self.excel_path)
        write_data = copy(read_value)#复制一份修改后,再存储
        write_data.get_sheet(0).write(row, 9, value)
        write_data.save(self.excel_path)
        time.sleep(1)

if __name__ == '__main__':
    path = os.path.abspath(dir_path + '/config/keyword.xls')
    ex = ExcelUtil(path)
    print(ex.get_col_value(10, 8))


from colorama import Fore, Back, Style

maximum_number = 50

def isPrime(value):
    for i in range (2, value):
        remainder = value % i
        # If the remainder is zero, the division is exact and the number is not prime
        if remainder == 0:
            # Prints all divisors calculated for the prime number
            print("The divisors for wich the number " + str(value) + " is not prime are: " + str(list(range(2, i+1))))
            return False

    return True

def main():
    print("Start to compute prime numbers up to " + str(maximum_number) + " :")

    for i in range(1, maximum_number + 1):
        if isPrime(i):
            # Prints the prime number text as bright green
            print(Style.BRIGHT + Fore.GREEN + "Number " + str(i) + "is prime" + Style.RESET_ALL)
        else:
            print("Number " + str(i) + " is not prime.")

if __name__ == "__main__":
    main()


import numpy as np
import re
from PIL import Image # pip install Pillow
def MatrizAImagen(matriz, filename='pixelart.PNG', factor=10):
    '''
    Convierte una matriz de valores RGB en una imagen y la guarda como un archivo png.
    Las imagenes son escaladas por un factor ya que con los ejemplos se producirian imagenes muy pequeñas.
        Parametros:
                matriz (lista de lista de tuplas de enteros): Matriz que representa la imagen en rgb.
                filename (str): Nombre del archivo en que se guardara la imagen.
                factor (int): Factor por el cual se escala el tamaño de las imagenes.
    '''
    matriz = np.array(matriz, dtype=np.uint8)
    np.swapaxes(matriz, 0, -1)

    N = np.shape(matriz)[0]

    img = Image.fromarray(matriz, 'RGB')
    img = img.resize((N*10, N*10), Image.Resampling.BOX)
    img.save(filename)
    print("se ha creado el archivo PNG :",filename)

def PalabraToRGB(frase):
    ''' CAMBIA TODOS LOS COLORES A SU RGB CORRESPONDIENTE (tupla de 3 valores entre 0 y 255 en Python).'''
    a = re.sub("Blanco", "(255,255,255)", frase)
    if a:
        stra="".join(a)
        frase=stra

    b = re.sub("Negro", "(0,0,0)", frase)
    if b:
        strb="".join(b)
        frase=strb

    c = re.sub("Rojo", "(255,0,0)", frase)
    if c:
        strc="".join(c)
        frase=strc
    d = re.sub("Verde", "(0,255,0)", frase)
    if d:
        strd="".join(d)
        frase=strd
    e = re.sub("Azul", "(0,0,255)", frase)
    if e:
        stre="".join(e)
        frase=stre

    return frase

def ListaStrToInt(y):
    '''AQUI SE EXTRAE EL COLOR PARA CREAR LA MATRIZ, EL COLOR VIENE ALMACENADO EN UNA LISTA DE NUMEROS EN STR LA CUAL PASARÁ A INT, POSTERIORMENTE LAS LISTAS CREADAS PASARAN A TUPLA '''

    num=0
    for elem in y:
        y[num]=int(elem)
        num+=1

    return y

def matrizInicial(y,ancho):
    '''AQUI SE CREA LA MATRIZ DE ANCHO NxN DE 1 COLOR'''
    matriz=[]
    for fila in range(ancho):
        l=[]
        for col in range(ancho):
            l.append(y)
        matriz.append(l)

    return matriz

def AnalizarLinea(linea,posicion,der,izq,ancho,M,archivo):
    '''PARA SEGUIR UNA SECUENCIA EN EL PROGRAMA SE REALIZA LA REESCRITURA DEL ARCHIVO Y SE VAN ENCONTRANDO LAS EXPRESIONES
        COMO AVANZAR-DERECHA-REPETIR-PINTAR ...etc
        LA POSICION SIGNIFICA UN CURSOS EN LA MATRIZ QUE NOS AYUDARA A DESPLAZARNOS EN ELLA Y PODER PINTARLA CON FACILIDAD
        LA POSICION DEPENDE DE LA DERECHA(GIRO 90° HORARIO) E IZQUIERDA (GIRO ANTIHORARIO 90°)
        LA POSICION PARTE EN [0,0] MIRANDO HACIA [0,1]
        '''

    expresion=""
    repexp=""
    frase=""
    t=False
    x=0
    flag=False
    for a in linea:
        expresion+=a
        Izq=re.findall("Izquierda",expresion)
        Der=re.findall("Derecha",expresion)
        Avance=re.findall("Avanzar [1-9][0-9]*|Avanzar \w|Avanzar\n",expresion)
        Pintar=re.findall("Pintar \([0-9]+,[0-9]+,[0-9]+\)|Pintar RGB\([0-9]+,[0-9]+,[0-9]+\)",expresion)
        Repetir=re.findall("Repetir [0-9]+ veces {",expresion)
        Abrir=re.findall("{ ",repexp)
        CierreRep=re.findall("}|\n",a)
        Cerrar=re.findall("}",a)

        if Repetir:
            expresion=""
            t=True

        if t==True:
            expresion=""
            repexp+=a
            if Cerrar:
                flag=True

            if CierreRep:
                linearep=Repeticion(frase,linea,archivo,flag)
                M,posicion,der,izq =AnalizarLinea(linearep,posicion,der,izq,ancho,M,archivo)
                flag=False
                repexp=""
                expresion=""
                t=False

            if Abrir and t==True :
                finalizarFrase=re.findall("}|\n",a)
                if finalizarFrase:
                   frase=frase
                else:
                    frase+=a

        if Izq:
            izq+=1
            expresion=""
            if izq==4:
                izq=0
        if Der:
            der+=1
            expresion=""
            if der==4:
                der=0

        if Avance:
            AvanceMasNum=re.findall("Avanzar [0-9]+",expresion)
            AvanceNum="".join(AvanceMasNum)
            if AvanceMasNum:
                Num=re.findall("[0-9]+",AvanceNum)
                strNum="".join(Num)
                intNum=int(strNum)

                expresion=""
            else:
                intNum=1
                expresion=""
                expresion+=Avance[0][-1]

            if der==izq:
              posicion[1]+=intNum

            if der==izq+1 or izq==der+3:
              posicion[0]+=intNum
            if der==izq+2 or izq==der+2:
              posicion[1]+=-intNum
            if der==izq+3 or izq==der+1:
              posicion[0]+=-intNum
            FuerdaDeRango=False
            FueraDeRango=RangoPosicion(posicion,ancho)
            if FueraDeRango==True:
                break

        if Pintar:
            f=0
            c=0
            Color=re.findall("\([0-9]*,[0-9]*,[0-9]*\)",expresion)
            strColor="".join(Color)
            strTupla=re.findall("[0-9]*,[0-9]*,[0-9]*",strColor)
            strTupla="".join(strTupla)
            strTupla+=","
            numsTupla=""
            listaToTupla=[]
            for a in strTupla:
                Coma=re.findall(",",a)
                if Coma:
                    numsTupla=int(numsTupla)
                    listaToTupla.append(numsTupla)
                    numsTupla=""
                else:
                    numsTupla+=a
            M[posicion[0]][posicion[1]]=tuple(listaToTupla)

            expresion=""
        x+=1
    return M,posicion,der,izq

def RangoPosicion(posicion, ancho):
    '''AQUI SE ANALIZA CUANDO LA POSICION DE LA MATRIZ SALE DEL RANGO '''
    if posicion[0]>=0 and posicion[1]>=0 and posicion[0]<ancho and posicion[1]<ancho:

        return False
    else:
        return True

def Repeticion(frase,linea,archivo,flag):
    '''TODO LO QUE ESTÁ EN EL PARENTESIS DEL REPETIR SE REPITE X VECES, Y SE ENVIA A LA FUNCION A AnalizarLinea'''
    frase+=" "
    t=flag  #linea con  rep x vec {}  necesita True

    if flag == False :
        for l in archivo:

            for a in l:
                corchete=re.findall("}",a)
                if corchete:
                    t=True
                    break
                frase+=a
            if t==True:
                break

    Repetir=re.findall("Repetir [0-9]* veces {",linea)
    strRepetir="".join(Repetir)
    numreps=re.findall("\d*",strRepetir)
    strNumreps="".join(numreps)
    Nr=int(strNumreps)
    c2=0
    frase=PalabraToRGB(frase)
    fraserep=""
    frase = re.sub("Avanzar  |Avanzar *\n", "Avanzar 1", frase)
    while c2<Nr :
        fraserep+=frase+" "

        c2+=1
    return fraserep

'''EN ESTA PRIMERA APERTURA DEL ARCHIVO.txt ANALIZAREMOS SIN CONTIENE ERRORES DE SINTAXIS'''
NombreArchivo=input("Ingrese nombre del archivo.txt :")
with open(NombreArchivo,"r") as archivo :
    c=0
    error=False
    ErrorFrase=""
    for linea in archivo :
        PrimeraLinea=re.findall("Ancho [1-9][0-9]*\n",linea)
        SegundaLinea=re.findall("(Color de fondo )+(Negro|Blanco|Rojo|Azul|Verde|RGB\(([0-1]+[0-9]*[0-9]*|[0-2]+[0-5]*[0-5]*),([0-1]+[0-9]*[0-9]*|[0-2]+[0-5]*[0-5]*),([0-1]+[0-9]*[0-9]*|[0-2]+[0-5]*[0-5]*)\))",linea)
        TerceraLinea=re.findall("\n",linea)
        l=[]

        if c==0 :
            l.append(linea)
            if not PrimeraLinea==l:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

        if c==1 :
            if not SegundaLinea:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

        if c==2:
            l.append(linea)
            if not TerceraLinea==l:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

        if c>2:
            Derecha=re.findall("Derecha [0-9]+|Derecha[0-9]+|Derecha[a-zA-Z]+|[a-zA-Z]+Derecha",linea)
            Izquierda=re.findall("Izquierda [0-9]+|Izquierda[0-9]+|Izquierda[a-zA-Z]+|[a-zA-Z]+Izquierda",linea)
            Avanzar=re.findall("Avanzar[0-9]+|Avanzar[a-zA-Z]+",linea)
            RepetirSolo=re.findall("Repetir",linea)
            Pintar=re.findall("Pintar",linea)
            PintarColor=re.findall("(Pintar )+(Negro|Blanco|Rojo|Azul|Verde|RGB\([0-2]+[0-5]*[0-5]*,[0-2]+[0-5]*[0-5]*,[0-2]+[0-5]*[0-5]*\))",linea)
            if Avanzar:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

            if Derecha:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

            if Izquierda:
                ErrorFrase+=str(c+1)+" "+linea
                error=True

            if RepetirSolo:
                RepetirEnLinea=re.findall("Repetir [0-9]+ veces {",linea)
                if not RepetirEnLinea:
                    ErrorFrase+=str(c+1)+" "+linea
                    error=True

            if Pintar:
                if not PintarColor:
                    ErrorFrase+=str(c+1)+" "+linea
                    error=True

        c+=1

    archivo.close()

'''SE HAN ENCONTRADO ERRORES DE SINTAXIS'''
if error==True:
        archivoErrores=open("errores.txt","w")
        ListaErroresRepetidos=re.split("\n",ErrorFrase)
        print(ListaErroresRepetidos)
        ListaErrores=[]
        ListaErrores.append(ListaErroresRepetidos[0])
        archivoErrores.write(ListaErroresRepetidos[0]+"\n")
        k=0
        Rep=False
        for a in ListaErroresRepetidos:
            for b in ListaErrores:
               if k!=0 and a==b:
                   Rep=True
            if k!=0 and Rep==False:
                ListaErrores.append(ListaErroresRepetidos[k])
                archivoErrores.write(ListaErroresRepetidos[k]+"\n")
            k+=1
        print(ListaErrores)

        archivoErrores.close()
        print("se ha creado el archivo : errores.txt")

'''NO SE HAN ENCONTRADO ERRORES DE SINTAXIS'''
if error==False:
    archivoErrores=open("errores.txt","w")
    NoErroresFrase="No hay errores!"
    archivoErrores.write(NoErroresFrase)
    archivoErrores.close()
    print("se ha creado el archivo : errores.txt")

''' COMIENZA LA EJECUCION DEL PROGRAMA, LUEGO DE COMRPOBAR QUE NO CONTIENE ERRORES'''

with open(NombreArchivo,"r") as archivo :
    if error==False:
        c=0
        posicion=[0,0]
        der=0
        izq=0
        for linea in archivo :
            linea=PalabraToRGB(linea)

            if(c==0):
                x = re.findall("[1-9][0-9]*", linea)
                ancho="".join(x)
                ancho=int(ancho)

            if (c==1):
                y = re.findall("\d+", linea)
                y=ListaStrToInt(y)
                M=matrizInicial(y,ancho)
                posicion=[0,0]

            if(c>2):
                M,posicion,der,izq=AnalizarLinea(linea,posicion,der,izq,ancho,M,archivo)
                FueraDeRango=RangoPosicion(posicion,ancho)
                if FueraDeRango==True:
                    print("ERROR : se accedio a la posicion :",posicion)
                    break

            c+=1

    archivo.close()

''' AQUI SE HACE UN CAMBIO EN LA MATRIZ, LOS COLORES RGB ESTÁN EN LISTAS, Y SE PASARÁN A TUPLAS , PARA PODER OCUPAR LA FUNCION MatrizAImagen'''

if error==False:
    fila=0
    for a in M:
        columna=0
        for b in a:
            M[fila][columna]=tuple(b)
            columna+=1
        fila+=1
    MatrizAImagen(M)


import argparse
import toml
import os
import glob
import shutil
from funcs.audio import AudioGenerator
from funcs.image import ImageGenerator
from funcs.movie import MovieGenerator

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('path', help='台本tomlファイルのパス')
    parser.add_argument(
        '-m', '--mode', choices=['0', '1', '2', '3'], default='3',
        help='何を生成するか指定する: ' \
             + '0.何も生成しない, 1.画像のみ, 2.音声のみ, 3.動画(デフォルト)')
    parser.add_argument(
        '-r', '--refresh', choices=['0', '1', '2'], default='0',
        help='出力済み中間生成物を: 0.削除しない(デフォルト), ' \
             + '1.現在の台本上必要な合成音声のみ残す, 2.全削除する')
    parser.add_argument(
        '-n', '--n_shots', type=int, default=0,
        help='正数を指定した場合にn場面目までで打ち切る')
    args = parser.parse_args()
    mode = int(args.mode)
    refresh = int(args.refresh)
    n_shots = args.n_shots

    # 台本tomlファイルを読み込みます
    with open(args.path, encoding='utf-8') as f:
        storyboard = toml.load(f)
    out_dir = storyboard['out_dir']
    if out_dir == '':  # 出力パスが空文字列の場合台本ファイルがあるパスにする
        out_dir = os.path.dirname(args.path) + '/'
        storyboard['out_dir'] = out_dir
    out_dir_intermediate = out_dir + 'intermediate/'  # 中間生成物用
    storyboard['out_dir_intermediate'] = out_dir_intermediate

    # 最終生成物、中間生成物用フォルダを作成します
    os.makedirs(out_dir, exist_ok=True)
    os.makedirs(out_dir_intermediate, exist_ok=True)

    # 立ち絵画像設定をスタイル ID をキーにした辞書にしておきます
    storyboard['character_images'] = {str(c['speaker']): c for c
                                      in storyboard['character_images']}
    # 各場面はデフォルトとの差分だけ指定してあるので完全にしておきます
    shots_ = []
    for i_shot, shot in enumerate(storyboard['shots']):
        shot_ = storyboard['shot_default'].copy()
        shot_.update(shot)
        # 後方互換性のための処理
        if ('front_img_paths' not in shot_) and ('front_img' in shot_):
            shot_['front_img_paths'] = [shot_['front_img']]
            shot_['front_img_coordinates'] = [shot_['front_img_coordinate']]
            del shot_['front_img'], shot_['front_img_coordinate']
        shots_.append(shot_)
        if i_shot + 1 == n_shots:
            break
    storyboard['shots'] = shots_

    # 各ジェネレータを用意します
    ig = ImageGenerator(storyboard)
    ag = AudioGenerator(storyboard)
    mg = MovieGenerator(storyboard)

    if refresh == 1:  # 不要な中間生成物を削除する場合は削除します
        required_wav_files = ag.get_required_wav_files()
        intermediates = glob.glob(out_dir_intermediate + '*')
        for intermediate_ in intermediates:
            intermediate = intermediate_.replace('\\', '/')  # for win
            _, ext = os.path.splitext(intermediate)
            if intermediate in required_wav_files:
                continue
            if ext not in ['.png', '.wav', '.mp3']:
                continue
            os.remove(intermediate)
    elif refresh == 2:  # 中間生成物を全削除する場合は全削除します
        shutil.rmtree(out_dir_intermediate)
        os.makedirs(out_dir_intermediate, exist_ok=True)

    # 各場面で必要な画像を合成し出力します
    if mode in [1, 3]:
        ig.generate()

    # 各場面の台詞 wav を生成し全体を通した音声ファイルを出力します
    if mode in [2, 3]:
        audio_file, durations = ag.generate()

    # 動画を生成します
    if mode == 3:
        mg.generate(durations, audio_file)

if __name__ == '__main__':
    main()