#!/usr/bin/env python3

from os import system
import sys
import typing
import tempfile
import yaml
import json
import subprocess
import os
import enumn
import dataclasses
from dataclasses import dataclass

from arcaflow_plugin_sdk import plugin
from arcaflow_plugin_sdk import schema
from arcaflow_plugin_sdk import annotations

class Stressors(enum.Enum):
    CPU = "cpu"
    VM = "vm"
    MATRIX = "matrix"
    MQ = "mq"

@dataclass
class cpuStressorParams:
    """
    The parameters for the CPU stressor
    """
    stressor: str
    cpu_count: int
    cpu_method: typing.Optional[str] = "all"

    def to_jobfile(self) -> str:
        result = "cpu {}\n".format(self.cpu_count)
        if self.cpu_method is not None:
            result = result + "cpu-method {}\n".format(self.cpu_method)
        return result

@dataclass
class vmStressorParams:
    """
    The parameters for the vm (virtual memory) stressor
    vm: number of virtual-memory stressors
    vm_bytes: amount of vm stressor memory
    """
    stressor: str
    vm: int
    vm_bytes: str
    mmap: typing.Optional[str] = None
    mmap_bytes: typing.Optional[str] = None

    def to_jobfile(self) -> str:
        vm = "vm {}\n".format(self.vm)
        vm_bytes = "vm-bytes {}\n".format(self.vm_bytes)
        result = vm + vm_bytes
        if self.mmap is not None:
            result = result + "mmap {}\n".format(self.mmap)
        if self.mmap_bytes is not None:
            result = result + "mmap-bytes {}\n".format(self.mmap_bytes)
        return result

@dataclass
class matrixStressorParams:
    """
    This is the data structure that holds the results for the Matrix stressor.
    This stressor is a good way to exercise the CPU floating point operations
    as well as memory and processor data cache
    """
    stressor: str
    matrix: int

    def to_jobfile(self) -> str:
        matrix = "matrix {}\n".format(self.matrix)
        result = matrix
        return result

@dataclass
class mqStressorParams:
    """
    This is the data structure that holds the results for the MQ stressor
    """
    stressor: str
    mq: int

    def to_jobfile(self) -> str:
        mq = "mq {}\n".format(self.mq)
        result = mq
        return result

@dataclass
class StressNGParams:
    """
    The parameters in this schema will be passed through to the stressng
    command unchanged
    """
    timeout: str
    cleanup: bool
    items: typing.List[
        typing.Annotated[
            typing.Union[
                typing.Annotated[cpuStressorParams,
                                 annotations.discriminator_value("cpu")],
                typing.Annotated[vmStressorParams,
                                 annotations.discriminator_value("vm")],
                typing.Annotated[matrixStressorParams,
                                 annotations.discriminator_value("matrix")],
                typing.Annotated[mqStressorParams,
                                 annotations.discriminator_value("mq")]
            ],
            annotations.discriminator("stressor")
        ]
    ]
    verbose: typing.Optional[bool] = None
    metrics_brief: typing.Optional[bool] = None

    def to_jobfile(self) -> str:
        result = "timeout {}\n".format(self.timeout)
        if self.verbose is not None:
            result = result + "verbose {}\n".format(self.verbose)
        if self.metrics_brief is not None:
            result = result + "metrics-brief {}\n".format(self.metrics_brief)
        return result

@dataclass
class WorkloadParams:
    """
    This is the data structure for the input parameters of the step
    defined below
    """
    StressNGParams: StressNGParams
    cleanup: typing.Optional[str] = "True"

@dataclass
class SystemInfoOutput:
    """
    This is the data structure that holds the generic info for the
    tested system
    """
    stress_ng_version: str = dataclasses.field(
        metadata={"id": "stress-ng-version"})
    run_by: str = dataclasses.field(metadata={"id": "run-by"})
    date: str = dataclasses.field(metadata={"id": "date-yyyy-mm-dd"})
    time: str = dataclasses.field(metadata={"id": "time-hh-mm-ss"})
    epoch: int = dataclasses.field(metadata={"id": "epoch-secs"})
    hostname: str
    sysname: str
    nodename: str
    release: str
    version: str
    machine: str
    uptime: int
    totalram: int
    freeram: int
    sharedram: int
    bufferram: int
    totalswap: int
    freeswap: int
    pagesize: int
    cpus: int
    cpus_online: int = dataclasses.field(metadata={"id": "cpus-online"})
    ticks_per_second: int = dataclasses.field(
        metadata={"id": "ticks-per-second"})

system_info_output_schema = plugin.build_object_schema(SystemInfoOutput)

@dataclass
class VMOutput:
    """
    This is the data structure that holds the results for the VM stressor
    """
    stressor: str
    bogo_ops: int = dataclasses.field(metadata={"id": "bogo-ops"})
    bogo_ops_per_second_usr_sys_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-usr-sys-time"}
    )
    bogo_ops_per_second_real_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-real-time"}
    )
    wall_clock_time: float = dataclasses.field(
        metadata={"id": "wall-clock-time"})
    user_time: float = dataclasses.field(metadata={"id": "user-time"})
    system_time: float = dataclasses.field(metadata={"id": "system-time"})
    cpu_usage_per_instance: float = dataclasses.field(
        metadata={"id": "cpu-usage-per-instance"}
    )

vm_output_schema = plugin.build_object_schema(VMOutput)

@dataclass
class CPUOutput:
    """
    This is the data structure that holds the results for the CPU stressor
    """
    stressor: str
    bogo_ops: int = dataclasses.field(metadata={"id": "bogo-ops"})
    bogo_ops_per_second_usr_sys_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-usr-sys-time"}
    )
    bogo_ops_per_second_real_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-real-time"}
    )
    wall_clock_time: float = dataclasses.field(
        metadata={"id": "wall-clock-time"})
    user_time: float = dataclasses.field(metadata={"id": "user-time"})
    system_time: float = dataclasses.field(metadata={"id": "system-time"})
    cpu_usage_per_instance: float = dataclasses.field(
        metadata={"id": "cpu-usage-per-instance"}
    )

cpu_output_schema = plugin.build_object_schema(CPUOutput)

@dataclass
class MatrixOutput:
    """
    This is the data structure that holds the results for the Matrix stressor
    """
    stressor: str
    bogo_ops: int = dataclasses.field(metadata={"id": "bogo-ops"})
    bogo_ops_per_second_usr_sys_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-usr-sys-time"})
    bogo_ops_per_second_real_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-real-time"})
    wall_clock_time: float = dataclasses.field(
        metadata={"id": "wall-clock-time"})
    user_time: float = dataclasses.field(metadata={"id": "user-time"})
    system_time: float = dataclasses.field(metadata={"id": "system-time"})
    cpu_usage_per_instance: float = dataclasses.field(
        metadata={"id": "cpu-usage-per-instance"}
    )

matrix_output_schema = plugin.build_object_schema(MatrixOutput)

@dataclass
class MQOutput:
    """
    This is the data structure that holds the results for the MQ stressor
    """
    stressor: str
    bogo_ops: int = dataclasses.field(metadata={"id": "bogo-ops"})
    bogo_ops_per_second_usr_sys_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-usr-sys-time"})
    bogo_ops_per_second_real_time: float = dataclasses.field(
        metadata={"id": "bogo-ops-per-second-real-time"})
    wall_clock_time: float = dataclasses.field(
        metadata={"id": "wall-clock-time"})
    user_time: float = dataclasses.field(metadata={"id": "user-time"})
    system_time: float = dataclasses.field(metadata={"id": "system-time"})
    cpu_usage_per_instance: float = dataclasses.field(
        metadata={"id": "cpu-usage-per-instance"}
    )

mq_output_schema = plugin.build_object_schema(MQOutput)

@dataclass
class WorkloadResults:
    """
    This is the output data structure for the success case
    """
    systeminfo: SystemInfoOutput
    vminfo: typing.Optional[VMOutput] = None
    cpuinfo: typing.Optional[CPUOutput] = None
    matrixinfo: typing.Optional[MatrixOutput] = None
    mqinfo: typing.Optional[MQOutput] = None

@dataclass
class WorkloadError:
    """
    This is the output data structure for the failure case
    """
    error: str

# The following is a decorator (starting with @). We add this in front of our function to define the medadata for our step.
@plugin.step(
    id="workload",
    name="stress-ng workload",
    description="Run the stress-ng workload with the given parameters",
    outputs={"success": WorkloadResults, "error": WorkloadError},
)
def stressng_run(params: WorkloadParams) -> typing.Tuple[str, typing.Union[WorkloadResults, WorkloadError], ]:
    # def stressng_run(params: WorkloadParams) -> str:
    """
    This function is implementing the step. It needs the decorator to turn it into a step. The type hints for the params are required.

    :param params

    :return: the string identifying which output it is, as well as the output structure
    """

    print("==>> Generating temporary jobfile...")
    # generic parameters are in the StressNGParams class (e.g. the timeout)
    result = params.StressNGParams.to_jobfile()
    # now we need to iterate of the list of items
    for item in params.StressNGParams.items:
        result = result + item.to_jobfile()

    stressng_jobfile = tempfile.mkstemp()
    stressng_outfile = tempfile.mkstemp()

    # write the temporary jobfile
    with open(stressng_jobfile[1], 'w') as jobfile:
        jobfile.write(result)
    stressng_command = ["/usr/bin/stress-ng", "-j",
                        stressng_jobfile[1], "--metrics", "-Y", stressng_outfile[1]]

    print("==>> Running stress-ng with the temporary jobfile...")
    try:
        print(subprocess.check_output(stressng_command,
              cwd="/tmp", text=True, stderr=subprocess.STDOUT))
    except subprocess.CalledProcessError as error:
        return "error", WorkloadError(f"{error.cmd[0]} failed with return code {error.returncode}:\n{error.output}")

    with open(stressng_outfile[1], 'r') as output:
        try:
            stressng_yaml = yaml.safe_load(output)
        except yaml.YAMLError as e:
            print(e)

    system_info = (stressng_yaml['system-info'])
    metrics = (stressng_yaml['metrics'])

    # allocate all stressor information with None in case they don't get called
    cpuinfo_un = None
    vminfo_un = None
    matrixinfo_un = None
    mqinfo_un = None

    system_un = system_info_output_schema.unserialize(system_info)
    for metric in metrics:
        if metric['stressor'] == "cpu":
            cpuinfo_un = cpu_output_schema.unserialize(metric)
        if metric['stressor'] == "vm":
            vminfo_un = vm_output_schema.unserialize(metric)
        if metric['stressor'] == "matrix":
            matrixinfo_un = matrix_output_schema.unserialize(metric)
        if metric['stressor'] == "mq":
            mqinfo_un = mq_output_schema.unserialize(metric)

    print("==>> Workload run complete!")
    os.close(stressng_jobfile[0])
    os.close(stressng_outfile[0])

    # TODO: if cleanup is set to true, remove the temporary files
    if params.StressNGParams.cleanup == True:
        print("==>> Cleaning up operation files...")
        os.remove(stressng_jobfile[1])
        # os.remove(stressng_outfile)

    return "success", WorkloadResults(system_un, vminfo_un, cpuinfo_un, matrixinfo_un, mqinfo_un)

if __name__ == "__main__":
    sys.exit(
        plugin.run(
            plugin.build_schema(
                stressng_run,
            )
        )
    )


import tensorflow as tf
import cv2
import matplotlib.pyplot as plt
import numpy as np

import os
import tarfile
import random
import glob
import shutil

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Layer, Conv2D, Dense, MaxPooling2D, Input, Flatten

# Create Paths for positive, negative and Anchor Images
POSITIVE_PATH = os.path.join("data", "positive")
NEGATIVE_PATH = os.path.join("data", "negative")
ANCHOR_PATH = os.path.join("data", "anchor")

# Create directories for positive and anchor images
if os.path.isdir(POSITIVE_PATH) is False:
    os.makedirs(POSITIVE_PATH)
    os.makedirs(ANCHOR_PATH)

# download link for lfw dataset
# download "All images as gzipped tar file"
# url = http://vis-www.cs.umass.edu/lfw/#download

# Move the lfw.tgz file to the project directory

# extracting the lfw tar gz file
if os.path.isdir('lfw') is False:
    file = tarfile.open('lfw.tgz')
    file.extractall()
    file.close()

# Create negative directory
if os.path.isdir(NEGATIVE_PATH) is False:
    os.makedirs(NEGATIVE_PATH)
    # Moving images from lfw folder to negative folder
    for directory in os.listdir('lfw'):
        for file in os.listdir(os.path.join('lfw', directory)):
            EX_PATH = os.path.join('lfw', directory, file)
            NEW_PATH = os.path.join(NEGATIVE_PATH, file)
            os.replace(EX_PATH, NEW_PATH)

# Accessing the Web cam
cap = cv2.VideoCapture(0)

i = j = 0
while cap.isOpened():
    ret, frame = cap.read()

    # creating 250*250 frames
    frame = frame[120:370, 200:450, :]

    # Press a to collect anchor images
    # Collect anchors -- make sure to collect atleast 200 anchor images
    if cv2.waitKey(1) & 0xFF == 97:
        # create the unique file path
        imgname = os.path.join(ANCHOR_PATH, f'anchor_img{j}.jpg')
        cv2.imwrite(imgname, frame)
        j = j + 1

    # Press p to collect positive images
    # Collect positives -- make sure to collect atleast 200 positive images
    if cv2.waitKey(1) & 0xFF == 112:
        # create the unique file path
        imgname = os.path.join(POSITIVE_PATH, f'positive_img{i}.jpg')
        cv2.imwrite(imgname, frame)
        i = i + 1

    cv2.imshow('Image Collection', frame)

    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

# Taking 200 images from each directory
anchor = tf.data.Dataset.list_files(ANCHOR_PATH + '\*.jpg').take(200)
positive = tf.data.Dataset.list_files(POSITIVE_PATH + '\*.jpg').take(200)
negative = tf.data.Dataset.list_files(NEGATIVE_PATH + '\*.jpg').take(200)

# Preprocessing the data
def preprocess(file_path):
    # Read the images
    read_img = tf.io.read_file(file_path)
    # Convert images to tensors
    img = tf.io.decode_jpeg(read_img)
    # Resizing the images to 105 * 105
    img = tf.image.resize(img, (105, 105))
    # Normalizing the images
    img = img / 255.0
    return img

# Creating training data
positives = tf.data.Dataset.zip((anchor, positive, tf.data.Dataset.from_tensor_slices(tf.ones(len(anchor)))))
negatives = tf.data.Dataset.zip((anchor, negative, tf.data.Dataset.from_tensor_slices(tf.zeros(len(anchor)))))
data = positives.concatenate(negatives)

# Preprocessing training data
def preprocess_data(input_img, val_img, label):
    return (preprocess(input_img), preprocess(val_img), label)

# Mapping the data
data = data.map(preprocess_data)
# Shuffling the data
data = data.shuffle(buffer_size=1024)
# Creating the batch of 16
data = data.batch(16)

# Create the model
def create_model():
    inp = Input(shape=(105, 105, 3), name='input_image')
    conv1 = Conv2D(64, (10, 10), activation='relu')(inp)
    max1 = MaxPooling2D((2, 2), padding='same')(conv1)
    conv2 = Conv2D(128, (7, 7), activation='relu')(max1)
    max2 = MaxPooling2D((2, 2), padding='same')(conv2)
    conv3 = Conv2D(128, (4, 4), activation='relu')(max2)
    max3 = MaxPooling2D((2, 2), padding='same')(conv3)
    conv4 = Conv2D(256, (4, 4), activation='relu')(max3)
    flat1 = Flatten()(conv4)
    dense1 = Dense(4096, activation='sigmoid')(flat1)

    return Model(inputs=[inp], outputs=[dense1], name='model')

model = create_model()

# creating L1Dist class to calculate the difference value between two images
class L1Distance(Layer):
    def __init__(self, **kwargs):
        super().__init__()

    def call(self, input_value, valid_value):
        return tf.math.abs(input_value - valid_value)

def create_siamese_model():
    input_image = Input(name='input_image', shape=(105, 105, 3))
    validation_image = Input(name='validation_image', shape=(105, 105, 3))

    siamese_layer = L1Distance()
    distances = siamese_layer(model(input_image), model(validation_image))

    classifier = Dense(1, activation='sigmoid')(distances)

    return Model(inputs=[input_image, validation_image], outputs=classifier, name='siameseNetwork')

siamese_model = create_siamese_model()

binary_loss = tf.losses.BinaryCrossentropy()
optimizer = tf.optimizers.Adam(1e-4)

# Training the model
def train(data, epochs):
    for epoch in range(1, epochs+1):
        print(f'Epoch {epoch}/{epochs}')
        progbar = tf.keras.utils.Progbar(len(data))

        for idx, batch in enumerate(data):
            with tf.GradientTape() as tape:
                x = batch[:2]
                y = batch[2]

                y_pred = siamese_model(x, training=True)
                loss = binary_loss(y, y_pred)
            progbar.update(idx + 1)

            grad = tape.gradient(loss, siamese_model.trainable_variables)
            optimizer.apply_gradients(zip(grad, siamese_model.trainable_variables))

if os.path.isfile('siamesemodel.h5') is False:
    train(data, epochs=50)
    siamese_model.save('siamesemodel.h5')

final_model = tf.keras.models.load_model('siamesemodel.h5', custom_objects={'L1Distance':L1Distance, 'BinaryCrossentropy':tf.losses.BinaryCrossentropy()})

# Creating the path for validation and input images
VAL_PATH = os.path.join('app_data', 'verification_image')
INP_PATH = os.path.join('app_data', 'input_image')

# Creating validation and input directories
if os.path.isdir(VAL_PATH) is False:
    os.makedirs(VAL_PATH)
    os.makedirs(INP_PATH)
    # copying 50 random images from anchor folder to validation folder
    for c in random.sample(glob.glob(os.path.join(ANCHOR_PATH, 'anchor_img*')), 50):
        shutil.copy(c, VAL_PATH)

# Verification function
def verify(model, detection_threshold, verification_threshold):
    results = []
    for image in os.listdir(os.path.join(VAL_PATH)):
        input_img = preprocess(os.path.join(INP_PATH, 'input_image.jpg'))
        validation_img = preprocess(os.path.join('app_data', 'verification_image', image))

        result = model.predict(list(np.expand_dims([input_img, validation_img], axis=1)))
        results.append(result)

    detection = np.sum(np.array(results) > detection_threshold)
    verification = detection / len(os.listdir(os.path.join('app_data', 'verification_image')))
    verified = verification > verification_threshold

    return verified

cap = cv2.VideoCapture(0)
while cap.isOpened():
    ret, frame = cap.read()

    frame = frame[120:370, 200:450, :]

    cv2.imshow('Verification', frame)

    # Press V to verify
    if cv2.waitKey(10) & 0xFF == 118:
        cv2.imwrite(os.path.join('app_data', 'input_image', 'input_image.jpg'), frame)

        verified = verify(final_model, 0.5, 0.5)
        print(verified)

    # Press escape key to escape
    if cv2.waitKey(10) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()


#!/usr/bin/env python
# coding: utf-8

r"""Tests for the core.files.py module"""

from os import remove
from os.path import isfile

import pytest

from corelib.core.files import path_from_file, p_, is_binary

def test_happy_path():
    r"""The file_origin of path_from_file exists"""
    new_f = path_from_file(__file__, "tmp.txt")
    with open(new_f, "w") as nf:
        nf.write("\n")
    assert isfile(new_f) is True
    remove(new_f)
    assert isfile(new_f) is False

def test_happy_path_shortcut():
    r"""Same test, using the shortcut notation"""
    new_f = p_(__file__, "tmp.txt")
    with open(new_f, "w") as nf:
        nf.write("\n")
    assert isfile(new_f) is True
    remove(new_f)
    assert isfile(new_f) is False

def test_wrong_file():
    r"""The file_origin of path_from_file does not exist"""
    with pytest.raises(ValueError):
        _ = path_from_file("C:/unknown_file.txt", "tmp.txt")

def test_is_binary():
    r"""Test if the files are binary or ASCII"""
    assert is_binary(path_from_file(__file__,
                                    "files/stl/board_binary.stl")) is True
    assert is_binary(path_from_file(__file__,
                                    "files/stl/board.stl")) is False


import csv
import argparse

def loadData(path):
    data = []
    f = open(path, "r", encoding = "utf-8")
    for row in csv.reader(f):
        for i in range(len(row)):
            row[i] = row[i].strip(".?")
            try:
                row[i] = eval(row[i])
            except NameError:
                pass
        data += [row]
    f.close()
    return data

def saveData(path, data):
    f = open(path, "w", encoding = "utf-8", newline = "")
    csv.writer(f).writerows(data)
    f.close()

def zScoreNorm(data, prop):
    if prop not in data[0]:
        return data
    pos = data[0].index(prop)

    column = [data[i][pos] for i in range(1, len(data))]
    mean = sum(column) / len(column)
    deviation = (sum([(column[i] - mean) ** 2 for i in range(len(column))]) / len(column)) ** (1/2)

    f = lambda x: (x - mean) / deviation
    column = list(map(f, column))
    for i in range(1, len(data)):
        data[i][pos] = column[i - 1]

    return data

def removeOutlier(data, prop, threshold):
    if prop not in data[0]:
        return data
    pos = data[0].index(prop)

    data[1:] = [row for row in data[1:] if row[pos] <= threshold and row[pos] >= -threshold]
    return data

def main():
    parser = argparse.ArgumentParser(description = "Data preprocessing")
    parser.add_argument("--input", help = "Input file path", required = True)
    parser.add_argument("--output", help = "Output file path", required = True)
    parser.add_argument("--task", help = "Preprocessing task", required = True)
    parser.add_argument("--prop", help = "Property", required = True, nargs = "*")
    parser.add_argument("--threshold", help = "Threshold for removing outlier")
    args = parser.parse_args()

    data = loadData(args.input)
    if args.task == "zScoreNorm":
        for prop in args.prop:
            data = zScoreNorm(data, prop)
    elif args.task == "removeOutlier":
        for prop in args.prop:
            data = removeOutlier(data, prop, eval(args.threshold))
    saveData(args.output, data)

main()


"""
    Kids Hack Labs
    Fall 2020 - Senior
    Week 04: Application lifetime
    In-class activity 1
"""
#Suggested answer as comments
#Steps 1 and 2 involve external activites
#such as creating folders and files

#Step 3: module imports
import sys
import pygame

#Step 4: cleanup function
def cleanup():
    pygame.quit()
    sys.exit()

#Step 5: application entry point
def main():
    #Steps 5.1 through 5.5 -> Initialization step
    pygame.init()
    screen = pygame.display.set_mode((600, 600), pygame.RESIZABLE)
    new_size = screen.get_size()
    pygame.display.set_caption("Week 03 code")
    is_running = True

    #Steps 5.6 and substeps down to 5.6.4
    #Main Loop
    while is_running:
        #Event Processing stage
        for evt in pygame.event.get():
            if evt.type == pygame.QUIT:
                is_running = False
            if evt.type == pygame.VIDEORESIZE:
                new_size = evt.size
        #Event processing stage end

        #Update stage
        if new_size != screen.get_size():
            screen = pygame.display.set_mode(new_size, pygame.RESIZABLE)
        #Update stage end

        #Render stage
        screen.fill((63, 127, 255))
        pygame.display.flip()
        #Render stage end

    #Step 5.6.5 actually has to be called outside the while loop
    #De-initialization (cleanup) stage
    cleanup()
    #Cleanup stage end

#Step 5.7 and substeps: Driver Code
if __name__ == "__main__":
    main()

"""
    Obs.: The code was simplified, and it is just hard-coded so that
          students can get a starting point over which to expand. The
          details of the code will be discussed in Week 04. Students
          are also encouraged to re-code the example above as their
          'homework', so as to familiarize themselves with the steps.
"""


"""
Dataset loader for CIFAR100
"""
from copy import deepcopy

import torch
import numpy as np

from torch.utils.data import WeightedRandomSampler
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

def wif(id):
    """
    Used to fix randomization bug for pytorch dataloader + numpy
    Code from https://github.com/pytorch/pytorch/issues/5059
    """
    process_seed = torch.initial_seed()
    # Back out the base_seed so we can use all the bits.
    base_seed = process_seed - id
    ss = np.random.SeedSequence([id, base_seed])
    # More than 128 bits (4 32-bit words) would be overkill.
    np.random.seed(ss.generate_state(4))

class MultiTaskDataHandler():
    """
    Template class for a Multi-task data handler
    """
    def __init__(self) -> None:
        self.trainset: Dataset
        self.testset: Dataset

    def get_data_loader(self,
                        batch_size: int,
                        workers: int,
                        train: bool = True) -> DataLoader:
        """
        Get the Dataloader for the entire dataset
        Args:
            - shuf       : Shuffle
            - wtd_loss   : Dataloader also has wts along with targets
            - wtd_sampler: Sample data from dataloader with weights
                         according to self.tr_wts
        """
        data = self.trainset if train else self.testset
        loader = DataLoader(
            data, batch_size=batch_size, shuffle=train,
            num_workers=workers, pin_memory=True,
            worker_init_fn=wif)

        return loader

    def get_task_data_loader(self,
                             task: int,
                             batch_size: int,
                             workers: int,
                             train: bool = False) -> DataLoader:
        """
        Get Dataloader for a specific task
        """
        if train:
            task_set = deepcopy(self.trainset)
        else:
            task_set = deepcopy(self.testset)

        task_ind = [task == i[0] for i in task_set.targets]

        task_set.data = task_set.data[task_ind]
        task_set.targets = np.array(task_set.targets)[task_ind, :]
        task_set.targets = [(lab[0], lab[1]) for lab in task_set.targets]

        loader = DataLoader(
            task_set, batch_size=batch_size,
            shuffle=False, num_workers=workers, pin_memory=True,
            worker_init_fn=wif)

        return loader


from asciimatics.renderers import FigletText, Rainbow
from asciimatics.scene import Scene
from asciimatics.screen import Screen
from asciimatics.exceptions import ResizeScreenError
from asciimatics.effects import Cycle, Stars, RandomNoise
from asciimatics import event
import sys

def present_puzzle(length=230):
    def demo(screen):
        effects = [
            RandomNoise(screen,
                        signal=Rainbow(screen,FigletText("8 Puzzle")))
        ]
        screen.play([Scene(effects, length)], stop_on_resize=True,repeat=False)
        screen.close()
    Screen.wrapper(demo)

def present_god_mode(length=100,stars=500):
    def present(screen):
        effects = [
            Cycle(
                screen,
                FigletText("GOD MODE", font='doh'),
                int(screen.height / 2 - 13)),
            Cycle(
                screen,
                FigletText("ENGAGED", font='doom'),
                int(screen.height / 2 + 6)),
            Stars(screen, stars)
        ]
        screen.play([Scene(effects, length)],repeat=False)
        screen.close()

    Screen.wrapper(present)


"""Various repeated actions"""

from emulator.emulator import Emulator

def dialog(emu: Emulator, frames: int) -> None:

    """Skip dialogue at the highest speed possible"""

    emu.add("B", frames - 1, xpos=244, ypos=49)
    emu.add("", 1)

def enter_name(emu: Emulator, xpos: int, ypos: int) -> None:

    """Enter name in intro"""

    emu.add("", 1, xpos, ypos)
    emu.add("", 1, 20, 180)
    emu.add("", 2)
    emu.add("", 1, 37, 34)
    emu.add("A", 1)

def enter_calendar(emu: Emulator) -> None:

    """Enter calendar in intro"""

    emu.add("", 1, 81, 81)
    emu.add("", 1)
    emu.add("", 1, 78, 47)
    emu.add("", 1)
    emu.add("", 1, 7, 184)
    emu.add("", 2)
    emu.add("", 1, 31, 28)
    emu.add("A", 1)

def new_game(emu: Emulator):

    """Get pas the main menu"""
    emu.add("", 440)
    emu.add("", 1, xpos=100, ypos=100)
    emu.add("", 120)
    emu.add("", 1, xpos=100, ypos=100)

def talk_to_thomas(emu: Emulator) -> None:

    """Skip the conversation with Thomas"""

    emu.add("BR", 10)
    emu.add("BD", 100)
    dialog(emu, 300)
    emu.add("D", 1)
    emu.add("A", 1)
    dialog(emu, 500)

def intro(emu: Emulator) -> None:

    """Automate the intro"""

    new_game(emu)
    dialog(emu, 230)
    enter_name(emu, 114, 47)  # "E is for Exadrid"
    dialog(emu, 160)
    enter_calendar(emu)
    dialog(emu, 180)
    enter_name(emu, 48, 63)  # "F is for Farm"
    dialog(emu, 165)
    enter_name(emu, 98, 49)  # "D is for Dog"
    dialog(emu, 165)
    enter_name(emu, 84, 49)  # "C is for Cat"
    dialog(emu, 16070)
    talk_to_thomas(emu)


def is_palindrome(WORD):
    for word_idx in range(word_len):
        if WORD[word_idx] != WORD[N-word_idx-1]: return False
    return True

for _ in range(10):
    N = int(input())
    LIST = [[x for x in input()] for i in range(8)]
    LIST_reverse = list(map(list, zip(*LIST)))
    SUM, word_len = 0, N//2 if N%2==0 else N//2+1
    for col_idx in range(8):
        for idx in range(8-N+1):
            if is_palindrome(LIST[col_idx][idx:idx+N]): SUM += 1
        for idx in range(8-N+1):
            if is_palindrome(LIST_reverse[col_idx][idx:idx+N]): SUM += 1
    print("#{} {}".format(_+1, SUM))


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

def isNum(num):
    n = 0
    while num !=0:
        q = num %2
        num = int(num/2)
        if q == 1:
            n +=1
    if isNumber(n):
        return True
    else:
        return False

n = input()
list = n.split(" ")
number = list[0]

for i in range(1,int(number)+1):
    lower = int(list[i*2-1])
    upper = int(list[i*2])
    numOfAnswer = 0
    for j in range(lower,upper+1):
        if isNum(j):
            numOfAnswer +=1
    print(numOfAnswer)


import time

from selenium import webdriver
validateText = "Options3"
driver = webdriver.Chrome(executable_path="C:\\selenium\chromedriver.exe")
driver.get("https://rahulshettyacademy.com/AutomationPractice/")

driver.find_element_by_css_selector("#name").send_keys("Options3")
driver.find_element_by_id("alertbtn").click()
alert = driver.switch_to.alert
alertText = alert.text

assert validateText in alertText
alert.accept()

driver.find_element_by_css_selector("#name").send_keys("Options3")
driver.find_element_by_id("confirmbtn").click()
alert_confirm = driver.switch_to.alert
alertText_confirm = alert_confirm.text
print(alertText_confirm)

time.sleep(5)
#Sassert validateText in alertText
#assert alert_confirm.dismiss()
try:
    alert_confirm.accept()
    print("confirm")
except:
    print("confirm didn't work")
    alert_confirm.dismiss()
    print("Confirmation was cancelled")


import pandas as pd
import re

# We open the database and sort by population (biggest population first) so when we find 2 cities/country with the same name we favor the biggest one
file = pd.read_csv("database/geonames-all-cities-with-a-population-1000.csv", on_bad_lines="skip", delimiter=";")

# We remove all the data that we wont use and order it from the biggest population to the lowest
# We do that in case we first 2 cities with the same name
file = file[["Name","ASCII Name", "Country Code", "Country name EN", "Population", "Timezone"]]
file = file.sort_values(by=["Population"], ascending=False)

# This function allows us to find a match between the location entered by the user and a real location
# We first split the location and try each "sub value" from the split (usually people enter the location from the most precise to the most unprecise ex : Montréal, Quebec, Canada)
# If none of thoses "sub value" works we take the first one (most likely the city name) and we try combination without the first element, without the last etc.. untill we find a match
# We need to be carefull to not destroy the location name to much because we could find a match that isnt relevent
# For exemple : location = "San Francisco Bay Area/CA/USA"
# We cant try all the words in "San Fransisco Bay Area" because "San" in  a city in Mexico
def findMatch(location):

    clean_location = re.split(',|:|/', location)

    for subLocation in clean_location :
        subLocation = subLocation.strip()
        # print("Trying sublocation : " + subLocation.title())
        if (subLocation.upper() in file.values):
            return(subLocation.upper())
        elif (subLocation.title() in file.values):
            # print("Returning sublocation : " + subLocation.title())
            return (subLocation.title())
        # else :
            # print("Not sublocation : " + subLocation)

    splitLocation = clean_location[0].split(" ")

    if (len(splitLocation) == 1):
        # print("Lost in preprocessing ------------------------------") #This print is for debug purposes
        return "Lost in preprocessing"
    else :
        withoutLastElement = " ".join(splitLocation[:-1])
        # print("Trying without last : " + withoutLastElement)

        withLastReturn = findMatch(withoutLastElement)

        if (withLastReturn == "Lost in preprocessing"):

            withoutFirstElement = " ".join(splitLocation[1:])
            # print("Trying without first : " + withoutFirstElement)

            return (findMatch(withoutFirstElement))
        else :

            return(withLastReturn)

# After finding a country we want to have the corresponding UTC offset
def findTimezone(timezone):

    file = pd.read_csv("database/timezones.csv")

    if (timezone in file.values):
        filtered_df = file[file["timezone"] == timezone]
        return int((filtered_df["offset"].iloc[0])/3600) # The offset in the database is in second, we prefer to save it in second
    else :
        return ("no data")

# This function trys to find a country and a UTC offset for a location entered by a user.
def findCountry(location):

    if (location == "No Data" or type(location) != str):
        return ["no data", "no data"]

    match = findMatch(location)

    # Check if the match is a country
    if (match in file["Country name EN"].values):
        filtered_df = file[file["Country name EN"] == match]

        timezoneArea = filtered_df["Timezone"].iloc[0]
        timezone = findTimezone(timezoneArea)

        return [match, timezone]

    if (match in file["Country Code"].values):
        filtered_df = file[file["Country Code"] == match]
        country = filtered_df["Country name EN"].iloc[0]

        timezoneArea = filtered_df["Timezone"].iloc[0]
        timezone = findTimezone(timezoneArea)

        return [country, timezone]

    elif (match in file["ASCII Name"].values):
        filtered_df = file[file["ASCII Name"] == match]
        country = filtered_df["Country name EN"].iloc[0]

        timezoneArea = filtered_df["Timezone"].iloc[0]
        timezone = findTimezone(timezoneArea)

        return [country, timezone]

    elif (match in file["Name"].values) :
        filtered_df = file[file["Name"] == match]
        country = filtered_df["Country name EN"].iloc[0]

        timezoneArea = filtered_df["Timezone"].iloc[0]
        timezone = findTimezone(timezoneArea)

        return [country, timezone]

    # If we are not able to find a location we suppose our alogrithm isnt good enough
    # Some user enter random words but we cant make de difference between random words and the mistake from our algorithm ( random words arent that frequent anyway)
    else :
        return ["no data", "no data"]

# Return a world region corresponding to the country
def getRegion(country) :
    file1 = pd.read_csv("database/countryToRegion.csv", on_bad_lines="skip", delimiter=";", encoding="latin-1")

    if (country in file1.values):
        filtered_df = file1[file1["country"] == country]
        region = filtered_df["region"].iloc[0]
        return region

    else :
        return "no data"

# This function get a location and the UTC offset for the said location
def getLocationFromUser() :

    #Open database that we are gonna use
    df = pd.read_csv('tempData/GithubAPIData.csv')

    # Fill the empty location with No data
    df = df.fillna("no data")

    locationArray = df[["location"]].to_numpy()

    matchArray = []
    timezoneArray = []

    for item in locationArray :
        tempArray = findCountry(item[0])

        # Save the data to the corresponding type of data
        matchArray.append(tempArray[0])
        timezoneArray.append(tempArray[1])

    # We return an other array to match a country to a region
    regionArray = []

    for country in matchArray:
        regionArray.append(getRegion(country))

    # Adding the data to the dataframe
    subDf = df[["login", "contributions", "location"]]
    subDf.insert(len(subDf.columns), "country", matchArray)
    # subDf.insert(len(subDf.columns), "timezone", timezoneArray)

    # Displaying stats from the data used
    print(subDf)
    print("out of ", len(matchArray) ,"-> No data : ", matchArray.count("no data") ,"; Lost in preprocessing : ", matchArray.count("Lost in preprocessing"))

    # Saving the temporary data used form debug purposes
    subDf.to_csv("tempData/GetLocationFromUserData.csv")

    #  Adding data to the final dataframe
    Finaldf = pd.read_csv("database/FinalData.csv")
    # Finaldf.insert(len(Finaldf.columns), "LocationFromUser", matchArray)
    Finaldf.insert(len(Finaldf.columns), "regionFromUser", regionArray)
    Finaldf.to_csv("database/FinalData.csv")

# Start the main function
if __name__ == "__main__" :
    getLocationFromUser()

# value = findMatch("Edinburgh, Scotland")
# print(value)

#     country = findCountry("Cyprus")
#     print(country)


import os
import xml.etree.ElementTree as ET
from pathlib import Path

dir_path = 'D:/faster-rcnn-pytorch-master/VOCdevkit/VOC2007/Annotations'

listdir = os.listdir(dir_path)
for file in listdir:
    if file.endswith('.xml'):
        file_path = os.path.join(dir_path, file)
        tree = ET.parse(file_path)
        root = tree.getroot()
        image_path = root.find("path").text
        voc_file_name = Path(file).stem
        image_file_name, image_ext = os.path.splitext(image_path)
        new_image_path = os.path.join(dir_path, voc_file_name + image_ext)
        os.rename(image_path, new_image_path)
        print(image_file_name)
        print(voc_file_name)


import unittest
from unittest.mock import patch

from hbcbot import commands

class TestAbv(unittest.TestCase):
    def test_pastryboi(self):
        abv = commands._abv(1.135, 1.045)
        abv = round(abv, 1)
        self.assertEqual(abv, 14.1)

class TestBrix(unittest.TestCase):
    def test_brix(self):
        brix = commands._brix_to_og(31.2)
        brix = round(brix, 3)
        self.assertEqual(brix, 1.135)

class TestHydrometer(unittest.TestCase):
    def test_hyadj(self):
        ag = commands._hydro_temp_adj(1.131, 90, 60)
        ag = round(ag, 3)
        self.assertEqual(ag, 1.135)

class TestUntappd(unittest.TestCase):
    @patch("hbcbot.commands.requests.get")
    @patch.dict(
        "os.environ",
        {
            "UNTAPPD_CLIENT_ID": "mock_client_id",
            "UNTAPPD_CLIENT_SECRET": "mock_client_secret",
        },
    )
    def test_untappd_with_valid_input(self, mock_get):
        # Mock the response from the API
        expected_data = {"response": {"beers": {"items": [{"beer": {"bid": "12345"}}]}}}
        mock_get.return_value.status_code = 200
        mock_get.return_value.json.return_value = expected_data

        # Test the function with valid input
        args = "Heineken"
        expected_output = "https://untappd.com/beer/12345"
        self.assertEqual(commands.untappd(args), expected_output)

    @patch("hbcbot.commands.requests.get")
    @patch.dict(
        "os.environ",
        {
            "UNTAPPD_CLIENT_ID": "mock_client_id",
            "UNTAPPD_CLIENT_SECRET": "mock_client_secret",
        },
    )
    def test_untappd_with_invalid_input(self, mock_get):
        # Mock the response from the API
        expected_data = {}
        mock_get.return_value.status_code = 200
        mock_get.return_value.json.return_value = expected_data

        # Test the function with invalid input
        args = "Invalid Beer Name"
        expected_output = "Type in beer name accurately"
        self.assertEqual(commands.untappd(args), expected_output)

    @patch.dict(
        "os.environ",
        {
            "UNTAPPD_CLIENT_ID": "mock_client_id",
            "UNTAPPD_CLIENT_SECRET": "mock_client_secret",
        },
    )
    def test_untappd_api_call(self):
        # Test the API call made by the function
        args = "Heineken"
        expected_api_url = "https://api.untappd.com/v4/search/beer?q=Heineken&client_id=mock_client_id&client_secret=mock_client_secret"
        with patch("hbcbot.commands.requests.get") as mock_get:
            commands.untappd(args)
            mock_get.assert_called_with(expected_api_url)

    @patch.dict(
        "os.environ",
        {
            "UNTAPPD_CLIENT_ID": "mock_client_id",
            "UNTAPPD_CLIENT_SECRET": "mock_client_secret",
        },
    )
    def test_no_args(self):
        expected = "Usage: .untappd <beer name>"
        result = untappd(None)
        self.assertEqual(result, expected)


# ;==========================================
# ; Title:  SensorPi
# ; Author: Mingzhang Deng
# ; Date:   26 APR 2023
# ;==========================================

#This is a simple front end program
#The purpose of this program is to display the sensor data output

#This file could be further developed to be a front end control panel

from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
import utils
import datetime
from pprint import pprint

data = utils.loadSensorData("./logtest.txt")

def plotData(sensorID, parameter):
    dataframeDict = {parameter:[],
                    "TIME":[]}
    #Select Pressure
    for i in data["18"].keys():
        para = data["18"][i].get(parameter)
        if para is not None:
            dataframeDict[parameter].append(float(para))
            time = datetime.datetime.fromtimestamp(float(i))
            dataframeDict['TIME'].append(time)

    df = pd.DataFrame(data=dataframeDict)
    return df

#replace with Sensor Data

if __name__ == '__main__':
    # pprint(data)
    app = Dash(__name__)
    app.layout = html.Div([
        html.H2(children='Temperature', style={'textAlign':'center'}),
        dcc.Graph(figure=px.line(plotData("18","TEMPERATURE"),x='TIME', y='TEMPERATURE')),
        html.H2(children='PRESSURE', style={'textAlign':'center'}),
        dcc.Graph(figure=px.line(plotData("18","PRESSURE"),x='TIME', y='PRESSURE')),
        html.H2(children='PIR', style={'textAlign':'center'}),
        dcc.Graph(figure=px.line(plotData("18","PIR"),x='TIME', y='PIR'))
    ])

    app.run_server(debug=True)


class TicTacToeGame:
    def __init__(self):
        self.board = [" " for _ in range(9)]
        self.current_player = "O"
        self.ai_player = "X"  # Set AI player to "X"
        self.human_player = "O"  # Set human player to "O"
        self.winning_combinations = [
            [0, 1, 2],  # rows
            [3, 4, 5],  # rows
            [6, 7, 8],  # rows
            [0, 3, 6],  # cols
            [1, 4, 7],  # cols
            [2, 5, 8],  # cols
            [0, 4, 8],  # diagonals
            [2, 4, 6],  # diagonals
        ]
        self.winning_combination = []

    def make_move(self, position):
        if self.board[position] == " ":
            self.board[position] = self.current_player

    def change_player(self):
        self.current_player = (
            self.ai_player
            if self.current_player == self.human_player
            else self.human_player
        )

    def check_winner(self):
        for combination in self.winning_combinations:
            if all(self.board[i] == self.ai_player for i in combination):
                self.winning_combination = combination  # Save the winning combination
                return "AI"  # Indicate AI wins
            elif all(self.board[i] == self.human_player for i in combination):
                self.winning_combination = combination  # Save the winning combination
                return "Human"  # Indicate Human wins
        return None  # No winner yet

    def is_draw(self):
        return " " not in self.board

    def get_empty_cells(self):
        return [i for i, cell in enumerate(self.board) if cell == " "]

    def get_current_player(self):
        return self.current_player

    def get_winning_combination(self):
        return self.winning_combination


# -*- coding:utf-8 -*-
# Author: lamborghini1993
# Date: 2021-01-05 17:12:18
"""
https://leetcode-cn.com/problems/positions-of-large-groups/
"""

from typing import List

class Solution:
    def largeGroupPositions(self, s: str) -> List[List[int]]:
        tc, cnt, result = "", 0, []
        for i, c in enumerate(s):
            if c == tc:
                cnt += 1
                continue
            if cnt > 2:
                result.append([i - cnt, i - 1])
            tc, cnt = c, 1
        if cnt > 2:
            result.append([i - cnt + 1, i])
        return result

func = Solution().largeGroupPositions
print(func("aaa"))
print(func("abbxxxxzzy"))
print(func("abc"))
print(func(""))
print(func("abcdddeeeeaabbbcd"))
print(func("aba"))


import tkinter as tk

class FileReader:
    def __init__(self, file_directory):
        self.file_directory = file_directory
        try:
            if r_var.get():
                file = open(file_directory, "w")
                file.write(txt_result.get(1.0, tk.END))
            else:
                file = open(file_directory, "r")
                txt_result.insert(1.0, file.read())
            file.close()
        except FileNotFoundError:
            pass

def set_lbl_text():
    txt_result.delete(1.0, tk.END)
    if r_var.get():
        lbl_command["text"] = "Напишите путь к файлу\n который вы хотите скопировать"
    else:
        lbl_command["text"] = "Напишите путь к файлу\n содержимое которого вы хотите прочитать"

def resize_window(window, wight, height):
    size = [wight, height]
    w = window.winfo_screenwidth()
    h = window.winfo_screenheight()
    w = w // 2
    h = h // 2
    w = w - (size[0] // 2)
    h = h - (size[1] // 2)
    window.geometry('{}x{}+{}+{}'.format(size[0], size[1], w, h))

root = tk.Tk()
resize_window(root, 600, 500)
root.update()

root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_rowconfigure(2, weight=1)
root.grid_rowconfigure(3, weight=1)
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_columnconfigure(2, weight=1)

r_var = tk.BooleanVar()
r_var.set(False)

btn_read = tk.Radiobutton(root, text="read", variable=r_var, value=False, command=set_lbl_text)
btn_read.grid(row=0, column=0, sticky="we")

lbl_command = tk.Label(root, text="Напишите путь к файлу\n содержимое которого вы хотите прочитать")
lbl_command.grid(row=1, column=0, columnspan=2, sticky="we")

btn_write = tk.Radiobutton(root, text="write", variable=r_var, value=True, command=set_lbl_text)
btn_write.grid(row=0, column=2, sticky="we")

lbl_set_command = tk.Label(root, text="Выберите режим")
lbl_set_command.grid(row=0, column=1, sticky="we")

ent_set_command = tk.Entry(root)
ent_set_command.grid(row=1, column=2, sticky="we")

btn_choice = tk.Button(root, text="Выбрать", command=lambda: FileReader(ent_set_command.get()))
btn_choice.grid(row=2, column=0, columnspan=3)

txt_result = tk.Text()
txt_result.grid(row=3, column=0, columnspan=3)

root.mainloop()


import boto3
import json

dynamoDB = boto3.resource("dynamodb")
table_name = "prjctNotes-DB"
table = dynamoDB.Table(table_name)

def lambda_get_saved(event, ctx):

    url_request_type = event["requestContext"]["http"]["method"]

    if url_request_type == "GET":

        ctx = event["queryStringParameters"]["ctx"]
        email = event["queryStringParameters"]["email"]

        if ctx == "note":

            resp = table.get_item(TableName=table_name, Key={"email": email, "ctx": "saved"})

            if "Item" in resp:

                return {"saved": resp["Item"]["value"]}

            else:

                return {"Status Code": 404}

        else:

            resp = table.get_item(TableName=table_name, Key={"email": email, "ctx": "theme"})

            if "Item" in resp:

                return {"theme": resp["Item"]["value"]}

            else:

                return {"Status Code": 404}

    else:

        return {
            "Error": "Incorrect URL Request Type",
            "Want": "GET",
            "Got": url_request_type
        }


"""
Created on Sat Mar 6 2021

@author: Kuan-Lin Chen
"""
import torch
import argparse
from data import data_dict
from models import model_dict
from train import TrainParam,TrainClassifier
from utils import dir_path,cuda_device

parser = argparse.ArgumentParser(description='Train a DNN model',formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--data', default='CIFAR10', choices=['CIFAR10','CIFAR100'], help='image classification datasets')
parser_resume_group = parser.add_mutually_exclusive_group()
parser_resume_group.add_argument('--resume', dest='resume', action='store_true', help='resume from the last checkpoint',default=True)
parser_resume_group.add_argument('--no-resume', dest='noresume', action='store_true', help='start a new training or overwrite the last one',default=False)
parser.add_argument('--checkpoint_folder',default='./checkpoint/', type=dir_path, help='path to the checkpoint folder')
parser.add_argument('--device', default='cuda:0', type=cuda_device, help='specify a CUDA device')
parser.add_argument('--mu', default=0.1, type=float, help='learning rate')
parser.add_argument('--momentum', default=0.9, type=float, help='momentum')
parser_nesterov_group = parser.add_mutually_exclusive_group()
parser_nesterov_group.add_argument('--nesterov', dest='nesterov', action='store_true', help='enable Nesterov momentum',default=True)
parser_nesterov_group.add_argument('--no-nesterov', dest='nonesterov', action='store_true', help='disable Nesterov momentum',default=False)
parser.add_argument('--batch_size', default=128, type=int, help='batch size')
parser.add_argument('--weight_decay', default=0.0005, type=float, help='weight decay')
parser.add_argument('--mu_scale', default=[1.0,0.2,0.04,0.008], nargs='+', type=float, help='learning rate scaling')
parser.add_argument('--mu_epoch', default=[60,120,160,200], nargs='+', type=int, help='learning rate scheduling')
parser.add_argument('--milestone', default=[40,100,150], nargs='+', type=int, help='the model trained after these epochs will be saved')
parser.add_argument('--print_every_n_batch', default=50, type=int, help='print the training status every n batch')
parser.add_argument('--seed_list', default=[0,1,2,3,4,5,6], nargs='+', type=int, help='train a model with different random seeds')
parser.add_argument('--model', default='CIFAR10_Standard_ResNet_110', choices=list(model_dict.keys()), help='the DNN model')
args = parser.parse_args()

torch.autograd.set_detect_anomaly(True)
torch.backends.cudnn.deterministic = True
print(torch.cuda.get_device_name(int(args.device[-1]))) # print the GPU

trainset = data_dict[args.data]().trainset

for seed in args.seed_list:
    name = args.model+'_seed='+str(seed)
    tp = TrainParam(
        mu=args.mu,
        mu_scale=args.mu_scale,
        mu_epoch=args.mu_epoch,
        weight_decay=args.weight_decay,
        momentum=args.momentum,
        batch_size = args.batch_size,
        nesterov = args.nesterov and not args.nonesterov
        )
    c = TrainClassifier(
        name=name,
        net=model_dict[args.model],
        tp=tp,
        trainset=trainset,
        validationset=trainset,
        device=args.device,
        seed=seed,
        resume=args.resume and not args.noresume,
        checkpoint_folder = args.checkpoint_folder,
        milestone = args.milestone,
        print_every_n_batch = args.print_every_n_batch
    ).train()
    print('training for the model '+name+' is completed')


# 3:01 3:17

def main():

	# english = int(input("English grade: "))
	# math = int(input("Math grade: "))
	# global_studies = int(input("Global Studies grade: "))
	# art = int(input("Art grade: "))
	# music = int(input("Music grade: "))
	# grades = {'English':english, 'Math':math, 'Global Studies':global_studies, 'Art':art, 'Music':music}

	grades = {}

	grades['English'] = int(input("English grade: "))
	grades['Math'] = int(input("Math grade: "))
	grades['Global Studies']= int(input("Global Studies grade: "))
	grades['Art'] = int(input("Art grade: "))
	grades['Music'] = int(input("Music grade: "))

	# Determines the average grade and prints it out. Note, to do this you will need to convert the user input to integers.
	average = (sum(grades.values()))/len(grades)
	print("Your average is", average)

	#After printing the average, ask the user to change the grade in one subject and then get the new average and print it out. Hint: you will have to prompt the user twice, once for the subject and once for the grade.
	change_subject = input("What subject do you want to change? ")
	change_grade = int(input("New grade: "))
	grades[change_subject] = change_grade
	average = (sum(grades.values()))/len(grades)
	print("Your average is", average)

main()


from pathlib import Path
from shutil import copytree, rmtree, copyfileobj
from subprocess import check_output, Popen, PIPE, STDOUT, CalledProcessError
import os
import gzip

Import("env")

def gzipFile(file):
    with open(file, 'rb') as f_in:
        with gzip.open(file + '.gz', 'wb') as f_out:
            copyfileobj(f_in, f_out)
    os.remove(file)

def buildWeb():
    os.chdir("interface")
    print("Building interface with npm")
    try:
        env.Execute("npm install")
        env.Execute("npm run build")
        buildPath = Path("../interface/dist/")
        dataPath = Path("../data/")
        if dataPath.exists() and dataPath.is_dir():
            rmtree(dataPath)
        print("Copying interface to data directory")
        copytree(buildPath, dataPath)
        for currentpath, folders, files in os.walk(dataPath):
            for file in files:
                gzipFile(os.path.join(currentpath, file))
    finally:
        os.chdir("..")

if (len(BUILD_TARGETS) == 0 or "upload" in BUILD_TARGETS):
    buildWeb()
else:
    print("Skipping build interface step for target(s): " + ", ".join(BUILD_TARGETS))


from tkinter import*
import backend

class Front (object):
    def __init__(self, window):
        self.window = window
        self.window.title("This is my Database project")
        self.myfont = ("Times New Roman", 18)
        self.yourfont = ("Times New Roman", 14)
        # need to create backend instance
        self.bk = backend.Back()
        # lets create widgets
        self.text_title = StringVar()
        self.lb1 = Label(master=self.window, text="Title", font=self.myfont)
        self.lb1.grid(row=0, column=0, sticky="w")

        self.text_year = StringVar()
        self.lb2 = Label(master=self.window, text="Year", font=self.myfont)
        self.lb2.grid(row=0, column=2, sticky="w")

        self.text_director = StringVar()
        self.lb3 = Label(master=self.window, text="Director", font=self.myfont)
        self.lb3.grid(row=1, column=0, sticky="w")

        self.text_lead = StringVar()
        self.lb4 = Label(master=self.window, text="Actor/Actress", font=self.myfont)
        self.lb4.grid(row=1, column=2, sticky="w")

        #entry text
        self.text_title = StringVar()
        self.et1 = Entry(master=self.window, textvariable = self.text_title, font=self.myfont)
        self.et1.grid(row=0, column=1)

        self.text_year = StringVar()
        self.et2 = Entry(master=self.window, textvariable=self.text_year, font=self.myfont)
        self.et2.grid(row=0, column=3)

        self.text_director = StringVar()
        self.et3 = Entry(master=self.window, textvariable=self.text_director, font=self.myfont)
        self.et3.grid(row=1, column=1)

        self.text_lead = StringVar()
        self.et4 = Entry(master=self.window, textvariable=self.text_lead, font=self.myfont)
        self.et4.grid(row=1, column=3)

        #main screen, list box is a bigger entry box
        self.listbox = Listbox(master=self.window, font=self.yourfont, height = 10, width = 80)
        self.listbox.grid(row=2, column=0, rowspan=8, columnspan=2, padx=20, pady=40)

        # need to bind action for clicking in listbox
        self.listbox.bind("<<ListboxSelect>>", action=self.get_row)

        self.scroll = Scrollbar(master=self.window)
        self.scroll.grid(row=2, column=2, rowspan = 8, columnspan=1, sticky="nsw", pady=40)
        self.scroll.configure(command=self.listbox.yview)

        # the buttons
        self.bt1 = Button(master=self.window, width= 10, text="View All", font=self.myfont, command=self.view)
        self.bt1.grid(row=2, column=3)

        self.bt2 = Button(master=self.window,width= 10, text="Delete", font=self.myfont, command=self.view)
        self.bt2.grid(row=3, column=3)

        self.bt3 = Button(master=self.window, width= 10, text="Add", font=self.myfont, command=self.view)
        self.bt3.grid(row=4, column=3)

        self.bt4 = Button(master=self.window,width= 10, text="Search", font=self.myfont, command=self.view)
        self.bt4.grid(row=5, column=3)

        self.bt5 = Button(master=self.window,width= 10, text="Update", font=self.myfont, command=self.update)
        self.bt5.grid(row=6, column=3)

        self.bt6 = Button(master=self.window,width= 10, text="Close", font=self.myfont, command=self.close)
        self.bt6.grid(row=7, column=3)

    def get_row(self, action=None):
        # curselection returns list of all selected lines
        if not self.listbox.curselection():
            return
        line_num = self.listbox.curselection() [0]
        idx = self.listbox.get(line_num) [0]
        title = self.listbox.get(line_num) [1]
        year = self.listbox.get(line_num) [2]
        director = self.listbox.get(line_num) [3]
        lead = self.listbox.get(line_num) [4]
        self.text_title.set(title)
        self.text_year.set(year)
        self.text_director.set(director)
        self.text_lead.set(lead)
        self.kept_index = self.listbox.get(line_num) [0]

    def view(self):
        data = self.bk.view_all()
        self.listbox.delete(0,END)
        for line in data:
            self.listbox.insert(END, line)

    def add(self):
        title = self.text_title.get()
        year = self.text_year.get()
        director = self.text_director.get()
        lead = self.text_lead.get()
        self.bk.add_element(title, year, director, lead)
        self.view()

    def close(self):
        exit(1)

    def delete(self):
        # curselection returns list of all selected lines
        line_num = self.listbox.curselection()[0]
        idx = self.listbox.get(line_num)[0]

    def update(self):
        if not self.listbox.curselection():
            return
        line_num = self.listbox.curselection()[0]
        title = self.listbox.get()
        year = self.listbox.get()
        director = self.listbox.get()
        lead = self.listbox.get()
        self.text_title.set(title)
        self.text_year.set(year)
        self.text_director.set(director)
        self.text_lead.set(lead)

window = Tk()
Front(window)
window.mainloop()


from __future__ import absolute_import, unicode_literals

import json
from cloudipsp import Order
from .tests_helper import TestCase

class OrderTest(TestCase):
    def setUp(self):
        self.api = self.get_api()
        self.order = Order(api=self.api)
        self.order_id = self.create_order().get('order_id')

    def test_get_order_status(self):
        data = {
            'order_id': self.order_id
        }
        response = self.order.status(data)
        self.assertEqual(response.get('response_status'), 'success')
        self.assertIn('order_status', response)

    def test_get_order_trans_list(self):
        data = {
            'order_id': self.order_id
        }
        response = self.order.transaction_list(data)
        self.assertIsInstance(response, list)
        self.assertIn('order_id', response[0])

    def test_refund(self):
        data = {
            'order_id': self.order_id
        }
        data.update(self.data['order_full_data'])
        response = self.order.reverse(data)
        self.assertEqual(response.get('response_status'), 'success')
        self.assertIn('reverse_status', response)

    def test_capture(self):
        data = {
            'order_id': self.order_id
        }
        data.update(self.data['order_full_data'])
        response = self.order.capture(data)
        self.assertEqual(response.get('response_status'), 'success')
        self.assertEqual(response.get('order_id'), self.order_id)
        self.assertEqual(response.get('capture_status'), 'captured')

    def test_settlement(self):
        self.api.api_protocol = '2.0'
        data = {
            'operation_id': self.order_id,
            'receiver': [
                {
                    'requisites': {
                        'amount': 500,
                        'merchant_id': 600001
                    },
                    'type': 'merchant'
                },
                {
                    'requisites': {
                        'amount': 500,
                        'merchant_id': 700001
                    },
                    'type': 'merchant'
                }
            ]
        }
        data.update(self.data['order_full_data'])
        data_capture = {
            'order_id': self.order_id
        }
        data_capture.update(self.data['order_full_data'])
        self.order.capture(data_capture)
        response = self.order.settlement(data)
        response_data = json.loads(response.get('data'))
        self.assertEqual(response_data.get('order')['order_status'], 'created')
        self.assertIn('payment_id', response_data.get('order'))


#! /usr/bin/python3

class Solution:
    cache = {}
    def kthGrammar(self, N: int, K: int) -> int:
        if N in self.cache: return self.cache[N][K-1]
        self.cache[N] = self.NthRow(N)
        print("Row(%d) : %s" % (N, self.cache[N]))
        return self.cache[N][K-1]

    def NthRow(self, N:int) -> list:
        if N == 1: return [0]
        if N in self.cache: return self.cache[N]
        if N-1 in self.cache:
            prev = self.cache[N-1]
        else:
            prev = self.NthRow(N-1)
            self.cache[N-1] = prev
        idx = 0
        max_idx = 2 * len(prev)
        while idx < max_idx:
            if prev[idx] == 0:
                prev.insert(idx+1, 1)
            else:
                prev.insert(idx+1, 0)
            idx += 2
        return prev

    row_cached = '0'
    def kthGrammar(self, N: int, K: int) -> int:
        N -= 1
        K -= 1
        if K >= len(self.row_cached):
            self.update_row_cached(N, K)
        #print("Row(%d) : %s" % (N+1, self.row_cached))
        return int(self.row_cached[K])

    def update_row_cached(self, N:int, K: int) -> None:
        if len(self.row_cached) > K:
            return
        missing_01s = len(self.row_cached)
        idx = 0
        while missing_01s:
            to_add = '0'
            if self.row_cached[idx] == '0':
                to_add = '1'
            self.row_cached += to_add
            missing_01s -= 1
            idx += 1
        self.update_row_cached(N, K)

    def kthGrammar(self, N: int, K: int) -> int:
        if K < 3:
            return K - 1
        K -= 1
        pivot = 1
        while K >= (pivot * 2):
            pivot *= 2
        return int(1 - self.get_mirror(pivot, K))

    def get_mirror(self, pivot:int, K: int) -> int:
        if K <= 1:
            return 1 - K
        while pivot > K:
            pivot /= 2
        return 1 - self.get_mirror(pivot/2, K-pivot)

    translate = {
        0: [0, 1],
        1: [1, 0]
    }

    def kthGrammar_sol1(self, N: int, K: int) -> int:
        if N == 1 and K == 1:
            return 0

        index = (K+1) % 2
        source = (K+1) // 2

        res = self.kthGrammar_sol1(N-1, source)
        return res if index == 0 else res ^ 1

    def kthGrammar_sol2(self, N, K):
        if N == 1:
            if K == 1:
                return 0
            else:
                return 1

        half = 2**(N - 1)
        if K <= half:
            return self.kthGrammar_sol2(N - 1, K)
        else:
            res = self.kthGrammar_sol2(N - 1, K - half)
            if res == 0:
                return 1
            else:
                return 0

    def kthGrammar_sol3(self, N: 'int', K: 'int') -> 'int':
        # my solution ... 28 ms ... 100 % without bar ... 12.4 MB ... 87 %
        def find(N, K):
            if N == 1:
                return 0
            if K <= 2**(N-2):                           # row 3: "0110"
                return find(N-1, K)
            else:
                return 1 - find(N-1, K - 2**(N-2))      # row 4: "0110" + "1001"

        return find(N, K)

def check_solution():
    s = Solution()
    # N = 1
    # K = 1
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 0)
    #
    # N = 2
    # K = 1
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 0)
    #
    # N = 2
    # K = 2
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 3
    # K = 3
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 3
    # K = 4
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 0)
    #
    # N = 4
    # K = 5
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 5
    # K = 5
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 6
    # K = 5
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 7
    # K = 5
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    #
    # N = 8
    # K = 5
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    #
    # N = 8
    # K = 10
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 0)
    #
    # N = 30
    # K = 434991989
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 0)
    #
    # N = 30
    # K = 434991990
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)
    #
    # N = 60
    # K = 84349919900
    # res = s.kthGrammar(N, K)
    # print("kthGrammar(%d, %d) = %d" % (N, K, res))
    # assert(res == 1)

    N = 30
    K = 434991990
    for idx in range(0, 800000):
        s.kthGrammar(N, K)

check_solution()


import sys
import math

count = 0
n = int(sys.stdin.readline())
pos = []

line_A = [False]*n
line_B = [False]*(2*n-1)
line_C = [False]*(2*n-1)

def setting(i,n) :
    global count

    for j in range(n):
        if(not line_A[j]
           and not line_B[i+j]
           and not line_C[i-j+n-1]):

            if i==(n-1) :
                count = count+1
            else:
                line_A[j] = line_B[i+j] = line_C[i-j+n-1] = True
                setting(i+1,n)
                line_A[j] = line_B[i+j] = line_C[i-j+n-1] = False

setting(0,n)
print(count)

## 2차 배열로 구현하는 것도 한번 생각해보기

# def chessTableReset(n) :
#     tempTable = [0]*n
#     chessTable = []
#     for i in range(n):
#         chessTable.append(tempTable)
#     return chessTable

# for i in range(row,n):
#     for j in range(n):
#         if table[i][j] == 0 :
#             table[i][j] = 1
#             table[j][j] = 1
#             set
#     for j in range(n):
#         if table[i-1][j] == 0:
#             table[i][j] = 1
#             continue
#         else :

## 생각해보니 대각선 검사 때 위 방법이 시간 복잡도가 낮아서 위가 최선임


#!/usr/bin/python3
import os
import zipper

##########################################################################
# base website URL
URL : str = 'http://laorbitadeendor.com/'

##########################################################################
# execute ./bin/python3 src/comic.py
def main():
   try:
      # comic to scrape
      title : str = 'Conan-the-Barbarian-1970'
      # dir destiny
      dir = "LODE"
      if not os.path.exists(dir):
         os.makedirs(dir)
      # scrape
      for num in ["1","2","3","4","5","6","7","8","9","10","11","12"]:
         temp = zipper.get_html(URL + "/category/lode/temporada-"+num+"/")

      # div.id=categorying - img.src
      issues = temp.find('ul', attrs={'class':'list'}).findAll('li')

      # zip result directory with cbz extension
      zipper.zip(dir, dir + '.cbz')
   except Exception as e:
      print(e)

if __name__ == "__main__":
    main()


n=int(input())
need=[]
money=[]
res=0
for i in range(n):
    m=list(map(int,input().split()))
    need.append(m[0])
    money.append(m[1])
count=0
while count<n:
    counter=count+1
    res+=need[count]*money[count]
    while counter<n and money[count]<=money[counter]:
        res+=need[counter]*money[count]
        counter+=1
    count=counter
print(res)


import math
import numpy as np
import os
import pandas as pd
import torch
from tqdm import tqdm
from spacy import displacy
from spacy.util import is_in_jupyter
from transformers import AutoTokenizer
from typing import Dict

from thermostat.data import get_local_explanations
from thermostat.utils import delistify, detach_to_list, read_path

class ColorToken:
    def __init__(self, token, attribution, text_field, token_index, thermounit_vars: Dict):
        self.token = token
        self.attribution = attribution
        self.text_field = text_field
        self.token_index = token_index
        for var_name, value in thermounit_vars.items():
            if var_name not in ['texts']:
                setattr(self, var_name, value)

        # White color per default
        self.red = '255'
        self.green = '255'
        self.blue = '255'
        self.score = None

        assert not math.isnan(self.attribution), 'Attribution of token {} is NaN'.format(self.token)

    def add_color(self, gamma, threshold=0):
        """ Needs to be explicitly called to calculate the color of a token """
        score = self.gamma_correction(self.attribution, gamma)
        if score >= threshold:
            r = str(int(255))
            g = str(int(255 * (1 - score)))
            b = str(int(255 * (1 - score)))
        else:
            b = str(int(255))
            r = str(int(255 * (1 + score)))
            g = str(int(255 * (1 + score)))

        # TODO: Add more color schemes from: https://colorbrewer2.org/#type=diverging&scheme=RdBu&n=5
        self.red = r
        self.green = g
        self.blue = b
        setattr(self, 'score', round(score, ndigits=3))

    def __repr__(self):
        if "score" in vars(self):
            score_str = f'Score: {self.score}'
        else:
            score_str = f'Attribution: {self.attribution}'
        return f'{self.token} (Index: {self.token_index}, {score_str}, Color: {self.hex()}, ' \
               f'Text field: {self.text_field})'

    def __str__(self):
        return repr(self)

    @staticmethod
    def gamma_correction(score, gamma):
        return np.sign(score) * np.power(np.abs(score), gamma)

    def hex(self):
        return '#%02x%02x%02x' % (int(self.red), int(self.green), int(self.blue))

class TextField(list):
    def __init__(self, color_tokens):
        super().__init__(color_tokens)

    def __repr__(self):
        return ' '.join([ctok.token for ctok in self])

class Heatmap(TextField):
    def __init__(self, color_tokens, attributions=None, gamma=1.0):
        super().__init__(color_tokens)
        for i in range(len(self)):
            if attributions:
                self[i].attribution = attributions[i]
            self[i].add_color(gamma=gamma)
        self.table = pd.DataFrame({
            'token_index': delistify(self['token_index']),
            'token': delistify(self['token']),
            'attribution': delistify(self['attribution']),
            'text_field': delistify(self['text_field'])}
        ).set_index('token_index').T

    def __getitem__(self, idx):
        if isinstance(idx, str):
            """ String indexing """
            if idx in list(self[0].__dict__.keys()):
                return [getattr(u, idx) for u in self]
        return list(self)[idx]

    def __repr__(self):
        return repr(self.table)

    def render(self, labels=False):
        """ Uses the displaCy visualization tool to render a HTML from the heatmap """

        # Call this function once for every text field
        if len(set([t.text_field for t in self])) > 1:
            for field in self[0].text_fields:
                print(f'Heatmap "{field}"')
                Heatmap([t for t in self if t.text_field == field]).render(labels=labels)
            return

        ents = []
        colors = {}
        ii = 0
        for color_token in self:
            ff = ii + len(color_token.token)

            # One entity in displaCy contains start and end markers (character index) and optionally a label
            # The label can be added by setting "attribution_labels" to True
            ent = {
                'start': ii,
                'end': ff,
                'label': str(color_token.score),
            }

            ents.append(ent)
            # A "colors" dict takes care of the mapping between attribution labels and hex colors
            colors[str(color_token.score)] = color_token.hex()
            ii = ff

        to_render = {
            'text': ''.join([t.token for t in self]),
            'ents': ents,
        }

        if labels:
            template = """

                {text}
                {label}

            """
        else:
            template = """

                {text}

            """

        html = displacy.render(
            to_render,
            style='ent',
            manual=True,
            jupyter=is_in_jupyter(),
            options={'template': template,
                     'colors': colors,
                     }
        )
        return html if not is_in_jupyter() else None

def token_to_html(token, rgb):
    return f" {token.replace('<', '').replace('>', '')} "

def summarize(summary: Dict):
    res = "
"
    for k, v in summary.items():
        res += f"{k}: {summary[k]}
"
    res += "
"
    return res

def append_heatmap(tokens, scores, latex, gamma, caption, pad_token, formatting="colorbox", truncate_pad=True):
    """
    Produce a heatmap for LaTeX
    Format options: colorbox, text"""
    if gamma != 1:
        raise NotImplementedError
    latex += "\n\\begin{figure}[!htb]"
    for token, score in zip(tokens, scores):
        if token == pad_token and truncate_pad:
            continue
        color = "blue"
        if score >= 0:
            color = "red"
        latex += f"\\{formatting}" + "{" + f"{color}!{abs(score) * 100}" + "}" + "{" + token + "}"
    latex += "\\caption{" + f"{caption}" + "}"
    latex += "\\end{figure}\n"
    return latex

def normalize_attributions(attributions):
    max_abs_score = max(max(attributions), abs(min(attributions)))
    return [(score / max_abs_score) for score in attributions]

def run_visualize(config: Dict, dataset=None):
    raise NotImplementedError("Deprecated due to Heatmap and ColorToken refactoring")
    tokenizer = AutoTokenizer.from_pretrained(config['model']['name'])
    visualization_config = config['visualization']

    if not dataset:
        dataset = get_local_explanations(config=visualization_config)
    dataset_name = f'{config["dataset"]["name"]}' \
                   f': {config["dataset"]["subset"]}' if 'subset' in config['dataset'] else \
        config['dataset']['name']
    str_dataset_name = f'{dataset_name} ({config["dataset"]["split"]})'

    file_out = open(read_path(config['path_html']), 'w+')

    tokenizer_str = str(type(tokenizer)).split('.')[-1].strip("'>")
    for idx_instance in tqdm(range(len(dataset))):
        instance = dataset[idx_instance]

        html = f"
"
        html += f"
Instance: {instance['idx']} | Dataset: {str_dataset_name} |" \
                f" Model: {config['model']['name']} | Tokenizer: {tokenizer_str}"
        html += '

'

        html += "
"

        tokens = [tokenizer.decode(token_ids=token_ids) for token_ids in instance['input_ids']]
        atts = detach_to_list(instance['attributions'])

        if visualization_config['normalize']:
            atts = normalize_attributions(atts)

        heatmap = Heatmap(words=tokens, scores=atts, gamma=visualization_config['gamma'])

        summary = {'Sum of Attribution Scores': str(sum(atts))}

        if 'dataset' in dataset:
            label_names = dataset['dataset'][0]['label_names']
        else:
            label_names = dataset.info.features['label'].names
        if 'labels' in instance or 'label' in instance:
            if 'labels' in instance:
                label = detach_to_list(instance['labels'])
            else:
                label = instance['label']
            summary['True Label Index'] = str(label)
            summary['True Label'] = str(label_names[label])
        if 'predictions' in instance:
            preds = instance['predictions']
            summary['Logits'] = detach_to_list(preds)
            preds_max = torch.argmax(preds) if type(preds) == torch.Tensor else preds.index(max(preds))
            preds_max_detached = detach_to_list(preds_max)
            summary['Predicted Label'] = str(label_names[preds_max_detached])
        html += summarize(summary)

        for instance in heatmap:  # brackets to reuse iterator
            html += token_to_html(instance['token'], instance['color'])
        html += "

"
        html += "
"
        html += "

"
        file_out.write(html + os.linesep)


"""
Parser
=========

Provides useful functions to parse API responses.
"""

# Parsing dates ----

def parse_date(date_text):
	from dateutil.parser import parse as date_parse, ParserError

	try:
		return date_parse(date_text).date()
	except ParserError: # Result with uncertain date, use January/1st by default
		year, month, day = date_text.split('-')
		month = '01' if not int(month) else month
		day = '01' if not int(day) else day
		fixed_date = year + '-' + month + '-' + day
		return date_parse(fixed_date).date()

# Parsing links ----

def get_url_parameters(url): # Adapted from https://stackoverflow.com/questions/21584545/url-query-parameters-to-dict-python
	from urllib import parse as url_parse
	return dict(url_parse.parse_qsl(url_parse.urlsplit(url).query))

def rider_link_to_id(a):
	return int(get_url_parameters(a['href'])['r'])

def team_link_to_id(a):
	return int(get_url_parameters(a['href'])['l'])

def race_link_to_race_id(a):
	return int(get_url_parameters(a['href'])['r'])

def race_link_to_stage_num(a):
	return int(get_url_parameters(a['href'])['e'])

def link_to_twitter_handle(a):
	return a['href'].split('/')[3]

# Parsing icons ----

def get_img_name(img):
	return img['src'].split('/')[-1]

def img_to_country_code(img):
	""" Obtain three-letter country code, or 'UCI' or 'OL' from html img tag """
	return get_img_name(img).split('.')[0]

def img_to_profile(img):
	""" Return profile type for image """
	return profile_icon_map[get_img_name(img)]

# Parsing tables ----

def parse_table(table):
	""" Convert HTML table from bs4 to pandas DataFrame. Return None if no data. """
	# TODO for rider results, format dates nicely with hidden column we are throwing away
	import pandas as pd

	# Load pandas DataFrame from raw text only
	out_df = pd.read_html(str(table), decimal=',')[0]

	if out_df.iat[0, 0] == 'No data': # No data
		return None

	# Convert decimal points to thousands separator
	# NOTE: Cannot use thousands='.' in pd.read_html because will ruin other columns (e.g. CAT for races)
	thousands_cols = ['Points']
	for col in thousands_cols:
		if col in out_df:
			out_df[col] = out_df[col].astype(str).str.replace('.', '', regex=False).astype(int)

	# Parse soup to add information hidden in tags/links
	headers = [th.text for th in table.find_all('th')]
	trs = [tr for tr in table.find_all('tr') if tr.th is None]

	if 'Race.1' in out_df:
		out_df = out_df.rename(columns={'Race': 'Race_Country', 'Race.1': 'Race'})
		headers.insert(headers.index('Race'), 'Race_Country')

	soup_df = pd.DataFrame([tr.find_all('td') for tr in trs], columns=headers)

	# Add information hidden in tags
	for col, series in soup_df.items():
		if col in ('Rider', 'Winner', 'Second', 'Third'):
			out_df[col + '_ID'] = series.apply(lambda td: rider_link_to_id(td.a))
			try:
				out_df[col + '_Country'] = series.apply(lambda td: img_to_country_code(td.img))
			except TypeError:
				pass

		elif col == 'Team':
			out_df['Team_ID'] = series.apply(lambda td: team_link_to_id(td.a) if td.a else None)
			out_df['Team_Country'] = series.apply(lambda td: img_to_country_code(td.img) if td.img else None)

		elif col == 'Race':
			out_df['Race_ID'] = series.apply(lambda td: get_url_parameters(td.a['href'])['r'] if td.a else None)

		elif col == 'Race_Country':
			out_df['Race_Country'] = series.apply(lambda td: img_to_country_code(td.img) if td.img else None)

		elif col == '':
			try:
				out_df['Icon'] = series.apply(lambda td: get_img_name(td.img) if td.img else None)
			except AttributeError:
				pass

	out_df = out_df.replace({'-': None}).dropna(how='all', axis=1)

	# TODO Remove Unnamed columns

	return out_df