import os
import time

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import torch
from torch.autograd import Variable

def save_results_in_csv(y_pred):
    '''
    Saves the predictions of test lung images in the provided csv file
    :param y_pred: numpy array containing the boolean predictions
    '''
    fname = os.path.join(os.path.abspath(__file__), '..', 'data', 'CPSC340_Q2_SUBMISSION.csv')
    y_pred = y_pred.astype(bool)

    df = pd.DataFrame(columns=['Id', 'Predicted'])
    df['Id'] = np.arange(0, y_pred.shape[0])
    df['Predicted'] = y_pred
    df.to_csv(fname, index=False)

# Reference: Mitchell, L., Subramanian, V., & K., S. Y. (2019). Deep learning with PyTorch 1.x: implement deep
# learning techniques and neural network architecture variants using Python. page 173. Birmingham: Packt Publishing.
def train(model, dataloaders, dataset_sizes, criterion, optimizer, scheduler, num_epochs=20):
    since = time.time()
    if torch.cuda.is_available():
        model.cuda()

    best_model_wts = model.state_dict()
    best_acc = 0.0

    for epoch in range(num_epochs):
        print(scheduler.get_lr())
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)
        # Each epoch has a training and validation phase
        for phase in ['train', 'valid']:
            if phase == 'train':
                scheduler.step()
                model.train(True)  # Set model to training mode
            else:
                model.train(False)  # Set model to evaluate mode

            running_loss = 0.0
            running_corrects = 0

            # Iterate over data.
            for data in dataloaders[phase]:
                # get the inputs
                inputs, labels = data

                # wrap them in Variable
                if torch.cuda.is_available():
                    inputs = Variable(inputs.cuda())
                    labels = Variable(labels.cuda())
                else:
                    inputs, labels = Variable(inputs), Variable(labels)

                # zero the parameter gradients
                optimizer.zero_grad()

                # forward
                outputs = model(inputs)
                _, preds = torch.max(outputs.data, 1)
                loss = criterion(outputs, labels)

                # backward + optimize only if in training phase
                if phase == 'train':
                    loss.backward()
                    optimizer.step()

                # statistics
                # print(loss)
                running_loss += loss.item()
                print(preds, labels.data)
                print(preds.item() == labels.data.item())
                running_corrects += np.sum(int(preds.item()) == int(labels.data.item()))
                print("running_corrects", running_corrects)
            epoch_loss = running_loss / dataset_sizes[phase]
            epoch_acc = running_corrects / dataset_sizes[phase]
            print("epoch_acc running_corrects ", running_corrects)
            print("epoch_acc ", dataset_sizes[phase])

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            # deep copy the model
            if phase == 'valid' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = model.state_dict()

        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))

    # load best model weights
    model.load_state_dict(best_model_wts)
    return model

def save_images(data_loaders, train_labels):
    """
    Load and save the images in the following folders
    :param data_loaders: contains the tensors of the image pixels
    :param train_labels: contains 1/0 labels indicating whether the lung image is of covid patient or not
    :return:
    """
    training_images_rgb_folder = os.path.join(os.path.abspath(__file__), '..', 'training_images_rgb')
    training_images_grayscale_folder = os.path.join(os.path.abspath(__file__), '..', 'training_images_grayscale')
    test_images_rgb_folder = os.path.join(os.path.abspath(__file__), '..', 'test_images_rgb')
    test_images_grayscale_folder = os.path.join(os.path.abspath(__file__), '..', 'test_images_grayscale')

    if not os.listdir(training_images_rgb_folder):
        index = 0
        for sample in data_loaders["train"].dataset.imgs:
            image_name = f"Image_{index}_covid{train_labels[index].numpy()}.png"
            plt.imsave(os.path.join(training_images_rgb_folder, image_name), sample[0])
            plt.imsave(os.path.join(training_images_grayscale_folder, image_name), sample[0], cmap='gray')
            print(f"Saved {image_name}")
            index += 1

    if not os.listdir(test_images_rgb_folder):
        index = 0
        for sample in data_loaders["test"].dataset.imgs:
            image_name = f"Image_{index}.png"
            plt.imsave(os.path.join(test_images_rgb_folder, image_name), sample[0])
            plt.imsave(os.path.join(test_images_grayscale_folder, image_name), sample[0], cmap='gray')
            print(f"Saved {image_name}")
            index += 1


#!/usr/bin/python
# coding:utf-8
from futu import *

quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
ret, data, page_req_key = quote_ctx.request_history_kline('HK.00700', start='2019-09-11', end='2019-09-18',
                                                          max_count=5)  # 每页5个，请求第一页
if ret == RET_OK:
    print(data)
    print(data['code'][0])  # 取第一条的股票代码
    print(data['close'].values.tolist())  # 第一页收盘价转为 list
else:
    print('error:', data)
while page_req_key != None:  # 请求后面的所有结果
    print('*************************************')
    ret, data, page_req_key = quote_ctx.request_history_kline('HK.00700', start='2019-09-11', end='2019-09-18',
                                                              max_count=5, page_req_key=page_req_key)  # 请求翻页后的数据
    if ret == RET_OK:
        print(data)
    else:
        print('error:', data)
print('All pages are finished!')
quote_ctx.close()  # 结束后记得关闭当条连接，防止连接条数用尽


import sys, os, time, random

from basic.constant import ROOT_PATH
from basic.common import  makedirsforfile, checkToSkip, printStatus
from basic.annotationtable import readAnnotationsFrom, writeAnnotationsTo, readConcepts, writeConceptsTo

from util.simpleknn.bigfile import BigFile

from svms.mlengine_util import classify_large_data
from svms.fiksvm.svm import KERNEL_TYPE

DEFAULT_NPR = 10
DEFAULT_NR_ITER = 10
DEFAULT_NR_BINS = 50
DEFAULT_STRATEGY = 'top'
MIN_ERROR_RATE = 1e-4

INFO = __file__

def get_model_name(params):
    name = params['model']
    assert(name in ['fik', 'fastlinear'])
    if 'fik' == name:
        name += str(params['nr_bins'])
    return name

def get_new_annotation_name(params):
    assert(params['strategy'] in ['top', 'toprand'])
    startAnnotationName = params['startAnnotationName']
    assert(startAnnotationName.endswith('.txt'))
    startPoint = startAnnotationName[:-4]
    name = get_model_name(params)
    return '%s.%s.%s.npr%d.T%d.txt' % (startPoint, name, params['strategy'], params['npr'], params['iterations'])

class NegativeBootstrap:
    @staticmethod
    def __init__(params):
        rootpath = params['rootpath']
        trainCollection = params['trainCollection']
        feature = params['feature']

        misc = {}
        # the following is required by fiksvm
        minmaxfile = os.path.join(rootpath, trainCollection, 'FeatureData', feature, 'minmax.txt')
        with open(minmaxfile, 'r') as f:
            misc['min_vals'] = map(float, str.split(f.readline()))
            misc['max_vals'] = map(float, str.split(f.readline()))
        return misc

    @staticmethod
    def sampling(predictions, strategy, n):
        printStatus(INFO, '%s sampling: %d out of %d instances' % (strategy, n, len(predictions)))
        if 'toprand' == strategy:
            temp = [(x[0], x[1]*random.uniform(0.9,1)) for x in predictions]
            temp.sort(key=lambda v:v[1], reverse=True)
            return [x[0] for x in temp[:n]]
        else:
            return [x[0] for x in predictions[:n]]

    @staticmethod
    def learn(concept, params):
        rootpath = params['rootpath']
        trainCollection = params['trainCollection']
        baseAnnotationName = params['baseAnnotationName']
        startAnnotationName = params['startAnnotationName']
        strategy = params['strategy']
        feature = params['feature']
        feat_file = params['feat_file']
        feat_dim = feat_file.ndims
        npr = params['npr']
        iterations = params['iterations']
        beta = 0.5

        names,labels = readAnnotationsFrom(trainCollection, startAnnotationName, concept, skip_0=True, rootpath=rootpath)
        positive_bag = [x[0] for x in zip(names,labels) if x[1] > 0]
        negative_bag = [x[0] for x in zip(names,labels) if x[1] < 0]

        names,labels = readAnnotationsFrom(trainCollection, baseAnnotationName, concept, skip_0=True, rootpath=rootpath)
        negative_pool = [x[0] for x in zip(names,labels) if x[1] < 0]

        Usize = max(5000, len(positive_bag) * npr)
        Usize = min(10000, Usize)
        Usize = min(Usize, len(negative_pool))

        new_model = None

        for t in range(1, iterations+1):
            printStatus(INFO, 'iter %d (%s)' % (t, concept))
            if t > 1: # select relevant negative examples
                # check how good at classifying positive training examples
                results = classify_large_data(assemble_model, positive_bag, feat_file)
                pos_error_rate = len([1 for x in results if x[1]<0])/float(len(results))

                U = random.sample(negative_pool, Usize)
                predictions = classify_large_data(assemble_model, U, feat_file)
                neg_error_rate = len([1 for x in predictions if x[1]>0])/float(len(predictions))

                error_rate = (pos_error_rate + neg_error_rate)/2.0

                printStatus(INFO, 'iter %d: %s %.3f -> %s %.3f, pe=%.3f, ne=%.3f, error=%.3f' % (t, predictions[-1][0], predictions[-1][1],
                                                                                predictions[0][0], predictions[0][1],
                                                                                pos_error_rate, neg_error_rate, error_rate))
                if error_rate < MIN_ERROR_RATE:
                    printStatus(INFO, 'hit stop criteria: error (%.3f) < MIN_ERROR_RATE (%.3f)' % (error_rate, MIN_ERROR_RATE))
                    break

                # assume that 1% of the randomly sampled set is truely positive, and the classifier will rank them at the top
                # so ignore them
                nr_of_estimated_pos = int(len(predictions)*0.01)
                negative_bag = NegativeBootstrap.sampling(predictions[nr_of_estimated_pos:], strategy, max(1000, len(positive_bag)))

            new_names = positive_bag + negative_bag
            new_labels = [1] * len(positive_bag) + [-1] * len(negative_bag)
            name2label = dict(zip(new_names,new_labels))
            renamed, vectors = feat_file.read(new_names)
            Ys = [name2label[x] for x in renamed]

            np = len([1 for y in Ys if y>0])
            nn = len([1 for y in Ys if y<0])
            assert(len(positive_bag) == np)
            assert(len(negative_bag) == nn)
            wp = float(beta) * (np+nn) / np
            wn = (1.0-beta) * (np+nn) /nn
            C = 1
            svm_params = '-w1 %g -w-1 %g' % (wp*C, wn*C)
            if 'fik' == params['model']:
                svm_params += ' -s 0 -t %d' % KERNEL_TYPE.index("HI")
            else:
                svm_params += ' -s 2'
            g_t = train_model(Ys, vectors, svm_params + ' -q')
            if t == 1:
                assemble_model = compress_model([g_t], [1.0], feat_dim, params)
            else:
                new_model = compress_model([g_t], [1.0], feat_dim, params)
                assemble_model.add_fastsvm(new_model, 1-1.0/t, 1.0/t)

        return assemble_model

def process(options, trainCollection, baseAnnotationName, startAnnotationName, feature, modelName):
    global train_model, compress_model, save_model
    assert(modelName in ['fik', 'fastlinear'])
    if 'fik' == modelName:
        from model_based.svms.fiksvm.svmutil import svm_train as train_model
        from model_based.svms.fiksvm.fiksvm import svm_to_fiksvm as compress_model
        from model_based.svms.fiksvm.fiksvm import fiksvm_save_model as save_model
    else:
        from model_based.svms.fastlinear.liblinear193.python.liblinearutil import train as train_model
        from model_based.svms.fastlinear.fastlinear import liblinear_to_fastlinear as compress_model
        from model_based.svms.fastlinear.fastlinear import fastlinear_save_model as save_model

    rootpath = options.rootpath
    overwrite = options.overwrite
    params = {'rootpath': rootpath, 'trainCollection': trainCollection, 'baseAnnotationName': baseAnnotationName,
              'startAnnotationName': startAnnotationName, 'feature': feature, 'model': modelName, 'strategy': options.strategy,
              'iterations': options.iterations, 'npr': options.npr, 'nr_bins': options.nr_bins}

    concepts = readConcepts(trainCollection, startAnnotationName, rootpath)
    newAnnotationName = get_new_annotation_name(params)
    newModelName = get_model_name(params)
    modeldir = os.path.join(rootpath, trainCollection, 'Models', newAnnotationName, feature, newModelName)
    todo = [concept for concept in concepts if overwrite or os.path.exists(os.path.join(modeldir,'%s.txt'%concept)) is False]
    activeConcepts = [todo[i] for i in range(len(todo)) if (i%options.numjobs+1) == options.job]

    params['feat_file'] = BigFile(os.path.join(rootpath, trainCollection, 'FeatureData', feature))

    if 'fik' == modelName:
        minmax_file = os.path.join(rootpath, trainCollection, 'FeatureData', feature, 'minmax.txt')
        with open(minmax_file, 'r') as f:
            params['min_vals'] = map(float, str.split(f.readline()))
            params['max_vals'] = map(float, str.split(f.readline()))

    s_time = time.time()

    for concept in activeConcepts:
        printStatus(INFO, 'processing %s' % concept)
        modelfile = os.path.join(modeldir, '%s.model'%concept)
        if checkToSkip(modelfile, overwrite):
            continue
        new_model = NegativeBootstrap.learn(concept, params)
        makedirsforfile(modelfile)
        printStatus(INFO, 'save model to %s' % modelfile)
        save_model(modelfile, new_model)
        printStatus(INFO, '%s done' % concept)

    timecost = time.time() - s_time
    writeConceptsTo(concepts, trainCollection, newAnnotationName, rootpath)
    printStatus(INFO, 'done for %g concepts: %s' % (len(activeConcepts), ' '.join(activeConcepts)))
    printStatus(INFO, 'models stored at %s' % modeldir)
    printStatus(INFO, '%g seconds in total' % timecost)

def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    from optparse import OptionParser
    parser = OptionParser(usage="""usage: %prog [options] trainCollection baseAnnotationName startAnnotationName feature modelName""")
    parser.add_option("--overwrite", default=0, type="int", help="overwrite existing file (default: 0)")
    parser.add_option("--nr_bins", default=DEFAULT_NR_BINS, type="int", help="level of quantization (default: %d)"%DEFAULT_NR_BINS)
    parser.add_option("--npr", default=DEFAULT_NPR, type="int", help="|U|=max(10000, npr*|pos_bag|) (default: %d)"%DEFAULT_NPR)
    parser.add_option("--iterations", default=DEFAULT_NR_ITER, type="int", help="number of iterations (default: %d)"%DEFAULT_NR_ITER)
    parser.add_option("--rootpath", default=ROOT_PATH, type="string", help="rootpath where the train and test collections are stored (default: %s)"%ROOT_PATH)
    parser.add_option("--strategy", default=DEFAULT_STRATEGY, type="string", help="sampling strategy (default: %s)"%DEFAULT_STRATEGY)
    parser.add_option("--numjobs", default=1, type="int", help="number of jobs (default: 1)")
    parser.add_option("--job", default=1, type="int", help="current job (default: 1)")

    (options, args) = parser.parse_args(argv)
    if len(args) < 5:
        parser.print_help()
        return 1

    assert(options.job>=1 and options.numjobs >= options.job)
    return process(options, args[0], args[1], args[2], args[3], args[4])

if __name__ == "__main__":
    sys.exit(main())


import pandas as pd
import numpy as np
from datetime import datetime

import talib

from ta.volatility import BollingerBands
from ta.trend import MACD

import plotly as py
from plotly import tools
import plotly.graph_objects as go

import re

file = r'dataset\data\USDJPY_H1.csv'

data = pd.read_csv(file)
data.columns = ['date', 'open', 'high', 'low', 'close', 'volume']

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

# Select Row by year

years = data['date'].str.split("-", expand=True)[0]
years = pd.DataFrame({'year': years.values})
years['month'] = data['date'].str.split("-", expand=True)[1]
years['day'] = data['date'].str.split("-", expand=True)[2]
years['day'] = years['day'].str.split(" ", expand=True)[0]

data = pd.concat([years, data], axis=1)
data["year"] = pd.to_numeric(data["year"])
data["day"] = pd.to_numeric(data["day"])
data["month"] = pd.to_numeric(data["month"])

data = data.loc[(data['year'] >= 2015) & (data['year'] <= 2020)]

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

#  Clean data

grouped = data.groupby(data.year)
df = pd.DataFrame()

for y in range(2015, 2021):
    month_grouped = grouped.get_group(y)
    day_grouped = month_grouped.groupby(month_grouped.month)
    for m in range(1, 13):
        day = day_grouped.get_group(m)
        counts = day['day'].value_counts()
        del_rows = counts[counts <= 12].index.values
        temp_df = day[~day['day'].isin(del_rows)]
        if m == 1 and y == 2015:
            temp_df.reset_index
            df = temp_df.copy()
        else:
            df = pd.concat([df, temp_df], ignore_index=True)

# df.drop(['year', 'month', 'day'], axis=1, inplace=True)
df = df.reset_index(drop=True)
data = df.copy()
for y in range(2015,2021):
    df = data.copy()
    df = df.reset_index(drop=True)
    df = df.loc[df['year'] == y]
    # df.to_csv(r'dataset\data\test.csv')
    # --------------------------------------------------------------------------------

    df['dayOfweek'] = pd.to_datetime(df['date'].str.split(
        " ", expand=True)[0], errors='coerce').dt.day_name()
    # df['isMonday'] = pd.to_datetime(df['date'].str.split(" ", expand=True)[0], errors='coerce').dt.day_name()
    # df['isFriday'] = np.where(df['isFriday'] == "Friday", 1, 0)
    # df['isMonday'] = np.where(df['isMonday'] == "Monday", 1, 0)
    df['time'] = df['date'].str.split(" ", expand=True)[1]
    df['time'] = pd.to_numeric(df['time'].str.split(":", expand=True)[0])

    # df = df.loc[~((df['isMonday'] == 1) & (df['time'] > 21))]

    # cond = ~((df['dayOfweek'] == "Thursday") & (df['time'] > 21))
    # features = df.loc[cond].copy()
    features = df.copy()
    max_firstM = -1
    for i in range(24):
        if max_firstM < features['time'].iloc[i]:
            max_firstM = i
        else:
            break
    print(max_firstM)

    # cond = ~((df['dayOfweek'] == "Monday") & (df['time'] > 21))
    # targets = df.loc[cond].copy()
    targets = df.copy()
    max_lastM = targets['time'].iloc[-1]

    features.drop(features.tail(max_lastM+1).index, inplace=True)
    targets.drop(targets.head(max_firstM+1).index, inplace=True)

    print(features)
    print(targets)

    # features = features.loc[ features['date'] != "2015-03-12 21:00"].copy()
    # targets = targets.loc[ targets['date'] != "2015-03-16 21:00"].copy()
    # features = features.loc[ features['date'] != "2015-03-19 21:00"].copy()
    # targets = targets.loc[ targets['date'] != "2015-03-23 21:00"].copy()
    # features = features.loc[ features['date'] != "2015-03-26 21:00"].copy()
    features = features.reset_index(drop=True)
    targets = targets.reset_index(drop=True)

    i = 0
    while i < len(targets):
        print("INDEX = ", i)
        print("Size : ", len(features), len(targets))

        target_date = targets['date'].iloc[i]
        target_time = targets['time'].iloc[i]
        feature_date = features['date'].iloc[i]
        feature_time = features['time'].iloc[i]
        target_dayOfweek = targets['dayOfweek'].iloc[i]
        feature_dayOfweek = features['dayOfweek'].iloc[i]

        feature_month = features['month'].iloc[i]
        target_month = targets['month'].iloc[i]

        if target_time != feature_time:
            print("Date : " , feature_date , " // " , target_date)
            print("DayOfWeek : " , feature_dayOfweek , " // " ,  target_dayOfweek)

            if target_time > feature_time:
                print("---- Targets was remove")
                targets = targets.loc[targets['date'] != target_date].copy()
            elif target_time < feature_time:
                print("---- Features was remove")
                features = features.loc[features['date'] != feature_date].copy()
            else:
                print("Method was BREAKING !!")
                break
            i = i-3
            features = features.reset_index(drop=True)
            targets = targets.reset_index(drop=True)
            print("--------------------------")

        if (len(targets) > len(features) and (len(targets)-i <= 2 or len(features)-i <= 2)):
            print("---- **Targets was remove")
            targets = targets.loc[targets['date'] != target_date].copy()
        elif (len(targets) < len(features) and (len(targets)-i <= 2 or len(features)-i <= 2)):
            print("---- **Features was remove")
            features = features.loc[features['date'] != feature_date].copy()
        i += 1
    features = features.reset_index(drop=True)
    targets = targets.reset_index(drop=True)
    features.to_csv(r'dataset\data\finish\features{}.csv'.format(y))
    targets.to_csv(r'dataset\data\finish\targets{}.csv'.format(y))
    print(len(features) == len(targets))


import re
fs = open('2020/day7/input.txt', 'r')

link = {}
inside = {}

line = fs.readline().strip('\n')
count = 1

def cAndB(bag):
    if bag == 'no other':
        return
    s = bag.split(' ')
    return (' '.join(s[1:]), s[0])

while line:
    bag, contained = line.split(' bags contain ')
    # print(contained.split(' bag'))
    p = re.sub(' bags*', '', contained).strip('.').split(', ')
    s = [re.sub('\d+ *', '', b) for b in p]
    t = [cAndB(b) for b in p]
    inside[bag] = set(t)
    for c in s:
        if c in link:
            link[c].add(bag)
        else:
            link[c] = {bag}

    line = fs.readline().strip('\n')
    count += 1

sg = set()

def search(bag):
    if bag in link:
        for b in link[bag]:
            sg.add(b)
            search(b)

search('shiny gold')
print(len(sg))

def look(bag):
    count = 0
    for b in inside[bag]:
        if b is None:
            count += 0
        else:
            count += int(b[1]) * look(b[0])
    print(bag, count)
    return 1 + count
print(look('shiny gold'))

fs.close()


import copy
import numpy as np
from scipy.optimize import minimize

def objective_function_full(parameters: np.array, model, solution):
    count = 0
    for task in model.last_scenario.tasks:
        if task != solution:
            if model.comparison_function(parameters, task, solution) == solution:
                count += 1
    return -count + model.weight*np.square(parameters).sum()

class Selector:

    def __init__(self, comparison_function, comparison_parameters, learning_rate, weight):
        self.comparison_function = comparison_function
        self.comparison_parameters = comparison_parameters
        self.learning_rate = learning_rate
        self.last_scenario = None
        self.weight = weight

    def compare(self, task1, task2):
        return self.comparison_function(self.comparison_parameters, task1, task2)

    def predict(self, scenario):
        self.last_scenario = scenario
        # compare all tasks with each other and count the wins of each one
        count = [0 for task in scenario.tasks]
        for i, task1 in enumerate(scenario.tasks):
            for j, task2 in enumerate(scenario.tasks):
                if i < j:
                    if self.compare(task1, task2) == task1:
                        count[i] += 1
                    else:
                        count[j] += 1
        # predict the task that has one more comparisons
        return scenario.tasks[count.index(max(count))]

    def update_params(self, new_params):
        self.comparison_parameters = [old + self.learning_rate*new for old, new in
                                      zip(self.comparison_parameters, new_params)]

    def compute_new_params(self, solution_id):
        # find which task is the solution
        for task in self.last_scenario.tasks:
            if task.id == solution_id:
                solution = task

        def objective_function(parameters):
            return objective_function_full(parameters, self, solution)

        result_opt = minimize(objective_function, np.array(self.comparison_parameters))
        new_params = copy.deepcopy(result_opt['x'])
        return new_params


from setuptools import setup, find_packages

# requirement file
with open('requirements.txt') as f:
    required = f.read().splitlines()

# readme file
with open('README.md') as f:
    readme = f.read()

setup(
    name='textstada',
    version='0.0.1',
    description='No frills text data cleaning methods. Stada means to tidy in Swedish.',
    long_description=readme,
    long_description_content_type="text/md",
    url='https://github.com/jhags/text-stada',
    author='J Hagstrom',
    license='MIT',
    classifiers=[
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.7",
    ],
    packages=find_packages(include=['textstada', 'textstada.*']),
    package_data={
        "textstada": [
            "data/*.json",
            "data/*.txt"
            ]
    },
    install_requires=required,
    tests_require=['pytest', 'pytest-cov', 'coveralls'],
    python_requires='>=3.7',
)


from matplotlib import pyplot as plt
import numpy as np
from tensorflow import keras

def go():
    X_train = np.linspace(0, 20, 100)
    y_train = 3 * np.sin(X_train) + np.random.normal(0, 0.3, 100)
    X_test = np.linspace(20, 30, 50)
    y_test = 3 * np.sin(X_test) + np.random.normal(0, 0.3, 50)

    model = keras.Sequential()
    model.add(keras.layers.Dense(20, input_shape=(1,), activation="sigmoid"))
    model.add(keras.layers.Dense(20, activation="sigmoid"))
    model.add(keras.layers.Dense(1, activation="linear"))

    model.compile(optimizer='adam', loss="mean_squared_error")

    for _ in range(10):
        model.fit(X_train, y_train, epochs=10000, verbose=0)

        y1_train = model.predict(X_train)
        y1_test = model.predict(X_test)

        plt.figure()
        plt.plot(X_train, y_train, "g-")
        plt.plot(X_test, y_test, "g-")
        plt.plot(X_train, y1_train, "b-")
        plt.plot(X_test, y1_test, "r-")
        plt.show()


# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: hidden_treasure.pyw
import time, queue, msilib, threading, base64, struct, sys, hashlib
from Crypto.PublicKey import RSA
import platform, securesocket
from utils import *
import solver
with open('textures.msi', 'rb') as (f):
    PSK = hashlib.sha256(f.read()).digest()
    assert len(PSK) == 32
SERVER_ADDR = ('prob10.geekgame.pku.edu.cn', 10010)
SERVER_PUBKEY = RSA.construct((135906273688931402589220204382871553870909804965399698890068262170520688884372045298141155906503818444426612681815829913189804909686158514999348437913468766184178386093808168943112695723474687346392228439951048402868123712946874173233503831688658127511363374069037033641735788196504560132107647546163113244313,
                               65537))

TOKEN = 'TOKEN'

def get_platform_name():
    u = platform.uname()
    name = '%s (%s %s) on %s' % (u.node, u.system, u.version, u.processor)
    name = name.encode()
    name = name[:500]
    print(name)
    return name

class Player:

    def __init__(self, game, y, x):
        self.life = 100
        self.life_restore = 0
        self.left = False
        self.command = Command.empty
        self.y = y
        self.x = x

class Game:

    def __init__(self):
        self.g = [[Elem.dirt for y in range(GX)] for x in range(GY)]
        self.level = -1
        self.cur = 0
        self.goal = 0
        self.player = Player(self, 0, 0)
        self.callbacks = {}
        self.socket = None
        self.token = None
        self.register(Sync.sync_level, self.on_sync_level)
        self.register(Sync.sync_status, self.on_sync_status)
        self.register(Sync.sync_map, self.on_sync_map)
        self.lastcnt = 0

    def trigger(self, event, *args, **kwargs):
        for callback in self.callbacks.get(event, []):
            callback(*args, **kwargs)

    def register(self, event, callback):
        self.callbacks.setdefault(event, []).append(callback)

    def socket_listener(self):

        def read_once():
            type = Sync._check(struct.unpack('!b', self.socket.recv(1))[0])
            # print('Sync', type)
            callbacks = self.callbacks.get(type, [])
            if not callbacks:
                return

            def call(args):
                for callback in callbacks:
                    callback(*args)

            if type == Sync.sync_level:
                args = struct.unpack('!ii', self.socket.recv(1024))
                call(args)
            elif type == Sync.sync_status:
                args = struct.unpack('!iii?iii', self.socket.recv(1024))
                call(args)
            else:
                if type == Sync.sync_map:
                    args_all = list(struct.iter_unpack('!bbb', self.socket.recv(None)))
                    for args in args_all:
                        call(args)

                else:
                    if type == Sync.init_level:
                        call([])
                    else:
                        if type == Sync.show_hud:
                            text = self.socket.recv(None).decode('utf-8')
                            call([text])
                        else:
                            if type == Sync.tick_routine:
                                call([])
                            else:
                                print('unknown sync type', type)

        try:
            while True:
                read_once()

        except Exception as e:
            try:
                print(type(e), repr(e))
                print('神秘小游戏', '与服务器的连接中断！')
                sys.exit(1)
            finally:
                e = None
                del e

    def start(self, token):
        self.token = token
        self.socket = securesocket.connect(SERVER_ADDR, PSK, SERVER_PUBKEY)
        self.socket.send(token.encode('utf-8'))
        self.socket.send(get_platform_name())
        threading.Thread(target=(self.socket_listener), daemon=True).start()

    def tick(self):
        if self.player.command != Command.empty:
            # print("Game cmd:",self.player.command, flush=True)
            self.socket.send(struct.pack('!b', self.player.command))
            # self.player.command = Command.empty
    def on_sync_level(self, level, goal):
        self.level = level
        self.goal = goal
        clear_cmd_queue()

    def on_sync_status(self, cur, plife, pliferestore, pleft, py, px, pcmd):
        if (self.player.command == Command.left or self.player.command == Command.right) and pcmd == Command.empty:
            assert self.player.x != px or self.player.y != py or self.player.left != pleft
        self.cur = cur
        self.player.life = plife
        self.player.life_restore = pliferestore
        self.player.left = pleft
        self.player.y = py
        self.player.x = px
        # print('Player', px, py, pleft, pcmd, flush=True)
        if pcmd == Command.empty:
            self.player.command = pcmd
        else:
            # print('Resend', flush=True)
            self.socket.send(struct.pack('!b', pcmd))

    def on_sync_map(self, y, x, val):
        self.g[y][x] = Elem._check(val)

game = Game()
cmds = queue.Queue()
# TICKTIME = 0.001

def show_hud(msg):
    print(msg, file=sys.stderr)

def start():

    def game_controller(token):
        game.register(Sync.init_level, init_level)
        game.register(Sync.show_hud, show_hud)
        try:
            game.start(token)
        except Exception as e:
            try:
                print(type(e), repr(e))
                print('神秘小游戏', '服务器连接失败！')
                sys.exit(1)
            finally:
                e = None
                del e

        else:
            while True:
                try:
                    if game.player.command == Command.empty:
                        x = cmds.get_nowait()
                        game.player.command = x
                        game.tick()
                except queue.Empty:
                    pass

    def game_controller_wrapped():
        try:
            game_controller(TOKEN)
        except Exception as e:
            try:
                print(type(e), e)
                sys.exit(1)
            finally:
                e = None
                del e

    game_controller_wrapped()

def clear_cmd_queue():
    try:
        while True:
            cmds.get_nowait()
    except queue.Empty:
        pass
    game.player.command = Command.empty

def init_level():
    clear_cmd_queue()
    commands = solver.better_solve(game.g)
    for command in commands:
        cmds.put(command)

start()


from functools import partial

from robotide.lib.robot.errors import VariableError
from robotide.lib.robot.utils import (is_dict_like, is_list_like, normalize,
                         RecommendationFinder)

def variable_not_found(name, candidates, msg=None, deco_braces=True):
    """Raise DataError for missing variable name.

    Return recommendations for similar variable names if any are found.
    """
    if msg is None:
        msg = "Variable '%s' not found." % name
    candidates = _decorate_candidates(name[0], candidates, deco_braces)
    normalizer = partial(normalize, ignore='$@%&*{}_', caseless=True,
                         spaceless=True)
    finder = RecommendationFinder(normalizer)
    recommendations = finder.find_recommendations(name, candidates)
    msg = finder.format_recommendations(msg, recommendations)
    raise VariableError(msg)

def _decorate_candidates(identifier, candidates, deco_braces=True):
    template = '%s{%s}' if deco_braces else '%s%s'
    is_included = {'$': lambda value: True,
                   '@': is_list_like,
                   '&': is_dict_like,
                   '%': lambda value: True}[identifier]
    return [template % (identifier, name)
            for name in candidates if is_included(candidates[name])]


from detection import *
from get_url import *
from image import *
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
import os

def auth():
    l = []
    k = []
    k.append("your-key")
    k.append("your-key")
    k.append("your-key")
    k.append("your-key")
    k.append("your-key")
    endpoint = "https://southcentralus.api.cognitive.microsoft.com/"

    for i in range(0, 5):
        l.append(FaceClient(endpoint, CognitiveServicesCredentials(k[i])))

    return l

def compute(detec1, path2, face_client, image_list, number, th_nb):
    detec2 = face_detection(face_client, getImageUrl(path2))
    face_info = -1

    if len(detec1) == 0 or len(detec2) == 0:
        print("No face detected...")
        return -1

    face_info = similar_check(face_client, detec1, detec2)

    if face_info == -1:
        print("no matching face")
        return -1
    draw_rectangle(Image.open(path2), detec2, face_info, path2)
    res_name = r'./static/detected_' + str(th_nb) + "_" + str(number) + '.jpg'
    os.rename(r'./static/frame' + str(th_nb)  + '.jpg',res_name)
    print('./static/detected_' + str(th_nb) + "_" + str(number) + '.jpg')
    image_list.append('detected_' + str(th_nb) + "_" + str(number) + '.jpg')
    return 0


from cgitb import html
from keras.models import load_model
from flask import *
from PIL import Image
from sqlalchemy import false, true
from werkzeug.utils import secure_filename
import cv2
import numpy as np
import easyocr
import os

model = load_model('icrecognition.h5')

classes = {
    0 : 'No Pain',
    1 : 'Pain'
}

def textprocessing(img):

    print (img)
    img = cv2.imread(img)

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(src=gray, ksize=(5, 5), sigmaX=0, sigmaY=0) #Bluring image in a small amount
    filter = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]]) # Creating our sharpening filter

    sharpen_img = cv2.filter2D(gray,-1,filter) # Applying cv2.filter2D sharpening function on image

    reader = easyocr.Reader(['en'])
    result = reader.readtext(sharpen_img)

    result_val = " "
    for x in result:
        result_val += (x[1]+",")

    result_val.strip()

    return (result_val)

# main -----------------------------------------------------------------------------------------------------------------------
app = Flask(__name__)
print ("Hello")
@app.route("/", methods=['GET', 'POST'])
def summary():
    uploads_dir = os.path.join('')
    ic = request.files['ic']

    if ic != '':
        image = Image.open(ic)
        image = image.convert("RGB")
        image.save(os.path.join(uploads_dir, secure_filename("uploadedimage.jpg")))
        resizeimage = image.resize((200,200))
        resizeimage = np.expand_dims(resizeimage, axis = 0)
        resizeimage = np.array(resizeimage)
        pred = model.predict([resizeimage])[0]
        icpath = 'uploadedimage.jpg'
        icpath = str(icpath)
        dataic = textprocessing(icpath)

        if (pred == 0):
            data = {
                "status" : bool(true),
                "extraction" : dataic
            }
        else:
            data = {
                "tatus" : bool(false)
            }

        os.remove(icpath)
        return jsonify(data)

    else:
        return ('error')

if __name__ == '__main__':
    app.run(host = '0.0.0.0',port=8001,debug=True)

# main ----------------------------------------------------------------------------------------------------------------------------


# USAGE
# python gradient_descent.py

# import the necessary packages
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
import numpy as np
import argparse

def sigmoid_activation(x):
	return 1.0 / (1 + np.exp(-x))

def next_training_batch(X, y, batchSize):
    for i in np.arange(0, X.shape[0], batchSize):
        yield (X[i:i + batchSize], y[i:i + batchSize])

ap = argparse.ArgumentParser()
ap.add_argument("-e", "--epochs", type=float, default=100,
	help="# of epochs")
ap.add_argument("-a", "--alpha", type=float, default=0.01,
	help="learning rate")
ap.add_argument("-b", "--batch-size", type=int, default=32,
    help="size of SGD mini-batches")
args = vars(ap.parse_args())

(X, y) = make_blobs(n_samples=250, n_features=2, centers=2,
    cluster_std=1.05, random_state=20)
X = np.c_[np.ones((X.shape[0])), X]

print("[INFO] starting training...")
W = np.random.uniform(size=(X.shape[1],))

lossHistory = []

for epoch in np.arange(0, args["epochs"]):
    epochLoss = []

    for (batchX, batchY) in next_training_batch(X, y, args["batch_size"]):

        preds = sigmoid_activation(batchX.dot(W))

        error = preds - batchY

        loss = np.sum(error ** 2)
        epochLoss.append(loss)

        gradient = batchX.T.dot(error) / batchX.shape[0]

        W += -args["alpha"] * gradient

    lossHistory.append(np.average(epochLoss))
    print("[INFO] epoch #{}, loss={:.7f}".format(epoch + 1, loss))

for i in np.random.choice(250, 10):
	activation = sigmoid_activation(X[i].dot(W))

	label = 0 if activation < 0.5 else 1

	# show our output classification
	print("activation={:.4f}; predicted_label={}, true_label={}".format(
		activation, label, y[i]))

Y = (-W[0] - (W[1] * X)) / W[2]
plt.figure()
plt.scatter(X[:, 1], X[:, 2], marker="o", c=y)
plt.plot(X, Y, "r-")

fig = plt.figure()
plt.plot(np.arange(0, args["epochs"]), lossHistory)
fig.suptitle("Training Loss")
plt.xlabel("Epoch #")
plt.ylabel("Loss")
plt.show()


import requests
import httpx

chrome_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' \
                                ' (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
                  'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
print(chrome_headers)

# url = 'https://sleeping.town/api/v1/instance/peers'
url = 'http://httpbin.org/headers'
print('Making request with headers set as chrome...')

r = requests.get(url, headers=chrome_headers, timeout=3.5)
out = r.json()
print(f'requests: {out}')

print('Making request with default headers:')
r = requests.get(url, timeout=3.5)  # never response, not exception, no time out...
out = r.json()
print(f'requests: {out}')

print('Making request with default headers:')
r = httpx.get(url, timeout=3.5)
out = r.json()
print(f'httpx: {out}')


'''
An efficient program to solve loopover
'''
from collections import deque
def SOLVED(scrambled, solved, INVERSE):
    scrambled = list(map(lambda x: list(map(lambda y:INVERSE[tuple(y)], x)), scrambled))
    return scrambled == solved
def parity(board):
    Q = [[1 if board[i][j]!=[i, j] else 0 for j in range(len(board[0]))] for i in range(len(board))]
    if sum(sum(i) for i in Q) != 2:
        return "Fucked up"
    if Q[-1][-1] == 1:
        if Q[-2][-1] == 1:
            return 'V'
        if Q[-1][-2] == 1:
            return 'H'
    return "O"
def loopover(scrambled, solved):
    print(scrambled, solved)
    MAP = {solved[i][j]:[i, j] for j in range(len(solved[0])) for i in range(len(solved))}
    INVERSE = {tuple(j): i for i, j in MAP.items()}
    scrambled = list(map(lambda x: list(map(lambda y:MAP[y], x)), scrambled))
    to_find = [0, 0]
    current = [0, 0]
    H, W = len(scrambled), len(scrambled[0])

    RS = []
    if SOLVED(scrambled, solved, INVERSE):
        return RS
    #Perform up/down movement in matrix
    #c is number of column in which the movement is required
    #n is number of moves required
    def ud(matrix, c, n):
        nonlocal RS
        if n < 0:
            RS += [f'{"U"}{c}']*abs(n)
        elif n > 0:
            RS += [f'{"D"}{c}']*abs(n)
        column = deque([i[c] for i in matrix])
        column.rotate(n)
        for i in range(len(matrix)):
            matrix[i][c] = column.popleft()
        return matrix

    #Performs left/right movement in matrix
    #r is the number of row in which the movement is required
    #n is number of moves required, which can be positive or negative
    def lr(matrix, r, n):
        nonlocal RS
        if n > 0:
            RS += [f'{"R"}{r}']*abs(n)
        elif n < 0:
            RS += [f'{"L"}{r}']*abs(n)
        row = deque(matrix[r])
        row.rotate(n)
        matrix[r] = list(row)
        return matrix

    def finder(to_find, mode = 'H'):
        for i in range(H):
            for j in range(W):
                if scrambled[i][j] == to_find:
                    if mode == 'H':
                        if W - 1 == to_find[1]:
                            to_find[0], to_find[1] = to_find[0] + 1, 0
                        else:
                            to_find[1] = to_find[1] + 1
                    else:
                        to_find[0] += 1
                    return [i, j]

    while to_find[1] < W - 1:
        location = finder(to_find)
        if location[0] == current[0]:
            location[0] += 1
            scrambled = ud(scrambled, location[1], 1)

        scrambled = lr(scrambled, location[0], current[1] - location[1])

        location[1] = current[1]
        scrambled = ud(scrambled, location[1], current[0] - location[0])

        current = to_find[::]

    to_find = [1, 0]
    current = [1, 0]

    while to_find[0] < H - 1:
        location = finder(to_find)
        if location[0] == current[0]:
            temp = W - 1 - location[1]
            scrambled = lr(scrambled, location[0], temp)
            location[1] = W - 1
            scrambled = ud(scrambled, W - 1, 1)
            location[0] += 1
            scrambled = lr(scrambled, current[0], -temp)

        if location[0] != current[0] + 1 and location[1] == W - 1:
            scrambled = ud(scrambled, location[1], current[0] + 1 - location[0])
            location[0] = current[0] + 1

        scrambled = lr(scrambled, location[0], current[1] - location[1])

        for each_row in range(current[0]):
            scrambled = lr(scrambled, each_row, current[1] - W + 1)
        scrambled = ud(scrambled, current[1], current[0] - location[0])
        for each_row in range(current[0]):
            scrambled = lr(scrambled, each_row, -(current[1] - W + 1))

        current = to_find[::]

    if SOLVED(scrambled, solved, INVERSE):
        return RS

    to_find = [0, W - 1]
    current = [0, W - 1]

    while to_find[0] < H - 1:
        location = finder(to_find, 'W')
        if location[0] == H - 1:
            scrambled = lr(scrambled, H - 1, W - 1 - location[1])
            location = [H - 1, W - 1]
        saved = -location[0] - 1
        scrambled = ud(scrambled, W - 1, saved)
        location = [H - 1, W - 1]
        scrambled = lr(scrambled, H - 1, -1)
        location = [H - 1, W - 2]
        scrambled = ud(scrambled, W - 1, -saved)
        scrambled = lr(scrambled, H - 1, 1)
        scrambled = ud(scrambled, W - 1,-1)

    scrambled = lr(scrambled, H - 1, -finder([H - 1, 0])[1])
    if SOLVED(scrambled, solved, INVERSE):
        return RS

    #Assuming that now the whole board except the last row is solved
    temp = [H - 1, 0]
    location = finder(temp)
    scrambled = lr(scrambled, H - 1, -location[1])
    scrambled = ud(scrambled, W - 1, 1)
    scrambled = lr(scrambled, H - 1, 1)
    scrambled = ud(scrambled, W - 1, -1)
    #^^ This is setup part for solving the last row(I think(but I can be wrong))
    K = [H - 1, 1]
    for i in range(W-2):
        K_D = K[::]
        location = finder(K)
        if location == [H - 2, W - 1]:
            last = [K_D[0], K_D[1] - 1]
            location_last = finder(last[::])
            scrambled = lr(scrambled, H - 1, W - 1 - location_last[1] - 1)
            scrambled = ud(scrambled, W - 1, 1)
            if K_D != [H - 1, W - 2]:
                scrambled = lr(scrambled, H - 1, - 1)
            else:
                scrambled = lr(scrambled, H - 1, W - 2 - finder(K_D)[1])
            scrambled = ud(scrambled, W - 1, -1)
        elif location[0] == H - 1:
            last = [K_D[0], K_D[1] - 1]
            scrambled = lr(scrambled, H - 1, W - 1 - location[1])
            scrambled = ud(scrambled, W - 1, 1)
            location_last = finder(last[::])
            scrambled = lr(scrambled, H - 1, W - 1 - location_last[1] - 1)
            scrambled = ud(scrambled, W - 1, -1)
            scrambled = lr(scrambled, H - 1, -1)

    scrambled = lr(scrambled, H - 1, -finder([H - 1, 0])[1])
    if SOLVED(scrambled, solved, INVERSE):
        return RS
    P = parity(scrambled)

    if P == 'V' and len(scrambled) % 2 == 1:
        scrambled = lr(scrambled, H - 1,  1)
        scrambled = ud(scrambled, W - 1,  1)
        scrambled = lr(scrambled, H - 1, -1)
        scrambled = ud(scrambled, W - 1, -1)
    P = parity(scrambled)
    if P == 'V':
        scrambled = lr(scrambled, H - 1, -1)
        scrambled = ud(scrambled, W - 1,  1)
        scrambled = lr(scrambled, H - 1,  1)
        scrambled = ud(scrambled, W - 1, -1)
        scrambled = lr(scrambled, H - 1, -1)
        scrambled = lr(scrambled, H - 1,  1)
        scrambled = ud(scrambled, W - 1, -1)
        to_find = [H - 1, W - 1]
        while 1:
            location = finder(to_find, 'W')
            if location[1] == W - 1:
                scrambled = ud(scrambled, W - 1, -location[0] - 1)
                scrambled = lr(scrambled, H - 1, -1)
                scrambled = ud(scrambled, W - 1, location[0] + 1)
                scrambled = lr(scrambled, H - 1, 1)
                scrambled = ud(scrambled, W - 1, -1)
            elif location[0] == H - 1:
                scrambled = lr(scrambled, H - 1, W - 1 -location[1])
                scrambled = ud(scrambled, W - 1, -1)
            if to_find[0] == H:
                to_find = [0, W - 1]
            if to_find[0] == H - 1:
                break
    elif P == 'H':
        scrambled = ud(scrambled, W - 1, -1)
        scrambled = lr(scrambled, H - 1,  1)
        scrambled = ud(scrambled, W - 1,  1)
        scrambled = lr(scrambled, H - 1, -1)
        scrambled = ud(scrambled, W - 1, -1)
        scrambled = ud(scrambled, W - 1,  1)
        scrambled = lr(scrambled, H - 1, -1)
        to_find = [H - 1, W - 1]
        while 1:
            print(to_find)
            location = finder(to_find)
            if location[0] == H - 1:
                scrambled = lr(scrambled, H - 1, -location[1] - 1)
                scrambled = ud(scrambled, W - 1, -1)
                scrambled = lr(scrambled, H - 1, location[1] + 1)
                scrambled = ud(scrambled, W - 1, 1)
                scrambled = lr(scrambled, H - 1, -1)
            elif location[1] == W - 1:
                scrambled = ud(scrambled, W - 1, H - 1 -location[0])
                scrambled = lr(scrambled, H - 1, -1)
            if to_find[0] == H:
                to_find = [H - 1, 0]
            if to_find[1] == W - 1:
                break

        for i in scrambled:
            print(i)

    if SOLVED(scrambled, solved, INVERSE):
        return RS
    return


from math import factorial
total = 0
for i in range(3,10000000):
    digits = []
    for num in str(i):

        digits.append(int(num))

    sum = 0
    for j in digits:
        sum += factorial(j)
    #print(i, digits, sum)
    if i == sum:
        total += sum
print(total)


# 参考 https://stats.stackexchange.com/questions/71335/decision-boundary-plot-for-a-perceptron

import numpy as np
from sklearn.linear_model import Perceptron
import matplotlib.pyplot as plt

def g(x):
    if x > 0:
        return 1
    else:
        return 0

def update_weights(w, X, y, a = 1):
    py = 0
    for i in range(X.shape[0]):
        py = g(np.dot(X[i], w))
        w = w + a*(y[i] - py)*X[i]
        print('weights: {}'.format(w))
    return w

if __name__ == '__main__':

    X = np.array([[1.0, 0.2, 0.1],
                  [1.0, 0.4, 0.6],
                  [1.0, 0.5, 0.2],
                  [1.0, 0.7, 0.9]])

    y = np.array([1, 1, 1, 0])
    w = np.array([0, 0, 0])

    n_epoch = 6
    for i in range(n_epoch):
        w = update_weights(w, X, y)
        print('_'*n_epoch, (i+1))

    # x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    # y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x_min, x_max = -0.9, 1.9
    y_min, y_max = -1.05, 2.05
    h = 0.02
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    fig, ax = plt.subplots()
    xyc = np.c_[xx.ravel(), yy.ravel()]
    Z = np.zeros(xyc.shape[0])
    for i in range(len(Z)):
        Z[i] = g(np.dot(xyc[i], w[1:]) + w[0])

    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, cmap=plt.cm.Paired)
    # ax.axis('off')
    ax.scatter(X[:, 1], X[:, 2], c=y, cmap=plt.cm.Paired, edgecolors='blue')
    ax.set_title('Perceptron')