import random
import time
from pathlib import Path
from typing import Any

import numpy as np
from midi.decode import get_array_of_notes
from midi.encode import get_file_from_standard_features

from models.music_model import MusicModel, ProgressCallback, ProgressMetadata

class MarkovChain(MusicModel):
    n_gram_size: int

    def __init__(self, n_gram_size: int = 1) -> None:
        self.data: list = []
        self.tokens: set = set()
        self.n_grams: set = set()
        self.tokens_list: list[tuple] = []
        self.n_grams_list: list[tuple] = []
        self.probabilities: np.ndarray
        self.n_gram_size = n_gram_size

    def train(self, epochs: int | None, x_train: Any, y_train: Any, progress_callback: ProgressCallback,
              checkpoint_path: Path | None = None) -> None:

        # count probabilities
        n = len(self.n_grams_list[0])
        n_gram_next: np.ndarray = np.ndarray(
            (len(self.n_grams_list, )), dtype=object)

        for i in range(n_gram_next.shape[0]):
            n_gram_next[i] = []

        start = time.time()
        time.perf_counter()

        for i in range(len(self.data)):
            elapsed = time.time() - start
            progress_callback([(elapsed, 100 * i / len(self.data))])
            for j in range(len(self.data[i]) - 1 - self.n_gram_size):
                curr_n_gram = tuple(self.data[i][j:j + n])
                next_note = self.data[i][j + n]
                n_gram_next[self.n_grams_list.index(
                    curr_n_gram)].append(next_note)

        elapsed = time.time() - start
        progress_callback([(elapsed, 100)])

        self.probabilities = np.ndarray(
            (len(self.n_grams_list, )), dtype=object)
        for i in range(n_gram_next.shape[0]):
            self.probabilities[i] = {}

        len_n_gram_next = len(n_gram_next)

        for i in range(len_n_gram_next):
            for j in range(len(n_gram_next[i])):
                if len(n_gram_next[i]) <= 1:
                    self.probabilities[n_gram_next[i]][j] = 1
                else:
                    if self.probabilities[i].get(n_gram_next[i][j]) is None:
                        self.probabilities[i][n_gram_next[i][j]] = float(
                            n_gram_next[i].count(n_gram_next[i][j]) / len(n_gram_next[i]))

    def create_dataset(self, dataset: list[tuple[Any, Any]]) -> tuple[Any, Any]:

        self.generate_tokens()
        self.generate_n_grams(self.n_gram_size)
        return 0, 0

    def generate_tokens(self) -> None:

        for i in range(len(self.data)):
            for j in range(len(self.data[i])):
                notes = []
                for k in range(128):
                    if self.data[i][j][k]:
                        notes.append(k)

                self.data[i][j] = tuple(notes)
                self.tokens.add(tuple(notes))

    def prepare_data(self, midi_file: Path) -> tuple[Any, Any]:
        data_lines = get_array_of_notes(midi_file, False, False)
        for i in range(len(data_lines)):  # serialize tracks
            self.data.append(data_lines[i].tolist())
        return 0, 0

    def save(self, path: Path) -> None:
        np.savez(path, probabilities=np.asarray(self.probabilities, dtype=object),
                 tokens=np.asarray(self.tokens_list, dtype=object))

    def load(self, path: Path) -> None:
        path = path if path.name.endswith('.npz') else path.with_suffix('.npz')
        data = np.load(path, allow_pickle=True)
        self.probabilities = data['probabilities']
        self.tokens_list = data['tokens']

    def generate_n_grams(self, n: int) -> None:
        print("Generating " + str(n) + "-grams")
        for i in range(len(self.data)):
            for j in range(len(self.data[i]) - n + 1):
                self.n_grams.add(tuple(self.data[i][j:j + n]))

        self.tokens_list = list(self.tokens)
        self.n_grams_list = list(self.n_grams)
        print(str(len(self.n_grams_list)) + " " + str(n) + "-grams generated!")

    def model_summary(self) -> str:
        return ("Markov chain basing on " +
                str(self.n_gram_size) + "-grams:\n" +
                str(len(self.tokens_list)) + " tokens\n" +
                str(len(self.n_grams_list)) + " n_grams\n" +
                str(len(self.data)) + " files")

    def generate(self, path: Path, seed: int | None = None) -> None:

        assert len(self.tokens_list) > 0, "Model was not initiated with data"

        if seed is not None:
            random.seed(seed)

        result = self.predict(random.choice(self.tokens_list), 512, False, 0)
        get_file_from_standard_features(
            result, 1000000, path, False, True, False, [8 for _ in result])

    def predict(self, initial_notes: tuple, length: int, deterministic: bool, rand: int) -> np.ndarray:

        # deterministic - if True, next note will be always note with maximum probability
        #               - if False, next note will be sampled according to all notes probability
        # rand - % chance of selecting random token next (int [0;100])

        prediction = []
        previous_n_gram = initial_notes

        for i in range(len(initial_notes)):
            prediction.append(initial_notes[i])

        # generating length - initial_token
        for i in range(length - len(self.tokens_list[0])):
            idx = None
            if tuple(previous_n_gram) in self.n_grams:
                idx = self.n_grams_list.index(previous_n_gram)
            else:
                idx = random.randrange(len(self.probabilities))

            probs = self.probabilities[idx]
            while len(probs) == 0:
                idx = random.randrange(len(self.probabilities))
                probs = self.probabilities[idx]

            next_note = None
            if random.randrange(100) < rand:
                next_note = random.choice(self.tokens_list)
            elif deterministic:
                next_note = max(probs, key=probs.get)
            else:
                next_note = random.choices(
                    list(probs.keys()), weights=probs.values(), k=1)[0]

            prediction.append(next_note)
            if next_note is not None:
                previous_n_gram = next_note

        result = np.full((len(prediction), 128), False)
        for i in range(len(prediction)):
            if isinstance(prediction[i], int):
                result[i][prediction[i]] = True
            else:
                for j in range(len(prediction[i])):
                    note = prediction[i][j]
                    result[i][note] = True

        return result

    @staticmethod
    def get_progress_metadata() -> ProgressMetadata:
        return ProgressMetadata(x_label='Time [s]', y_label='Progress [%]', legends=['Markov Chain'])


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

import sys
import io
import json
import numpy as np
from matplotlib import pyplot as plt
from tensorflow import keras
import tensorflow as tf
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession
from pathlib import Path
import cv2
import skimage
from tensorflow.keras.applications import ResNet50V2, ResNet50
from tensorflow.keras.regularizers import l2
from tensorflow.keras import layers
from tensorflow.keras.layers import Input, Conv2DTranspose
from tensorflow.keras.layers import concatenate
from tensorflow.keras import regularizers
from tensorflow.keras.layers import Dense, Flatten, MaxPooling2D, BatchNormalization, Conv2D, Dropout, LeakyReLU
from tensorflow.keras.regularizers import l2
from adamp_tf import AdamP
from sgdp_tf import SGDP
from collections import Callable
import time
from tensorflow.keras import backend as K

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)
tf.test.is_gpu_available()
tf.config.list_physical_devices('GPU')

tf.keras.mixed_precision.experimental.set_policy('mixed_float16')

from skimage.transform import resize
import albumentations as A

def augment_img_mask(x, y):
    transform = A.Compose(
        [
            A.VerticalFlip(p=0.5),
            A.HorizontalFlip(p=0.5),
            A.ElasticTransform(p=0.5, alpha=240, sigma=240 * 0.05, alpha_affine=240 * 0.03)
        ]
    )

    transform_image = transform(image=x, mask=y)
    return transform_image['image'], transform_image['mask']

class DataGeneratorDivide(tf.keras.utils.Sequence):
    'Generates data for Keras'
    def __init__(self, path_to_dataset, batch_size=32,
                 shuffle=True, use_augmentations=False,
                 mode='train', val_percent=0.3):
        """
        mode: train or val
        """
        self.batch_size = batch_size
        self.path_to_dataset = path_to_dataset
        self.val_percent = val_percent
        self.mode = mode
        self.initialize()

        self.shuffle = shuffle
        self.on_epoch_end()
        self.use_aug = use_augmentations

    def __len__(self):
        'Denotes the number of batches per epoch'
        return int(np.floor(len(self.X) / self.batch_size))

    def __getitem__(self, index):
        'Generate one batch of data'
        # Generate indexes of the batch
        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]

        # Generate data
        X, Y = self.__data_generation(indexes)

        return X, Y

    def initialize(self):
        slice_nums = list(set(
            int(file.name.split('_')[-1].split('.')[0]) for file in (self.path_to_dataset / 'gt').iterdir()
        ))
        slice_nums = sorted(list(slice_nums))
        num_of_slices = len(slice_nums)
        val_num = int(num_of_slices * self.val_percent)
        if self.mode == 'train':
            curr_slices_to_use = slice_nums[val_num:]
        else:
            curr_slices_to_use = slice_nums[:val_num]

        self.curr_slices_to_use = curr_slices_to_use

        self.X, self.Y = [], []
        for file in (self.path_to_dataset / 'images').iterdir():
            slice_num = int(file.name.split('_')[-1].split('.')[0])
            if slice_num in self.curr_slices_to_use:
                self.X.append(file)
                self.Y.append(self.path_to_dataset / 'gt' / file.name)

    def on_epoch_end(self):
        'Updates indexes after each epoch'
        self.indexes = np.arange(len(self.X))
        if self.shuffle == True:
            np.random.shuffle(self.indexes)

    def __data_generation(self, indexes):
        'Generates data containing batch_size samples'
        # Resize or padd?
        # imread (M, N, 3). can take only first dim to make them grey
        # but resnet preprocessing wants rgb images!!!
        X = [np.load(self.X[ind]) for ind in indexes]
        Y = [np.load(self.Y[ind]) for ind in indexes]
        # batch_shapes = [el.shape for el in X]
        max_w, max_h = 256, 256
        # print(max_w, max_h)
        # # Generate data
        for i, img in enumerate(X):
            w, h = X[i].shape
            X[i] = resize(X[i], (256, 256), preserve_range=True)
            Y[i] = resize(Y[i], (256, 256), preserve_range=True)
            if self.use_aug:
                X[i], Y[i] = augment_img_mask(X[i], Y[i])
                # y[i] = y[i][:, :, np.newaxis]
            # X[i] = (np.pad(X[i], pad_width=((0, max_w - w), (0, max_h - h), (0, 0))))

#             X[i] = tf.keras.applications.resnet.preprocess_input(X[i])

            # np.pad(y[i], pad_width=((0, max_w - w), (0, max_h - h), (0, 0)))
            # X[i], y[i] = np.pad()
        X, Y = np.array(X)[:, :, :, np.newaxis], np.array(Y)[:, :, :, np.newaxis]
#         X_padded = np.zeros([X.shape[0], 512, 512, 1])
#         X_padded[:, :X.shape[1], :X.shape[2], :] = X
#         Y_padded = np.zeros([Y.shape[0], 512, 512, 1])
#         Y_padded[:, :Y.shape[1], :Y.shape[2], :] = Y
        return X, Y

def get_model(
        weight_decay=0.0001,
        start_neuron_number=16
    ):
    keras.backend.clear_session()

    wd_reg = l2(weight_decay)

    inputs = Input((256, 256, 1))
    x = inputs
    # s = Lambda(lambda x: x / 255) (inputs)

    c1 = Conv2D(start_neuron_number * 1, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (x)
    # c1 = Dropout(0.1) (c1)
    c1 = BatchNormalization()(c1)
    c1 = Conv2D(start_neuron_number * 1, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c1)
    p1 = MaxPooling2D((2, 2)) (c1)

    c2 = Conv2D(start_neuron_number * 2, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (p1)
    # c2 = Dropout(0.1) (c2)
    c2 = BatchNormalization()(c2)
    c2 = Conv2D(start_neuron_number * 2, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c2)
    p2 = MaxPooling2D((2, 2)) (c2)

    c3 = Conv2D(start_neuron_number * 4, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (p2)
    # c3 = Dropout(0.2) (c3)
    c3 = BatchNormalization()(c3)
    c3 = Conv2D(start_neuron_number * 4, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c3)
    p3 = MaxPooling2D((2, 2)) (c3)

    c4 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (p3)
    # c4 = Dropout(0.2) (c4)
    c4 = BatchNormalization()(c4)
    c4 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal',kernel_regularizer=wd_reg,  padding='same') (c4)
    p4 = MaxPooling2D(pool_size=(2, 2)) (c4)
    # p4 = p3

    c5 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (p4)
    # c5 = Dropout(0.3) (c5)
    c5 = BatchNormalization()(c5)
    c5 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c5)

    u6 = Conv2DTranspose(start_neuron_number * 8, (4, 4), strides=(2, 2), padding='same', kernel_regularizer=wd_reg) (c5)
    u6 = concatenate([u6, c4])
    c6 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal',kernel_regularizer=wd_reg,  padding='same') (u6)
    # c6 = Dropout(0.2) (c6)
    c6 = BatchNormalization()(c6)
    c6 = Conv2D(start_neuron_number * 8, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c6)

    u7 = Conv2DTranspose(start_neuron_number * 4, (4, 4), strides=(2, 2), padding='same', kernel_regularizer=wd_reg) (c6)
    u7 = concatenate([u7, c3])
    u7 = Dropout(0.2)(u7)
    c7 = Conv2D(start_neuron_number * 4, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (u7)
    # c7 = BatchNormalization()(c7)
    c7 = Conv2D(start_neuron_number * 4, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c7)

    u8 = Conv2DTranspose(start_neuron_number * 2, (4, 4), strides=(2, 2), padding='same', kernel_regularizer=wd_reg) (c7)
    u8 = concatenate([u8, c2])
    u8 = Dropout(0.2)(u8)
    c8 = Conv2D(start_neuron_number * 2, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (u8)
    # c8 = BatchNormalization()(c8)
    c8 = Conv2D(start_neuron_number * 2, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c8)

    u9 = Conv2DTranspose(start_neuron_number, (4, 4), strides=(2, 2), padding='same') (c8)
    u9 = concatenate([u9, c1], axis=3)
    u9 = Dropout(0.2)(u9)
    c9 = Conv2D(start_neuron_number, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (u9)
    c9 = BatchNormalization()(c9)
    c9 = Conv2D(start_neuron_number, (3, 3), activation='relu', kernel_initializer='he_normal', kernel_regularizer=wd_reg, padding='same') (c9)

    outputs = Conv2D(1, (1, 1), activation='linear', dtype='float32') (c9)

    model = keras.Model(inputs=[inputs], outputs=[outputs])
    return model

def l1(y_true, y_pred):
    #print(y_true)
    #print(y_pred)
    """Calculate the L1 loss used in all loss calculations"""
    if K.ndim(y_true) == 4:
        return K.mean(K.abs(y_pred - y_true), axis=[1,2,3])
    elif K.ndim(y_true) == 3:
        return K.mean(K.abs(y_pred - y_true), axis=[1,2])
    else:
        raise NotImplementedError("Calculating L1 loss on 1D tensors? should not occur for this network")

def compute_perceptual(vgg_out, vgg_gt):
    """Perceptual loss based on VGG16, see. eq. 3 in paper"""
    loss = 0
    for o, g in zip(vgg_out, vgg_gt):
        loss += l1(o, g)
    return loss

def gram_matrix(x, norm_by_channels=False):
    """Calculate gram matrix used in style loss"""

    # Assertions on input
#     print(K.ndim(x), x.shape)
    assert K.ndim(x) == 4, 'Input tensor should be a 4d (B, H, W, C) tensor'
    assert K.image_data_format() == 'channels_last', "Please use channels-last format"
    #import pdb
    #pdb.set_trace()
    # Permute channels and get resulting shape
    x = K.permute_dimensions(x, (0, 3, 1, 2))
    shape = K.shape(x)
    B, C, H, W = shape[0], shape[1], shape[2], shape[3]

    # Reshape x and do batch dot product
    features = K.reshape(x, K.stack([B, C, H*W]))
    gram = K.batch_dot(features, features, axes=2)

    # Normalize with channels, height and width
    gram = gram /  K.cast(C * H * W, x.dtype)

    return gram

def compute_style(vgg_out, vgg_gt):
    """Style loss based on output/computation, used for both eq. 4 & 5 in paper"""
    loss = 0
    for o, g in zip(vgg_out, vgg_gt):
        loss += l1(gram_matrix(o), gram_matrix(g))
    return loss

def get_extracted_values(feature_extractor, y_true, y_pred):
    vgg_out = feature_extractor(y_true)
    vgg_gt = feature_extractor(y_pred)

    if not isinstance(vgg_out, list):
        vgg_out = [vgg_out]
        vgg_gt = [vgg_gt]

    # TODO: make output of autoencoder float32 / это же слои!!! я не  смогу так сделать
    vgg_out_ = []
    vgg_gt_ = []
    for el1, el2 in zip(vgg_out, vgg_gt):
        vgg_out_.append(K.cast(el1, 'float32'))
        vgg_gt_.append(K.cast(el2, 'float32'))

    vgg_gt = vgg_gt_
    vgg_out = vgg_out_
    return vgg_gt, vgg_out

def compute_loss_tv(P):
    # Calculate total variation loss
    a = l1(P[:,1:,:,:], P[:,:-1,:,:])
    b = l1(P[:,:,1:,:], P[:,:,:-1,:])
    return a+b

def loss_total(
        feature_extractor_content,
        feature_extractor_style
    ):
    """
    Creates a loss function which sums all the loss components
    and multiplies by their weights. See paper eq. 7.
    """
    def loss(y_true, y_pred):
        y_true = K.cast(y_true, 'float32')

        # Here I assume that rectangular shape is always the same
        mask = np.zeros(y_true.shape)
        xmin, xmax, ymin, ymax = (55, 200, 86, 169)
        mask[:, xmin-20:xmax+20, ymin-20:ymax+20] = 1
        mask = K.cast(mask, 'float32')

        vgg_gt_c, vgg_out_c = get_extracted_values(feature_extractor_content, y_true, y_pred)
        vgg_gt_s, vgg_out_s = get_extracted_values(feature_extractor_style, y_true, y_pred)

        loss_mae_hole = l1(mask * y_true, mask * y_pred)
        loss_mae_valid = l1((1 - mask) * y_true, (1 - mask) * y_pred)

        loss_perceptual = compute_perceptual(vgg_out_c, vgg_gt_c)
        loss_style = compute_style(vgg_out_s, vgg_gt_s)
        loss_tv_val = compute_loss_tv(P=mask * y_pred)

        # Return loss function
        return loss_mae_valid, loss_mae_hole, loss_perceptual, loss_style, loss_tv_val

    return loss

def make_linear_lr(min_lr, max_lr, number_of_steps):
    def gen_lr(step):
        return (max_lr - min_lr) / number_of_steps * step + min_lr
    return gen_lr

def make_cosine_anneal_lr(learning_rate, alpha, decay_steps):
    def gen_lr(global_step):
        global_step = tf.minimum(global_step, decay_steps)
        global_step = tf.cast(global_step, tf.float32)
        cosine_decay = 0.5 * (1 + tf.math.cos(3.1415926 * global_step / decay_steps)) # changed np.pi to 3.14
        decayed = (1 - alpha) * cosine_decay + alpha
        decayed_learning_rate = learning_rate * decayed
        return decayed_learning_rate
    return gen_lr

def make_cosine_annealing_with_warmup(min_lr, max_lr, number_of_steps, alpha, decay_steps):
    gen_lr_1 = make_linear_lr(min_lr, max_lr, number_of_steps)
    gen_lr_2 = make_cosine_anneal_lr(max_lr, alpha, decay_steps)
    def gen_lr(global_step):
        a = global_step < number_of_steps
        a = tf.cast(a, tf.float32)
        b = 1. - a
        return a * gen_lr_1(global_step) + b * gen_lr_2(global_step - number_of_steps)

    return gen_lr

class CosineAnnealingWithWarmUP(tf.keras.optimizers.schedules.LearningRateSchedule):
    def __init__(self, min_lr, max_lr, number_of_steps, alpha, decay_steps):
        super(CosineAnnealingWithWarmUP, self).__init__()
        self.min_lr = min_lr
        self.max_lr = max_lr
        self.number_of_steps = number_of_steps
        self.alpha = alpha
        self.decay_steps = decay_steps
        self.gen_lr_ca =  make_cosine_annealing_with_warmup(min_lr, max_lr, number_of_steps, alpha, decay_steps)

    def __call__(self, step):
        return self.gen_lr_ca(step)

    def get_config(self):
        config = {
            'min_lr': self.min_lr,
            'max_lr': self.max_lr,
            'number_of_steps': self.number_of_steps,
            'alpha': self.alpha,
            'decay_steps': self.decay_steps
            }
        return config

def choose_optimizer(
        optimizer_name='Adam',
        learning_rate_fn=0.001
    ):
    # (learning_rate=learning_rate_fn)
    if optimizer_name == 'Adam':
        optimizer = tf.keras.optimizers.Adam
    elif optimizer_name == 'SGD':
        optimizer = tf.keras.optimizers.SGD
    elif optimizer_name == 'AdamP':
        optimizer = AdamP
    else:
        print('Choosing SGDP')
        optimizer = SGDP

    optimizer_with_lr = optimizer(learning_rate_fn)
    return optimizer_with_lr

def choose_learning_rate_func(
        type_lr_func='constant', max_lr = 0.001,
        warmup_steps = 900, max_number_of_steps = 60_000,
        epochs=60
    ):
    if type_lr_func == 'constant':
        return max_lr
    else:
        return CosineAnnealingWithWarmUP(.0000001, max_lr, warmup_steps, 0, max_number_of_steps)

def plot_to_image(figure):
    """Converts the matplotlib plot specified by 'figure' to a PNG image and
    returns it. The supplied figure is closed and inaccessible after this call."""
    # Save the plot to a PNG in memory.
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    # Closing the figure prevents it from being displayed directly inside
    # the notebook.
    plt.close(figure)
    buf.seek(0)
    # Convert PNG buffer to TF image
    image = tf.image.decode_png(buf.getvalue(), channels=4)
    # Add the batch dimension
    image = tf.expand_dims(image, 0)
    return image

def main(params):
    weight_decay = params['weight_decay']
    start_neuron_number = params['start_neuron_number']
    optimizer_name = params['optimizer_name']
    type_lr_func = params['type_lr_func']
    max_lr = params['max_lr']
    warmup_steps = params['warmup_steps']
    max_number_of_steps = params['max_number_of_steps']
    epochs = params['epochs']
    save_model_tensorboard = params['save_model_tensorboard']
    style_layer_names = params['style_layer_names']
    content_layer_name = params['content_layer_name']
    mae_valid_weight = params['mae_valid_weight']
    mae_hole_weight = params['mae_hole_weight']
    perceptual_weight = params['perceptual_weight']
    style_weight = params['style_weight']
    tv_weight = params['tv_weight']

    model = get_model(weight_decay, start_neuron_number)
    path_to_dataset = Path('./dataset')
    autoencoder = tf.keras.models.load_model('./best_weights_24.h5', compile=False)
    autoencoder.trainable = False

    feature_extractor_style = keras.Model(
        inputs=autoencoder.input,
        outputs=[autoencoder.get_layer(l).output for l in style_layer_names]
    )

    feature_extractor_content = keras.Model(
        inputs=autoencoder.input,
        outputs=[autoencoder.get_layer(content_layer_name).output]
    )

    optimizer = choose_optimizer(
        optimizer_name,
        choose_learning_rate_func(type_lr_func, max_lr, warmup_steps, max_number_of_steps, epochs)
    )

    dg_train = DataGeneratorDivide(
        path_to_dataset, mode='train',
        val_percent=0.2, use_augmentations=True,
        batch_size=6
    )

    dg_val = DataGeneratorDivide(path_to_dataset, mode='val', val_percent=0.2, batch_size=6)

    writer = tf.summary.create_file_writer(save_model_tensorboard)

    global_step = 0
    for ind in range(epochs):
        model.save(f'./{save_model_tensorboard}.h5')
        print(f'{ind} epoch')
        dg_train.on_epoch_end()

        for ind, (x, y) in enumerate(dg_val):
            if ind == 1:
                break
            prediction = model.predict(x)
            fig, axes = plt.subplots(1, 3, figsize=(10, 5))
            for pred, x_, y_ in zip(prediction, x, y):
                axes[0].imshow(pred, cmap='gray')
                axes[1].imshow(x_, cmap='gray')
                axes[2].imshow(y_, cmap='gray')
    #         plt.show()
            with writer.as_default():
                tf.summary.image("Val data", plot_to_image(fig), step=global_step)

        start = time.time()
        for step_num, (inputs, targets) in enumerate(dg_train):
            global_step += 1
            with tf.GradientTape() as tape:
                predictions = model(inputs)
                func = loss_total(feature_extractor_content, feature_extractor_style)
                loss_value_list = func(targets, predictions)
                loss_value =\
                    mae_valid_weight * loss_value_list[0] +\
                    mae_hole_weight * loss_value_list[1] +\
                    perceptual_weight * loss_value_list[2] +\
                    style_weight * loss_value_list[3] +\
                    tv_weight * loss_value_list[4]

            gradients = tape.gradient(loss_value, model.trainable_weights)
            optimizer.apply_gradients(zip(gradients, model.trainable_weights))
            if step_num % 10 == 0:
                with writer.as_default():
                    tf.summary.scalar("loss_train", loss_value.numpy().mean(), step=global_step)
                    tf.summary.scalar("loss_train_mae_valid", loss_value_list[0].numpy().mean(), step=global_step)
                    tf.summary.scalar("loss_train_mae_hole", loss_value_list[1].numpy().mean(), step=global_step)
                    tf.summary.scalar("loss_train_percept" , loss_value_list[2].numpy().mean(), step=global_step)
                    tf.summary.scalar("loss_train_style", loss_value_list[3].numpy().mean(), step=global_step)
                    tf.summary.scalar("loss_train_tv", loss_value_list[4].numpy().mean(), step=global_step)
                    if isinstance(optimizer.lr, Callable):
                        cur_lr = optimizer.lr(global_step).numpy()
                    else:
                        cur_lr = optimizer.lr.numpy()
                    tf.summary.scalar("learning_rate", cur_lr, step=global_step)
                    writer.flush()
        end = time.time()
        print(f'Training took {end - start}')

        start = time.time()
        val_loss_value = 0
        corr_coef_value = 0
        batch_num = 0
        for step_num, (inputs, targets) in enumerate(dg_val):
            predictions = model(inputs)

            corr_coefs = []
            for pred, x_, y_ in zip(predictions, inputs, targets):
                xmin, xmax = min(np.where(x_ < 0.001)[0]), max(np.where(x_ < 0.001)[0])
                ymin, ymax = min(np.where(x_ < 0.001)[1]), max(np.where(x_ < 0.001)[1])
                y_ = y_[xmin-10:xmax+10, ymin-10:ymax+10]
                pred = pred[xmin-10:xmax+10, ymin-10:ymax+10]
                corr_coef = np.corrcoef(y_.ravel(), pred.numpy().ravel())[0, 1]
                corr_coefs.append(corr_coef)
            corr_coef_value += np.mean(corr_coefs)

            func = loss_total(feature_extractor_content, feature_extractor_style)
            loss_value_list = func(targets, predictions)
            loss_value =\
                    mae_valid_weight * loss_value_list[0] +\
                    mae_hole_weight * loss_value_list[1] +\
                    perceptual_weight * loss_value_list[2] +\
                    style_weight * loss_value_list[3] +\
                    tv_weight * loss_value_list[4]
            val_loss_value += loss_value.numpy().mean()
            batch_num += 1

        with writer.as_default():
            tf.summary.scalar("loss_val", val_loss_value / batch_num, step=global_step)
            tf.summary.scalar("corr_coeff_val", corr_coef_value / batch_num, step=global_step)
            writer.flush()
        end = time.time()
        print(f'Val took {end - start}')

if __name__ == '__main__':
    path_to_json = sys.argv[1]
    with open(path_to_json, 'r') as f:
        params = json.load(f)
    main(params)


"""
Created on Sat Sep 25 00:00:00 2018

@author: Nikhil
"""

"""
    If you have any questions or suggestions regarding this script,
    feel free to contact me via nikhil.ss4795@gmail.com
"""

# Polynomial Regression

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2].values

plt.scatter(X, y, color = 'red')
plt.title('Salary vs Experience')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()

# Fitting Linear Regression to the dataset
from sklearn.linear_model import LinearRegression
linear_reg = LinearRegression()
linear_reg.fit(X, y)

# Visualising the Linear Regression results
plt.scatter(X, y, color = 'red')
plt.plot(X, linear_reg.predict(X), color = 'blue')
plt.title('Salary vs Experience')
plt.xlabel('Experience')
plt.ylabel('Salary')
plt.show()

# Fitting Polynomial Regression to the dataset
from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree = 4)
X_polynomial = poly_features.fit_transform(X)
poly_features.fit(X_polynomial, y)

polynomial_regression = LinearRegression()
polynomial_regression.fit(X_polynomial, y)

# Visualising the Polynomial Regression results
plt.scatter(X, y, color = 'red')
plt.plot(X, polynomial_regression.predict(poly_features.fit_transform(X)), color = 'blue')
plt.title('Salary vs Experience')
plt.xlabel('Experience')
plt.ylabel('Salary')
plt.show()

# Predicting a new result with Linear Regression
linear_reg.predict(6.5)

# Predicting a new result with Polynomial Regression
polynomial_regression.predict(poly_features.fit_transform(6.5))

"""
    If you have any questions or suggestions regarding this script,
    feel free to contact me via nikhil.ss4795@gmail.com
"""


from time import sleep

from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
from appium.webdriver.extensions.android.gsm import GsmCallActions
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

class TestBrowser():
    def setup(self):
        des_caps = {
            'platformName':'android',
            'platformVersion':'6.0',
            'appPackage':'com.xueqiu.android',
            'appActivity':'com.xueqiu.android.common.MainActivity',
            # 'browserName':'Browser',
            # 不停止APP，不清除app数据，不卸载app
            'noReset':True,
            # 停止app，清除app数据卸载app
            # 'fullReset':True,
            # 不停止测试app的进程
            'dontStopAppOnReset':True,
            'deviceName':'127.0.0.1:7555',
            'autoGrantPermissions':True,
            # 自动启动模拟器 emulator -list-avds 中的 Pixel_23_6
            # 只能是安卓自带的模拟器 第三方的不可以
            # 'avd':'Pixel_23_6'
            'newCommandTimeout':300

        }
        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des_caps)
        self.driver.implicitly_wait(10)

    def teardown(self):
        self.driver.quit()

    def test_mobile(self):
        pass
        # self.driver.make_gsm_call('15910852286',GsmCallActions.CALL)
        # self.driver.send_sms('15910852286','hello appium api')
        # # 录屏 8.0版本以上可以 华为不可
        # self.driver.start_recording_screen()
        # # 开启飞行模式
        # self.driver.set_network_connection(1)
        # self.driver.get_screenshot_as_file('./photos/img.png')
        # sleep(3)
        # self.driver.set_network_connection(4)
        # sleep(3)
        # self.driver.stop_recording_screen()


# coding: utf-8
import itertools
import re

from simpleai.search import (backtrack, CspProblem, LEAST_CONSTRAINING_VALUE,
                             min_conflicts, MOST_CONSTRAINED_VARIABLE)

largos = {
    '1H': 2, '2H': 3, '4H': 2, '5H': 2, '7H': 2, '8H': 2, '10H': 3, '11H': 2,
    '1V': 2, '2V': 2, '3V': 3, '4V': 2, '6V': 3, '7V': 2, '8V': 2, '9V': 2,
}

palabras = set(re.sub(r'[^\w] ', '', '''Este es un texto para sacar palabras y asi
emular las claves del diccionario expuesto en el ejercicio.

Artificial Intelligence (AI) is a big field, and this is a big book. We have tried to explore the
full breadth of the field, which encompasses logic, probability, and continuous mathematics;
perception, reasoning, learning, and action; and everything from microelectronic devices to
robotic planetary explorers. The book is also big because we go into some depth.
The subtitle of this book is “A Modern Approach.” The intended meaning of this rather
empty phrase is that we have tried to synthesize what is now known into a common frame-
work, rather than trying to explain each subfield of AI in its own historical context. We
apologize to those whose subfields are, as a result, less recognizable.

How to use Machine Learning on a Very Complicated Problem
So far in Part 1, 2 and 3, we’ve used machine learning to solve isolated problems that have only
one step — estimating the price of a house, generating new data based on existing data and telling
if an image contains a certain object. All of those problems can be solved by choosing one machine
learning algorithm, feeding in data, and getting the result.
But face recognition is really a series of several related problems:
First, look at a picture and find all the faces in it
Second, focus on each face and be able to understand that even if a face is turned in a weird
direction or in bad lighting, it is still the same person.
Third, be able to pick out unique features of the face that you can use to tell it apart from other
people— like how big the eyes are, how long the face is, etc.
Finally, compare the unique features of that face to all the people you already know to determine
the person’s name.
As a human, your brain is wired to do all of this automatically and instantly. In fact, humans are
too good at recognizing faces and end up seeing faces in everyday objects:

Computers are not capable of this kind of high-level generalization (at least not yet…), so we have
to teach them how to do each step in this process separately.
We need to build a pipeline where we solve each step of face recognition separately and pass the
result of the current step to the next step. In other words, we will chain together several machine
learning algorithms:
''').lower().split())

variables = []
dominios = {}

for var, largo in largos.items():
    # agrego variables
    variables.append(var)

    # optamos por restringir el dominio a solo las palabras que poseen el largo
    # para completar la variable. Otra posibilidad es agregar restricciones.
    dominios[var] = [x for x in palabras if len(x) == largo]

restricciones = []

def distinto_valor(variables, valores):
    'Compara que los valores de las variables sean distintos'
    return valores[0] != valores[1]

# Todas las variables tienen que ser distintas. Con este diccionario no alcanza
# para que se cumpla esta restriccion; si se quiere ver un resultado hay que
# comentar esta restriccion o agregar un texto que contenga mas palabras para
# formar el vocabulario.
for var1, var2 in itertools.combinations(variables, 2):
    restricciones.append(((var1, var2), distinto_valor))

def interseccion(pos1, pos2):
    '''
    Devuelve una "restriccion" que controla que la interseccion de la primer
    palabra[pos1] sea igual a la segunda palabra[pos2].
    '''
    def restriccion(variables, valores):
        return valores[0][pos1] == valores[1][pos2]
    return restriccion

# Agregamos las intersecciones donde tienen que coincidir los caracteres
restricciones.append((('1H', '1V'), interseccion(0, 0)))
restricciones.append((('2H', '2V'), interseccion(0, 0)))
restricciones.append((('2H', '3V'), interseccion(2, 0)))
restricciones.append((('4H', '4V'), interseccion(0, 0)))
restricciones.append((('4H', '2V'), interseccion(1, 1)))
restricciones.append((('5H', '4V'), interseccion(1, 1)))
restricciones.append((('7H', '7V'), interseccion(0, 0)))
restricciones.append((('8H', '8V'), interseccion(0, 0)))
restricciones.append((('8H', '7V'), interseccion(1, 1)))
restricciones.append((('6V', '10H'), interseccion(2, 0)))
restricciones.append((('10H', '8V'), interseccion(2, 1)))
restricciones.append((('11H', '9V'), interseccion(1, 1)))

problem = CspProblem(variables, dominios, restricciones)

print('backtrack:')
result = backtrack(problem,
                   variable_heuristic=MOST_CONSTRAINED_VARIABLE,
                   value_heuristic=LEAST_CONSTRAINING_VALUE,
                   inference=True)
posiciones = {
    '1H': (0, 0), '2H': (0, 3), '4H': (1, 2), '5H': (2, 1), '7H': (3, 3),
    '8H': (4, 2), '10H': (5, 0), '11H': (5, 4),
    '1V': (0, 0), '2V': (0, 3), '3V': (0, 5), '4V': (1, 2), '6V': (3, 0),
    '7V': (3, 3), '8V': (4, 2), '9V': (4, 5),
}

posiciones_letras = {}
crucigrama = [['\u25A0'] * 6 for x in range(6)]
for palabra, (fila, columna) in posiciones.items():
    for letra in range(largos[palabra]):
        fila_letra = fila
        columna_letra = columna
        if palabra.endswith('H'):
            columna_letra += letra
        else:
            fila_letra += letra
        crucigrama[fila_letra][columna_letra] = result[palabra][letra]
print(result)
print('\n'.join(['| ' + ' | '.join(palabra) + ' |' for palabra in crucigrama]))


import argparse
import auxil.mydata as mydata
import auxil.mymetrics as mymetrics
import gc
import tensorflow as tf
import keras.backend as K
from keras.callbacks import ModelCheckpoint
from keras.models import load_model
from keras.losses import categorical_crossentropy
from keras.layers import *
from keras.models import Sequential, Model
from keras.optimizers import Adam
from keras import regularizers
from keras.models import Model
from keras.utils import to_categorical as keras_to_categorical
import numpy as np
import sys

class AttentionBlock(Layer):
    def __init__(self, filters):

        super(AttentionBlock, self).__init__()
        self.filters = filters
        #self.init = RandomNormal()
    def call(self, x):
        conv_3d = Conv3D(filters = self.filters, kernel_size=3, strides = 1, padding = 'same')(x)
        conv_3d_shape = conv_3d._keras_shape
        print(conv_3d_shape)
        conv_3d = Reshape((conv_3d_shape[1], conv_3d_shape[2], conv_3d_shape[3]*conv_3d_shape[4]))(conv_3d)

        conv_2d = Conv2D(filters = self.filters, kernel_size=3, strides = 1, padding = 'same')(conv_3d)
        conv_2d_shape = conv_2d._keras_shape
        print(conv_2d_shape)

        conv_2d = Reshape((conv_2d_shape[1],conv_2d_shape[2]*conv_2d_shape[3]))(conv_2d)

        conv_1d = Conv1D(filters = self.filters, kernel_size=3, strides = 1, padding = 'same')(conv_2d)
        conv_1d_shape = conv_1d._keras_shape
        print(conv_1d_shape)

        gap = GlobalAveragePooling1D()(conv_1d)
        fc = Dense(self.filters, use_bias = True)(gap)
        softmax = Activation('softmax')(fc)

        reshape_1d = Reshape((1, self.filters))(softmax)
        deconv_1d = Conv1D(filters = self.filters, kernel_size = 3, strides = 1, padding = 'same')(reshape_1d)
        reshape_2d = Reshape((1,1, self.filters))(deconv_1d)
        deconv_2d = Conv2DTranspose(filters = self.filters, kernel_size=3, strides = 1, padding = 'same')(reshape_2d)
        reshape_3d = Reshape((1,1,1, self.filters))(deconv_2d)
        deconv_3d = Conv3DTranspose(filters = self.filters, kernel_size = 3, strides = 1, padding = 'same')(reshape_3d)
        x = tf.multiply(deconv_3d, x)
        return x

def set_params(args):
    args.batch_size = 64
    args.epochs = 200
    return args

def get_model_compiled(shapeinput, num_class, w_decay=0):
    inputs = Input((shapeinput[0],shapeinput[1],shapeinput[2],1))
    filters = [4,4,4,8]
    x = Conv3D(filters=4,use_bias=False,kernel_size=(3,3,5), padding =       'valid',strides = 1)(inputs)
    x = BatchNormalization()(x)
    x = LeakyReLU()(x)

    for i in range(4):
      x = Conv3D(filters=filters[i],use_bias=False,  kernel_size=(3,3,5),padding = 'valid',strides = 1)(x)
      a1 = AttentionBlock(filters[i])(x)
      #a1 = LeakyReLU()(a1)
      b1 = AttentionBlock(filters[i])(x)
      #b1 = LeakyReLU()(b1)
      x = Add()([a1,b1])
      x = Dropout(0.4)(x)
      x = BatchNormalization()(x)
      x = LeakyReLU()(x)

    x = Dropout(0.85)(x)
    x = Flatten()(x)
    x = Dropout(0.85)(x)
    x = Dense(units=128, use_bias=True)(x)
    x = LeakyReLU()(x)
    x = Dense(units=64, use_bias=True)(x)
    x = LeakyReLU()(x)

    output_layer = Dense(units=num_class, activation='softmax')(x)
    clf = Model(inputs=inputs, outputs=output_layer)
    clf.compile(loss='categorical_crossentropy',
                optimizer=Adam(learning_rate=0.001), metrics=['accuracy'])
    return clf

def main():
    parser = argparse.ArgumentParser(description='Algorithms traditional ML')
    parser.add_argument('--dataset', type=str, required=True,
                        choices=["IP", "UP", "SV", "UH",
                                 "DIP", "DUP", "DIPr", "DUPr"],
                        help='dataset (options: IP, UP, SV, UH, DIP, DUP, DIPr, DUPr)')
    parser.add_argument('--repeat', default=1, type=int, help='Number of runs')
    parser.add_argument('--components', default=None,
                        type=int, help='dimensionality reduction')
    parser.add_argument('--spatialsize', default=9,
                        type=int, help='windows size')
    parser.add_argument('--wdecay', default=0.02, type=float,
                        help='apply penalties on layer parameters')
    parser.add_argument('--preprocess', default="standard",
                        type=str, help='Preprocessing')
    parser.add_argument('--splitmethod', default="sklearn",
                        type=str, help='Method for split datasets')
    parser.add_argument('--random_state', default=42, type=int,
                        help='The seed of the pseudo random number generator to use when shuffling the data')
    parser.add_argument('--tr_percent', default=0.1,
                        type=float, help='samples of train set')
    parser.add_argument('--use_val', action='store_true',
                        help='Use validation set')
    parser.add_argument('--val_percent', default=0.1,
                        type=float, help='samples of val set')
    parser.add_argument(
        '--verbosetrain', action='store_true', help='Verbose train')
    #########################################
    parser.add_argument('--set_parameters', action='store_false',
                        help='Set some optimal parameters')
    ############## CHANGE PARAMS ############
    parser.add_argument('--batch_size', default=64, type=int,
                        help='Number of training examples in one forward/backward pass.')
    parser.add_argument('--epochs', default=100, type=int,
                        help='Number of full training cycle on the training set')
    #########################################

    args = parser.parse_args()
    state = {k: v for k, v in args._get_kwargs()}

    if args.set_parameters:
        args = set_params(args)

    pixels, labels, num_class = \
        mydata.loadData(args.dataset, num_components=args.components,
                        preprocessing=args.preprocess)
    pixels, labels = mydata.createImageCubes(
        pixels, labels, windowSize=args.spatialsize, removeZeroLabels=False)
    stats = np.ones((args.repeat, num_class+3)) * -1000.0  # OA, AA, K, Aclass
    for pos in range(args.repeat):
        rstate = args.random_state+pos if args.random_state != None else None
        if args.dataset in ["UH", "DIP", "DUP", "DIPr", "DUPr"]:
            x_train, x_test, y_train, y_test = \
                mydata.load_split_data_fix(
                    args.dataset, pixels)  # , rand_state=args.random_state+pos)
        else:
            pixels = pixels[labels != 0]
            labels = labels[labels != 0] - 1
            x_train, x_test, y_train, y_test = \
                mydata.split_data(
                    pixels, labels, args.tr_percent, rand_state=rstate)

        if args.use_val:
            x_val, x_test, y_val, y_test = \
                mydata.split_data(
                    x_test, y_test, args.val_percent, rand_state=rstate)

        inputshape = x_train.shape[1:]
        clf = get_model_compiled(inputshape, num_class, w_decay=args.wdecay)
        valdata = (x_val, keras_to_categorical(y_val, num_class)) if args.use_val else (
            x_test, keras_to_categorical(y_test, num_class))
        clf.fit(x_train, keras_to_categorical(y_train, num_class),
                batch_size=args.batch_size,
                epochs=args.epochs,
                verbose=args.verbosetrain,
                validation_data=valdata,
                callbacks=[ModelCheckpoint("/tmp/best_model.h5", monitor='val_accuracy', verbose=0, save_best_only=True)])
        clf.load_weights("/tmp/best_model.h5")
        clf.compile(loss='categorical_crossentropy',
                optimizer=Adam(learning_rate=0.001), metrics=['accuracy'])
        print("PARAMETERS", clf.count_params())
        stats[pos, :] = mymetrics.reports(
            np.argmax(clf.predict(x_test), axis=1), y_test)[2]
    print(args.dataset, list(stats[-1]))

if __name__ == '__main__':
    main()


# USAGE
# python align_faces.py --shape-predictor shape_predictor_68_face_landmarks.dat --image images/example_01.jpg

# import the necessary packages
from imutils.face_utils import FaceAligner
from imutils.face_utils import rect_to_bb
import argparse
import imutils
import dlib
import cv2

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
	help="path to facial landmark predictor")
ap.add_argument("-i", "--image", required=True,
	help="path to input image")
args = vars(ap.parse_args())

# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor and the face aligner
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
# 0.25 is the desired zoom 0.25 is the default
fa = FaceAligner(predictor, desiredLeftEye=(0.25, 0.25),desiredFaceWidth=112)

# load the input image, resize it, and convert it to grayscale
image = cv2.imread(args["image"])
image = imutils.resize(image, width=800)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 2)

# loop over the face detections
# rect contains the bounding boxes
for rect in rects:
	# extract the ROI of the *original* face, then align the face
	# using facial landmarks
	(x, y, w, h) = rect_to_bb(rect)
	faceAligned = fa.align(image, gray, rect)
	#faceAligned = cv2.resize(faceAligned, (224, 224))
	import uuid
	f = str(uuid.uuid4())
	# write resulting image
	cv2.imwrite("/home/monete/monete@gmail.com/studying/IA/thesis/deeplearning/dataset/fer2013/output/7-surprise/" + f + ".png", faceAligned)

	# display the output images
	#cv2.imshow("Aligned", faceAligned)
	#cv2.waitKey(0)


import torch
import torch.nn as nn

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv_1 = self._con_dw_sep(3, 16)
        self.conv_2 = self._con_dw_sep(16, 32)
        self.conv_3 = self._con_dw_sep(32, 64)

        self.fc1 = nn.Linear(10816, 512)
        self.fc2 = nn.Linear(512, 1)

        self.dropout = nn.Dropout(0.5)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def _con_dw_sep(self, C_in, C_out):
        conv_layer = nn.Sequential(
            nn.Conv2d(C_in, C_in, kernel_size = 4, groups=C_in),
            nn.Conv2d(C_in, C_out , kernel_size=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        return conv_layer

    def forward(self, x):
        out = self.conv_1(x)
        out = self.conv_2(out)
        out = self.conv_3(out)

        out = out.view(-1, 10816)

        out = self.dropout(out)
        out = self.fc1(out)
        out = self.relu(out)

        out = self.dropout(out)
        out = self.fc2(out)

        out = out.squeeze()
        out = self.sigmoid(out)

        return out.float()


from django.contrib.auth.models import User
from django.db import models
import cover.models
from documents.models import (Book, Chunk, Image, BookPublishRecord,
        ImagePublishRecord)
from documents.signals import post_publish
from dvcs.signals import post_publishable

def book_changed(sender, instance, created, **kwargs):
    instance.touch()
    for c in instance:
        c.touch()
models.signals.post_save.connect(book_changed, sender=Book)

def chunk_changed(sender, instance, created, **kwargs):
    instance.book.touch()
    instance.touch()
models.signals.post_save.connect(chunk_changed, sender=Chunk)

def image_changed(sender, instance, created, **kwargs):
    instance.touch()
models.signals.post_save.connect(image_changed, sender=Image)

def publish_listener(sender, *args, **kwargs):
    if isinstance(sender, BookPublishRecord):
        sender.book.touch()
        for c in sender.book:
            c.touch()
    elif isinstance(sender, ImagePublishRecord):
        sender.image.touch()
post_publish.connect(publish_listener)

def chunk_publishable_listener(sender, *args, **kwargs):
    sender.tree.touch()
    if isinstance(sender.tree, Chunk):
        sender.tree.book.touch()
post_publishable.connect(chunk_publishable_listener)

def publishable_listener(sender, *args, **kwargs):
    sender.tree.touch()
post_publishable.connect(publishable_listener, sender=Image)

def listener_create(sender, instance, created, **kwargs):
    if created:
        instance.chunk_set.create(number=1, slug='1')
models.signals.post_save.connect(listener_create, sender=Book)

def cover_changed(sender, instance, created, **kwargs):
    for book in instance.book_set.all():
        book.build_cover()
models.signals.post_save.connect(cover_changed, sender=cover.models.Image)


"""AD&D Second Edition Combat Simulator"""

# Always prefer setuptools over distutils
from setuptools import setup, find_packages
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='adnd2e-combat-simulator',
    version='1.0.2',

    description='A tool to simulate combat in AD&D 2nd Edition',
    long_description=long_description,
    url='https://github.com/gene1wood/adnd2e-combat-simulator',
    author='Gene Wood',
    author_email='gene_wood@cementhorizon.com',
    license='GPL-3.0',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: End Users/Desktop',
        'Topic :: Games/Entertainment :: Role-Playing',
        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
    ],
    keywords='ad&d d&d adnd dnd combat',
    packages=find_packages(exclude=['contrib', 'docs', 'tests']),
    install_requires=['PyYAML', 'dice', 'colorama'],
    package_data={
        'adnd2e_combat_simulator': ['combatants.example.yaml'],
    },
    entry_points={
        'console_scripts': [
            'battle=adnd2e_combat_simulator:main',
        ],
    },
)


import pprint
import threading
from typing import Dict, TYPE_CHECKING
from PySide2.QtWidgets import QTabWidget, QTextBrowser, QWidget

from lib.comm import get_var, set_var
from widgets import PMTableView, PMGTableWidget, PMDockObject, PMGTableViewer, PMGJsonTree

if TYPE_CHECKING:
    from lib.extensions.extensionlib.extension_lib import extension_lib

class AbstractViewer(object):
    """
    抽象视图
    """

    @staticmethod
    def is_valid(data) -> bool:
        """
        判断data是否为合法的变量类型
        """
        return True

    def set_data(self, data: object, metadata: dict):
        """
        设置其显示数据的值为data，显示的元数据为meadata。
        """
        pass

class PDDataViewer(PMGTableViewer, AbstractViewer):
    """
    显示Pandas数据的视图
    """

    def __init__(self, parent=None):
        PMGTableViewer.__init__(self, parent, table_view=PMTableView())
        AbstractViewer.__init__(self)
        # self.action_split_by_columns:QAction = self.table_view.menu.addAction('提取当前列')
        # self.action_split_by_columns.triggered.connect(self.split_by_columns)

    def split_by_columns(self):
        # row =
        # self.table_view.data
        print('splitted!')

    @staticmethod
    def is_valid(data):
        import pandas as pd
        return isinstance(data, pd.DataFrame)

    def set_data(self, data: object, metadata: dict = None):
        super().set_data(data)

class NPDataViewer(PMGTableViewer, AbstractViewer):
    """
    显示numpy.ndarray的视图
    """

    def __init__(self, parent=None):
        PMGTableViewer.__init__(self, parent, table_view=PMTableView())
        AbstractViewer.__init__(self)

    @staticmethod
    def is_valid(data):
        import numpy
        return isinstance(data, numpy.ndarray)

    def set_data(self, data: object, metadata: dict = None):
        super(NPDataViewer, self).set_data(data)

class JsonViewer(PMGJsonTree, AbstractViewer):
    """
    树状图，专门显示dict型数据。
    """

    def __init__(self, parent=None):
        PMGJsonTree.__init__(self, parent)
        # AbstractViewer.__init__(self)

    @staticmethod
    def is_valid(data) -> bool:
        return isinstance(data, dict)

    def set_data(self, data: Dict[str, object], metadata: dict = None) -> None:
        self.set_data_dic({self.tr('Data:'): data})
        self.expandToDepth(1)

class GeneralIterableViewer(PMGTableWidget, AbstractViewer):
    """
    显示可迭代对象的视图
    这个变量可以为列表、每行长度不等的二维嵌套列表等。
    解析方式为先从第一个可迭代维度上解析，取出元素，也就是data[0],data[1]。。。data[len(data)-1]，逐行显示。
    如果元素不可迭代，那么就填在对应行的第一列；如果元素可迭代的，那么就把元素依次填写在同一行各个列中。
    data[0][1],data[0][2]....
    """

    def __init__(self, parent=None):
        PMGTableWidget.__init__(self, parent)
        AbstractViewer.__init__(self)

    @staticmethod
    def is_valid(data: object):
        import numpy
        import pandas
        if isinstance(data, numpy.ndarray) or isinstance(
                data, pandas.DataFrame):
            return False
        return PMGTableWidget.check_data_can_be_displayed_by_table(data=data)

    def set_data(self, data: 'np.ndarray', metadata: dict = None):
        super().set_data_2d(data)

class GeneralObjectViewer(QTextBrowser, AbstractViewer):
    """
    一个文本显示控件
    专门显示metadata。
    """

    def __init__(self, parent=None):
        QTextBrowser.__init__(self, parent)
        AbstractViewer.__init__(self)

    @staticmethod
    def is_valid(data: object):
        import numpy
        import pandas
        if isinstance(data, numpy.ndarray) or isinstance(
                data, pandas.DataFrame):
            return False
        elif GeneralIterableViewer.is_valid(data):
            return False
        return True

    def set_data(self, data: object, metadata: dict = None):
        self.setText(self.tr('value:') + '\n\n   ' + pprint.pformat(data)
                     + '\n\n\n' + self.tr('meta data:') + '\n\n' + pprint.pformat(metadata))

viewer_classes = [
    PDDataViewer,
    NPDataViewer,
    GeneralIterableViewer,
    JsonViewer,
    GeneralObjectViewer]

def build_viewer(data: object, metadata: object) -> 'QWidget':
    """
    创建变量视图的工厂函数。
    """
    for viewer_class in viewer_classes:
        if viewer_class.is_valid(data):
            viewer = viewer_class()
            viewer.set_data(data, metadata)

            return viewer

def get_viewer_class(data):
    for viewer_class in viewer_classes:
        if viewer_class.is_valid(data):
            return viewer_class

class PMVariableViewerWidget(QTabWidget, PMDockObject):
    """
    在这里采用了多继承的方式。注意，一定要把PMDockObject写在右边。
    """
    if TYPE_CHECKING:
        lib = extension_lib

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTabsClosable(True)
        self.var_view_tables: Dict[str, object] = {}
        self.tabCloseRequested.connect(self.on_tab_close_request)

        self.variable_view_factory = None

    def is_temporary(self) -> bool:
        return True

    def get_widget_text(self) -> str:
        return self.tr('Variable Viewer')

    def set_lib(self, lib):
        '''
        设置回调函数。注意，只有主线程中才能刷新界面，否则将引起崩溃。
        :param varname:
        :param variable:
        :return:
        '''
        self.lib = lib

        def on_changed(varname: str, variable, source: str):
            if threading.current_thread() is threading.main_thread():
                if varname in self.var_view_tables:
                    self.show_data(varname, raise_window=False)

        def on_deletion(varname: str, provider: str):
            if threading.current_thread() is threading.main_thread():
                if varname in self.var_view_tables:
                    tab = self.var_view_tables.pop(varname)
                    index = self.indexOf(tab)
                    self.removeTab(index)

        self.lib.Data.add_data_changed_callback(on_changed)
        self.lib.Data.add_data_deleted_callback(on_deletion)

    def show_data(self, dataname: str, raise_window=True):
        """
        显示数据，显示数据之后，使得上层控件将其提升到上层可见。特别适用于几个dockwidget叠在一起的情况。
        如果与已有的数据不是同一种类型，就移除原先的，重建新的。
        :param dataname:
        :return:
        """
        from lib.comm.base import DataDesc
        desc: DataDesc = self.lib.Data.get_data_desc(dataname)
        if desc.big:
            data = get_var(dataname, preview=True)
        else:
            data = get_var(dataname)

        try:
            dataview: 'QWidget' = self.var_view_tables.get(dataname)
            metadata = self.lib.Data.get_metadata(dataname)
        except BaseException:
            import traceback
            traceback.print_exc()
            return
        last_index = self.count()
        if dataview is not None:
            if not isinstance(dataview, get_viewer_class(data)):
                index = self.indexOf(dataview)
                self.removeTab(index)
                last_index = index
                self.var_view_tables.pop(dataname)
                dataview = None

        if dataview is None:
            dataview = build_viewer(data, metadata)
            self.insertTab(last_index, dataview, dataname)
            self.addTab(dataview, dataname)
            self.var_view_tables[dataname] = dataview
        dataview.set_data(data, metadata)

        if hasattr(dataview, 'data_modified_signal'):
            def set_var_data_modified():
                set_var(dataname, dataview.get_data())

            dataview.data_modified_signal.connect(set_var_data_modified)

        dataview.setWindowTitle(dataname)
        dataview.windowTitleChanged.connect(self.on_tab_window_title_changed)

        self.setCurrentWidget(dataview)
        if raise_window:
            self.lib.UI.raise_dock_into_view('data_view_table')

    def on_tab_window_title_changed(self, title: str):
        widget = self.sender()
        self.setTabText(self.indexOf(widget), title)

    def on_tab_close_request(self, close_index: int):
        self.var_view_tables.pop(self.tabText(close_index))

        tab_to_close: 'QTextBrowser' = self.widget(close_index)
        tab_to_close.deleteLater()

        self.removeTab(close_index)

{'numpy': 'numpy', 'pandas': 'pandas'}.is_valid


import argparse
import os
import shutil
import numpy as np
import torch
import torchvision
from torch import nn as nn
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import Dataset, DataLoader
from tqdm import tqdm

import helpers
from dcgan import generators, discriminators
from dcgan.train_config import TrainConfig

def train(dataset: Dataset, train_config: TrainConfig,
          generator, discriminator):

    global_step = epoch = 0

    if train_config.overwrite and os.path.exists(train_config.experiment_dirpath):
        shutil.rmtree(train_config.experiment_dirpath)

    real_images_writer = SummaryWriter(f"{train_config.experiment_dirpath}/real")
    fake_images_writer = SummaryWriter(f"{train_config.experiment_dirpath}/fake")
    stats_writer = SummaryWriter(f"{train_config.experiment_dirpath}/stats")

    dataloader = DataLoader(
        dataset=dataset, batch_size=train_config.batch_size, shuffle=True, num_workers=train_config.num_workers
    )
    num_iterations_per_epoch = len(dataset) // train_config.batch_size

    generator = generator.to(device=train_config.device).train()
    discriminator = discriminator.to(device=train_config.device).train()

    criterion = torch.nn.BCELoss()
    gen_opt = torch.optim.Adam(params=generator.parameters(), lr=train_config.lr, betas=(0.5, 0.999))
    disc_opt = torch.optim.Adam(params=discriminator.parameters(), lr=train_config.lr, betas=(0.5, 0.999))

    while True:
        for batch_idx, (real_img_batch, labels) in tqdm(enumerate(dataloader), total=num_iterations_per_epoch, leave=False):
            img_batch = normalize(real_img_batch)
            if train_config.conditional_dim > 0:
                conditional_input = helpers.conditional_input_encoder_discriminator(
                    labels=labels, cardinality=train_config.conditional_dim, spatial_size=train_config.image_size
                )
                img_batch = torch.cat([img_batch, conditional_input], dim=1)
            img_batch = img_batch.to(device=train_config.device)

            # train discriminator
            noise = torch.randn(size=(len(labels), train_config.z_dim))
            if train_config.conditional_dim > 0:
                conditional_input = helpers.conditional_input_encoder_generator(
                    labels=labels, cardinality=train_config.conditional_dim
                )
                noise = torch.cat([noise, conditional_input], dim=1)
            noise = noise.to(device=train_config.device)
            fake_img_batch = generator(noise)
            if train_config.conditional_dim > 0:
                conditional_input = helpers.conditional_input_encoder_discriminator(
                    labels=labels, cardinality=train_config.conditional_dim, spatial_size=train_config.image_size
                ).to(device=train_config.device)
                fake_img_batch = torch.cat([fake_img_batch, conditional_input], dim=1)

            real_proba = discriminator(img_batch)
            fake_proba = discriminator(fake_img_batch.detach())

            disc_loss = (criterion(real_proba, torch.ones_like(real_proba)) +
                         criterion(fake_proba, torch.zeros_like(fake_proba)))
            disc_loss = disc_loss / 2

            disc_opt.zero_grad()
            disc_loss.backward()
            disc_opt.step()

            # train generator
            fake_proba = discriminator(fake_img_batch)
            gen_loss = criterion(fake_proba, torch.ones_like(fake_proba))

            gen_opt.zero_grad()
            gen_loss.backward()
            gen_opt.step()

            if global_step % train_config.send_every == 0:
                stats_writer.add_scalar("generator loss", gen_loss, global_step=global_step)
                stats_writer.add_scalar("discriminator loss", disc_loss, global_step=global_step)
                stats_writer.add_scalar("total loss", gen_loss + disc_loss, global_step=global_step)

            if global_step % train_config.show_every == 0:
                # visualize
                real_images_grid = torchvision.utils.make_grid(
                    real_img_batch, normalize=True
                )
                real_images_writer.add_image("real images", real_images_grid, global_step=epoch)

                generated_images = generate(train_config=train_config, generator=generator)
                generated_images = torchvision.utils.make_grid(
                    generated_images, normalize=True
                )
                fake_images_writer.add_image("fake images", generated_images, global_step=global_step)
            global_step += 1
        epoch += 1

def normalize(x):
    return 2 * x - 1

def generate(train_config: TrainConfig, generator: nn.Module) -> torch.Tensor:
    noise = torch.randn(train_config.batch_size, train_config.z_dim)
    if train_config.conditional_dim > 0:
        label = np.random.randint(low=0, high=train_config.conditional_dim)
        labels = np.asarray([label] * train_config.batch_size)
        labels = torch.from_numpy(labels)
        conditional_input = helpers.conditional_input_encoder_generator(
            labels=labels, cardinality=train_config.conditional_dim
        )
        noise = torch.cat([noise, conditional_input], dim=1)
    noise = noise.to(device=train_config.device)
    with torch.no_grad():
        generated_images = generator(noise).view(train_config.batch_size, -1, train_config.image_size, train_config.image_size)
    return generated_images

def get_dataset_and_in_channels(dataset_name: str, image_size: int):
    name_to_dataset_cls = {
        "mnist": (torchvision.datasets.MNIST, 1),
        "cifar-10": (torchvision.datasets.CIFAR10, 3)
    }
    dataset_cls, in_channels = name_to_dataset_cls[dataset_name]
    dataset = dataset_cls(
        root="data/", train=True,
        transform=torchvision.transforms.Compose([
            torchvision.transforms.Resize(image_size),
            torchvision.transforms.ToTensor()
        ]),
        download=True
    )
    return dataset, in_channels

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--exp_name")
    parser.add_argument("--dataset", choices=["mnist", "cifar-10"],  default="mnist")
    parser.add_argument("--image_size", type=int, default=32)
    return parser.parse_args()

def main():
    args = parse_args()

    exp_dir = "../experiments"
    if args.exp_name is not None:
        exp_dir = f"{exp_dir}/{args.exp_name}"

    dataset, in_channels = get_dataset_and_in_channels(dataset_name=args.dataset, image_size=args.image_size)

    config = TrainConfig(
        experiment_dirpath=exp_dir,
        image_size=args.image_size,
        in_channels=in_channels
    )

    generator = generators.DCGenerator.from_train_config(config)
    discriminator = discriminators.DCDiscriminator.from_train_config(config)

    train(
        dataset=dataset, train_config=config, generator=generator, discriminator=discriminator
    )

if __name__ == '__main__':
    main()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import os
from vgg import load_pretrained_VGG16_pool5
import cifar10_utils
import tensorflow as tf
import numpy as np

LEARNING_RATE_DEFAULT = 1e-4
BATCH_SIZE_DEFAULT = 128
MAX_STEPS_DEFAULT = 15000
EVAL_FREQ_DEFAULT = 1000
CHECKPOINT_FREQ_DEFAULT = 5000
PRINT_FREQ_DEFAULT = 10
OPTIMIZER_DEFAULT = 'ADAM'
REFINE_AFTER_K_STEPS_DEFAULT = 0

DATA_DIR_DEFAULT = './cifar10/cifar-10-batches-py'
LOG_DIR_DEFAULT = './logs/cifar10'
CHECKPOINT_DIR_DEFAULT = './checkpoints'

def train_step(loss):
    """
    Defines the ops to conduct an optimization step. You can set a learning
    rate scheduler or pick your favorite optimizer here. This set of operations
    should be applicable to both ConvNet() and Siamese() objects.

    Args:
        loss: scalar float Tensor, full loss = cross_entropy + reg_loss

    Returns:
        train_op: Ops for optimization.
    """
    ########################
    # PUT YOUR CODE HERE  #
    ########################
    train_op = tf.train.AdamOptimizer(FLAGS.learning_rate).minimize(loss)
    ########################
    # END OF YOUR CODE    #
    ########################

    return train_op

def fully_connected_layers(vgg_output):
    # dense layers
    with tf.name_scope('dense'):
        flat = tf.reshape(vgg_output, [vgg_output.get_shape()[0].value, -1], name='flat_out')

        xavier = tf.contrib.layers.xavier_initializer()
        const0 = tf.constant_initializer(0.)
        l2_reg = tf.contrib.layers.l2_regularizer(0.1)
        n_classes = 10

        with tf.name_scope('dense1'):
            w1 = tf.get_variable('w1', shape=[flat.get_shape()[1], 384], dtype=tf.float32,
                                 initializer=xavier, regularizer=l2_reg)
            b1 = tf.get_variable('b1', shape=[384], dtype=tf.float32,
                                 initializer=const0)
            fc1 = tf.nn.relu(tf.matmul(flat, w1) + b1, name='d1_out')

        # fc2	        Multiplication	[384, 192]
        #               ReLU
        with tf.name_scope('dense2'):
            w2 = tf.get_variable('w2', shape=[384, 192], dtype=tf.float32,
                                 initializer=xavier, regularizer=l2_reg)
            b2 = tf.get_variable('b2', shape=[192], dtype=tf.float32,
                                 initializer=const0)
            fc2 = tf.nn.relu(tf.matmul(fc1, w2) + b2, name='d2_out')

        # fc3	        Multiplication	[192, 10]
        with tf.name_scope('dense3'):
            w3 = tf.get_variable('w3', shape=[192, n_classes], dtype=tf.float32,
                                 initializer=xavier, regularizer=l2_reg)
            b3 = tf.get_variable('b3', shape=[n_classes], dtype=tf.float32,
                                 initializer=const0)
            fc3 = tf.matmul(fc2, w3) + b3
        return fc3

def vgg_loss(logits, labels):
    ce_loss = tf.nn.softmax_cross_entropy_with_logits(logits, labels)
    ce_loss = tf.reduce_mean(ce_loss)
    reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
    reg_loss = tf.to_float(0.)
    if None not in reg_losses:  # this IS meant to switch while building the graph
        reg_loss = reduce(lambda x, y: tf.add(x, y), reg_losses)
    loss = ce_loss + reg_loss
    tf.scalar_summary('ce_loss', ce_loss)
    tf.scalar_summary('reg_loss', reg_loss)
    tf.scalar_summary('full_loss', loss)

    return loss

def accuracy(logits, labels):
        guesses = tf.argmax(logits, dimension=1)
        targets = tf.argmax(labels, dimension=1)
        score = tf.to_int32(tf.equal(guesses, targets))
        acc = tf.reduce_sum(score) / tf.size(score)

        tf.scalar_summary('accuracy', acc)
        return acc

def train():
    """
    Performs training and evaluation of your model.

    First define your graph using vgg.py with your fully connected layer.
    Then define necessary operations such as trainer (train_step in this case),
    savers and summarizers. Finally, initialize your model within a
    tf.Session and do the training.

    ---------------------------------
    How often to evaluate your model:
    ---------------------------------
    - on training set every PRINT_FREQ iterations
    - on test set every EVAL_FREQ iterations

    ---------------------------
    How to evaluate your model:
    ---------------------------
    Evaluation on test set should be conducted over full batch, i.e. 10k images,
    while it is alright to do it over minibatch for train set.
    """

    # Set the random seeds for reproducibility. DO NOT CHANGE.
    tf.set_random_seed(42)
    np.random.seed(42)

    ########################
    # PUT YOUR CODE HERE  #
    ########################
    cifar10 = cifar10_utils.get_cifar10(FLAGS.data_dir)
    data_dims = list(cifar10.train.images.shape[1:])
    n_classes = 10
    with tf.Graph().as_default():
        x_pl = tf.placeholder(dtype=tf.float32, shape=[FLAGS.batch_size] + data_dims)
        y_pl = tf.placeholder(dtype=tf.float32, shape=[FLAGS.batch_size, n_classes])
        stopgrads = tf.placeholder(dtype=tf.bool)
        pool5, assign_ops = load_pretrained_VGG16_pool5(x_pl, scope_name='vgg')
        pool5 = tf.cond(stopgrads, lambda: tf.stop_gradient(pool5), lambda: pool5)
        logits = fully_connected_layers(pool5)
        loss = vgg_loss(logits, y_pl)
        acc = accuracy(logits, y_pl)

        train_op = train_step(loss)
        summary_op = tf.merge_all_summaries()
        init_op = tf.initialize_all_variables()

        with tf.Session() as sess:
            saver = tf.train.Saver()
            sess.run(init_op)
            sess.run(assign_ops)
            train_summary_writer = tf.train.SummaryWriter(FLAGS.log_dir + '/train', sess.graph)
            test_summary_writer = tf.train.SummaryWriter(FLAGS.log_dir + '/test', sess.graph)

            for step in range(FLAGS.max_steps):
                x, y = cifar10.train.next_batch(FLAGS.batch_size)
                switch = True if step < FLAGS.refine_after_k else False
                feed = {x_pl: x, y_pl: y, stopgrads: switch}
                train_loss, train_acc, summary_str, _ = sess.run([loss, acc, summary_op, train_op], feed_dict=feed)

                if step == 0 or (step + 1) % FLAGS.print_freq == 0 or step + 1 == FLAGS.max_steps:
                    print('TRAIN step: ', str(step), ' err: ', str(train_loss), ' acc: ', str(train_acc))
                    train_summary_writer.add_summary(summary_str, step)
                    train_summary_writer.flush()
                if step == 0 or (step + 1) % FLAGS.eval_freq == 0 or step + 1 == FLAGS.max_steps:
                    x, y = cifar10.test.images, cifar10.test.labels
                    num_batches = int(np.floor(x.shape[0] / FLAGS.batch_size))

                    test_err = 0.
                    test_acc = 0.
                    for idx in range(num_batches):

                        x_batch = x[idx * FLAGS.batch_size:(idx + 1) * FLAGS.batch_size, :, :, :]
                        y_batch = y[idx * FLAGS.batch_size:(idx + 1) * FLAGS.batch_size, :]
                        feed = {x_pl: x_batch, y_pl: y_batch, stopgrads: True}

                        batch_err, batch_acc = sess.run([loss, acc], feed_dict=feed)

                        test_err += batch_err
                        test_acc += batch_acc
                        summary_str = sess.run(summary_op, feed_dict=feed)  # possibly incorrect. should pool summaries
                        test_summary_writer.add_summary(summary_str, step)
                        test_summary_writer.flush()
                    test_err /= num_batches
                    test_acc /= num_batches
                    print('--- TEST --- step: ', str(step), ' err: ', str(train_loss), ' acc: ', str(train_acc))

                    # summary_str = sess.run(summary_op, feed_dict=feed)  # possibly incorrect. should pool summaries
                    # test_summary_writer.add_summary(summary_str, step)
                    # test_summary_writer.flush()
                if (step + 1) % FLAGS.checkpoint_freq == 0 or step + 1 == FLAGS.max_steps:
                    checkpoint_file = os.path.join(FLAGS.checkpoint_dir, 'ckpt')
                    saver.save(sess, checkpoint_file, global_step=(step + 1))

    ########################
    # END OF YOUR CODE    #
    ########################

def initialize_folders():
    """
    Initializes all folders in FLAGS variable.
    """

    if not tf.gfile.Exists(FLAGS.log_dir):
        tf.gfile.MakeDirs(FLAGS.log_dir)

    if not tf.gfile.Exists(FLAGS.data_dir):
        tf.gfile.MakeDirs(FLAGS.data_dir)

    if not tf.gfile.Exists(FLAGS.checkpoint_dir):
        tf.gfile.MakeDirs(FLAGS.checkpoint_dir)

def print_flags():
    """
    Prints all entries in FLAGS variable.
    """
    for key, value in vars(FLAGS).items():
        print(key + ' : ' + str(value))

def main(_):
    print_flags()

    initialize_folders()
    train()

if __name__ == '__main__':
    # Command line arguments
    parser = argparse.ArgumentParser()

    parser.add_argument('--learning_rate', type = float, default = LEARNING_RATE_DEFAULT,
                        help='Learning rate')
    parser.add_argument('--max_steps', type = int, default = MAX_STEPS_DEFAULT,
                        help='Number of steps to run trainer.')
    parser.add_argument('--batch_size', type = int, default = BATCH_SIZE_DEFAULT,
                        help='Batch size to run trainer.')
    parser.add_argument('--print_freq', type = int, default = PRINT_FREQ_DEFAULT,
                        help='Frequency of evaluation on the train set')
    parser.add_argument('--eval_freq', type = int, default = EVAL_FREQ_DEFAULT,
                        help='Frequency of evaluation on the test set')
    parser.add_argument('--refine_after_k', type = int, default = REFINE_AFTER_K_STEPS_DEFAULT,
                        help='Number of steps after which to refine VGG model parameters (default 0).')
    parser.add_argument('--checkpoint_freq', type = int, default = CHECKPOINT_FREQ_DEFAULT,
                        help='Frequency with which the model state is saved.')
    parser.add_argument('--data_dir', type = str, default = DATA_DIR_DEFAULT,
                        help='Directory for storing input data')
    parser.add_argument('--log_dir', type = str, default = LOG_DIR_DEFAULT,
                        help='Summaries log directory')
    parser.add_argument('--checkpoint_dir', type = str, default = CHECKPOINT_DIR_DEFAULT,
                        help='Checkpoint directory')

    FLAGS, unparsed = parser.parse_known_args()

    tf.app.run()


"""gistandard URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.views.static import serve
from gistandard.settings import MEDIA_ROOT

import xadmin

from users.views_user import LoginView, IndexView, LogoutView
from system.views import SystemView
from adm.views import AdmView
from personal import views as personal_views
from personal import views_work_order as order

urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),
    url(r'^$', IndexView.as_view(), name='index'),
    # 用户登录
    url(r'^login/$', LoginView.as_view(), name='login'),
    url(r'^logout/$', LogoutView.as_view(), name="logout"),

    url(r'^system/$', SystemView.as_view(), name="system"),
    url(r'^system/basic/', include('users.urls', namespace='system-basic')),
    url(r'^system/rbac/', include('rbac.urls', namespace='system-rbac')),
    url(r'^system/tools/', include('system.urls', namespace='system-tools')),

    url(r'^adm/$', AdmView.as_view(), name="adm-main"),
    url(r'^adm/bsm/', include('adm.urls', namespace='adm-bsm')),
    url(r'^adm/equipment/', include('adm.urls_equipment', namespace='adm-equipment')),
    url(r'^adm/asset/', include('adm.urls_asset', namespace='adm-asset')),

    url(r'^personal/$', personal_views.PersonalView.as_view(), name="personal"),
    url(r'^personal/userinfo', personal_views.UserInfoView.as_view(), name="personal-user_info"),
    url(r'^personal/uploadimage', personal_views.UploadImageView.as_view(), name="personal-uploadimage"),
    url(r'^personal/passwordchange', personal_views.PasswdChangeView.as_view(), name="personal-passwordchange"),
    url(r'^personal/phonebook', personal_views.PhoneBookView.as_view(), name="personal-phonebook"),
    url(r'^personal/workorder_Icrt/$', order.WorkOrderView.as_view(), name="personal-workorder_Icrt"),
    url(r'^personal/workorder_Icrt/list', order.WorkOrderListView.as_view(), name="personal-workorder-list"),
    url(r'^personal/workorder_Icrt/create', order.WorkOrderCreateView.as_view(), name="personal-workorder-create"),
    url(r'^personal/workorder_Icrt/detail', order.WorkOrderDetailView.as_view(), name="personal-workorder-detail"),
    url(r'^personal/workorder_Icrt/delete', order.WorkOrderDeleteView.as_view(), name="personal-workorder-delete"),
    url(r'^personal/workorder_Icrt/update', order.WorkOrderUpdateView.as_view(), name="personal-workorder-update"),
    url(r'^personal/workorder_app/$', order.WorkOrderView.as_view(), name="personal-workorder_app"),
    url(r'^personal/workorder_app/send', order.WrokOrderSendView.as_view(), name="personal-workorder-send"),
    url(r'^personal/workorder_rec/$', order.WorkOrderView.as_view(), name="personal-workorder_rec"),
    url(r'^personal/workorder_rec/execute', order.WorkOrderExecuteView.as_view(), name="personal-workorder-execute"),
    url(r'^personal/workorder_rec/finish', order.WorkOrderFinishView.as_view(), name="personal-workorder-finish"),
    url(r'^personal/workorder_rec/upload', order.WorkOrderUploadView.as_view(), name="personal-workorder-upload"),
    url(r'^personal/workorder_rec/return', order.WorkOrderReturnView.as_view(), name="personal-workorder-return"),
    url(r'^personal/workorder_Icrt/upload', order.WorkOrderProjectUploadView.as_view(),
        name="personal-workorder-project-upload"),
    url(r'^personal/workorder_all/$', order.WorkOrderView.as_view(), name="personal-workorder_all"),
    url(r'^personal/document/$', order.WorkOrderDocumentView.as_view(), name="personal-document"),
    url(r'^personal/document/list', order.WorkOrderDocumentListView.as_view(), name="personal-document-list"),

]


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

# refer to https://machinelearningmastery.com/multivariate-time-series-forecasting-lstms-keras/
#
# to tune parameters
# refer to http://yangguang2009.github.io/2017/01/08/deeplearning/grid-search-hyperparameters-for-deep-learning/

# In[1]:

from __future__ import print_function

import json
import numpy as np
import os
import pandas as pd
import urllib
import math

from sklearn.model_selection import GridSearchCV
from keras.wrappers.scikit_learn import KerasClassifier

from hyperopt import Trials, STATUS_OK, tpe
from hyperas import optim
from hyperas.distributions import choice, uniform

# connect to poloniex's API
url = 'https://poloniex.com/public?command=returnChartData&currencyPair=USDT_BTC&start=1546300800&end=9999999999&period=300&resolution=auto'

# parse json returned from the API to Pandas DF
openUrl = urllib.request.urlopen(url)
r = openUrl.read()
openUrl.close()
d = json.loads(r.decode())
df = pd.DataFrame(d)

original_columns=[u'date', u'close',  u'high', u'low', u'open', u'volume']
new_columns = ['Timestamp','Close','High','Low','Open','Volume']
df = df.loc[:,original_columns]
df.columns = new_columns
df.to_csv('bitcoin201901to201905.csv',index=None)

# In[2]:

df = df.set_index('Timestamp')
df.head()

# In[3]:

from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM

import seaborn as sns
import numpy as np

# convert series to supervised learning
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	n_vars = 1 if type(data) is list else data.shape[1]
	df = DataFrame(data)
	cols, names = list(), list()
	# input sequence (t-n, ... t-1)
	for i in range(n_in, 0, -1):
		cols.append(df.shift(i))
		names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		if i == 0:
			names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
		else:
			names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
	# put it all together
	agg = concat(cols, axis=1)
	agg.columns = names
	# drop rows with NaN values
	if dropnan:
		agg.dropna(inplace=True)
	return agg

# In[4]:

pyplot.plot(df['Close'].values, label='price')
pyplot.legend()
pyplot.show()

# In[5]:

sns.heatmap(df.corr(), annot=True, cmap='RdYlGn', linewidths=0.1, vmin=0)

# In[6]:

# load dataset
#dataset = read_csv('update_20190301_bitbank_f.csv', header=0, index_col=0)
#values = dataset.values

#dataset.head()

values = df['Close'].values
values = values.reshape(-1, 1)
print(values)

# In[7]:

# ensure all data is float
values = values.astype('float32')
# normalize features
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(values)
# frame as supervised learning
reframed = series_to_supervised(scaled, 1, 1)

#test =  series_to_supervised(values, 1, 1)
#print(test.head())
#print(test.shape)

# In[8]:

print(values.shape)
print(reframed.shape)
print('---------')
#print(reframed.columes)

# split into train and test sets
values = reframed.values
print(values.shape)

n_train_rate = 0.7
n_train = values.shape[0] * n_train_rate
n_train = math.floor(n_train)
print(n_train)

train = values[:n_train, :]
test = values[n_train:, :]

# split into input and outputs
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
# reshape input to be 3D [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)

# In[9]:

import math

# drop columns we don't want to predict
# 只留下 close 列
#reframed.drop(reframed.columns[[6, 7, 8, 10, 11]], axis=1, inplace=True)
#print(reframed.head())

# split into train and test sets
values = reframed.values
print(values.shape)

n_train_rate = 0.7
n_train = values.shape[0] * n_train_rate
n_train = math.floor(n_train)
print(n_train)

train = values[:n_train, :]
test = values[n_train:, :]

# split into input and outputs
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
# reshape input to be 3D [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)

# In[10]:

#!pip install tqdm --upgrade
#!pip install hyperopt --upgrade
#!pip install hyperas --upgrade
type(train_X)

# In[16]:

def data():
    global train_X, test_X, train_y, test_y
    return train_X, test_X, train_y, test_y

# design network
def model(train_X, train_Y, test_X, test_Y):
    model = Sequential()
    model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    model.add(Dense(1))
    model.compile(loss='mae', optimizer='adam')
    history = model.fit(train_X, train_y, epochs={{choice([10, 25, 50])}}, batch_size={{choice([8, 16, 32,50])}}, validation_data=(test_X, test_y), verbose=2, shuffle=False)
    score, acc = model.evaluate(test_X, test_y, verbose=0)
    print('Test accuracy:', acc)
    return {'loss': -acc, 'status': STATUS_OK, 'model': model}

best_run, best_model = optim.minimize(model=model,
                                          data=data,
                                          algo=tpe.suggest,
                                          max_evals=10,
                                          trials=Trials(),
                                          notebook_name='LSTMsinKeras-VirtualCurrency-Simple')
print("Evalutation of best performing model:")
print(best_model.evaluate(test_X, test_y))

# In[ ]:

# plot history
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='test')
pyplot.legend()
pyplot.show()

# In[ ]:

# make a prediction
yhat = model.predict(test_X)
print('yhat.shape', yhat.shape, yhat[0:5, :])
test_X_reshape = test_X.reshape((test_X.shape[0], test_X.shape[2]))
print(test_X_reshape.shape, test_X_reshape[0:5, -7:])

# invert scaling for forecast
inv_yhat = concatenate((yhat, test_X_reshape[:, 1:]), axis=1)
inv_yhat = scaler.inverse_transform(inv_yhat)
print('inv_yhat.shape', inv_yhat.shape, inv_yhat[0:5, :])

inv_yhat = inv_yhat[:,0]
# invert scaling for actual
test_y = test_y.reshape((len(test_y), 1))
inv_y = concatenate((test_y, test_X_reshape[:, 1:]), axis=1)
inv_y = scaler.inverse_transform(inv_y)
inv_y = inv_y[:,0]
# calculate RMSE
# 因为inv_y 预测是下一时刻的值，所以需要把 inv_yhat 往后 shift 一个时刻
rmse = sqrt(mean_squared_error(inv_y[:-1], inv_yhat[1:]))
print('Test RMSE: %.3f' % rmse)

# In[ ]:

print(test_X.shape)
#print(range(test_X.shape))

#pyplot.plot( inv_y[-100:-1], label='predict')
#pyplot.plot( inv_yhat[-99:], label='actual')
pyplot.plot( inv_y, label='predict')
pyplot.plot( inv_yhat, label='actual')
pyplot.legend()
pyplot.show()

#涨跌的判准率

#获取预测跟实际对应元素值，是否大于0
a = np.diff(inv_y) > 0
b = np.diff(inv_yhat) > 0

#比较相同值的个数
print(sum(a ==b)/a.shape[0])

# In[14]:

x = 6
def func():
    global x
    print(x)
    return x
func()

# In[ ]:


from collections import deque
import sys

dx = [1,-1,0,0]
dy = [0,0,-1,1]

def iswall(x,y):
    if x<0 or y<0 :
        return False
    if x >= n or y >= m :
        return False
    if matrix[x][y] == 0 : # 방문한 경우
        return False
    return True # 그 외의 경우

def bfs(x,y):
    queue = deque()
    print(queue)
    queue.append((x, y))
    print(queue)
# queue = deque((x,y)) # 시작 지점을 넣는다.
    while queue:
        x,y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if iswall(nx,ny) and matrix[nx][ny]==1:
                matrix[nx][ny] = matrix[x][y]+1
                queue.append((nx,ny))
    return matrix[n-1][m-1]

n,m = map(int,input().split())
matrix = [[1, 1, 0], [0, 1, 0], [0, 1, 1]]
print(bfs(0,0))

파이썬 알고리즘 인터뷰/미로탈출.py


import time
import json
import datetime

invalid = "\n--Invalid response, please try again.--"
scheduleFile = "schedule.json"
assignmentFile = "assignment.json"

def load():
    for i in range(0, 40):
        time.sleep(0.00000000000001)
        print("-", end='', flush=True)
    print()

def unload():
    for i in range(0, 40):
        time.sleep(0.00000000000001)
        print('-' * (40 - i))
    print("--Goodbye!--")

def anythingElse():
    load()
    while True:
        userInput = input("Anything else?\n[0] - Yes\n[1] - No\n\nPlease choose an option: ")
        if userInput == "0":
            load()
            break
        elif userInput == "1":
            unload()
            return 1
        else:
            print(invalid)

def createSchedule():
    with open(scheduleFile) as f:
        data = json.load(f)
    while True:
        sched = input("Schedule Name: ")
        if sched not in data:
            break
        print(f'"{sched}" is already a schedule. Please enter a different name.')
    data[sched] = {}
    while True:
        number = input("Number of Classes (1 - 7): ")
        try:
            number = int(number)
            if number > 7 or number < 1:
                print(invalid)
            else:
                break
        except Exception:
            print(invalid)
    for i in range(1, number + 1):
        name = input(f"\nPeriod {i}: ")
        teacher = input("Teacher: ")
        description = input("Description: ")
        data[sched][name] = {}
        data[sched][name]["teacher"] = teacher
        data[sched][name]["description"] = description
    with open(scheduleFile, "w") as f:
        json.dump(data, f, indent=2)
    load()
    print(f'--Schedule "{sched}" created!--')

def seeSchedule():
    with open(scheduleFile) as f:
        data = json.load(f)
    if len(data) < 1:
        print("--There are currently no schedules.--")
        return
    num = 0
    while True:
        lister = []
        for i in data:
            lister += [i]
            print(f"[{num}] {i}\nPeriods: {len(data[i])}\n")
            num += 1
        num -= 1
        userInput = input("Please choose a schedule (or press e to exit): ")
        if userInput == "e":
            return
        else:
            try:
                userInput = int(userInput)
                if userInput > -1 and userInput <= num:
                    num = 0
                    load()
                    for i in data[lister[userInput]]:
                        print(f"Period {num + 1}: {i}\nTeacher: {data[lister[userInput]][i]['teacher']}\nDescription: {data[lister[userInput]][i]['description']}\n")
                        num += 1
                    userInput = input("Enter any key to return: ")
                    load()
                else:
                    print(invalid)
            except Exception:
                print(invalid)

def deleteSchedule():
    with open(scheduleFile) as f:
        data = json.load(f)
    if len(data) < 1:
        print("--There are currently no schedules.--")
        return
    num = 0
    while True:
        lister = []
        for i in data:
            lister += [i]
            print(f"[{num}] {i}\nPeriods: {len(data[i])}\n")
            num += 1
        num -= 1
        userInput = input("Please choose a schedule to delete (or press e to exit): ")
        if userInput == "e":
            return
        else:
            print()
            try:
                userInput = int(userInput)
                if userInput > -1 and userInput <= num:
                    num = 0
                    confirm = input(f'Are you sure you want to delete "{lister[userInput]}"?\nEnter "13579" to confirm, or enter anything else to cancel: ')
                    if confirm == "13579":
                        load()
                        del data[i]
                        with open(scheduleFile, "w") as f:
                            json.dump(data, f, indent=2)
                        userInput = input("--Schedule has been deleted.--\n\nEnter any key to return: ")
                        print()
                        break
                    else:
                        return
                else:
                    print(invalid)
            except Exception:
                print(invalid)

def createAssignment():
    with open(assignmentFile) as f:
        data = json.load(f)
    while True:
        name = input("Assignment Name: ")
        if name not in data:
            break
        else:
            print(f'"{name}" is already an assignment. Please enter a different name.')
    classname = input("Class: ")
    while True:
        due = input('Due Date (mm/dd/yyyy): ')
        try:
            s = datetime.date(int(due.split("/")[2]), int(due.split("/")[1]), int(due.split("/")[0]))
            n = datetime.datetime.now().date()
            if s > n and len(due.split("/")) == 3:
                break
            elif(s <= n):
                print("\n--That date has already passed. Please enter a different response.--")
            else:
                print(invalid)
        except Exception:
            print(invalid)
    description = input("Description: ")
    data[name] = {}
    data[name]["class"] = classname
    data[name]["due"] = due
    data[name]["description"] = description
    with open(assignmentFile, "w") as f:
        json.dump(data, f, indent=2)
    load()
    print(f'--Assignment "{name}" created!--')

def seeAssignment():
    with open(assignmentFile) as f:
        data = json.load(f)
    if len(data) < 1:
        print("--There are currently no assignments.--")
        return
    num = 0
    for i in data:
        print(f"[{num}] Assignment: {i}{len(data[i])}\n{' ' * len(str(len(data[i])))}   Class: {data[i]['class']}\n{' ' * len(str(len(data[i])))}   Due Date: {data[i]['due']}\n{' ' * len(str(len(data[i])))}   Description: {data[i]['description']}\n")
        num += 1
    userInput = input("Press any key to return: ")

def deleteAssignment():
    with open(assignmentFile) as f:
        data = json.load(f)
    lister = [x for x in data]
    if len(data) < 1:
        print("--There are currently no assignments.--")
        return
    num = 0
    for i in data:
        print(f"[{num}] Assignment: {i}{len(data[i])}\n{' ' * len(str(len(data[i])))}   Class: {data[i]['class']}\n{' ' * len(str(len(data[i])))}   Due Date: {data[i]['due']}\n{' ' * len(str(len(data[i])))}   Description: {data[i]['description']}\n")
        num += 1
    num -= 1
    while True:
        try:
            userInput = input("Please choose an assignment to delete (or press e to exit): ")
            if userInput == "e":
                return
            elif int(userInput) > -1 and int(userInput) <= num:
                confirm = input(f'\nAre you sure you want to delete "{lister[int(userInput)]}"?\nEnter "13579" to confirm, or enter anything else to cancel: ')
                if confirm == "13579":
                    del data[lister[int(userInput)]]
                    with open(assignmentFile, "w") as f:
                        json.dump(data, f, indent=2)
                    userInput = input("--Assignment has been deleted.--\n\nEnter any key to return: ")
                    print()
                    break
            else:
                print(invalid)
        except Exception as e:
            print(e)

def programChoice():
    while True:
        userInput = input("[0] - Create a schedule\n[1] - See existing schedules\n[2] - Delete a schedule\n[3] - Create an assignment\n[4] - Create an assignment\n[5] - Delete a schedule\n\nPlease choose the program you would like to use: ")
        if userInput == "0":
            load()
            createSchedule()
            if anythingElse() == 1:
                break
        elif userInput == "1":
            load()
            seeSchedule()
            if anythingElse() == 1:
                break
        elif userInput == "2":
            load()
            deleteSchedule()
            if anythingElse() == 1:
                break
        elif userInput == "3":
            load()
            createAssignment()
            if anythingElse() == 1:
                break
        elif userInput == "4":
            load()
            seeAssignment()
            if anythingElse() == 1:
                break
        elif userInput == "5":
            load()
            deleteAssignment()
            if anythingElse() == 1:
                break
        else:
            print(invalid)

def main():
    print("\n\n-----Welcome to Scheduler.py, a program made to schedule classes and assignments.-----")
    while True:
        userInput = input("[0] - Begin\n[1] - Quit\n\nPlease choose an option: ")
        if userInput == "0":
            load()
            programChoice()
            break
        elif userInput == "1":
            unload()
            break
        else:
            print(invalid)

main()