import bpy
import sys
#import mathutils
from mathutils import *
import bgl
import blf
import gpu
from gpu_extras.batch import batch_for_shader
from ..math.vecmath import *

from enum import Enum

from .graphics import DrawContext2D

#----------------------------------
class Size2D:
    def __init__(width = 0, height = 0):
        self.width = width
        self.height = height

#----------------------------------

class Rectangle2D:
    def __init__(self, x = 0, y = 0, width = 0, height = 0):
        self.x = x
        self.y = y
        self.width = width
        self.height = height

    def contains(self, x, y):
        return x >= self.x and x < self.x + self.width and y >= self.y and y < self.y + self.height

    def __str__(self):
        return str(self.x) + ", " + str(self.y) + ", " + str(self.width) + ", " + str(self.height)

#----------------------------------

class Layout:

    def __init__(self):
        self.parent = None
        self.window = None

    def get_parent(self):
        return self.parent

    def set_parent(self, parent):
        self.parent = parent

    def get_window(self):
        return self.window

    def set_window(self, window):
        self.window = window

    def layout_components(self, bounds):
        pass

    def draw(self, ctx):
        pass

    def handle_event(self, context, event):
        return False

    def get_screen_position(self):
        if self.parent != None:
            return self.parent.get_screen_position()
        elif self.window != None:
            return self.window.get_screen_position()
        return Vector((0, 0))

    def mouse_pressed(self, event):
        return False

    def mouse_released(self, event):
        return False

    def mouse_moved(self, event):
        return False

#----------------------------------

class LayoutAxis(Enum):
    X = 1
    Y = 2
#----------------------------------

class ExpansionType(Enum):
    EXPAND = 1
    PREFERRED = 2
#    MIN = 3
#    MAX = 4

#----------------------------------

class LayoutBox(Layout):
    class Info:
        def __init__(self):
            self.span = 0

    def __init__(self, axis = Axis.X):
        super().__init__()

        self.axis = axis
        self.children = []

    def dump(self, indent = ""):
        print(indent + "LayoutBox " + str(self.axis))

        for child in self.children:
            child.dump(indent + " ")

    def add_child(self, child):
        self.children.append(child)
        child.set_parent_layout(self)

    def handle_event(self, context, event):
        for child in self.children:
            result = child.handle_event_dispatch(context, event)
            if result:
                return True

        return False

    def calc_minimum_size(self):
        span_x = 0
        span_y = 0

        for child in self.children:
            size = child.calc_minimum_size()

            if self.axis == Axis.X:
                span_x += size.x
                span_y = max(span_y, size.y)
            else:
                span_x = max(span_x, size.x)
                span_y += size.y

        return Vector((span_x, span_y))

    def calc_preferred_size(self):
        span_x = 0
        span_y = 0

        for child in self.children:
            size = child.calc_preferred_size()

            if self.axis == Axis.X:
                span_x += size.x
                span_y = max(span_y, size.y)
            else:
                span_x = max(span_x, size.x)
                span_y += size.y

        return Vector((span_x, span_y))

    def calc_maximum_size(self):
        span_x = 0
        span_y = 0

        for child in self.children:
            size = child.calc_maximum_size()

            if self.axis == Axis.X:
                span_x += size.x
                span_y = max(span_y, size.y)
            else:
                span_x = max(span_x, size.x)
                span_y += size.y

        return Vector((span_x, span_y))

    def layout_components(self, bounds):
        local_span = bounds.width if self.axis == Axis.X else bounds.height

        infoList = []
        total_span = 0

        #Allocate min sizes first
#        print("calc min")
        for i in range(len(self.children)):
            child = self.children[i]
            size = child.calc_minimum_size()

            info = self.Info()
            infoList.append(info)
            info.span = size.x if self.axis == Axis.X else size.y
            total_span += info.span

#            print("child %d: span %d" % (i, info.span))

        #Expand to preferred sizes if there is room
#        print("calc pref")
        for i in range(len(self.children)):
            if total_span < local_span:
                child = self.children[i]
                size = child.calc_preferred_size()
                pref_span = size.x if self.axis == Axis.X else size.y
                span_remaining = local_span - total_span

#                print("span_remaining " + str(span_remaining))
#                print("pref_span " + str(pref_span))

                info = infoList[i]
#                print("info.span " + str(info.span))
                span_to_add = min(span_remaining, pref_span - info.span)
                info.span += span_to_add
                total_span += span_to_add

#                print("child %d: span %d" % (i, info.span))

        #If there is space left, expand children with expand set
        # print("calc max")
        # print("local_span " + str(local_span))
        # print("total_span " + str(total_span))
        for i in range(len(self.children)):
            if total_span < local_span:
                child = self.children[i]
                info = infoList[i]
#                print("info.span " + str(info.span))

                if (self.axis == Axis.X and child.expansion_type_x == ExpansionType.EXPAND) or (self.axis == Axis.Y and child.expansion_type_y == ExpansionType.EXPAND):
                    size = child.calc_maximum_size()
                    max_span = size.x if self.axis == Axis.X else size.y

                    expand_to = min(max_span, local_span - total_span + info.span)

                    # print("max_span " + str(max_span))
                    # print("expand_to " + str(expand_to))

                    # info = infoList[i]
                    # print("info.span " + str(info.span))

                    span_to_add = expand_to - info.span
                    info.span += span_to_add
                    total_span += span_to_add

#                print("child %d: span %d" % (i, info.span))

        #Apply sizes
        cursor_offset = 0
        for i in range(len(self.children)):
            child = self.children[i]
            info = infoList[i]

            if self.axis == Axis.X:
                child.position.x = cursor_offset
                child.position.y = 0
                child.size.x = info.span
                child.size.y = bounds.height
            else:
                child.position.x = 0
                child.position.y = cursor_offset
                child.size.x = bounds.width
                child.size.y = info.span

            child.layout_components()

            cursor_offset += info.span

    def draw(self, ctx):
        for child in self.children:
            child.draw(ctx)

    def pick_panel_stack(self, pos):
        for child in self.children:
            child_pos = child.position

            #Bounds relative to parent
            bounds = child.bounds()

#            print ("testing bounds " + str(bounds))
            if bounds.contains(pos[0], pos[1]):
#                print ("bounds test passed")

                rel_pos = pos - child_pos
                result = child.pick_panel_stack(rel_pos)

                # if result:
                    # return True
                result.insert(0, child)
                return result

        return []

    def mouse_pressed(self, event):
        # print ("layout mouse_pressed")
        # print ("in event " + str(event))

        for child in self.children:
            pos = child.position

            #Bounds relative to parent
            bounds = child.bounds()

#            print ("testing bounds " + str(bounds))
            if bounds.contains(event.pos[0], event.pos[1]):
#                print ("bounds test passed")

                evt = event.copy()
                evt.pos -= pos
                result = child.mouse_pressed(evt)

                if result:
                    return True

        return False

    def mouse_released(self, event):
        for child in self.children:
            pos = child.position

            #Bounds relative to parent
            bounds = child.bounds()
            if bounds.contains(event.pos[0], event.pos[1]):

                evt = event.copy()
                evt.pos -= pos
                result = child.mouse_released(evt)
                if result:
                    return True

        return False

    def mouse_moved(self, event):
        for child in self.children:
            pos = child.position

            #Bounds relative to parent
            bounds = child.bounds()
            if bounds.contains(event.pos[0], event.pos[1]):

                evt = event.copy()
                evt.pos -= pos
                result = child.mouse_moved(evt)
                if result:
                    return True

        return False


from django.urls import path
from .views import index , login , signup ,cart
from .middlewares.auth import authMiddleware

urlpatterns = [
    path('' , index.Index.as_view()),
    # path('category/<categoryID>' , productByCategory)
    path('signup' , signup.Signup.as_view()),
    path('login' ,  login.Login.as_view()),
    path('logout' , login.Logout),
    # to add custom middleware to check whther the user is logged in or not.
    path('cart' , authMiddleware(cart.Cart.as_view()) ),
    path('checkout' , cart.Checkout.as_view()),
    # to add custom middleware to check whther the user is logged in or not.
    path('orders/' , authMiddleware(cart.OrderView.as_view()) ),
]


# -*- coding: utf-8 -*-
"""
Created on Mon Feb 21 16:32:04 2022

@author: Toyin
"""

# importing libraries used
import streamlit as st
import pandas as pd
import numpy as np
import sklearn
import pickle

# loading the pretrained model
model = pickle.load(open('model.sav', 'rb'))

# function to carry out the prediction
def prediction(data):
    data = np.array(data).reshape(1, -1)
    predicted_price = model.predict(data)
    return(predicted_price)

def main():
    st.title("Apple Stock Price Prediction")
    open_price = st.number_input('Open Price')
    high = st.number_input('High Price')
    low = st.number_input('Low Price')
    price = ''
    if st.button("Predict"):
        price = prediction([open_price, high, low])

    st.success(price)

if __name__ == '__main__':
    main()


import numpy as np
import matplotlib.pyplot as plt

import csv
import math
from typing import List, Tuple
import time

class ActivationFunction:
    def __init__(self, activation_function: callable, activation_derivative: callable):
        self.activation_function = activation_function
        self.activation_derivative = activation_derivative

class RecursiveNeuralNetwork:
    def __init__(
        self, input_size: int, activation_function: ActivationFunction, seed: int = 0
    ):
        """A simple 1 layer recurent neural network

        Args:
            input_size (int): The size of the input / output / hidden layer
            activation_function (ActivationFunction): which activation function we will adjust our data by
            seed (int, optional): consistency is key! Try to use a seed to get repeatable data. Defaults to 0.
        """

        self.input_size = input_size
        self.activation_function = activation_function
        self.seed = seed

        self.recursion_predictions = np.array([])
        self.input_data = np.array([])

        # Setting a seed, so we can always reproduce results
        if self.seed:
            np.random.seed(self.seed)

        # We only want one output at a time, and we use that to recursively feed foward
        self.weights = np.random.rand(1, input_size)
        # Since we will always have an output size of 1, we want to have a bias of 1
        self.biases = np.random.rand(1, 1)

    def _forward_propagation(
        self, inputs: np.array, step_size: int = 0, is_training: bool = False
    ) -> np.array:
        """A function to recurently predict data

        Args:
            inputs (np.array): the data to start our model with
            step_size (int, optional): how far into the future to predict. Defaults to 0.
            is_training (bool, optional): an indicator letting us know if we need to store any data. Defaults to False.

        Returns:
            np.array: The predictions that the AI made
        """

        # if we are trainging, we want to store all of our predictions in a list, so we can adjust the model during back propigation
        if is_training:
            self.recursion_predictions = np.array([])
            self.input_data = inputs

        # Itterating over the stepsize to make a prediction, and then a followup prediction off of that prediction
        for _ in range(step_size):
            # forward prop
            prediction = self.activation_function.activation_function(
                np.dot(self.weights, inputs) + self.biases
            )

            # rolling our data and adding the prediction
            # ex.
            # [ 1, 2, 3 ] -> [ 2, 3, 1 ]
            #  pred 4 -> [2, 3, 4 ]
            inputs = np.roll(inputs, -1)
            inputs[-1] = prediction

            # if training we want to store our predictions
            if is_training:
                self.recursion_predictions = np.append(
                    self.recursion_predictions, prediction
                )

        return inputs

    def _backwards_propagation_through_time(
        self, error_derivatives: np.array, learning_rate: float = 0.1
    ):
        """A function to adjust the weights and biases of our RNN

        Args:
            error_derivatives (np.array): 2 * (prediction - target output) * actionvation_derivatives( prediction )
            learning_rate (float, optional): How fast to grow the model by. Defaults to .1.
        """
        # setting the weights and bias adjustment to 0
        weight_delta = 0
        bias_delta = 0

        # the error derivate should be a shape ( input_size, 1 )
        # we only want the want the final error derivate, because that is the predicted value
        # ex
        # with a step of 1, we get...
        # Input         : [ A, B, C ]
        #
        # Prediction    : [ B, C, P ]
        # Expected      ; [ B, C, D ]
        #
        # Notice how the error derivative for index, 0 and 1 are not needed, because we are not predicting with them
        # we are looking for the error of the last element that we should have gotten ( P & D )
        error_derivatives = error_derivatives[-1]

        # Itterating over the predictions and grabbing the updated error_derivatives until we reach the first prediction
        for index, prediction in enumerate(self.recursion_predictions[:-1]):
            '''
            When viewing back propigation through time, imagine that you are itterating over a model of that size. For instance...
            If I have a layer of 3 nodes, and I stepped forward 4 times in my prediction, my model can be represented as :

            W1
            W2
            W3

            in1 - h11 - h21 - h31 - out1
            in2 - h12 - h22 - h32 - out2
            in3 - h13 - h23 - h33 - out3

            each - represents a fully connected layer. This means that while we only have 1 set of weights and biases, we really
            made our model into a deep neural network by propigating the data forward 4 amount of times.
            This also means, that in adjusting the weights and biases,
            we too need to adjust them for the new 4 deep neural network that we created recurently
            '''
            # getting the input for the given state.
            # logic explained
            # predictions = [ 4, 5, 6 ]
            # input = [ 1, 2, 3 ]
            #
            # recursive predictions data = [ 4, 5 ]
            # since smaller than 3
            # recusive data inputs = [ 5, 4 ] join [ 3, 2, 1 ]
            # recusive data inputs = [ 5, 4, 3, 2, 1 ]
            # recusive data inputs = [ 5, 4, 3 ]
            #
            # if it was >= the size, we then just make sure that the predictions is the size
            recursive_input_data = self.recursion_predictions[ index + 1 : len(self.recursion_predictions) - 1 ]
            if len(recursive_input_data) < self.input_size:
                recursive_input_data = np.append(recursive_input_data[::-1], self.input_data[::-1])
                recursive_input_data = recursive_input_data[0 : self.input_size]
                recursive_input_data = recursive_input_data[::-1]
            else:
                recursive_input_data = recursive_input_data[0 : self.input_size]

            # Updating the weight and bias delta, before finding the new error derivative
            # We want to update a delta, because we still need the weights and biases that we used to predict our data in finding the new error derivative
            weight_delta += ( np.dot(np.array(recursive_input_data), error_derivatives) * learning_rate / len(self.recursion_predictions) )
            bias_delta += ( np.sum(error_derivatives, axis=0) * learning_rate / len(self.recursion_predictions) )

            # Calculating the new error derivative and grabbing its last elm (see comments above on why we want only the last elm)
            error_derivatives = np.dot( self.weights, error_derivatives ) * self.activation_function.activation_derivative(recursive_input_data)
            error_derivatives = [0][-1]

        # Updating the weight and bias delta
        weight_delta += (
            np.dot(np.array(self.input_data).T, error_derivatives)
            * learning_rate
            / len(self.recursion_predictions)
        )
        bias_delta += (
            np.sum(error_derivatives, axis=0)
            * learning_rate
            / len(self.recursion_predictions)
        )

        # updating the weights and biases by their delta
        self.weights -= np.array([weight_delta])
        self.biases -= bias_delta

    def predict_full(self, inputs: np.array, step_size: int = 0) -> np.array:
        """An abstracted function for forward propagation

        Args:
            inputs (np.array): The data that we are to predict off of
            step_size (int, optional): how far into the future to predict. Defaults to 0.

        Returns:
            np.array: an array that is the same size as the inputs. Containing the snippet of the final prediction(s)
        """
        _ = self._forward_propagation(
            inputs=np.array(inputs), step_size=step_size, is_training=True
        )
        return self.recursion_predictions

    def predict(self, inputs: np.array, step_size: int = 0) -> List[float]:
        """An abstracted function for forward propagation

        Args:
            inputs (np.array): The data that we are to predict off of
            step_size (int, optional): how far into the future to predict. Defaults to 0.

        Returns:
            List[float]: All of the predicted values from the start to the end of the step_size
        """
        return self._forward_propagation(inputs=inputs, step_size=step_size)

    def train(
        self,
        training_inputs: List[float],
        training_outputs: List[float],
        step_size: int = 0,
        learning_rate: float = 0.01,
    ):
        """An abstracted function of back propagation through time.

        Args:
            training_inputs (List[float]): The data that we are to predict off of
            training_outputs (List[float]): The data that we are to match
            step_size (int, optional): how far into the future to predict. Defaults to 0.
            learning_rate (float, optional): How fast to grow the model by. Defaults to .01.
        """
        # itterating  over a list of all of the training inputs and outputs
        for training_input, training_output in zip(training_inputs, training_outputs):
            # making a prediction
            prediction = self._forward_propagation(
                inputs=np.array(training_input), step_size=step_size, is_training=True
            )
            # calculating the error derivative
            error_derivatives = (
                2
                * (prediction - np.array(training_output))
                * self.activation_function.activation_derivative(prediction)
            )
            # adjusting the model
            self._backwards_propagation_through_time(
                error_derivatives=error_derivatives, learning_rate=learning_rate
            )

    def reset(self):
        """A function to rest the neural network"""
        self.recursion_predictions = np.array([])
        self.input_data = np.array([])

        if self.seed:
            np.random.seed(self.seed)
        # We only want one output at a time, and we use that to recursively feed foward
        self.weights = np.random.rand(1, self.input_size)
        # Since we will always have an output size of 1, we want to have a bias of 1
        self.biases = np.random.rand(1, 1)

"""
ACTIVATION FUNCTIONS
--------------------
"""

# Leaky Relu (BEST!!!)
def _leaky_relu(x, alpha=0.01):
    return np.maximum(x, alpha * x)

def _leaky_relu_derivative(x, alpha=0.01):
    dx = np.ones_like(x)
    dx[x < 0] = alpha
    return dx

LEAKY_RELU = ActivationFunction(
    activation_function=_leaky_relu, activation_derivative=_leaky_relu_derivative
)

# Relu
def _relu(x):
    return np.maximum(x, 0)

def _relu_derivative(x):
    return np.ones_like(x)

RELU = ActivationFunction(
    activation_function=_relu, activation_derivative=_relu_derivative
)

# Sigmoid
def _sigmoid(x):
    return 1 / (1 + np.exp(-x))

def _sigmoid_derivative(x):
    sigmoid_x = _sigmoid(x)
    return sigmoid_x * (1 - sigmoid_x)

SIGMOID = ActivationFunction(
    activation_function=_sigmoid, activation_derivative=_sigmoid_derivative
)

"""
GRAPHS
------
"""

def get_sin(size: int):
    return [(math.sin(x) + 1) / 2 for x in range(size)]

def get_y_x(size: int):
    return [float(x) / size for x in range(size)]

def get_sigmoid(size: int):
    return [_sigmoid(x / (size // 8)) for x in range(-(size // 2), (size // 2))]

def get_uber_2019_2022():
    # Open the CSV file
    # https://www.kaggle.com/datasets/varpit94/uber-stock-data
    # *NOTE* WARNING, this is not stock advice, this is to illistrate a use case for RNNs

    data = []

    REDUCE_RATIO = 10
    with open("UBER.csv", "r") as file:
        # Create a CSV reader object
        csv_reader = csv.reader(file)

        # Read the CSV file row by row
        for index, row in enumerate(csv_reader):
            if index % REDUCE_RATIO:
                continue
            # Concatenate all values in the row into a single string
            try:
                data.append((float(row[1]) - 25) / 40)
            except:
                continue

    return data

def get_training_in_out(
    data: List[float], input_size: int, step_size: int
) -> Tuple[List[float], List[float]]:
    """A function to turn 1 list into the input outputs needed for training

    Args:
        data (List[float]): the list that we have of Y points over X time
        input_size (int): how large the rnn input is
        step_size (int): how far into the future to make the prediction per model

    Returns:
        Tuple[List[float], List[float]]: training inputs and outputs
    """
    inputs = []
    outputs = []
    for index in range(len(data[: -(input_size + step_size - 1)])):
        inputs.append(list(data[index : index + input_size]))
        outputs.append(list(data[index + step_size : index + step_size + input_size]))

    return inputs, outputs

def main():
    INPUT_SIZE = 16
    STEP_SIZE = 1
    LEARNING_RATE = 0.01
    EPOCHES = 100
    PREDICT_LENGTH = 30

    rnn = RecursiveNeuralNetwork(
        input_size=INPUT_SIZE,
        activation_function=LEAKY_RELU,
        seed=1
    )

    data = get_uber_2019_2022()  # get_sin(INPUT_SIZE*2)

    training_inputs, training_outputs = get_training_in_out(data, INPUT_SIZE, STEP_SIZE)

    for _ in range(EPOCHES):
        rnn.train(
            training_inputs=training_inputs,
            training_outputs=training_outputs,
            step_size=STEP_SIZE,
            learning_rate=LEARNING_RATE,
        )
        time.sleep(0.01)

    # Creating the plot
    fig, axes = plt.subplots(2, 2, figsize=(10, 8))
    # Full Data Graph
    axes[0, 0].plot([i for i in range(len(data))], data, label="Full Data")
    axes[0, 1].set_title("True Data")
    axes[0, 0].legend()
    # AI vs Expected Start
    guess = rnn.predict_full( inputs=np.array(training_inputs[0]), step_size=PREDICT_LENGTH )
    axes[0, 1].plot( [i for i in range(PREDICT_LENGTH + len(training_inputs[0]))], np.append(training_inputs[0], guess), label="AI", )
    axes[0, 1].plot( [i for i in range(len(training_inputs[0]))], training_inputs[0], label="Given" )
    axes[0, 1].set_title("Plot of AI and Expected Start")
    axes[0, 1].legend()
    # AI vs Expected MidPoint
    guess2 = rnn.predict_full(inputs=np.array( training_inputs[len(training_inputs) // 2]), step_size=PREDICT_LENGTH, )
    axes[1, 0].plot( [i for i in range(PREDICT_LENGTH + len(data) // 2)], np.append(data[: len(data) // 2], guess2), label="AI", )
    axes[1, 0].plot( [i for i in range(len(data[: len(data) // 2]))], data[: len(data) // 2], label="Given", )
    axes[1, 0].set_title("Plot of AI and Expected MidPoint")
    axes[1, 0].legend()  # Display legend
    # AI vs Expected End
    guess3 = rnn.predict_full( inputs=np.array(training_outputs[-1]), step_size=PREDICT_LENGTH )
    axes[1, 1].plot( [i for i in range(PREDICT_LENGTH + len(data))], np.append(data, guess3), label="AI", )
    axes[1, 1].plot([i for i in range(len(data))], data, label="Given")
    axes[1, 1].set_title("Plot of AI and Expected End")
    axes[1, 1].legend()  # Display legend

    plt.show()

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# testing.py
from termcolor import colored

word = 'fail'
guess = 'fall'

list_of_word = []
for letter in word:
    list_of_word.append(letter)

list_of_guess = []
for letter in guess:
    list_of_guess.append(letter)

print(list_of_word)
print(list_of_guess)

correct_placement = []
incorrect_placement = []

for i, letter in enumerate(list_of_word):
    if list_of_word[i] == list_of_guess[i]:
        correct_placement.append(letter)

    elif letter in list_of_guess:
        incorrect_placement.append(letter)

    else:
        pass

#print(correct_placement, incorrect_placement)
#print(colored_letters)

colored_guess = []
for letter in guess:
    if letter in correct_placement:
        colored_guess.append(colored(letter, 'green'))
    elif letter in incorrect_placement:
        colored_guess.append(colored(letter, 'yellow'))
    else:
        colored_guess.append(letter)

#print(*colored_guess)
print(correct_placement)
print(incorrect_placement)


from os.path import splitext
from os import walk
import easygui as eg
from cv2 import imread, imwrite, resize

path = eg.diropenbox()
fileExt = list(input("File extentions (write comma seperated): ").split(","))
new_shape = (int(input("width: ")), int(input("height: ")))

try:
    _, _, filenames = next(walk(path))

    for f in filenames:
        _, ext = splitext(f)
        if ext[1:] in fileExt:
            filepath = path + '/' + f
            img = imread(filepath)
            img = resize(img, new_shape)
            imwrite(filepath, img)
            print("Saved:", filepath)

except Exception as e:
    print("Error:", e)


from selenium.webdriver.common.by import By

search_type = {
    'xpath': By.XPATH,
    'tag_name': By.TAG_NAME,
    'id': By.ID
}

movie_list = [
        "American Dreamz",
        "Animal Factory",
        "Aurora Borealis",
        "Baadasssss!",
        "The Ballad of Little Jo",
        "Better than Sex",
        "The Big Hit",
        "Blood and Wine",
        "Brick",
        "Brothers",
        "Bubba Ho-Tep",
        "Career Girls",
        "Casanova",
        "Chop Shop",
        "Citizen Ruth",
        "Connie and Carla",
        "C.R.A.Z.Y",
        "Criminal",
        "Crush",
        "Dark Days",
        "The Dead Girl",
        "The Devil's Backbone",
        "Diamond Men",
        "Dick",
        "The Dinner Game",
        "Dinner Rush",
        "The Dish",
        "Teacher's Pet",
        "The Door in the Floor",
        "Driving Lessons",
        "Duck Season",
        "East is East",
        "Everything Put Together",
        "Fast, Cheap and Out of Control",
        "15 Minutes",
        "Find Me Guilty",
        "Firelight",
        "Following",
        "Gilles' Wife",
        "Gloomy Sunday",
        "Go Tigers!",
        "Going in Style",
        "The Great Buck Howard",
        "The Greatest Game Ever Played",
        "The Hard Word",
        "The Harmonists",
        "Hedwig and the Angry Inch",
        "Hidalgo",
        "A Home at the End of the World",
        "The House of Sand",
        "How to Lose Friends & Alienate People",
        "I Served the King of England",
        "Idiocracy",
        "In the Shadow of the Moon",
        "Indigenes",
        "Innocent Blood",
        "Intermission",
        "Island in the Sky",
        "Julia",
        "Keeping Mum",
        "Kill Me Later",
        "King of California",
        "The King of Masks",
        "King of the Hill",
        "Kontroll",
        "Las Ciudad",
        "La Petite Lili",
        "La Promesse",
        "Lady for a Day",
        "The Last Shot",
        "Lawless Heart",
        "Levity",
        "Look Both Ways",
        "The Lookout",
        "Love and Death On Long Island",
        "Mad Money",
        "The Maltese Falcon",
        "The Man from Elysian Fields",
        "Man Push Cart",
        "Marvin's Room",
        "The Matador",
        "Matchstick Men",
        "Matewan",
        "Maybe Baby",
        "The Merry Gentleman",
        "Metroland",
        "A Midnight Clear",
        "The Mighty",
        "Millions",
        "Mirrormask",
        "Moonlighting",
        "Mountains of the Moon",
        "Mrs. Palfrey at the Claremont",
        "My First Mister",
        "The Mystery of Picasso",
        "Nine Lives",
        "Nothing But the Truth",
        "October Sky",
        "Off the Map",
        "Once Were Warriors",
        "One Fine Day",
        "Owning Mahowny",
        "The Painted Veil",
        "Paradise Now",
        "Peter's Friends",
        "Phoebe in Wonderland",
        "The Pledge",
        "Priceless",
        "Prisoner of Paradise",
        "The Prize Winner of Defiance, Ohio",
        "Queen of Hearts",
        "Quinceanera",
        "Raising Victor Vargas",
        "Resurrecting the Champ",
        "Resurrection",
        "Safe Men",
        "Scarecrow",
        "Seven Men from Now",
        "Shadowboxer",
        "Something New",
        "Son of Rambow",
        "Songcatcher",
        "Spring Forward",
        "Starting Out in the Evening",
        "Startup.com",
        "State of the Union",
        "The Steel Helmet",
        "Still Crazy",
        "Stone Reader",
        "Sweet Land",
        "The Tao of Steve",
        "Taste of Cherry",
        "The Third Miracle",
        "Thumbsucker",
        "Tristram Shandy: A Cock and Bull Story",
        "Tumbleweeds",
        "Tuvalu",
        "The TV Set",
        "Two Family House",
        "Two Lovers",
        "Walking the Dead",
        "The Weather Man",
        "Welcome to Sarajevo",
        "Went to Coney Island on a Mission from God… Be Back by Five",
        "What Doesn’t Kill You",
        "The Whole Wide World",
        "The Wide Blue Road",
        "Winter Solstice",
        "Word Wars",
        "The World's Fastest Indian",
        "Zathura: A Space Adventure",
]


from collections import deque
import sys

input = sys.stdin.readline

n, m, h = map(int, input().split())

box = [[[0] * (n) for _ in range(m)] for _ in range(h)]

for i in range(h):
    for j in range(m):
        tomato = list(map(int, input().split()))
        box[i][j] = tomato

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

def find_ripe_tomate(n, m, h):
    queue = deque()
    for z in range(h):
        for y in range(m):
            for x in range(n):
                if box[z][y][x] == 1:
                    queue.append((x, y, z))

    return queue

def bfs(x, y, z):

    for i in range(6):
        nx = x + dx[i]
        ny = y + dy[i]
        nz = z + dz[i]

        if nx < 0 or ny < 0 or nz < 0 or nx >= n or ny >= m or nz >= h:
            continue
        if box[nz][ny][nx] == -1:
            continue
        if box[nz][ny][nx] == 0:
            box[nz][ny][nx] = box[z][y][x] + 1
            ripe_tomate.append((nx, ny, nz))

    return

def find_max_tomato(n, m, h):
    max_tomato = 0
    for z in range(h):
        for y in range(m):
            for x in range(n):
                if box[z][y][x] > max_tomato:
                    max_tomato = box[z][y][x]
                if box[z][y][x] == 0:
                    return 0
    return max_tomato

ripe_tomate = find_ripe_tomate(n, m, h)

while ripe_tomate:
    x, y, z = ripe_tomate.popleft()
    bfs(x, y, z)

max_tomato = find_max_tomato(n, m, h)
if max_tomato == 0:
    print(-1)
else:
    print(max_tomato - 1)


import json
import datetime
import requests
import time
import secret

from requests.auth import HTTPBasicAuth

# some constants for search
URL_BASE = secret.query_url_base
AUTH = HTTPBasicAuth(secret.query_user, secret.query_pass)

class MatchText:
    def __init__(self, text, tokenize, stem, alias, delimiter):
        text = text.strip()
        self.use_tokens = tokenize
        self.use_stemming = stem
        self.use_aliases = alias
        self.text = text.split(delimiter) if alias else [text]
        self.delimiter = delimiter
        self._tok_texts = [t.split() for t in self.text] if tokenize else None

    def _make_match_phrase_list(self, phrases):
        analyzer = 'abstract.english' if self.use_stemming else 'abstract'
        ret = [{'match_phrase': {analyzer: p}} for p in phrases]
        return ret

    def make_match_bool(self):
        ret = None
        # if not using aliases, there's just one item (tokens or not)
        if not self.use_aliases:
            # grab either the single phrase as a list or the list of tokens
            phrases = self.text if not self.use_tokens else self._tok_texts[0]
            # this can just be a must list
            must = self._make_match_phrase_list(phrases)
            ret = {'bool': {'must': must}}
        # otherwise there is more than one string in the phrases
        else:
            # this will be a should match
            should = None
            # if no tokenization, it's a flat should across the aliases
            if not self.use_tokens:
                should = self._make_match_phrase_list(self.text)
            # otherwise it is a should across musts for the tokens
            else:
                should = []
                # make a must for each token list
                for tok_list in self._tok_texts:
                    must = self._make_match_phrase_list(tok_list)
                    should.append({'bool': {'must': must}})
            # wrap it up
            ret = {'bool': {'should': should}}
        # done
        return ret

    def get_name(self):
        # just give back the one name if not using aliases
        if not self.use_aliases:
            return self.text[0]
        # otherwise make a comma-separated-list
        return self.delimiter.join(self.text)

# this is the API version used for the web interface

def api_full_query(
        all_targets,
        key_phrase,
        through_year,
        sep_kp,
        stem_kp=False,
        sep_targ=False,
        stem_targ=False,
        alias=False,
        delim=','):
    # first make our keyphrase
    keyphrase_mt = MatchText(key_phrase, sep_kp, stem_kp, alias, delim)
    # and prepare all the target terms
    targ_list = [MatchText(t, sep_targ, stem_targ, alias, delim)
                 for t in all_targets]
    # we will return this as a dictionary stored somewhat compactly
    ret = dict()
    # compute the total number of articles in the database
    db_article_cnt = get_db_count(through_year, URL_BASE, AUTH)
    ret['db_article_cnt'] = db_article_cnt
    # and the number of times the key phrase shows up
    kp_cnt = get_kp_count(keyphrase_mt, through_year, URL_BASE, AUTH)
    ret['kp_cnt'] = kp_cnt
    # and do each target
    ret['target'] = list()
    ret['targ_cnt'] = list()
    ret['targ_with_kp_cnt'] = list()
    for targ_mt in targ_list:
        targ_cnt, targ_with_kp_cnt = get_targ_and_targkp_count(
            targ_mt, keyphrase_mt, through_year, URL_BASE, AUTH, kp_cnt=kp_cnt)
        ret['target'].append(targ_mt.get_name())
        ret['targ_cnt'].append(targ_cnt)
        ret['targ_with_kp_cnt'].append(targ_with_kp_cnt)
    return ret

def make_query_object(target_mt, keyphrase_mt, through_year):
    # build the constraint list first
    must = []
    # are we searching on a target term
    if target_mt is not None:
        must.append(target_mt.make_match_bool())
    # and key phrase
    if keyphrase_mt is not None:
        must.append(keyphrase_mt.make_match_bool())
    # always add the year constraint
    must.append({'range': {'publication_date.year': {'lte': through_year}}})
    query = {'query': {'bool': {'must': must}}}
    return query

def try_get(url, data, auth):
    timeout = 5.0
    backoff = 1.0
    max_backoff = 30.0
    res = None
    done = False
    while not done:
        # try to do the query
        try:
            res = requests.get(url, data=data, auth=auth, timeout=timeout)
        except (requests.ConnectionError, requests.HTTPError, requests.Timeout):
            # should do something more here, perhaps specific to each error
            pass
        # did we get a good response
        if res is not None and res.status_code == 200:
            done = True
        else:
            res = None
            # we didn't get what we wanted, so retry with a backoff
            backoff = min(backoff * 2.0, max_backoff)
            time.sleep(backoff)
    return res

def get_count(target_mt, keyphrase_mt, through_year, url_base, auth):
    # target term and/or key phrase may be None
    q = make_query_object(target_mt, keyphrase_mt, through_year)
    res = try_get(url_base, json.dumps(q), auth)
    ret_cnt = res.json()['count']
    return ret_cnt

def get_db_count(through_year, url_base, auth):
    return get_count(None, None, through_year, url_base, auth)

def get_kp_count(keyphrase_mt, through_year, url_base, auth):
    return get_count(None, keyphrase_mt, through_year, url_base, auth)

def get_targ_and_targkp_count(
        target_mt,
        keyphrase_mt,
        through_year,
        url_base,
        auth,
        kp_cnt=None):
    # we may get a kp_cnt to speed up querying or we should compute
    if kp_cnt is None:
        kp_cnt = get_kp_count(keyphrase_mt, through_year, url_base, auth)
    # default to 0 for the combined match
    targ_with_kp_cnt = 0
    # first the individual count
    targ_cnt = get_count(target_mt, None, through_year, url_base, auth)
    # only need to query combined if articles exist for both individually
    if targ_cnt > 0 and kp_cnt > 0:
        # now do both key phrase and target
        targ_with_kp_cnt = get_count(
            target_mt, keyphrase_mt, through_year, url_base, auth)
    return targ_cnt, targ_with_kp_cnt


"""

This program loads the graph from the file and draws it,
processes and outputs information about its connected components,
determines a diameter and displays it on the graphic file,
and draws the spanning forest of the Graph.

Variant: 52.
Coded by Nazarenko Andriy

"""

import networkx as nx
import matplotlib.pyplot as plt

class Graph(nx.Graph):
    """
    Inherited from networkx.Graph() class, which has additional methods.
    """

    def draw_a_tree(self, pos: dict = None):
        """
        Makes a graphic file, where is drawn a graph whit its spanning forest.
        :param pos: determines the positions of nodes.
        :return:
        """
        tree = nx.minimum_spanning_tree(self)
        edge_tree_colors = ['g' if t_e in tree.edges() else 'k' for t_e in self.edges()]
        node_tree_colors = ['g' if t_n in tree.nodes() else 'k' for t_n in self.nodes()]
        nx.draw(self, pos=pos, with_labels=True, node_color=node_tree_colors, font_color='white',
                edge_color=edge_tree_colors)
        plt.show()

    def info_about_components(self):
        """
        Prints the number of nodes and edges, degrees,eccentricities,
        radius and diameter of each connected component
        :return: Nothing
        """
        number = 0
        for component in nx.connected_components(self):
            subgraph = self.subgraph(component)
            number += 1
            print(f"Connected Component №{number}.")
            print(f"The number of vertex = {nx.number_of_nodes(subgraph)}.")
            print(f"The number of edges = {nx.number_of_edges(subgraph)}.")
            print(f"Nodes degrees: {subgraph.degree}.")
            print(f"Nodes eccentricities: {nx.eccentricity(subgraph)}.")
            print(f"Radius of the component = {nx.radius(subgraph)}.")
            print(f"Diameter of the component = {nx.diameter(subgraph)}.")

    def draw_diameters(self, pos=None):
        """
        Makes a graphic file, where is drawn a graph whit its diameters.
        :param pos: argument that determines positions of the nodes.
        :return:
        """
        diameter_paths = []
        diameter = None

        for component in nx.connected_components(self):
            subgraph = self.subgraph(component)
            d = nx.diameter(subgraph)
            short_paths = dict(nx.all_pairs_shortest_path(subgraph))
            for node in short_paths.values():
                for path in node.values():
                    if 0 < len(path) - 1 == d:
                        diameter = path
                        break
            diameter_paths += [tuple(diameter)]
        d_graph = nx.Graph(diameter_paths)
        d_edge_colors = ['r' if (d_e in d_graph.edges) else 'k' for d_e in self.edges()]
        d_node_colors = ['r' if (d_n in d_graph.nodes) else 'k' for d_n in self.nodes()]

        nx.draw(self, with_labels=True, pos=pos, font_color='white', edge_color=d_edge_colors,
                node_color=d_node_colors)
        plt.show()

try:
    # 2
    g = Graph(nx.read_adjlist('C:/Temp/adj_list.txt'))
    nx.draw_shell(g, with_labels=True, font_color='w', edge_color='k', node_color='k')
    plt.show()

    # 3
    positions = {'1': [3, 3], '2': [0, 0], '3': [3, 6], '4': [6, 0], '5': [8, 0], '6': [11, 6], '7': [14, 0],
                 '8': [16, 0],
                 '9': [19, 6], '10': [22, 0], '11': [24, 0], '12': [24, 6], '13': [25, 3]}
    nx.draw(g, pos=positions, with_labels=True, font_color='w', edge_color='k', node_color='k')
    plt.show()

    # 4
    g.info_about_components()

    # 5
    g.draw_diameters(pos=positions)

    # 6
    g.draw_a_tree(pos=positions)
except Exception as e:
    print(e)


from typing import Optional, List
from pydantic.error_wrappers import ErrorWrapper, ValidationError

from dispatch.exceptions import NotFoundError
from dispatch.project import service as project_service

from .models import (
    SourceStatus,
    SourceStatusCreate,
    SourceStatusUpdate,
    SourceStatusRead,
)

def get(*, db_session, source_status_id: int) -> Optional[SourceStatus]:
    """Gets a status by its id."""
    return db_session.query(SourceStatus).filter(SourceStatus.id == source_status_id).one_or_none()

def get_by_name(*, db_session, project_id: int, name: str) -> Optional[SourceStatus]:
    """Gets a status by its name."""
    return (
        db_session.query(SourceStatus)
        .filter(SourceStatus.name == name)
        .filter(SourceStatus.project_id == project_id)
        .one_or_none()
    )

def get_by_name_or_raise(
    *, db_session, project_id, source_status_in=SourceStatusRead
) -> SourceStatusRead:
    """Returns the status specified or raises ValidationError."""
    status = get_by_name(db_session=db_session, project_id=project_id, name=source_status_in.name)

    if not status:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(
                        msg="SourceStatus not found.",
                        status=source_status_in.name,
                    ),
                    loc="status",
                )
            ],
            model=SourceStatusRead,
        )

    return status

def get_all(*, db_session, project_id: int) -> List[Optional[SourceStatus]]:
    """Gets all sources."""
    return db_session.query(SourceStatus).filter(SourceStatus.project_id == project_id)

def create(*, db_session, source_status_in: SourceStatusCreate) -> SourceStatus:
    """Creates a new status."""
    project = project_service.get_by_name_or_raise(
        db_session=db_session, project_in=source_status_in.project
    )
    source_status = SourceStatus(**source_status_in.dict(exclude={"project"}), project=project)
    db_session.add(source_status)
    db_session.commit()
    return source_status

def get_or_create(*, db_session, source_status_in: SourceStatusCreate) -> SourceStatus:
    """Gets or creates a new status."""
    # prefer the status id if available
    if source_status_in.id:
        q = db_session.query(SourceStatus).filter(SourceStatus.id == source_status_in.id)
    else:
        q = db_session.query(SourceStatus).filter_by(name=source_status_in.name)

    instance = q.first()
    if instance:
        return instance

    return create(
        db_session=db_session,
        source_status_in=source_status_in,
    )

def update(
    *,
    db_session,
    source_status: SourceStatus,
    source_status_in: SourceStatusUpdate,
) -> SourceStatus:
    """Updates an existing status."""
    source_status_data = source_status.dict()
    update_data = source_status_in.dict(skip_defaults=True, exclude={})

    for field in source_status_data:
        if field in update_data:
            setattr(source_status, field, update_data[field])

    db_session.commit()
    return source_status

def delete(*, db_session, source_status_id: int):
    """Deletes an existing status."""
    source_status = (
        db_session.query(SourceStatus).filter(SourceStatus.id == source_status_id).one_or_none()
    )
    db_session.delete(source_status)
    db_session.commit()


import collections
import socket
from email import utils
from ago import human
from django.core import signing
from django.conf import settings
from django.utils import timezone
from datetime import timedelta, datetime
from django.core.urlresolvers import reverse
from django.utils.timezone import utc
from notification.models import SlackRoom, HipChatRoom
import whois
from pygeoip import GeoIP
from deepdiff import DeepDiff
import re

DOMAIN = settings.DOMAIN_NAME

import logging

LOG = logging.getLogger(__name__)

TIME_FORMAT = "%Y-%m-%d %H:%M:%S"

def fqdn_to_ip(fqdn):
    """Util function to get IP for a given fqdn
    """
    ip_addr = socket.gethostbyname(fqdn)
    return ip_addr

def decode(token, expiring=True):
    """
    Use Django signing to decode the token.
    :param token: the token object (signed)
    :return: decoded dictionary if success, else None
    """
    try:
        if expiring:
            val = signing.loads(token, max_age=settings.TOKEN_LIFETIME)
        else:
            val = signing.loads(token)
    except Exception as e:
        LOG.info("The token seems to be invalid (%s)" % str(e))
        val = None
    return val

def encode(d):
    """
    Encode the object (dict) using django signing
    :param d: the Dictionary object to sign (encode)
    :return: the encoded object
    """
    val = None
    if isinstance(d, dict):
        try:
            val = signing.dumps(d)
        except Exception as e:
            LOG.error("Error occurred during encoding (%s)" % str(e))
    return val

def _get_snooze_timestamp(td):
    now = timezone.now()
    later = now + td
    return later.strftime(TIME_FORMAT)

def generate_sslcheck_email_links(email, sslcheck_id):
    url = "https://%s%s" % (DOMAIN, reverse('ssl_no_auth'))
    ret = dict(unsubscribe=None, snooze={})

    # Snooze links
    for x in settings.DAYS_TO_SSL_SNOOZE:
        d = dict(action="snooze",
                 email=email,
                 snooze_days=x,
                 snooze_until=_get_snooze_timestamp(x),
                 sslcheck_id=sslcheck_id)
        ret['snooze'][x] = "%s?tk=%s" % (url, encode(d))

    # Unsubscribe link
    d = dict(action="unsubscribe",
             email=email,
             sslcheck_id=sslcheck_id)
    ret['unsubscribe'] = "%s?tk=%s" % (url, encode(d))
    return ret

def datetime_json_encoder(obj):
    return obj.isoformat() if hasattr(obj, 'isoformat') else obj

def ack_notification_email_link(emails=None, notification_id=None, snooze_durations=[]):
    ack_urls_for_emails = {}

    for email in emails:

        url = "https://%s%s" % (DOMAIN, reverse('notification_no_auth'))
        ack_urls = collections.OrderedDict()

        for x in snooze_durations:
            d = dict(action="ack", email=email,
                     snooze_duration=humanize_snooze_durations(x),
                     ack_untill=_get_snooze_timestamp(x),
                     notification_id=notification_id)

            ack_urls[humanize_snooze_durations(x)] = "%s?tk=%s" % (url, encode(d))

        ack_urls_for_emails[email] = ack_urls

    return ack_urls_for_emails

def time_from_epoch(epoch):
    return utils.formatdate(epoch)

def humanize_snooze_durations(td):
    return human(td).replace(' ago', '')

def parse_whois_data(domain_name):
    """Util function to parse domain's whois Information
    :param domain_name: name of domain for which we want whois information
    :return: tuple containing
    (parsed whois data, no. of days remaining to expire domain, already expire the domain or not)
    """
    whois_data = whois.whois(domain_name).query(redirect=False)
    parsed_whois_data = whois.Parser(domain_name, whois_data[1]).parse()

    try:
        # ExpirationDate format is not consistent
        # some times it return Y-m-dTH:M:S and some times Y-m-d
        parsed_expire_date = parsed_whois_data["ExpirationDate"][0].split('T')[0]
        expiry_date = datetime.strptime(parsed_expire_date, "%Y-%m-%d").replace(tzinfo=utc)
        cur_date = timezone.now()

        expire_days = int((expiry_date - cur_date).days)
        is_expire = True if expire_days <= 0 else False
    except Exception as e:
        expire_days = None
        is_expire = False
        LOG.error("Error occurred during Parsing ExpirationDate for domain %s: (%s)" % (domain_name, str(e)))

    return parsed_whois_data, expire_days, is_expire

def compare_dict(first_dict, second_dict):
    """Util function to compare two dictionaries
    :param first_dict:
    :param second_dict:
    :return: dictionary object with changed Data
    """
    changed_data = DeepDiff(first_dict, second_dict)

    added_items_list = changed_data.changes['list_added'] if 'list_added' in changed_data.changes else None
    removed_items_list = changed_data.changes['list_removed'] if 'list_removed' in changed_data.changes else None

    added_items = {}
    if added_items_list:
        for added_item in added_items_list:
            # DeepDiff returns every thing in string
            # so need to convert it in dictionary
            key, values = added_item.split(":")
            find_key_name = re.search("\[\'(.*?)\'\]", key)
            if find_key_name:
                key_name = find_key_name.group(1)
                added_items[str(key_name)] = eval(values)

    removed_items = {}
    if removed_items_list:
        for removed_item in removed_items_list:
            key, values = removed_item.split(":")
            find_key_name = re.search("\[\'(.*?)\'\]", key)
            if find_key_name:
                key_name = find_key_name.group(1)
                removed_items[str(key_name)] = eval(values)

    return {
        'added_items': added_items,
        'removed_items': removed_items
    }

def country_from_ip(ip, geo_conn=None):
    """
     Helper method to return the coutry_code from
     a given ip address
     :rtype : dict
     :param ip: The ip (string) e.g. 106.185.47.165
     :param geo_conn: The connection object to use
     :return: Two letter country code e.g. JP
    """
    if not geo_conn:
        geo_conn = geo_connection()
    try:
        return geo_conn.country_code_by_addr(ip)
    except Exception as e:
        LOG.error("Error occurred while converting ip %s "
                  " to country code" % (ip))

def geo_connection():
    geo_conn = GeoIP("%s/%s" % (settings.GEOIP_DB_LOCATION,
                                settings.GEOIP_FILENAME))
    return geo_conn


try:
    import sys
    import argparse
    import os
    import subprocess
    import io
    import signal
    import datetime
    import csv
    import numpy as np
    import matplotlib.pyplot as plt
    import time
    import socket
except ImportError as e:
    print(f"[ERROR] in {__file__} " + str(e))
    sys.exit(1)

kVerbose = False  # Set this to True for debugging

# set matplotlib font size
SMALL_SIZE = 10
MEDIUM_SIZE = 10
BIGGER_SIZE = 12

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE)    # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title

def parse_csv(file_path):
    with open(file_path) as csvfile:
        csv_reader = csv.reader(csvfile, delimiter=',')
        line_count = 0
        names = None
        data = {}
        data['filename'] = os.path.basename(file_path)
        for row in csv_reader:
            if line_count == 0:
                names = row
                for i in range(0,len(names)):
                    if i == 0:
                        names[0] = names[0][1:].strip()
                    else:
                        names[i] = names[i].strip()
                print(f'names: {names}')
            else:
                #print(row)
                assert(len(names) == len(row))
                for i in range(0,len(row)):
                    if line_count == 1:
                        data[names[i]] = []
                    #print(names[i] + ' ' + row[i])
                    data[names[i]].append(row[i])
            line_count += 1
        data['keys'] = names
        return data
    return None

# Save figure with nice margin
def save_fig(figure, name, dpi = 300, bbox_inches = 0, pad_inches = 0.1):
    # mng = plt.get_current_fig_manager()
    # mng.full_screen_toggle()
    print(f'saving figure: {name}')
    figure.set_size_inches(24, 18)
    figure.savefig(name, dpi = dpi, bbox_inches = bbox_inches, pad_inches = pad_inches, orientation='landscape')

def draw_path(ax, path, color, marker, label, dashed=False):
    path_x = [x[0] for x in path]
    path_y = [x[1] for x in path]
    if dashed:
        ax.plot(path_x, path_y, c=color, marker=marker, label=label, linestyle='dashed')
    else:
        ax.plot(path_x, path_y, c=color, marker=marker, label=label)

def draw_data(data, args):
    assert(data is not None)

    markersize = 3

    # comment = f'# x, y '

    data_to_draw = ['timestamp','x', 'y']

    filename = data['filename']

    names = data['keys']
    timestamps = np.array(data['timestamp'], dtype=float)
    t0 = timestamps[0]
    timestamps = np.subtract(timestamps, t0)

    x = np.array(data['x'], dtype=float)
    y = np.array(data['y'], dtype=float)

    #print(f'timestamps size: ', len(timestamps))

    fig_cartesian, ax_cartesian = plt.subplots(1)
    fig_components, [ax_x, ax_y] = plt.subplots(2)

    # set big figures (otherwise tight_layout() won't work below)
    fig_size_inches = (24, 18)
    fig_cartesian.set_size_inches(fig_size_inches)
    fig_components.set_size_inches(fig_size_inches)

    suptitle_fontsize = 12
    subfig_title_fontsize = 8
    subfig_xlabel_fontsize = 8

    fig_cartesian.suptitle('Data from: ' + filename, fontsize=suptitle_fontsize)
    fig_components.suptitle('Data from: ' + filename, fontsize=suptitle_fontsize)

    ax_cartesian.set_title('x-y plane', fontsize=subfig_title_fontsize)
    ax_x.set_title('x component', fontsize=subfig_title_fontsize)
    ax_y.set_title('x component', fontsize=subfig_title_fontsize)

    ax_cartesian.plot(x, y, c='blue', marker='.', label='path')
    ax_x.plot(timestamps, x, c='blue', marker='.', label='x')
    ax_y.plot(timestamps, y, c='blue', marker='.', label='y')

    ax_cartesian.grid(True)
    ax_cartesian.axis('equal')
    ax_cartesian.set_xlabel('m', fontsize=subfig_xlabel_fontsize)
    ax_cartesian.set_ylabel('m')

    ax_x.set_xlabel('time', fontsize=subfig_xlabel_fontsize)
    ax_x.set_ylabel('m')
    ax_x.legend(loc='upper right', frameon=False)
    ax_x.grid(True)
    ax_x.set_xticks(np.arange(min(timestamps), max(timestamps)+1, args.tick))

    ax_y.set_xlabel('time', fontsize=subfig_xlabel_fontsize)
    ax_y.set_ylabel('m')
    ax_y.legend(loc='upper right', frameon=False)
    ax_y.grid(True)
    ax_y.set_xticks(np.arange(min(timestamps), max(timestamps)+1, args.tick))

    # NOTE: as for tight_layout(), you may provide an optional rect parameter, which specifies the bounding box
    # that the subplots will be fit inside. The coordinates must be in normalized figure coordinates and
    # the default is (0, 0, 1, 1). From https://matplotlib.org/2.0.2/users/tight_layout_guide.html
    layout_rect_delta = 0.03
    layout_rect = [layout_rect_delta, layout_rect_delta, (1.0-layout_rect_delta), (1.0-layout_rect_delta)]
    layout_pad = 5
    #fig.tight_layout()  # avoid text overlapping
    fig_cartesian.tight_layout(rect=layout_rect, pad=layout_pad)   # avoid text overlapping
    fig_components.tight_layout(rect=layout_rect, pad=layout_pad)   # avoid text overlapping
    if args.save_plots:
        folder_name = os.path.dirname(os.path.abspath(args.input_file))
        path = os.path.join(folder_name, filename)
        save_fig(fig_cartesian, f'{path}_cartesian_plot.png')
        save_fig(fig_components, f'{path}_components_plot.png')
    plt.show()

def signal_handler(sig, frame):
    print('\n{} intercepted Ctrl+C!'.format(os.path.basename(__file__)))
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

if __name__ == '__main__':

    argparser = argparse.ArgumentParser(description='Parse and draw a log')
    argparser.add_argument("-i", "--input-file", type=str, default=None, help="Path of the input file we want to draw.")
    argparser.add_argument("-t", "--tick", default=0.5, help="Horizontal tick on the time axis.")
    argparser.add_argument("-s", "--save-plots", default=False, action='store_true', help="Save the plots in case you give an input file.")
    args = argparser.parse_args()

    # check if we have to draw an input file
    if args.input_file:
        print('parsing and drawing input file ' + args.input_file)
        data = parse_csv(args.input_file)
        #print('data: ' + str(data))
        draw_data(data, args)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import csv
import datetime
import os
import signal
import sys
from time import time
import uuid
from warnings import warn

from configobj import ConfigObj, ConfigObjError, flatten_errors
from validate import Validator

from logfile import write_metapop_data, write_population_data, write_population_genotypes
from Metapopulation import *
from misc import *
from Topology import *

__version__ = '1.0.5'

def parse_arguments():
    """Parse command line arguments"""

    parser = argparse.ArgumentParser(prog='ncsimulate.py',
                                     description='Run a simluation')
    parser.add_argument('--config', '-c', metavar='FILE', help='Configuration '\
                        'file to use (default: base.cfg)', default='base.cfg',
                        dest='configfile')
    parser.add_argument('--checkconfig', '-C', action='store_true',
                        default=False,
                        help='Check the given configuration file and quit (note: includes parameters specified with --param')
    parser.add_argument('--data_dir', '-d', metavar='DIR',
                        help='Directory to store data (default: data)')
    parser.add_argument('--param', '-p', nargs=3, metavar=('SECTION', 'NAME',
                                                           'VALUE'),
                        action='append', help='Set a parameter value')
    parser.add_argument('--seed', '-s', metavar='S', help='Set the '\
                        'pseudorandom number generator seed', type=int)
    parser.add_argument('--quiet', '-q', action='store_true', default=False,
                        help='Suppress output messages')
    parser.add_argument('--version', action='version', version=__version__)

    return parser.parse_args()

def ncsimulate():
    """Run a simulation"""

    start_time = time()

    # Print a status message when SIGINFO (ctrl-T) is received on BSD or
    # OS X systems or SIGUSR1 is received on POSIX systems
    def handle_siginfo(signum, frame):
        try:
            print("Cycle {c}: Size {ps}, {pc:.0%} cooperators".format(c=cycle, ps=metapop.shape[0], pc=metapop.Coop.mean()))
        except NameError:
            print("Simulation has not yet begun")

    signal.signal(signal.SIGUSR1, handle_siginfo)
    if hasattr(signal, 'SIGINFO'):
        signal.signal(signal.SIGINFO, handle_siginfo)

    # Some scheduling systems send SIGTERM before killing a job. If SIGTERM
    # is received, flush all of the log files
    def handle_sigterm(signum, frame):
        if log_metapopulation:
            try:
                outfilemp.flush()
            except NameError:
                pass
        if log_population:
            try:
                outfilep.flush()
            except NameError:
                pass
        if log_genotypes:
            try:
                outfileg.flush()
            except NameError:
                pass
    signal.signal(signal.SIGTERM, handle_sigterm)

    # Get the command line arguments
    args = parse_arguments()

    # Read the configuration file
    try:
        config = ConfigObj(infile=args.configfile, configspec='configspec.ini',
                           file_error=True)
    except (ConfigObjError, OSError) as e:
        print("Error: {e}".format(e=e))
        sys.exit(1)

    # Add any parameters specified on the command line to the configuration
    if args.param:
        for param in args.param:
            config[param[0]][param[1]] = param[2]

    # Validate the configuration
    validation = config.validate(Validator(), copy=True)

    if validation != True:
        errors = flatten_errors(config, validation)
        print("Found {n} error(s) in configuration:".format(n=len(errors)))
        for (section_list, key, _) in errors:
            if key is not None:
                print("\t* Invalid value for '{k}' in Section '{s}'".format(k=key, s=section_list[0]))
            else:
                print("\t* Missing required section '{s}'".format(s=section_list[0]))

        sys.exit(2)

    if args.checkconfig:
        print("No errors found in configuration file {f}".format(f=args.configfile))
        sys.exit(0)

    # If the random number generator seed specified, add it to the config,
    # overwriting any previous value. Otherwise, if it wasn't in the
    # supplied configuration file, create one.
    if args.seed:
        config['Simulation']['seed'] = args.seed
    elif 'seed' not in config['Simulation'] or config['Simulation']['seed']==None:
        seed = np.random.randint(low=0, high=np.iinfo(np.uint32).max)
        config['Simulation']['seed'] = seed

    np.random.seed(seed=config['Simulation']['seed'])

    # Generate a universally unique identifier (UUID) for this run
    config['Simulation']['UUID'] = str(uuid.uuid4())

    # If the data directory is specified, add it to the config, overwriting any
    # previous value
    if args.data_dir:
        config['Simulation']['data_dir'] = args.data_dir

    # If the data_dir already exists, append the current date and time to
    # data_dir, and use that. Afterwards, create the directory.
    if os.path.exists(config['Simulation']['data_dir']):
        newname = '{o}-{d}'.format(o=config['Simulation']['data_dir'],
                                   d=datetime.datetime.now().strftime("%Y%m%d%H%M%S"))
        msg = '{d} already exists. Using {new} instead.'.format(d=config['Simulation']['data_dir'],
                                                                new=newname)
        warn(msg)
        config['Simulation']['data_dir'] = newname

    os.mkdir(config['Simulation']['data_dir'])

    # Write information about the run
    infofile = os.path.join(config['Simulation']['data_dir'], 'run_info.txt')
    write_run_information(filename=infofile, config=config)

    # Write the configuration file
    config.filename = os.path.join(config['Simulation']['data_dir'],
                                   'configuration.cfg')
    config.write()
    config.num_births = 0

    # Create the log file of metapopulation-level data if enabled
    log_metapopulation = config['MetapopulationLog']['enabled']
    if log_metapopulation:
        log_metapopulation_freq = config['MetapopulationLog']['frequency']

        # Config options for logging metapopulation. Name, frequency, etc.
        fieldnames = ['Time', 'Births', 'PopulationSize', 'CooperatorProportion',
                      'MinCooperatorFitness', 'MaxCooperatorFitness',
                      'MeanCooperatorFitness', 'MinDefectorFitness',
                      'MaxDefectorFitness', 'MeanDefectorFitness',
                      'ShannonIndex', 'SimpsonIndex']

        outfilemp = open(os.path.join(config['Simulation']['data_dir'],
                         config['MetapopulationLog']['filename']), 'w')
        writermp = csv.DictWriter(outfilemp, fieldnames=fieldnames)
        writermp.writeheader()

    # Create the log file of population-level data if enabled
    log_population = config['PopulationLog']['enabled']
    if log_population:
        log_population_freq = config['PopulationLog']['frequency']

        # Config options for logging population. Name, frequency, etc.
        fieldnames = ['Time', 'Population', 'X', 'Y', 'PopulationSize',
                      'CooperatorProportion', 'MinCooperatorFitness',
                      'MaxCooperatorFitness', 'MeanCooperatorFitness',
                      'MinDefectorFitness', 'MaxDefectorFitness',
                      'MeanDefectorFitness', 'ShannonIndex', 'SimpsonIndex']

        outfilep = open(os.path.join(config['Simulation']['data_dir'],
                        config['PopulationLog']['filename']), 'w')
        writerp = csv.DictWriter(outfilep, fieldnames=fieldnames)
        writerp.writeheader()

    log_genotypes = config['GenotypeLog']['enabled']
    if log_genotypes:
        log_genotypes_freq = config['GenotypeLog']['frequency']
        fieldnames = ['Time', 'Population', 'X', 'Y', 'Genotype']

        outfileg = open(os.path.join(config['Simulation']['data_dir'],
                        config['GenotypeLog']['filename']), 'w')
        writerg = csv.DictWriter(outfileg, fieldnames=fieldnames)
        writerg.writeheader()

    # Create the migration topology. This is a graph where each population is a
    # node, and the edges between nodes represent potential paths for migration
    topology = build_topology(config=config)

    if config['Simulation']['export_topology']:
        fn = os.path.join(config['Simulation']['data_dir'], 'topology.gml')
        export_topology(topology=topology, filename=fn)

    # Create the metapopulation and apply the initial stress bottleneck
    metapop = create_metapopulation(config=config, topology=topology,
                                    initial_state=config['Metapopulation']['initial_state'])

    stress_tolerance = config['Population']['mutation_rate_tolerance']
    if stress_tolerance < 1:
        metapop = bottleneck(population=metapop,
                             survival_pct=config['Population']['mutation_rate_tolerance'])
    else:
        metapop = bottleneck(population=metapop,
                             survival_pct=config['Population']['dilution_factor'])

    # Keep track of how often the metapopulation should be mixed
    mix_frequency = config['Metapopulation']['mix_frequency']

    adaptive_columns = adaptive_colnames(L=config['Population']['genome_length'])

    # Iterate through each cycle of the simulation
    for cycle in range(config['Simulation']['num_cycles']):
        if not args.quiet:
            if len(adaptive_columns) > 0:
                c1 = (metapop.loc[metapop.Coop==1, adaptive_columns] > 0).sum(axis=1).max()
                d1 = (metapop.loc[metapop.Coop==0, adaptive_columns] > 0).sum(axis=1).max()
            else:
                c1 = d1 = 'NA'

            print("Cycle {c}: Size {ps}, Populations {pops}, {pc:.0%} cooperators, Fitness: {f:.02}, C1: {c1}, D1: {d1} ]".format(c=cycle, ps=metapop.shape[0], pops=metapop.Population.unique().shape[0], pc=metapop.Coop.mean(), f=metapop.Fitness.mean(), c1=c1, d1=d1))

        if log_metapopulation and cycle % log_metapopulation_freq == 0:
            write_metapop_data(writer=writermp, metapop=metapop,
                               topology=topology, cycle=cycle, config=config)

        if log_population and cycle % log_population_freq == 0:
            write_population_data(writer=writerp, metapop=metapop,
                                  topology=topology, cycle=cycle, config=config)

        if log_genotypes and cycle % log_genotypes_freq == 0:
            write_population_genotypes(writer=writerg, metapop=metapop,
                                       topology=topology, cycle=cycle,
                                       config=config)

        # Grow the population to carrying capacity, potentially mutating
        # offspring
        metapop = grow(M=metapop, config=config)
        #print("----- Num births: {nb}".format(nb=config.num_births))

        # Migrate individuals among subpopulations
        metapop = migrate(M=metapop, topology=topology,
                          rate=config['Metapopulation']['migration_rate'])

        # Mix the metapopulation (if configured)
        if mix_frequency > 0 and cycle > 0 and (cycle % mix_frequency == 0):
            metapop = mix(M=metapop, topology=topology)

        # Dilution
        metapop = bottleneck(population=metapop,
                             survival_pct=config['Population']['dilution_factor'])

        if config['Simulation']['stop_when_empty'] and \
                metapop.shape[0] == 0:
            break
        elif config['Simulation']['num_births'] and config.num_births > config['Simulation']['num_births']:
            break

    if log_metapopulation:
        write_metapop_data(writer=writermp, metapop=metapop, topology=topology,
                           cycle=cycle+1, config=config)
    if log_population:
        write_population_data(writer=writerp, metapop=metapop,
                              topology=topology, cycle=cycle, config=config)

    rt_string = 'Run Time: {t}\n'.format(t=datetime.timedelta(seconds=time()-start_time))
    append_run_information(filename=infofile, string=rt_string)

#-------------------------------------------------------------------------

if __name__ == "__main__":
    ncsimulate()


"""
=================
Template Matching
=================

We use template matching to identify the occurrence of an image patch
(in this case, a sub-image centered on a single coin). Here, we
return a single match (the exact same coin), so the maximum value in the
``match_template`` result corresponds to the coin location. The other coins
look similar, and thus have local maxima; if you expect multiple matches, you
should use a proper peak-finding function.

The ``match_template`` function uses fast, normalized cross-correlation [1]_
to find instances of the template in the image. Note that the peaks in the
output of ``match_template`` correspond to the origin (i.e. top-left corner) of
the template.

.. [1] J. P. Lewis, "Fast Normalized Cross-Correlation", Industrial Light and
       Magic.

"""
# import numpy as np
# import matplotlib.pyplot as plt
#

from skimage import data
from skimage.feature import match_template
# import time
#
#
# image = data.coins()
# coin = image[170:220, 75:130]
#
#
# start_time = time.time()
# result = match_template(image, coin)
# end_time = time.time()
# print("the image size is :", image.shape)
# print("the match cost:", (end_time - start_time)*1000)
# ij = np.unravel_index(np.argmax(result), result.shape)
# x, y = ij[::-1]
#
# fig = plt.figure(figsize=(8, 3))
# ax1 = plt.subplot(1, 3, 1)
# ax2 = plt.subplot(1, 3, 2)
# ax3 = plt.subplot(1, 3, 3, sharex=ax2, sharey=ax2)
#
# ax1.imshow(coin, cmap=plt.cm.gray)
# ax1.set_axis_off()
# ax1.set_title('template')
#
# ax2.imshow(image, cmap=plt.cm.gray)
# ax2.set_axis_off()
# ax2.set_title('image')
# # highlight matched region
# hcoin, wcoin = coin.shape
# rect = plt.Rectangle((x, y), wcoin, hcoin, edgecolor='r', facecolor='none')
# ax2.add_patch(rect)
#
# ax3.imshow(result)
# ax3.set_axis_off()
# ax3.set_title('`match_template`\nresult')
# # highlight matched region
# ax3.autoscale(False)
# ax3.plot(x, y, 'o', markeredgecolor='r', markerfacecolor='none', markersize=10)
#
# plt.show()

import cv2
import numpy as np
import time
from matplotlib import pyplot as plt

img_rgb = cv2.imread('D:/pictures/barcode/3.png')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('D:/pictures/barcode/bar.png', 0)
w, h = template.shape[::-1]

start_time = time.time()
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
end_time = time.time()
print("match cost : ", (end_time - start_time) * 1000)
threshold = 0.8
start_time = time.time()
result = match_template(img_gray, template)
end_time = time.time()
print("the image size is :", img_gray.shape)
print("the match cost:", (end_time - start_time)*1000)

# umpy.where(condition[, x, y])
# Return elements, either from x or y, depending on condition.
# If only condition is given, return condition.nonzero().
loc = np.where(res >= threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)

cv2.imwrite('res.png', img_rgb)


import collections
import random
import math
import torch
from torch import nn

def read_ptb():
    """将PTB数据集加载到文本行的列表中"""
    # Readthetrainingset.
    with open( r'D:\书籍资料整理\kaggle\ptb\ptb.train.txt') as f:
        raw_text = f.read()
    return [line.split() for line in raw_text.split('\n')]

def count_corpus(tokens):  #@save
    """统计词元的频率"""
    # 这里的tokens是1D列表或2D列表
    if len(tokens) == 0 or isinstance(tokens[0], list):
        # 将词元列表展平成一个列表
        tokens = [token for line in tokens for token in line]
    return collections.Counter(tokens)

class Vocab:  #@save
    """文本词表"""
    def __init__(self, tokens=None, min_freq=0, reserved_tokens=None):
        if tokens is None:
            tokens = []
        if reserved_tokens is None:
            reserved_tokens = []
        # 按出现频率排序
        counter = count_corpus(tokens)
        self._token_freqs = sorted(counter.items(), key=lambda x: x[1],
                                   reverse=True)
        # 未知词元的索引为0
        self.idx_to_token = ['<unk>'] + reserved_tokens
        self.token_to_idx = {token: idx
                             for idx, token in enumerate(self.idx_to_token)}
        for token, freq in self._token_freqs:
            if freq < min_freq:
                break
            if token not in self.token_to_idx:
                self.idx_to_token.append(token)
                self.token_to_idx[token] = len(self.idx_to_token) - 1

    def __len__(self):
        return len(self.idx_to_token)

    def __getitem__(self, tokens):
        if not isinstance(tokens, (list, tuple)):
            return self.token_to_idx.get(tokens, self.unk)
        return [self.__getitem__(token) for token in tokens]

    def to_tokens(self, indices):
        if not isinstance(indices, (list, tuple)):
            return self.idx_to_token[indices]
        return [self.idx_to_token[index] for index in indices]

    @property
    def unk(self):  # 未知词元的索引为0
        return 0

    @property
    def token_freqs(self):
        return self._token_freqs

def subsample(sentences, vocab):
    """下采样高频词"""
    # 排除未知词元'<unk>'
    sentences = [[token for token in line if vocab[token] != vocab.unk]
                 for line in sentences]
    counter = count_corpus(sentences)
    num_tokens = sum(counter.values())

    # 如果在下采样期间保留词元，则返回True
    def keep(token):
        return(random.uniform(0, 1) <
               math.sqrt(1e-4 / counter[token] * num_tokens))

    return ([[token for token in line if keep(token)] for line in sentences],
            counter)

def compare_counts(token):
    return (f'"{token}"的数量：'
            f'之前={sum([l.count(token) for l in sentences])}, '
            f'之后={sum([l.count(token) for l in subsampled])}')

def get_centers_and_contexts(corpus, max_window_size):
    """返回跳元模型中的中心词和上下文词"""
    centers, contexts = [], []
    for line in corpus:
        # 要形成“中心词-上下文词”对，每个句子至少需要有2个词
        if len(line) < 2:
            continue
        centers += line
        for i in range(len(line)):  # 上下文窗口中间i
            window_size = random.randint(1, max_window_size)
            indices = list(range(max(0, i - window_size),
                                 min(len(line), i + 1 + window_size)))
            # 从上下文词中排除中心词
            indices.remove(i)
            contexts.append([line[idx] for idx in indices])
    return centers, contexts

class RandomGenerator:
    """根据n个采样权重在{1,...,n}中随机抽取"""
    def __init__(self, sampling_weights):
        # Exclude
        self.population = list(range(1, len(sampling_weights) + 1))
        self.sampling_weights = sampling_weights
        self.candidates = []
        self.i = 0

    def draw(self):
        if self.i == len(self.candidates):
            # 缓存k个随机采样结果
            self.candidates = random.choices(
                self.population, self.sampling_weights, k=10000)
            self.i = 0
        self.i += 1
        return self.candidates[self.i - 1]

def get_negatives(all_contexts, vocab, counter, K):
    """返回负采样中的噪声词"""
    # 索引为1、2、...（索引0是词表中排除的未知标记）
    sampling_weights = [counter[vocab.to_tokens(i)]**0.75
                        for i in range(1, len(vocab))]
    all_negatives, generator = [], RandomGenerator(sampling_weights)
    for contexts in all_contexts:
        negatives = []
        while len(negatives) < len(contexts) * K:
            neg = generator.draw()
            # 噪声词不能是上下文词
            if neg not in contexts:
                negatives.append(neg)
        all_negatives.append(negatives)
    return all_negatives

#@save
def batchify(data):
    """返回带有负采样的跳元模型的小批量样本"""
    max_len = max(len(c) + len(n) for _, c, n in data)
    centers, contexts_negatives, masks, labels = [], [], [], []
    #masks,实际
    for center, context, negative in data:
        cur_len = len(context) + len(negative)
        centers += [center]
        contexts_negatives += \
            [context + negative + [0] * (max_len - cur_len)]
        masks += [[1] * cur_len + [0] * (max_len - cur_len)]
        labels += [[1] * len(context) + [0] * (max_len - len(context))]
    return (torch.tensor(centers).reshape((-1, 1)), torch.tensor(
        contexts_negatives), torch.tensor(masks), torch.tensor(labels))

class PTBDataset(torch.utils.data.Dataset):
    def __init__(self, centers, contexts, negatives):
        assert len(centers) == len(contexts) == len(negatives)
        self.centers = centers
        self.contexts = contexts
        self.negatives = negatives

    def __getitem__(self, index):
        return (self.centers[index], self.contexts[index],
                self.negatives[index])

    def __len__(self):
        return len(self.centers)

#---------------------模型部分函数---------------------------
def skip_gram(center, contexts_and_negatives, embed_v, embed_u):
    #这里有些疑问的,为啥第二层用contexts_and_negatives来乘.
    #contexts_and_negatives是形如这样的张量[12, 140, 5277, 3054, 1580]
    #embedding层的作用就是将上边索引为.12,140,5277,3054,1580的给取出来
    #注意仅做取出的动作,因为其实实际上,one-hot响应的位置为1,所以只取出来
    #最后用两个权重矩阵相乘就是输出.
    #再注意contexts_negatives这里是填充过的,是否是必要的就不知道了.并且使用为0填充会额外取出0向量.
    #再计算损失函数时会引入额外计算量
    v = embed_v(center)
    u = embed_u(contexts_and_negatives)
    pred = torch.bmm(v, u.permute(0, 2, 1))
    return pred

class SigmoidBCELoss(nn.Module):
    # 带掩码的二元交叉熵损失
    # 这里猜测weight=0的不参与损失函数的计算,不然整个逻辑是有问题的.
    def __init__(self):
        super().__init__()

    def forward(self, inputs, target, mask=None):
        out = nn.functional.binary_cross_entropy_with_logits(
            inputs, target, weight=mask, reduction="none")
        return out.mean(dim=1)

def sigmd(x):
    return -math.log(1 / (1 + math.exp(-x)))

class Accumulator:  # @save
    """在n个变量上累加"""

    def __init__(self, n):
        self.data = [0.0] * n

    def add(self, *args):
        self.data = [a + float(b) for a, b in zip(self.data, args)]

    def reset(self):
        self.data = [0.0] * len(self.data)

    def __getitem__(self, idx):
        return self.data[idx]

def try_gpu(i=0):  #@save
    """如果存在，则返回gpu(i)，否则返回cpu()"""
    if torch.cuda.device_count() >= i + 1:
        return torch.device(f'cuda:{i}')
    return torch.device('cpu')

def train(net, data_iter, lr, num_epochs, device=try_gpu()):
    def init_weights(m):
        if type(m) == nn.Embedding:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    net = net.to(device)
    optimizer = torch.optim.Adam(net.parameters(), lr=lr)

    # 规范化的损失之和，规范化的损失数
    metric = Accumulator(2)
    for epoch in range(num_epochs):
        for i, batch in enumerate(data_iter):
            optimizer.zero_grad()
            center, context_negative, mask, label = [
                data.to(device) for data in batch]

            # out = nn.functional.binary_cross_entropy_with_logits(
            #     inputs, target, weight=mask, reduction="none")

            pred = skip_gram(center, context_negative, net[0], net[1])
            # print(len(vocab),context_negative.shape,pred.shape)
            # print(pred)

            l = (loss(pred.reshape(label.shape).float(), label.float(), mask)
                     / mask.sum(axis=1) * mask.shape[1])
            l.sum().backward()
            optimizer.step()
            metric.add(l.sum(), l.numel())

    print(f'loss {metric[0] / metric[1]:.3f}, ')

if __name__ == '__main__':
    sentences = read_ptb()
    #建立语料库  语料库包含,索引和词频表
    vocab = Vocab(sentences, min_freq=10)
    #下采样
    subsampled, counter = subsample(sentences, vocab)
    print(compare_counts('the'))

    #将句子中的词元转换为索引
    corpus = [vocab[line] for line in subsampled]
    print(corpus[:3])
    #提取中心词和上下文词
    all_centers, all_contexts = get_centers_and_contexts(corpus, 5)
    print(f'# “中心词-上下文词对”的数量: {sum([len(contexts) for contexts in all_contexts])}')
    #负采样
    all_negatives = get_negatives(all_contexts, vocab, counter, 5)

    dataset = PTBDataset(all_centers, all_contexts, all_negatives)
    batch_size=3
    num_workers=2
    data_iter = torch.utils.data.DataLoader(
        dataset, batch_size, shuffle=True,
        collate_fn=batchify, num_workers=num_workers)

    names = ['centers', 'contexts_negatives', 'masks', 'labels']
    # for batch in data_iter:
    #     for name, data in zip(names, batch):
    #         print(name, 'shape:', data.shape)
    #     break

    batch_size, max_window_size, num_noise_words = 512, 5, 5
    embed_size = 100
    net = nn.Sequential(nn.Embedding(num_embeddings=len(vocab),
                                     embedding_dim=embed_size),
                        nn.Embedding(num_embeddings=len(vocab),
                                     embedding_dim=embed_size))
    loss = SigmoidBCELoss()

    lr, num_epochs = 0.002, 5
    train(net, data_iter, lr, num_epochs)

python/深度学习/torch学习/动手学习深度学习/7.NLP/数据文件处理.py


from typing import List
from adventures_sl.abilities import *

MELEE = 'melee'
RANGED = 'ranged'

class Unit:
    health: int = 0
    attack: int = 0
    max_health: int = 0
    abilities: List[Ability] = []

    def __init__(self,
                 health: int = 0,
                 attack: int = 0,
                 max_health: int=None,  # If None, healht is used
                 ):
        self.attack = attack
        self.health = health
        self.max_health = health if max_health is None else max_health

    def set_callback_dead(self, f):
        self.callback_dead = f

    def reduce_hp(self, value: int):
        value = int(value)
        assert value >= 0
        self.health = max(0, self.health - value)

        if self.health <= 0:
            print(f'{self} - dead')
            self.callback_dead()
        # TODO check dead state

    def increase_hp(self, value: int):
        value = int(value)
        assert value >= 0

        self.health = min(self.max_health, self.health + value)

    def get_attack(self):
        return self.attack

    def buff_attack(self, value: int):
        self.attack += int(value)

    def fight(self, battle):
        move = Melee(self, self.get_attack())
        d_log = [move.do(battle)]

        for ability in self.abilities:
            d_log.append(ability.do(battle))

        return d_log

    def __str__(self):
        return f'{self.__class__.__name__}(hp={self.health})'

class Enemy(Unit):
    def __init__(self,
                 lvl: int = 0,
                 health: int = 0,
                 attack: int = 0):
        self.health = health
        self.attack = attack
        self.lvl = lvl

class Friendly(Unit):

    def __init__(self,
                 lvl: int = 0,
                 health: int = 0,
                 attack: int = 0):
        self.health = health
        self.attack = attack
        self.lvl = lvl

# For testing
class ExampleEnemy(Enemy):
    def __init__(self,
                 health=250,
                 attack=10):
        super(ExampleEnemy, self).__init__(health=health, attack=attack)

    def __str__(self):
        return "Example enemy"

class ExampleFriendly(Friendly):
    def __init__(self, health=180,
                 attack=20):
        super(ExampleFriendly, self).__init__(health=health, attack=attack)

    def __str__(self):
        return "Example friendly"

class DarkGoliath(Enemy):
    """
    From "Dark Goliath's Rampage".
    """

    def __init__(self, lvl):
        if lvl == 14:
            health = 4452
            attack = 72
        else:
            # TODO
            raise NotImplemented()

        super(DarkGoliath, self).__init__(health=health, attack=attack)

        self.abilities = [GoliathSlam(self, lvl=lvl)]

class Gorgelimb(Friendly):
    """Necrolords"""

    def __init__(self, lvl):
        if lvl == 16:
            health = 1040
            attack = 52
        else:
            # TODO
            raise NotImplemented()

        super(Gorgelimb, self).__init__(health=health, attack=attack)

        self.abilities = [FleshEruption(self, lvl=lvl)]

class Emeni(Friendly):
    """Necrolords"""

    def __init__(self, lvl):
        self.role = MELEE
        if lvl == 8:
            health = 540
            attack = 108
        else:
            # TODO
            raise NotImplemented()

        super(Emeni, self).__init__(health=health, attack=attack)

        self.abilities = [SulfuricEmission(self, lvl=lvl),
                          GnashingChompers(self, lvl=lvl)]

class SecutorMevix(Friendly):
    """Necrolords"""

    def __init__(self, lvl):
        if lvl == 13:
            health = 805
            attack = 92

        else:
            # TODO
            raise NotImplemented()

        super(SecutorMevix, self).__init__(health=health, attack=attack)

        self.abilities = [SecutorsJudgement(self, lvl=lvl),
                          ]

class PlagueDeviserMarileth(Friendly):
    """Necrolords"""

    def __init__(self, lvl):
        if lvl == 20:  # TODO
            health = 900  # TODO
            attack = 180
        else:
            # TODO
            raise NotImplemented()

        super(PlagueDeviserMarileth, self).__init__(health=health, attack=attack)

        self.abilities = [VolatileSolvent(self, lvl=lvl),
                          OozeFrictionlessCoating(self, lvl=lvl)]

class MaldraxxusPlaguesinger(Friendly):
    """Necrolords normal unit"""

    def __init__(self, lvl):
        self.role = RANGED

        if lvl == 14:
            health = 240
            attack = 222
        else:
            raise NotImplementedError()

        super(MaldraxxusPlaguesinger, self).__init__(health=health, attack=attack)

        self.abilities = [PlagueSong(self, lvl=lvl)]


from alpha_vantage.timeseries import TimeSeries
from alpha_vantage.techindicators import TechIndicators
import matplotlib.pyplot as plt
from datetime import datetime
import time
import pandas as pd
import numpy as np
from enum import Enum
from statsmodels.tsa.stattools import coint
from staticData import ALPHAVANTAGE_APIKEY, eqArr , INTERVAL_1,INTERVAL_15,INTERVAL_60,OUTPUT_SIZE_FULL,PRICE_CLOSE,OPEN ,HIGH,LOW,CLOSE,VOLUME, NUM_DAYS
from plotFunctions import plotCointegratedPairs, plotZScore
from alphavantageFunctions import getAverageAlphaVantageDataframe

ts = TimeSeries(key=ALPHAVANTAGE_APIKEY, output_format='pandas')
ti = TechIndicators(key=ALPHAVANTAGE_APIKEY, output_format='pandas')

def convertDateIndex(df):
    convertedDate = []
    for i in df:
        newDate = i + ":00"
        convertedDate.append(newDate)

    return convertedDate

def getCorrelationValue(column1, column2):
    return column1.corr(column2)

def getCointegrationScore(equity1, equity2):
    score, pvalue, _ = coint(equity1, equity2)

    return score

def getCointegrationPvalue(equity1, equity2):
    score, pvalue, _ = coint(equity1, equity2)

    return pvalue

def zscore(series):
    return (series - series.mean()) / np.std(series)

def getZScoreSignal(equity1, equity2):
    eq1 = getAverageAlphaVantageDataframe(equity1)
    eq2 = getAverageAlphaVantageDataframe(equity2)
    combinedData = pd.concat([eq1, eq2], axis=1)
    combinedData = combinedData.dropna()

    combinedData['ratios'] = combinedData[equity1] / combinedData[equity2]
    combinedData = combinedData.iloc[::-1] # correct timeline
    combinedData['z'] = zscore(combinedData['ratios'])

    signal = combinedData['z'].iloc[-1]
    print(signal)
    if (signal < 0): # buy bc expect to revert to mean ratio
        buysell = "Buy the ratio(" + str(signal) + ") ---> Buy " + equity1 + " Sell " + equity2
        return buysell
    else:
        buysell = "Sell the ratio(" + str(signal) + ") ---> Sell " + equity1 + " Buy " + equity2
        return buysell

def getCorrelationAndCointegratedPairs(equity1, equity2):
    print("-------------------------- getCorrelationAndCointegratedPairs() --------------------------------")
    time.sleep(30) #alphavantage time lock

    priceData, priceMetadata = ts.get_daily(symbol=equity1, outputsize=OUTPUT_SIZE_FULL)
    priceData['avg1'] = (priceData[HIGH] + priceData[LOW])/2 #assume midpoint of high and low is executed price
    priceData.drop([OPEN, HIGH, LOW, CLOSE, VOLUME], axis=1, inplace=True)
    priceData = priceData.head(NUM_DAYS)

    priceData2, priceMetadata2 = ts.get_daily(symbol=equity2, outputsize=OUTPUT_SIZE_FULL)
    priceData2['avg2'] = (priceData2[HIGH] + priceData2[LOW])/2 #assume midpoint of high and low is executed price
    priceData2.drop([OPEN, HIGH, LOW, CLOSE, VOLUME], axis=1, inplace=True)
    priceData2 = priceData2.head(NUM_DAYS)

    combinedData = pd.concat([priceData, priceData2], axis=1)
    combinedData = combinedData.dropna()

    corr = getCorrelationValue(combinedData['avg1'], combinedData['avg2'])
    pvalue =  getCointegrationPvalue(combinedData['avg1'], combinedData['avg2'])

    print(equity1 + " & " + equity2 + " correlation: " + str(corr) + " coint: " + str(pvalue))
    #print(combinedData)

    return [corr, pvalue, equity1, equity2]

def getAllPairs():
    print("-------------------------- getAllPairs() --------------------------------")
    MIN_PVALUE = 0.05
    correlationArr = []

    for i in range(len(eqArr)):
        for j in range(len(eqArr)):
            if (eqArr[i]['name'] != eqArr[j]['name'] ):
                corrListObj = getCorrelationAndCointegratedPairs(eqArr[i]['name'] , eqArr[j]['name'] )
                print(corrListObj)
                if (corrListObj[1] < MIN_PVALUE):
                    correlationArr.append(corrListObj)

    return correlationArr

def mainzz():

    #res = equities_correlation()
    #print(res)
    res = [[0.8303010316568781, 0.008999534116927945, 'GOOGL', 'NKE'], [0.8465877548675863, 0.014318468108434462, 'GOOGL', 'AMZN'], [0.9230483904816502, 0.013301862473843282, 'NKE', 'AMZN'], [0.8677516812739479, 0.03705038629479192, 'COKE', 'PEP'], [0.8676595604577452, 0.027009363509322395, 'PEP', 'COKE'], [0.9217183557694564, 0.027048611523533345, 'AMZN', 'NKE']]

    equity1 = "COKE"
    equity2 = "PEP"
    #plotCointegratedPairs(equity1,equity2)
    #res = getCorrelationAndCointegratedPairs(equity1,equity2)
    #print(res)
    '''

    for x in range(len(res)):
        signalResult = getZScoreSignal(res[x][2], res[x][3])
        print(signalResult)
    '''
    #signalResult = getZScoreSignal(equity1, equity2)
    getAllPairs()

#mainzz()


'''
The Module can be used to read file and analyse the data. It has thr parts:
1) Read csv file, convert data into list, such that each row is a list and there is a dictionary which allow
access to different columns.
2) Data imputation: This involves changing strings to integers (list converts all objects into strings)
imputing no values to some value.
3) Summarizing the quantitative and qualitative variables. Provides, mean, median, max and min for quantitative
data and mode, categories for qualitative variables.
4) Print the summaries.
'''

import csv
from collections import Counter
import statistics as st
import re

csv_file = open('data.csv', encoding = "utf8", newline = '')
data_csv = csv.reader(csv_file, delimiter=',')

def convert_csv_into_list(data_csv):
	'''For data in csv file is converted into a list of all values. Also an access dictionary is
	drawn to access all columns of the data. This returns'''
	line_count = 0
	data = []
	access = {}
	for row in data_csv:
		if line_count == 0:
			start = 0
			for keys in row:
				access.update({keys:start})
				start += 1
			col_list = row
			line_count += 1
		else:
			line_count += 1
			data.append(row)
	return (data, access, col_list)

def convert_string_to_integer(data, access):
	'''returns the columns Positive Feedback Count, Rating and Age are converted to integers. The first
	column is unnamed and gives the serial number. This is also converted to integers.'''
	for i, row in enumerate(data):
		index = [0, 2, 5, 7]
		for j in index:
			data[i][j] = int(data[i][j])

# We can use col_name_cat = ['Division Name', 'Department Name', 'Class Name']
def summary_of_qualitative(data, access, column):
	'''the function returns unique set of categories and the counts of that categories.'''
	list_of_column = [row[access[column]] for row in data]
	column_unique = set(list_of_column)
	value_cnt = Counter(list_of_column)
	print('Counts : {}'.format(len(list_of_column)))
	print('Unique categories are:')
	for i in column_unique:
		print(i)
	print('Mode of the categories is {}'.format(max(value_cnt)))

def summary_of_quantitative(data, access, column):
	'''function returns the summary of the quatitative data in the column specified.'''
	list_of_column = [row[access[column]] for row in data]
	counts = len(list_of_column)
	mean_col = st.mean(list_of_column)
	median_col = st.median(list_of_column)
	min_col = min(list_of_column)
	max_col = max(list_of_column)
	print('Counts : {:20}'.format(counts))
	print('Mean : {:22.2f}'.format(mean_col))
	print('Median : {:20.1f}'.format(median_col))
	print('Minimum :{:20}'.format(min_col))
	print('Maximum :{:20}'.format(max_col))

def print_summary(data, access, col_list):
	'''something to add....'''
	col_name = ', '.join(col_list) #row 23
	print("Column names are {}".format(col_name[1:]))
	print("Processed {} lines.".format(len(data)))
	print('The following are the columns with type:')
	for key in access:
		print('{0:35} type is : {1}'.format(key, type(data[0][access[key]])))

def impute_data(data, access, column, from_value, to_value):
	'''function imputes the data accoding from the value to a given value. For example if we want to
	impute the quantitative values with mean or median.'''
	for i, row in enumerate(data):
		if row[access[column]] == from_value:
			row[access[column]] = to_value

### Analyse the data:
(data, access, col_list) = convert_csv_into_list(data_csv)
def analyse_data():
	'''Analysis part.'''
	print_summary(data, access, col_list)
	print('')
	print('All columns are in string format. We have to convert some columns to integer format.')
	convert_string_to_integer(data, access)
	print_summary(data, access, col_list)
	print('')
	print('Now the columns Age, Positive Feedback Count and Rating are integers.')
	col_list2 = ['Rating', 'Positive Feedback Count', 'Age']
	for column in col_list2:
		print('The summary of {} is:'.format(column))
		summary_of_quantitative(data, access, column)

analyse_data()
col_list3 = ['Division Name', 'Department Name', 'Class Name']
for i in col_list3:
	impute_data(data, access, i, '', 'Others')
for i in col_list3:
	print('The summary of {} is:'.format(i))
	summary_of_qualitative(data, access, i)

csv_file.close()