'''
Instagram Following Non-followers
Created Date: 01/21/23
Checks Instagram account followings to discover which followings are not following back the account.

Created by: Johnson Le
'''

import json

# Converts JSON files to Python in order to read
with open('following.json') as file:
    following_json = json.load(file)

with open('followers.json') as file:
    followers_json = json.load(file)

# Adds users from account's followers to a list of followers
users_not_following = []
for following in following_json["relationships_following"]:
    users_not_following.append(following["string_list_data"][0]["value"])

# Calculates the differences of account's followings versus account's followers
for follower in followers_json["relationships_followers"]:
    follower = follower["string_list_data"][0]["value"]
    if follower in users_not_following:
# Resulting only users with no mutual connections of users not following back the account
        users_not_following.remove(follower)

# Displays results
print("Users who don't follow back:")
for user in users_not_following:
    print("- @" + user)


### Coded by EYLL'
### github link : https://www.github.com/arda6
import requests
from colorama import Fore , init
init(autoreset=True)
mysite = open(r"C:\Users\ARDA\source\repos\sqlscanner2\sqlscanner2\targetsite.txt","r", encoding="utf-8")
site = mysite.readline()
url = requests.get(r""+site+"'")
url2 = requests.get(r""+site+"")
sql = str(url.content)
sql2 = str(url2.content)

url = requests.get(r""+site+"'")
url2 = requests.get(r""+site+"")
sql = str(url.content)
sql2 = str(url2.content)
if sql.find("error") == int('-1'):
    print("")
    print(Fore.YELLOW+"[#] "+site+" Hedefte Açık Tespit Edilemedi Tekrar Deneniyor")
    print("")
    if sql.find("SQL") == int("-1"):
        print(Fore.YELLOW+"[#] Hedefte Açık Bulunamadı Blind SQL Deneniyor")
        print("")
        if sql == sql2:
            print(Fore.RED + "[#] Blind SQL Bulunamadı")
            print("")
        elif sql != sql2 :
            print(Fore.GREEN + "[#] Blind SQL Bulundu ( TEST )")
            print("")
            dosya = open(r"C:\Users\ARDA\source\repos\sqlscanner2\sqlscanner2\sqlsite.txt", "a", encoding="utf-8")
            dosya.write(r"" + site + "\n")
        else :
            print(Fore.GREEN+"[#] Hedefte Açık Tespit Edildi")
            dosya = open("list.txt", "a", encoding="utf-8")
            dosya.write(r" Blind SQLi" + site + "\n")
else:
    print("")
    print(Fore.GREEN+"[#] "+site+  " Hedefte SQL İnjection Tespit Edildi")
    print("")
    dosya = open(r"C:\Users\ARDA\source\repos\sqlscanner2\sqlscanner2\sqlsite.txt", "a", encoding="utf-8")
    dosya.write(r" SQLi "+site+"\n")


import os
import torch
import requests
import urllib.parse
from modules.katakana import *
from google.cloud import texttospeech
from dotenv import load_dotenv
load_dotenv()

def silero_tts(text, language, model_name, speaker):
    device = torch.device('cpu')
    torch.set_num_threads(4)
    model_file = 'model.pt'

    if not os.path.isfile(model_file):
        torch.hub.download_url_to_file(
            f'https://models.silero.ai/models/tts/{language}/{model_name}.pt',
            model_file)

    model = torch.package.PackageImporter(model_file).load_pickle("tts_models", "model")
    model.to(device)
    sample_rate = 48000

    audio_paths = model.save_wav(text=text,
                                 speaker=speaker,
                                 sample_rate=sample_rate)

def voicevox_tts(text):
    voicevox_url = os.getenv('VOICEVOX_URL')
    katakana_text = katakana_converter(text)
    speaker_id = 46  # You can change the speaker ID according to your preference

    audio_query_params = urllib.parse.urlencode({'text': katakana_text, 'speaker': speaker_id})
    audio_query_response = requests.post(f'{voicevox_url}/audio_query?{audio_query_params}')

    synthesis_params = urllib.parse.urlencode({'speaker': speaker_id, 'enable_interrogative_upspeak': True})
    synthesis_response = requests.post(f'{voicevox_url}/synthesis?{synthesis_params}', json=audio_query_response.json())

    with open("test.wav", "wb") as outfile:
        outfile.write(synthesis_response.content)

# Google Text-to-Speech function
def google_tts(text, voice_name, language):
    # Instantiates a client
    client = texttospeech.TextToSpeechClient()

    # Set the text input to be synthesized
    synthesis_input = texttospeech.SynthesisInput(text=text)

    # Build the voice request, select the language code (language) and the voice name (voice_name)
    voice = texttospeech.VoiceSelectionParams(
        language_code=language, name=voice_name
    )

    # Select the type of audio file you want returned
    audio_config = texttospeech.AudioConfig(
        audio_encoding=texttospeech.AudioEncoding.MP3
    )

    # Perform the text-to-speech request on the text input with the selected
    # voice parameters and audio file type
    response = client.synthesize_speech(
        input=synthesis_input, voice=voice, audio_config=audio_config
    )

    # The response's audio_content is binary.
    with open("test.wav", "wb") as out:
        # Write the response to the output file.
        out.write(response.audio_content)

if __name__ == "__main__":
    silero_tts()


#push-relabel algorithm

class PushRelabel:
    def __init__(self):
        self.capacity = None  # capacity matrix
        self.max_flow = 0  # value of maximum flow
        self.mincut = None  # min cut

    def capacity_matrix(self, w_if, w_ib, hori_w_if, vert_w_if):
        """
        :param w_if: terminal weights associated with source node
        :param w_ib: terminal weights associated with target node
        :param hori_w_if: horizontal non terminal weights
        :param vert_w_if: vertical non terminal weights
        :return: equivalent of capacity matrix but as a dictionnary
        With key is origin node, value is dictionnary.
        With key as destination node and value is the weight of the corresponding edge
        """
        dico = {}
        sub_dico = {}
        w = w_if.shape[0]
        h = w_if.shape[1]
        target_num = w * h + 1

        # Source and target node
        for y in range(h):
            for x in range(w):
                node_id = y * h + x + 1
                sub_dico[node_id] = w_if[x, y]
                dico[node_id] = {target_num: w_ib[x, y]}
        dico[0] = sub_dico

        # Add horizontal non terminal weights
        for y in range(h):
            for x in range(w-1):
                node_id = y * h + x + 1
                dico[node_id][node_id + 1] = hori_w_if[x][y]

        # Add vertical non terminal weights
        for y in range(h-1):
            for x in range(w):
                node_id = y * h + x + 1
                dico[node_id][node_id + w] = vert_w_if[x][y]

        # Create matrix
        # n = h * w + 2
        # C = [[0] * n for i in range(n)]
        # for key in dico:
        #     for key2 in dico[key]:
        #         C[key][key2] = dico[key][key2]

        self.capacity = dico

    def MaxFlow(self, C, s, t):
        """
        :param C: capacity matrix of the graph
        :param s: source node
        :param t: target node
        :return: return the maximum flow value (what leaves from source node)
        """
        n = len(C) # C is the capacity matrix
        F = [[0] * n for i in range(n)] # Big flow matrix

        # the residual capacity from u to v is C[u][v] - F[u][v]
        height = [0] * n # height of node
        excess = [0] * n # flow into node minus flow from node
        seen   = [0] * n # neighbours seen since last relabel
        # node "queue"
        nodelist = [i for i in range(n) if i != s and i != t]

        def push(u, v):
            """
            :param u, v: two adjacent vertices of the graph, link by an edge
            Push the flow from a vertex with strictly postive overflow
            to one of its neighbours via a vertex with strictly positive residual capacity
            """
            send = min(excess[u], C[u][v] - F[u][v])
            F[u][v] += send
            F[v][u] -= send
            excess[u] -= send
            excess[v] += send

        def relabel(u):
            """
            :param u: node of the graph
            Find smallest new height for that node to make a push possible,
            if such a push is possible at all
            """
            # find smallest new height making a push possible,
            # if such a push is possible at all
            min_height = float('inf')
            for v in range(n):
                if C[u][v] - F[u][v] > 0:
                    min_height = min(min_height, height[v])
                    height[u] = min_height + 1

        def discharge(u):
            """
            :param u: targeted node of the graph
            Push or relabel process for node u
            """
            # If node has excess flow
            while excess[u] > 0:
                # Check neighbours
                if seen[u] < n:
                    v = seen[u]
                    # Push if conditions are met
                    if C[u][v] - F[u][v] > 0 and height[u] > height[v]:
                        push(u, v)
                    else:
                        seen[u] += 1
                # Relabel if we have check all neighbours of u and push is impossible
                else:
                    relabel(u)
                    seen[u] = 0

        # Set label of source to number of vertices
        height[s] = n

        # Saturate all edges incident to the source
        excess[s] = float("inf")
        for v in range(n):
            push(s, v)

        p = 0
        # Apply push relabel algo on the whole graph
        while p < len(nodelist):
            u = nodelist[p]
            old_height = height[u]
            # Push or relabel u
            discharge(u)
            # Move to front of the list if relabelling has been done
            if height[u] > old_height:
                nodelist.insert(0, nodelist.pop(p))
                p = 0
            else:
                p += 1

        self.max_flow = sum(F[s])

"""
TEST

# Make a capacity graph
# node s  o  p  q  r  t
C = [[ 0, 3, 3, 0, 0, 0 ],  # s
     [ 0, 0, 2, 3, 0, 0 ],  # o
     [ 0, 0, 0, 0, 2, 0 ],  # p
     [ 0, 0, 0, 0, 4, 2 ],  # q
     [ 0, 0, 0, 0, 0, 2 ],  # r
     [ 0, 0, 0, 0, 0, 3 ]]  # t

source = 0  # A
sink = 5   # F
max_flow_value = MaxFlow(C, source, sink)
print("Push-Relabeled(Preflow-push) algorithm")
print("max_flow_value is: ", max_flow_value)

"""


import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.graph_objs as go

def barplot(dataframe: pd.DataFrame, column: str, **kwargs):
    """
    Grafico de barras sobre una columna de interes
    :param dataframe: DataFrame
    :param column: columna de interes
    :return: NoneType
    """
    data = dataframe[column].value_counts().sort_values(ascending=True)
    bars = tuple(data.index.tolist())
    values = data.values.tolist()
    y_pos = np.arange(len(bars))
    colors = ["lightblue"] * len(bars)
    colors[-1] = "blue"
    plt.figure(figsize=(16, 10), **kwargs)
    plt.barh(y_pos, values, color=colors)
    plt.title(f"Distribución de {column}")
    plt.yticks(ticks=y_pos, labels=bars)
    return plt.show()

def box_plot(dataframe: pd.DataFrame, column: str, label: str = None, **kwargs):
    """
    Diagrama de caja y bigotes para ver la distribucion de una variable de interes y de esa variable con respeto
    a una variable categorica
    :param dataframe: DataFrame
    :param column: variable de interes
    :param label: variable categorica (suele ser la variable dependiente si es un problema de clasificacion)
    :return: NoneType
    """
    if label is None:
        return sns.catplot(data=dataframe, x=column, kind="box", **kwargs)
    else:
        return sns.catplot(data=dataframe, x=label, y=column, kind="box", **kwargs)

def distribution_plot(dataframe: pd.DataFrame, column: str, **kwargs):
    """
    Histograma de una columna de interes
    :param dataframe: DataFrame
    :param column: columna de interes
    :return: Nonetype
    """
    return sns.displot(data=dataframe, x=column, **kwargs)

def heat_map(dataframe: pd.DataFrame, **kwargs):
    """
    Matriz de calor sobre un DataFrame
    :param dataframe: DataFrame
    :return:
    """
    return sns.heatmap(dataframe, annot=True, fmt=".1g", linecolor="w", linewidths=3, **kwargs)

def radar_chart(df: pd.DataFrame, columns: list, label: str, title: str):
    """
    Radar chart filtering by the categories of the target variable
    :param title: title
    :param df: DataFrame
    :param columns: columns of interest
    :param label: target variable
    :return:
    """
    categories = sorted(df[label].unique().tolist())
    table = np.round(df.groupby(by=label, as_index=True)[columns].mean(), decimals=2)
    figure = go.Figure()
    for categorie in categories:
        figure.add_trace(go.Scatterpolar(r=table.loc[categorie].tolist(),
                                         theta=columns,
                                         fill='toself',
                                         name=categorie))
    figure.update_layout(polar=dict(radialaxis=dict(visible=True, range=[0, 1])),
                         showlegend=True, title=title)
    return figure.show()


import logging
import os
import sys
from dataclasses import dataclass, field
from typing import List, Optional, Tuple

import torch

import datasets
from datasets import load_dataset, load_metric
from torch.utils.data import DataLoader, Dataset, RandomSampler, SequentialSampler

import transformers
from trainer_seq2seq_qa import QuestionAnsweringSeq2SeqTrainer
from transformers import (
    DataCollatorForSeq2Seq,
    HfArgumentParser,
    Seq2SeqTrainingArguments,
    set_seed,
)
from nkb_t5 import T5ForConditionalGeneration
from transformers import T5Config, T5TokenizerFast
from transformers.trainer_utils import EvalLoopOutput, EvalPrediction, get_last_checkpoint
from transformers.utils import check_min_version
from transformers.utils.versions import require_version

# Will error if the minimal version of Transformers is not installed. Remove at your own risks.
check_min_version("4.17.0.dev0")

require_version("datasets>=1.8.0", "To fix: pip install -r examples/pytorch/question-answering/requirements.txt")

logger = logging.getLogger(__name__)

@dataclass
class MySeq2SeqTrainingArguments(Seq2SeqTrainingArguments):
    optim_group: str = field(
        default='all',
        metadata={"help": "indicate which parameter groups to be learned, could be ['all', 'ori', 'ex', 'ori-ada']"}
    )
    sec_lr: str = field(
        default='zero',
        metadata={"help": "how much learning rate the other parameters use, could be ['zero', '/10', '/100', '/1000']"}
    )

@dataclass
class ModelArguments:
    """
    Arguments pertaining to which model/config/tokenizer we are going to fine-tune from.
    """

    model_name_or_path: str = field(
        metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"}
    )
    config_name: Optional[str] = field(
        default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"}
    )
    tokenizer_name: Optional[str] = field(
        default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"}
    )
    cache_dir: Optional[str] = field(
        default=None,
        metadata={"help": "Path to directory to store the pretrained models downloaded from huggingface.co"},
    )
    use_fast_tokenizer: bool = field(
        default=True,
        metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."},
    )
    model_revision: str = field(
        default="main",
        metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."},
    )
    use_auth_token: bool = field(
        default=False,
        metadata={
            "help": "Will use the token generated when running `transformers-cli login` (necessary to use this script "
            "with private models)."
        },
    )

    # config for NKB settings
    kb_layer: Optional[str] = field(
        default='',
        metadata={"help": "Layers to be extended with NKB, should be separated by commas, e.g., '10,11' or '11'"}
    )
    ex_size: Optional[int] = field(
        default=3072,
        metadata={"help": "The number of the extended FFN slots"}
    )
    adaptive_nkb: bool = field(
        default=False,
        metadata={"help": "Whether to add adaptive layer outside the NKB"},
    )
    dropout: Optional[float] = field(
        default=None,
        metadata={"help": "dropout rate for the model"},
    )

@dataclass
class DataTrainingArguments:
    """
    Arguments pertaining to what data we are going to input our model for training and eval.
    """

    dataset_name: Optional[str] = field(
        default=None, metadata={"help": "The name of the dataset to use (via the datasets library)."}
    )
    dataset_config_name: Optional[str] = field(
        default=None, metadata={"help": "The configuration name of the dataset to use (via the datasets library)."}
    )
    question_column: Optional[str] = field(
        default="question",
        metadata={"help": "The name of the column in the datasets containing the questions (for question answering)."},
    )
    answer_column: Optional[str] = field(
        default="answers",
        metadata={"help": "The name of the column in the datasets containing the answers (for question answering)."},
    )
    train_file: Optional[str] = field(default=None, metadata={"help": "The input training data file (a text file)."})
    validation_file: Optional[str] = field(
        default=None,
        metadata={"help": "An optional input evaluation data file to evaluate the perplexity on (a text file)."},
    )
    test_file: Optional[str] = field(
        default=None,
        metadata={"help": "An optional input test data file to evaluate the perplexity on (a text file)."},
    )
    overwrite_cache: bool = field(
        default=False, metadata={"help": "Overwrite the cached training and evaluation sets"}
    )
    preprocessing_num_workers: Optional[int] = field(
        default=None,
        metadata={"help": "The number of processes to use for the preprocessing."},
    )
    max_seq_length: int = field(
        default=384,
        metadata={
            "help": "The maximum total input sequence length after tokenization. Sequences longer "
            "than this will be truncated, sequences shorter will be padded."
        },
    )
    max_answer_length: int = field(
        default=10,
        metadata={
            "help": "The maximum length of an answer that can be generated. This is needed because the start "
            "and end predictions are not conditioned on one another."
        },
    )
    val_max_answer_length: Optional[int] = field(
        default=10,
        metadata={
            "help": "The maximum total sequence length for validation target text after tokenization. Sequences longer "
            "than this will be truncated, sequences shorter will be padded. Will default to `max_answer_length`."
            "This argument is also used to override the ``max_length`` param of ``model.generate``, which is used "
            "during ``evaluate`` and ``predict``."
        },
    )
    pad_to_max_length: bool = field(
        default=True,
        metadata={
            "help": "Whether to pad all samples to `max_seq_length`. "
            "If False, will pad the samples dynamically when batching to the maximum length in the batch (which can "
            "be faster on GPU but will be slower on TPU)."
        },
    )
    max_train_samples: Optional[int] = field(
        default=None,
        metadata={
            "help": "For debugging purposes or quicker training, truncate the number of training examples to this "
            "value if set."
        },
    )
    max_eval_samples: Optional[int] = field(
        default=None,
        metadata={
            "help": "For debugging purposes or quicker training, truncate the number of evaluation examples to this "
            "value if set."
        },
    )
    max_predict_samples: Optional[int] = field(
        default=None,
        metadata={
            "help": "For debugging purposes or quicker training, truncate the number of prediction examples to this "
            "value if set."
        },
    )
    doc_stride: int = field(
        default=128,
        metadata={"help": "When splitting up a long document into chunks, how much stride to take between chunks."},
    )
    n_best_size: int = field(
        default=20,
        metadata={"help": "The total number of n-best predictions to generate when looking for an answer."},
    )
    num_beams: Optional[int] = field(
        default=None,
        metadata={
            "help": "Number of beams to use for evaluation. This argument will be passed to ``model.generate``, "
            "which is used during ``evaluate`` and ``predict``."
        },
    )
    ignore_pad_token_for_loss: bool = field(
        default=True,
        metadata={
            "help": "Whether to ignore the tokens corresponding to padded labels in the loss computation or not."
        },
    )

    def __post_init__(self):
        if (
            self.dataset_name is None
            and self.train_file is None
            and self.validation_file is None
            and self.test_file is None
        ):
            raise ValueError("Need either a dataset name or a training/validation file/test_file.")
        else:
            if self.train_file is not None:
                extension = self.train_file.split(".")[-1]
                assert extension in ["csv", "json"], "`train_file` should be a csv or a json file."
            if self.validation_file is not None:
                extension = self.validation_file.split(".")[-1]
                assert extension in ["csv", "json"], "`validation_file` should be a csv or a json file."
            if self.test_file is not None:
                extension = self.test_file.split(".")[-1]
                assert extension in ["csv", "json"], "`test_file` should be a csv or a json file."
        if self.val_max_answer_length is None:
            self.val_max_answer_length = self.max_answer_length

def main():
    # See all possible arguments in src/transformers/training_args.py
    # or by passing the --help flag to this script.
    # We now keep distinct sets of args, for a cleaner separation of concerns.

    parser = HfArgumentParser((ModelArguments, DataTrainingArguments, MySeq2SeqTrainingArguments))
    if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
        # If we pass only one argument to the script and it's the path to a json file,
        # let's parse it to get our arguments.
        model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]))
    else:
        model_args, data_args, training_args = parser.parse_args_into_dataclasses()

    # Setup logging
    logging.basicConfig(
        format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
        datefmt="%m/%d/%Y %H:%M:%S",
        handlers=[logging.StreamHandler(sys.stdout)],
    )

    log_level = training_args.get_process_log_level()
    logger.setLevel(log_level)
    datasets.utils.logging.set_verbosity(log_level)
    transformers.utils.logging.set_verbosity(log_level)
    transformers.utils.logging.enable_default_handler()
    transformers.utils.logging.enable_explicit_format()

    # Log on each process the small summary:
    logger.warning(
        f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"
        + f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}"
    )
    logger.info(f"Training/evaluation parameters {training_args}")

    # Detecting last checkpoint.
    last_checkpoint = None
    if os.path.isdir(training_args.output_dir) and training_args.do_train and not training_args.overwrite_output_dir:
        last_checkpoint = get_last_checkpoint(training_args.output_dir)
        if last_checkpoint is None and len(os.listdir(training_args.output_dir)) > 0:
            raise ValueError(
                f"Output directory ({training_args.output_dir}) already exists and is not empty. "
                "Use --overwrite_output_dir to overcome."
            )
        elif last_checkpoint is not None and training_args.resume_from_checkpoint is None:
            logger.info(
                f"Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change "
                "the `--output_dir` or add `--overwrite_output_dir` to train from scratch."
            )

    # Set seed before initializing model.
    set_seed(training_args.seed)

    # Get the datasets: you can either provide your own CSV/JSON/TXT training and evaluation files (see below)
    # or just provide the name of one of the public datasets available on the hub at https://huggingface.co/datasets/
    # (the dataset will be downloaded automatically from the datasets Hub).
    #
    # For CSV/JSON files, this script will use the column called 'text' or the first column if no column called
    # 'text' is found. You can easily tweak this behavior (see below).
    #
    # In distributed training, the load_dataset function guarantee that only one local process can concurrently
    # download the dataset.
    if data_args.dataset_name is not None:
        # Downloading and loading a dataset from the hub.
        raw_datasets = load_dataset(
            data_args.dataset_name, data_args.dataset_config_name, cache_dir=model_args.cache_dir
        )
    else:
        data_files = {}
        if data_args.train_file is not None:
            data_files["train"] = data_args.train_file
            extension = data_args.train_file.split(".")[-1]
        if data_args.validation_file is not None:
            data_files["validation"] = data_args.validation_file
            extension = data_args.validation_file.split(".")[-1]
        if data_args.test_file is not None:
            data_files["test"] = data_args.test_file
            extension = data_args.test_file.split(".")[-1]
        raw_datasets = load_dataset(extension, data_files=data_files, field="data", cache_dir=model_args.cache_dir)
    # See more about loading any type of standard or custom dataset (from files, python dict, pandas DataFrame, etc) at
    # https://huggingface.co/docs/datasets/loading_datasets.html.

    # Load pretrained model and tokenizer
    #
    # Distributed training:
    # The .from_pretrained methods guarantee that only one local process can concurrently
    # download model & vocab.
    config = T5Config.from_pretrained(
        model_args.model_name_or_path,
        cache_dir=model_args.cache_dir,
    )
    tokenizer = T5TokenizerFast.from_pretrained(
        model_args.model_name_or_path,
        cache_dir=model_args.cache_dir,
    )
    # update config for NKB settings
    config.kb_layer = model_args.kb_layer
    config.ex_size = model_args.ex_size
    config.adaptive_nkb = model_args.adaptive_nkb
    if model_args.dropout is not None:
        config.dropout_rate = model_args.dropout
    # model = T5ForConditionalGeneration(
    #     config=config,
    # )
    model = T5ForConditionalGeneration.from_pretrained(
        model_args.model_name_or_path,
        from_tf=False,
        config=config,
        cache_dir=model_args.cache_dir,
    )

    model.resize_token_embeddings(len(tokenizer))

    if model.config.decoder_start_token_id is None:
        raise ValueError("Make sure that `config.decoder_start_token_id` is correctly defined")

    # Preprocessing the datasets.
    # We need to generate and tokenize inputs and targets.
    column_names = raw_datasets["train"].column_names

    # Get the column names for input/target.
    question_column = data_args.question_column
    if question_column not in column_names:
        raise ValueError(
            f"--question_column' value '{data_args.question_column}' needs to be one of: {', '.join(column_names)}"
        )
    answer_column = data_args.answer_column
    if answer_column not in column_names:
        raise ValueError(
            f"--answer_column' value '{data_args.answer_column}' needs to be one of: {', '.join(column_names)}"
        )

    # Temporarily set max_answer_length for training.
    max_answer_length = data_args.max_answer_length
    padding = "max_length" if data_args.pad_to_max_length else False

    if training_args.label_smoothing_factor > 0 and not hasattr(model, "prepare_decoder_input_ids_from_labels"):
        logger.warning(
            "label_smoothing is enabled but the `prepare_decoder_input_ids_from_labels` method is not defined for"
            f"`{model.__class__.__name__}`. This will lead to loss being calculated twice and will take up more memory"
        )

    if data_args.max_seq_length > tokenizer.model_max_length:
        logger.warning(
            f"The max_seq_length passed ({data_args.max_seq_length}) is larger than the maximum length for the"
            f"model ({tokenizer.model_max_length}). Using max_seq_length={tokenizer.model_max_length}."
        )
    max_seq_length = min(data_args.max_seq_length, tokenizer.model_max_length)

    def preprocess_batch(
        examples,
        question_column: str,
        answer_column: str,
    ) -> Tuple[List[str], List[str]]:
        questions = examples[question_column]
        answers = examples[answer_column]

        # inputs = [question.strip() for question in questions]
        inputs = ['question: ' + question.strip() for question in questions]
        # inputs = ['answer the question: ' + question.strip() for question in questions]
        # inputs = [question + '?' if not question.endswith('?') else question for question in inputs]
        # inputs = [question.lower() for question in inputs]

        targets = [answer[0].strip() if len(answer) > 0 else "" for answer in answers]
        # targets = [answer.lower() for answer in targets]
        return inputs, targets

    def preprocess_function(examples):
        inputs, targets = preprocess_batch(examples, question_column, answer_column)

        model_inputs = tokenizer(inputs, max_length=max_seq_length, padding=padding, truncation=True)
        # Setup the tokenizer for targets
        with tokenizer.as_target_tokenizer():
            labels = tokenizer(targets, max_length=max_answer_length, padding=padding, truncation=True)

        # If we are padding here, replace all tokenizer.pad_token_id in the labels by -100 when we want to ignore
        # padding in the loss.
        if padding == "max_length" and data_args.ignore_pad_token_for_loss:
            labels["input_ids"] = [
                [(l if l != tokenizer.pad_token_id else -100) for l in label] for label in labels["input_ids"]
            ]

        model_inputs["labels"] = labels["input_ids"]
        return model_inputs

    # Validation preprocessing
    def preprocess_validation_function(examples):
        inputs, targets = preprocess_batch(examples, question_column, answer_column)

        model_inputs = tokenizer(
            inputs,
            max_length=max_seq_length,
            padding=padding,
            truncation=True,
            return_overflowing_tokens=True,
            return_offsets_mapping=True,
        )
        # Setup the tokenizer for targets
        with tokenizer.as_target_tokenizer():
            labels = tokenizer(targets, max_length=max_answer_length, padding=padding, truncation=True)

        # Since one example might give us several features if it has a long context, we need a map from a feature to
        # its corresponding example. This key gives us just that.
        sample_mapping = model_inputs.pop("overflow_to_sample_mapping")

        # For evaluation, we will need to convert our predictions to substrings of the context, so we keep the
        # corresponding example_id and we will store the offset mappings.
        model_inputs["example_id"] = []

        for i in range(len(model_inputs["input_ids"])):
            # One example can give several spans, this is the index of the example containing this span of text.
            sample_index = sample_mapping[i]
            model_inputs["example_id"].append(examples["id"][sample_index])

        # If we are padding here, replace all tokenizer.pad_token_id in the labels by -100 when we want to ignore
        # padding in the loss.
        if padding == "max_length" and data_args.ignore_pad_token_for_loss:
            labels["input_ids"] = [
                [(l if l != tokenizer.pad_token_id else -100) for l in label] for label in labels["input_ids"]
            ]

        model_inputs["labels"] = labels["input_ids"]
        return model_inputs

    if training_args.do_train:
        if "train" not in raw_datasets:
            raise ValueError("--do_train requires a train dataset")
        train_dataset = raw_datasets["train"]
        if data_args.max_train_samples is not None:
            # We will select sample from whole data if agument is specified
            train_dataset = train_dataset.select(range(data_args.max_train_samples))
        # Create train feature from dataset
        with training_args.main_process_first(desc="train dataset map pre-processing"):
            train_dataset = train_dataset.map(
                preprocess_function,
                batched=True,
                num_proc=data_args.preprocessing_num_workers,
                remove_columns=column_names,
                load_from_cache_file=not data_args.overwrite_cache,
                desc="Running tokenizer on train dataset",
            )
        if data_args.max_train_samples is not None:
            # Number of samples might increase during Feature Creation, We select only specified max samples
            train_dataset = train_dataset.select(range(data_args.max_train_samples))

    if training_args.do_eval:
        if "validation" not in raw_datasets:
            raise ValueError("--do_eval requires a validation dataset")
        eval_examples = raw_datasets["validation"]
        if data_args.max_eval_samples is not None:
            # We will select sample from whole data
            eval_examples = eval_examples.select(range(data_args.max_eval_samples))
        # Validation Feature Creation
        with training_args.main_process_first(desc="validation dataset map pre-processing"):
            eval_dataset = eval_examples.map(
                preprocess_validation_function,
                batched=True,
                num_proc=data_args.preprocessing_num_workers,
                remove_columns=column_names,
                load_from_cache_file=not data_args.overwrite_cache,
                desc="Running tokenizer on validation dataset",
            )
        if data_args.max_eval_samples is not None:
            # During Feature creation dataset samples might increase, we will select required samples again
            eval_dataset = eval_dataset.select(range(data_args.max_eval_samples))

    if training_args.do_predict:
        if "test" not in raw_datasets:
            raise ValueError("--do_predict requires a test dataset")
        predict_examples = raw_datasets["test"]
        if data_args.max_predict_samples is not None:
            # We will select sample from whole data
            predict_examples = predict_examples.select(range(data_args.max_predict_samples))
        # Predict Feature Creation
        with training_args.main_process_first(desc="prediction dataset map pre-processing"):
            predict_dataset = predict_examples.map(
                preprocess_validation_function,
                batched=True,
                num_proc=data_args.preprocessing_num_workers,
                remove_columns=column_names,
                load_from_cache_file=not data_args.overwrite_cache,
                desc="Running tokenizer on prediction dataset",
            )
        if data_args.max_predict_samples is not None:
            # During Feature creation dataset samples might increase, we will select required samples again
            predict_dataset = predict_dataset.select(range(data_args.max_predict_samples))

    # Data collator
    label_pad_token_id = -100 if data_args.ignore_pad_token_for_loss else tokenizer.pad_token_id
    data_collator = DataCollatorForSeq2Seq(
        tokenizer,
        model=model,
        label_pad_token_id=label_pad_token_id,
        pad_to_multiple_of=8 if training_args.fp16 else None,
    )

    # ============== knowledge editing ==============

    import json
    import random
    import copy

    model = model.cuda()
    model.requires_grad_(False)
    # dataset = train_dataset
    dataset = eval_dataset

    # single_token_examples = []
    # for i in list(range(len(dataset))):
    #     sample = dataset[i]
    #     if len(sample["labels"]) > 2:
    #         continue
    #     single_token_examples.append(i)
    # print("single_token_examples", len(single_token_examples), '/', len(dataset))

    # w2r_indices = []
    # r2w_indices = []

    # for i, index in enumerate(single_token_examples):
    #     sample = dataset[index]
    #     if 'offset_mapping' in sample:
    #         del sample['offset_mapping']
    #     if 'example_id' in sample:
    #         del sample['example_id']
    #     question = tokenizer.decode(sample["input_ids"])
    #     answer_token_ids = sample["labels"][:-1]
    #     answer = tokenizer.decode(answer_token_ids)
    #     answer_len = len(sample["labels"])
    #     for key in sample.keys():
    #         sample[key] = torch.LongTensor([sample[key]]).cuda()
    #     del sample['labels']
    #     results = model.generate(**sample)
    #     g_answer_token_ids = results[0].data.tolist()[1:-1]
    #     g_answer = tokenizer.decode(g_answer_token_ids)
    #     if len(g_answer_token_ids) > 1:
    #         continue
    #     print('============' * 5, index)
    #     print('question|', question)
    #     print('answer|', answer)
    #     print('answer_ids|', answer_token_ids, '|', answer_len)
    #     print('generated_answer_ids|', g_answer_token_ids)
    #     print('generated_answer|', g_answer)
    #     if g_answer == answer:
    #         r2w_indices.append(index)
    #     else:
    #         w2r_indices.append(index)
    #     if i % 20 == 0:
    #         print(f'{i}/{len(single_token_examples)} examples done')

    # print('r2w_indices number:', len(r2w_indices))
    # print('w2r_indices number:', len(w2r_indices))

    # with open(f'tmp_data/knowledge_editing/r2w_indices.json', 'w', encoding='utf-8') as f:
    #     json.dump(r2w_indices, f, indent=2)
    # with open(f'tmp_data/knowledge_editing/w2r_indices.json', 'w', encoding='utf-8') as f:
    #     json.dump(w2r_indices, f, indent=2)

    with open(f'tmp_data/knowledge_editing/r2w_indices.json', 'r', encoding='utf-8') as f:
        r2w_indices = json.load(f)
    with open(f'tmp_data/knowledge_editing/w2r_indices.json', 'r', encoding='utf-8') as f:
        w2r_indices = json.load(f)
    single_indices = r2w_indices + w2r_indices

    # ============== correct erroneous knowledge ==============

    def knowledge_updating_w2r(index):
        sample = dataset[index]
        if 'offset_mapping' in sample:
            del sample['offset_mapping']
        if 'example_id' in sample:
            del sample['example_id']
        question = tokenizer.decode(sample["input_ids"])
        answer_token_ids = sample["labels"][:-1]
        answer = tokenizer.decode(answer_token_ids)
        answer_len = len(sample["labels"])
        with open(f'tmp_data/knowledge_editing/tmp_weights.txt', 'w', encoding='utf-8') as f:
            print(f'{question}', file=f)
            print(f'{answer}', file=f)
            print(f'{answer_token_ids}', file=f)
            print(f'{answer_len}', file=f)
        for key in sample.keys():
            sample[key] = torch.LongTensor([sample[key]]).cuda()
        del sample['labels']
        results = model.generate(**sample)
        g_answer_token_ids = results[0].data.tolist()[1:-1]
        g_answer = tokenizer.decode(g_answer_token_ids)
        print('index|', index)
        print('question|', question)
        print('answer|', answer)
        print('answer_ids|', answer_token_ids, '|', answer_len)
        print('generated_answer_ids|', g_answer_token_ids)
        print('generated_answer|', g_answer)

        o_embedding = model.lm_head.weight
        nkb_values = model.decoder.block[11].layer[2].DenseReluDense.wo_ex.weight
        all_prob = o_embedding.matmul(nkb_values).t().softmax(dim=1)  # n_value, n_vocab

        to_update_pos = []
        with open(f'tmp_data/knowledge_editing/tmp_weights.txt', 'r', encoding='utf-8') as f:
            lines = f.readlines()
            weights = [float(x) for x in lines[4].split()]

            # update high-weight value
            weights_indices = [[float(x), i] for i, x in enumerate(lines[4].split())]
            weights_indices.sort(key=lambda x:-x[0])
            to_update_pos.append(weights_indices[0][1])

            # # update hard corresponding value
            # for i, weight in enumerate(weights):
            #     if weight <= 1e-10:
            #         continue
            #     topk, topk_pos = all_prob[i].topk(1)
            #     if topk_pos[0] != g_answer_token_ids[0]:
            #         continue
            #     to_update_pos.append(i)
            #     # print(i, weight, tokenizer.decode(topk_pos))

            # # update soft corresponding value
            # affinity = all_prob[:, g_answer_token_ids[0]]  # n_value
            # topk, topk_pos = affinity.topk(3072)
            # topk_pos = topk_pos.tolist()
            # for pos in topk_pos:
            #     if weights[pos] > 10:
            #         to_update_pos.append(pos)
            #         break

        print('to_update_pos|', len(to_update_pos), ':', to_update_pos)

        ori_token_id = g_answer_token_ids[0]
        new_token_id = answer_token_ids[0]
        ori_emb = o_embedding[ori_token_id, :]
        new_emb = o_embedding[new_token_id, :]
        scaling_factor = 0.09
        # editing
        for i, pos in enumerate(to_update_pos):
            nkb_values[:, pos] += new_emb * scaling_factor - ori_emb * scaling_factor

        results = model.generate(**sample)
        g_answer_token_ids = results[0].data.tolist()[1:-1]
        g_answer_token_ids = g_answer_token_ids[0:1]
        g_answer = tokenizer.decode(g_answer_token_ids)
        print('(after editing) generated_answer_ids|', g_answer_token_ids)
        print('(after editing) generated_answer|', g_answer)

        other_sample_indices = random.sample(list(range(len(dataset))), 5)

        other_answers_new = []
        for other_sample_index in other_sample_indices:
            other_sample = dataset[other_sample_index]
            if 'labels' in other_sample:
                del other_sample['labels']
            if 'offset_mapping' in other_sample:
                del other_sample['offset_mapping']
            if 'example_id' in other_sample:
                del other_sample['example_id']
            for key in other_sample.keys():
                other_sample[key] = torch.LongTensor([other_sample[key]]).cuda()
            other_results = model.generate(**other_sample)
            other_g_answer_token_ids = other_results[0].data.tolist()[1:-1]
            other_g_answer = tokenizer.decode(other_g_answer_token_ids)
            other_answers_new.append(other_g_answer)

        # restoring
        for i, pos in enumerate(to_update_pos):
            nkb_values[:, pos] += ori_emb * scaling_factor - new_emb * scaling_factor

        other_answers_ori = []
        for other_sample_index in other_sample_indices:
            other_sample = dataset[other_sample_index]
            if 'labels' in other_sample:
                del other_sample['labels']
            if 'offset_mapping' in other_sample:
                del other_sample['offset_mapping']
            if 'example_id' in other_sample:
                del other_sample['example_id']
            for key in other_sample.keys():
                other_sample[key] = torch.LongTensor([other_sample[key]]).cuda()
            other_results = model.generate(**other_sample)
            other_g_answer_token_ids = other_results[0].data.tolist()[1:-1]
            other_g_answer = tokenizer.decode(other_g_answer_token_ids)
            other_answers_ori.append(other_g_answer)

        succ = int(g_answer == answer)
        change = (5 - len(set(other_answers_ori).intersection(set(other_answers_new)))) / 5

        return [succ, change]

    succ_cnt = 0
    change_rate = []
    # w2r_indices = w2r_indices[:10]
    for index in w2r_indices:
        print('============' * 5, f'Editing {index}-th example')
        succ, change = knowledge_updating_w2r(index)
        print(f'**** Succ: {succ}, Change: {change}')
        succ_cnt += succ
        change_rate.append(change)
    print(f'success rate: {succ_cnt/len(w2r_indices)*100:.4}% ({succ_cnt}/{len(w2r_indices)})')
    print(f'change rate: {sum(change_rate)/len(change_rate)*100:.4}%')

    # # ============== erase knowledge ==============

    # def knowledge_erasing(index):
    #     sample = dataset[index]
    #     if 'offset_mapping' in sample:
    #         del sample['offset_mapping']
    #     if 'example_id' in sample:
    #         del sample['example_id']
    #     question = tokenizer.decode(sample["input_ids"])
    #     answer_token_ids = sample["labels"][:-1]
    #     answer = tokenizer.decode(answer_token_ids)
    #     answer_len = len(sample["labels"])
    #     with open(f'tmp_data/knowledge_editing/tmp_weights.txt', 'w', encoding='utf-8') as f:
    #         print(f'{question}', file=f)
    #         print(f'{answer}', file=f)
    #         print(f'{answer_token_ids}', file=f)
    #         print(f'{answer_len}', file=f)
    #     for key in sample.keys():
    #         sample[key] = torch.LongTensor([sample[key]]).cuda()
    #     del sample['labels']
    #     results = model.generate(**sample)
    #     g_answer_token_ids = results[0].data.tolist()[1:-1]
    #     g_answer = tokenizer.decode(g_answer_token_ids)
    #     print('index|', index)
    #     print('question|', question)
    #     print('answer|', answer)
    #     print('answer_ids|', answer_token_ids, '|', answer_len)
    #     print('generated_answer_ids|', g_answer_token_ids)
    #     print('generated_answer|', g_answer)

    #     assert answer == g_answer

    #     o_embedding = model.lm_head.weight
    #     nkb_values = model.decoder.block[11].layer[2].DenseReluDense.wo_ex.weight
    #     all_prob = o_embedding.matmul(nkb_values).t().softmax(dim=1)  # n_value, n_vocab

    #     to_erase_pos = []
    #     with open(f'tmp_data/knowledge_editing/tmp_weights.txt', 'r', encoding='utf-8') as f:
    #         lines = f.readlines()
    #         weights = [float(x) for x in lines[4].split()]

    #         # # update high-weight value
    #         # weights_indices = [[float(x), i] for i, x in enumerate(lines[4].split())]
    #         # weights_indices.sort(key=lambda x:-x[0])
    #         # to_erase_pos.append(weights_indices[0][1])

    #         # update hard corresponding value
    #         for i, weight in enumerate(weights):
    #             if weight <= 1e-10:
    #                 continue
    #             topk, topk_pos = all_prob[i].topk(1)
    #             if topk_pos[0] != g_answer_token_ids[0]:
    #                 continue
    #             to_erase_pos.append(i)
    #             # print(i, weight, tokenizer.decode(topk_pos))

    #         # # update soft corresponding value
    #         # affinity = all_prob[:, g_answer_token_ids[0]]  # n_value
    #         # topk, topk_pos = affinity.topk(3072)
    #         # topk_pos = topk_pos.tolist()
    #         # for pos in topk_pos:
    #         #     if weights[pos] > 10:
    #         #         to_erase_pos.append(pos)
    #         #         break

    #     print('to_erase_pos|', len(to_erase_pos))

    #     backup_values = []
    #     # editing
    #     for i, pos in enumerate(to_erase_pos):
    #         backup_values.append(nkb_values[:, pos])
    #         # nkb_values[:, pos] = torch.zeros_like(nkb_values[:, pos])
    #         nkb_values[:, pos] -= o_embedding[g_answer_token_ids[0], :]

    #     results = model.generate(**sample)
    #     g_answer_token_ids = results[0].data.tolist()[1:-1]
    #     g_answer_token_ids = g_answer_token_ids[0:1]
    #     g_answer = tokenizer.decode(g_answer_token_ids)
    #     print('(after editing) generated_answer_ids|', g_answer_token_ids)
    #     print('(after editing) generated_answer|', g_answer)

    #     other_sample_indices = random.sample(list(range(len(dataset))), 5)

    #     other_answers_new = []
    #     for other_sample_index in other_sample_indices:
    #         other_sample = dataset[other_sample_index]
    #         if 'labels' in other_sample:
    #             del other_sample['labels']
    #         if 'offset_mapping' in other_sample:
    #             del other_sample['offset_mapping']
    #         if 'example_id' in other_sample:
    #             del other_sample['example_id']
    #         for key in other_sample.keys():
    #             other_sample[key] = torch.LongTensor([other_sample[key]]).cuda()
    #         other_results = model.generate(**other_sample)
    #         other_g_answer_token_ids = other_results[0].data.tolist()[1:-1]
    #         other_g_answer = tokenizer.decode(other_g_answer_token_ids)
    #         other_answers_new.append(other_g_answer)

    #     # restoring
    #     for i, pos in enumerate(to_erase_pos):
    #         nkb_values[:, pos] = backup_values[i]

    #     other_answers_ori = []
    #     for other_sample_index in other_sample_indices:
    #         other_sample = dataset[other_sample_index]
    #         if 'labels' in other_sample:
    #             del other_sample['labels']
    #         if 'offset_mapping' in other_sample:
    #             del other_sample['offset_mapping']
    #         if 'example_id' in other_sample:
    #             del other_sample['example_id']
    #         for key in other_sample.keys():
    #             other_sample[key] = torch.LongTensor([other_sample[key]]).cuda()
    #         other_results = model.generate(**other_sample)
    #         other_g_answer_token_ids = other_results[0].data.tolist()[1:-1]
    #         other_g_answer = tokenizer.decode(other_g_answer_token_ids)
    #         other_answers_ori.append(other_g_answer)

    #     erase = int(g_answer != answer)
    #     change = (5 - len(set(other_answers_ori).intersection(set(other_answers_new)))) / 5

    #     return [erase, change]

    # erase_cnt = 0
    # change_rate = []
    # # r2w_indices = r2w_indices[:10]
    # for index in r2w_indices:
    #     print('============' * 5, f'Erasing {index}-th example')
    #     erase, change = knowledge_erasing(index)
    #     print(f'**** Erase: {erase}, Change: {change}')
    #     erase_cnt += erase
    #     change_rate.append(change)
    # print(f'erasing rate: {erase_cnt/len(r2w_indices)*100:.4}% ({erase_cnt}/{len(w2r_indices)})')
    # print(f'change rate: {sum(change_rate)/len(change_rate)*100:.4}%')

if __name__ == "__main__":
    main()


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # left subtree, right subtree, root
        res = []
        stack = []
        curr = root
        visited = set()
        #process node once you confirm the right child has been visited
        while stack or curr:
            while curr:
                stack.append(curr)
                visited.add(curr)
                curr = curr.left
            curr = stack[len(stack) - 1]
            #apped res and wait to be popped up a level
            if not curr.right or curr.right in visited:
                curr = stack.pop()
                res.append(curr.val)
                curr = None #don't want to go right again b/c already visisted
            else:
                curr = curr.right
        return res


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='EmailAddress',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('email', models.EmailField(max_length=255)),
                ('key', models.CharField(unique=True, max_length=40)),
                ('set_at', models.DateTimeField(default=django.utils.timezone.now, help_text='When the confirmation key expiration was set')),
                ('confirmed_at', models.DateTimeField(help_text='First time this email was confirmed', null=True, blank=True)),
                ('user', models.ForeignKey(related_name='email_address_set', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
            ],
            options={
                'verbose_name_plural': 'email addresses',
            },
            bases=(models.Model,),
        ),
        migrations.AlterUniqueTogether(
            name='emailaddress',
            unique_together=set([('user', 'email')]),
        ),
    ]


import cv2
import numpy as np
import os

pixel_norm_factor = 255

def read_and_transform_img(fpath):
    '''
    Reads image and transforms it for modeling. Inverse of normalize_pred_img_array fn.
    '''
    return tf_to_th_dim_order(cv2.imread(fpath)).astype(float) / pixel_norm_factor

def normalize_pred_img_array(img):
    '''
    Convert predicted values from generated model to properly formatted image
    Largely the inverse function of read_and_transform_img
    '''
    img_with_index = img[0,:,:,:]
    out = th_to_tf_dim_order(img_with_index) * pixel_norm_factor
    out = out.clip(0,255).astype('uint8')
    return out

def tf_to_th_dim_order(img):
    '''Moves channel from index position 2 to index position 0'''
    return img.swapaxes(1, 2).swapaxes(0, 1)

def th_to_tf_dim_order(img):
    '''Moves channel from index position 0 to index position 2'''
    return img.swapaxes(0, 1).swapaxes(1, 2)

def train_val_split(raw_vids_dir, num_training_images, images_per_video):
    vid_fnames = os.listdir(raw_vids_dir)
    train_fnames = []
    val_fnames = []
    for vid_fname_with_extension in vid_fnames:
        vid_name = vid_fname_with_extension.split('.')[0]
        train_fnames += [vid_name + '_' + str(i) + '.jpg' for i in range(num_training_images)]
        val_fnames += [vid_name + '_' + str(i) + '.jpg' for i in range(num_training_images, images_per_video)]
    return train_fnames, val_fnames

def save_predicted_images(gen_model, val_fnames):
    '''
    Creates predicted versions of clear image and saves it in tmp/predicted.
    '''
    for fname in val_fnames:
        blurred_img = read_and_transform_img('./tmp/blur/' + fname)
        blurred_img = blurred_img[np.newaxis, :, :, :]  # Image number is new index 0
        img = gen_model.predict(blurred_img)
        img = normalize_pred_img_array(img)
        out_fname = './tmp/predicted/' + fname
        cv2.imwrite(out_fname, img)


'''
Program 5: Write a Program that takes angles of a triangle from user and print
whether that triangle is valid or not.
{Note: Addition of angles of triangle has to be 180 in order to consider it as a
valid one}
Input: 30 60 70
Output: The triangle with angles 30 60 & 70 is a invalid one
'''
print("Enter angles of triangle: ")
s1 = int( input("Enter angle 1: ") )
s2 = int( input("Enter angle 1: ") )
s3 = int( input("Enter angle 1: ") )

if s1+s2+s3 == 180:
        print("The triangle with angles ", s1 , s2 , ', ' , "& " , s3 ,' is  valid ')
else:
        print("The triangle with angles ", s1 , s2 , ', ' , "& " , s3 ,' is  invalid ')


N, M = map(int, input().split()) # N과 M을 입력받는다

bag = list() # 바구니 리스트를 만들어준다

for i in range(1, N+1): # 바구니 리스트를 만들어준다
    bag.append(i)

for x in range(M): # M만큼 반복한다
    i, j, k = map(int, input().split()) # i, j, k를 입력받는다

    shuffle = bag[i-1 : k-1]  # j 앞까지 바구니 리스트를 슬라이싱 한다

    for y in range(len(shuffle)): # 슬라이싱한 부분을 j 뒤로 붙혀준다
        bag.insert(y+j, shuffle.pop(0))

    del bag[i-1 : k-1] # 슬라이싱 한 부분을 제거한다

print(' '.join(map(str,bag)))


"""
    opcodes.py

    A dictionary of opcodes with the format:
        {"opcode": opcode_function()}

    NOTE:
        This implementation(the dictionary implementation) won't work because it doesn't allow te use of parameters in
        the opcodes, a better solution must be found

    - Every instruction is 2 bytes long, so in the format 0x00
    - Among the parameters there are:
        - nnn or 0x0 < 0xC(12): a 12-bit value, the lowest 12 bits of the instruction
        - n or 0x0 < 0x4(4): a 4-bit value, the lowest 4 bits of the instruction
        - x or 0x0 < 0x4(4): a 4-bit value, lower 4 bits of the higher byte of the instruction
        - y or 0x0 < 0x4(4): a 4-bit value, upper 4 bits of the lower byte of the instruction
        - kk or 0x0: an 8-bit value, the lowest 8 bits of the instruction

    - Possible instruction formats
        [COP]   [COP]   [COP]   [COP]
        [COP]   [COP]   [COP]   [ n ]
        [COP]   [COP]   [ k ]   [ k ]
        [COP]   [ n ]   [ n ]   [ n ]
        [COP]   [ x ]   [   ]   [   ]
        [COP]   [ x ]   [ y ]   [   ]
        [COP]   [ x ]   [ k ]   [ k ]
        [COP]   [ x ]   [ y ]   [ n ]
"""

# IMPORTS #########################################################################################
import random
###################################################################################################

def _00E0(chip, _):
    """
        CLS
        Clear the display
    """
    pass

def _00EE(chip, _):
    """
        RET
        Return from a subroutine
        The interpreter sets the program counter to the address at the top of the stack, then substracts 1 from the
        stack pointer
    """
    chip.registers["PC"] = chip.registers["S"][-1]
    chip.registers["SP"] -= 0x1

def _1000(chip, opcode):
    """
        JP addr
        Jump to location nnn
        Sets the program counter to nnn
    """
    # Get the lower 12 bits of the instruction
    addr = opcode & 0x000C

    chip.registers["PC"] = addr

def _2000(chip, opcode):
    """
        CALL addr
        Call subroutine at nnn
        The interpreter increments the stack pointer, then puts the current PC on the top of the stac. The PC then is
        set to nnn
    """
    # Get the lower 12 bits of the instruction
    nnn = opcode & 0x0FFF

    chip.registers["SP"] += 0x1
    chip.registers["S"][-1] = chip.registers["PC"]
    chip.registers["PC"] = nnn

def _3000(chip, opcode):
    """
        SE Vx, byte
        Skip next instruction if Vx = kk.
        The interpreter compares register Vx to kk, and if they are equal, increments the program counter by 2.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    kk = opcode & 0x00FF

    if chip.registers[Vx] == kk:
        chip.registers["PC"] += 0x2

def _4000(chip, opcode):
    """
        SNE Vx, byte
        Skip next instruction if Vx != kk.
        The interpreter compares register Vx to kk, and if they are not equal, increments the program counter by 2.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    kk = opcode & 0x00FF

    if chip.registers[Vx] != kk:
        chip.registers["PC"] += 0x2

def _5000(chip, opcode):
    """
        SE Vx, Vy
        Skip next instruction if Vx = Vy.
        The interpreter compares register Vx to register Vy, and if they are equal, increments the program counter by 2.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    if chip.registers[Vx] == chip.registers[Vy]:
        chip.registers["PC"] += 0x2

def _6000(chip, opcode):
    """
        LD Vx, byte
        Set Vx = kk.
        The interpreter puts the value kk into register Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    kk = opcode & 0x00FF
    chip.registers[Vx] = kk

def _7000(chip, opcode):
    """
        ADD Vx, byte
        Set Vx = Vx + kk.
        Adds the value kk to the value of register Vx, then stores the result in Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    kk = opcode & 0x00FF
    chip.registers[Vx] += kk

def _8000(chip, opcode):
    """
        LD Vx, Vy
        Set Vx = Vy.
        Stores the value of register Vy in register Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    chip.registers[Vx] = chip.registers[Vy]

def _8001(chip, opcode):
    """
        OR Vx, Vy
        Set Vx = Vx OR Vy.
        Performs a bitwise OR on the values of Vx and Vy, then stores the result in Vx.
        A bitwise OR compares the corrseponding bits from two values, and if either bit is 1,
        then the same bit in the result is also 1. Otherwise, it is 0.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    chip.registers[Vx] = chip.registers[Vx] | chip.registers[Vy]

def _8002(chip, opcode):
    """
        AND Vx, Vy
        Set Vx = Vx AND Vy.
        Performs a bitwise AND on the values of Vx and Vy, then stores the result in Vx.
        A bitwise AND compares the corresponding bits from two values, and if both bits are 1,
        then the same bit in the result is also 1. Otherwise, it is 0.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    chip.registers[Vx] = chip.registers[Vx] and chip.registers[Vy]

def _8003(chip, opcode):
    """
        XOR Vx, Vy
        Set Vx = Vx XOR Vy.
        Performs a bitwise exclusive OR on the values of Vx and Vy, then stores the result in Vx.
        An exclusive OR compares the corresponding bits from two values, and if the bits are not both the same,
        then the corresponding bit in the result is set to 1. Otherwise, it is 0.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    chip.registers[Vx] = (chip.registers[Vx] & ~chip.registers[Vy])|(~chip.registers[Vx] & chip.registers[Vy])

def _8004(chip, opcode):
    """
        ADD Vx, Vy
        Set Vx = Vx + Vy, set VF = carry.
        The values of Vx and Vy are added together. If the result is greater than 8 bits (i.e., > 255,) VF is set to 1,
        otherwise 0. Only the lowest 8 bits of the result are kept, and stored in Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    result = chip.registers[Vx] + chip.registers[Vy]
    value = result & 0x000F
    chip.registers[Vx] = value
    chip.registers["VF"] = ((result & 0x00F0) & 0x0010) >> 4

def _8005(chip, opcode):
    """
        SUB Vx, Vy
        Set Vx = Vx - Vy, set VF = NOT borrow.
        If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    result = chip.registers[Vx] + ~chip.registers[Vy]
    chip.registers[Vx] = result & 0xF
    chip.registers["VF"] = ((result&0x10) >> 4)

def _8006(chip, opcode):
    """
        SHR Vx {, Vy}
        Set Vx = Vx SHR 1.
        If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    chip.registers["VF"] = chip.registers[Vx] & 0x1
    chip.registers[Vx] //= 2

def _8007(chip, opcode):
    """
        SUBN Vx, Vy
        Set Vx = Vy - Vx, set VF = NOT borrow.
        If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx.
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    result = chip.registers[Vy] + ~chip.registers[Vx]
    chip.registers[Vx] = result & 0xF
    chip.registers["VF"] = ((result&0x10) >> 4)

def _800E(chip, opcode):
    """
        SHL Vx {, Vy}
        Set Vx = Vx SHL 1.
        If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    chip.registers["VF"] = chip.registers[Vx] & 0x1
    chip.registers[Vx] *= 0x2

def _9000(chip, opcode):
    """
        SNE Vx, Vy
        Skip next instruction if Vx != Vy.
        The values of Vx and Vy are compared, and if they are not equal,
        the program counter is increased by 2
    """
    x = (opcode & 0x0F00) >> 0x8
    y = (opcode & 0x00F0) >> 0x4
    Vx = f"V{str(x)}"
    Vy = f"V{str(y)}"
    if chip.registers[Vx] != chip.registers[Vy]:
        chip.registers["PC"] += 2

def _A000(chip, opcode):
    """
        LD I, addr
        Set I = nnn.
        The value of register I is set to nnn
    """
    nnn = (opcode & 0x0FFF) >> 4
    chip.registers["I"] = nnn

def _B000(chip, opcode):
    """
        JP V0, addr
        Jump to location nnn + V0.
        The program counter is set to nnn plus the value of V0.
    """
    nnn = (opcode & 0x0FFF) >> 4
    chip.registers["PC"] = nnn + chip.registers["V0"]

def _C000(chip, opcode):
    """
        RND Vx, byte
        Set Vx = random byte AND kk.
        The interpreter generates a random number from 0 to 255, which is then ANDed with the value kk.
        The results are stored in Vx. See instruction 8xy2 for more information on AND.
    """
    x = (opcode & 0x0F00) >> 0x8
    Vx = f"V{str(x)}"
    kk = opcode & 0x00FF
    rnd = random.randint(0, 255)
    chip.registers[Vx] = rnd & kk

def _D000(chip, opcode):
    """
        DRW Vx, Vy, nibble
        Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
        The interpreter reads n bytes from memory, starting at the address stored in I.
        These bytes are then displayed as sprites on screen at coordinates (Vx, Vy). Sprites are XORed onto the
        existing screen. If this causes any pixels to be erased, VF is set to 1, otherwise it is set to 0.
        If the sprite is positioned so part of it is outside the coordinates of the display,
        it wraps around to the opposite side of the screen. See instruction 8xy3 for more information on XOR,
        and section 2.4, Display, for more information on the Chip-8 screen and sprites.
    """

dictionary = {
    "00E0": _00E0,
    "00EE": _00EE,
    "1000": _1000,
    "2000": _2000,
    "3000": _3000,
    "4000": _4000,
    "5000": _5000,
    "6000": _6000,
    "7000": _7000,
    "8000": _8000,
    "8001": _8001,
    "8002": _8002,
    "8003": _8003,
    "8004": _8004,
    "8005": _8005,
    "8006": _8006,
    "8007": _8007,
    "800E": _800E,
    "9000": _9000,
    "A000": _A000,
    "B000": _B000,
    "C000": _C000,
    "D000": _D000,
}

#dictionary = {
    #"0nnn": _0nnn, cop=0n000
    #"00E0": _00E0,
    #"00EE": _00EE,
    #"1NNN": _1nnn,
    #"2NNN": _2NNN,
    #"3XKK": _3XKK,
    #"4XKK": _4XKK,
    #"5XY0": _5XY0,
    #"6XKK": _6XKK,
    #"7XKK": _7XKK,
    #"8XY0": _8XY0,
    #"8XY1": _8XY1,
    #"8XY2": _8XY2,
    #"8XY3": _8XY3,
    #"8XY4": _8XY4,
    #"8XY5": _8XY5,
    #"8XY6": _8XY6,
    #"8XY7": _8XY7,
    #"8XYE": _8XYE,
    #"9XY0": _9XY0,
    #"ANNN": _ANNN,
    #"BNNN": _BNNN,
    #"CXKK": _CXKK,
    #"DXYN": _DXYN,
    #"EX9E": _EX9E,
    #"EXA1": _EXA1,
    #"FX07": _FX07,
    #"FX0A": _FX0A,
    #"FX15": _FX15,
    #"FX18": _FX18,
    #"FX1E": _FX1E,
    #"FX29": _FX29,
    #"FX33": _FX33,
    #"FX55": _FX55,
    #"FX65": _FX65,
#}


from pathlib import Path

import yaml
from labml import monit, logger
from labml.logger import Text

def create_default_project(path: Path):
    dot_remote = path / '.remote'
    if not dot_remote.exists():
        with monit.section(f"Creating {dot_remote}"):
            dot_remote.mkdir()

    configs_file = dot_remote / 'configs.yaml'
    configs = {}
    server = {}
    if not configs_file.exists():
        with monit.section(f"Generating configurations"):
            logger.log()
            configs['name'] = input("Project name: ").strip()
            server['hostname'] = input("Hostname or public ip of the remote computer: ").strip()
            server['username'] = input("Username of the remote computer (ubuntu): ").strip()
            if server['username'] == '':
                server['username'] = 'ubuntu'
            server['private_key'] = input("Path to the private key file:\n"
                                           "(leave blank if you've setup authorized keys)\n").strip()
            if server['private_key'] == '':
                del server['private_key']

            configs['servers'] = {'default': server}
            with open(str(configs_file), 'w') as f:
                f.write(yaml.dump(configs, default_flow_style=False))

    exclude_file = dot_remote / 'exclude.txt'
    if not exclude_file.exists():
        with monit.section(f"Creating boilerplate exclude file"):
            with open(str(exclude_file), 'w') as f:
                f.write('\n'.join([
                    '.remote',
                    '.git',
                    '__pycache__',
                    '.ipynb_checkpoints',
                    'logs',
                    '.DS_Store',
                    '.*.swp',
                    '*.egg-info/',
                    '.idea'
                ]))

    logger.log(["We have created a standard configurations file and"
                " exclude list specifying files and folders that shouldn't be copied to server."
                " You can edit them at ",
                ('.remote/configs.yaml', Text.meta),
                ' and ',
                ('.remote/exclude.txt', Text.meta)])