from flask import Flask, render_template, request, redirect, url_for, send_from_directory, g
from bs4 import BeautifulSoup
import os
import requests
import pandas as pd
import numpy
import json

df = pd.DataFrame()

prices = dict()

app = Flask(__name__)

dirpath = os.path.join(app.root_path,'download')

@app.route('/')
def index():

    filename = request.args.get('filename')

    return render_template('index.html', filename=filename)

@app.route('/crawler', methods=['POST'])
def crawler():

	#filename = request.args.get('filename')
	num = request.form.get('num')

	for j in range(2001,2018):

		for i in range(1,13):

			if i > 9 :

				res_post = requests.post("http://www.tse.com.tw/exchangeReport/STOCK_DAY_AVG?response=json&date="+str(j)+str(i)+"01&stockNo="+str(num)+"&_=1496303801885")

			else:

				res_post = requests.post("http://www.tse.com.tw/exchangeReport/STOCK_DAY_AVG?response=json&date="+str(j)+"0"+str(i)+"01&stockNo="+str(num)+"&_=1496303801885")

			stock_data = json.loads(res_post.text)

			if "data" in stock_data:

				price = stock_data['data']
				price.pop()
				price = dict(price)
				prices.update(price)

	pricesjson = json.dumps(prices)

	with open("./download/"+str(num)+".txt", 'w') as f:
		f.write(pricesjson)

	return render_template('index.html', filename=prices, num=num)

@app.route('/download', methods=['POST'])
def download():

	filename = request.form.get('num')+".txt"

	#filename = filename+".txt"

	return send_from_directory(dirpath,filename,as_attachment=True)

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


import pandas as pd
import numpy as np
from scipy import stats
from sklearn.model_selection import ShuffleSplit
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.base import BaseEstimator, ClassifierMixin

def load_data():
	data = pd.read_csv('./Data/RDC_Inventory_Core_Metrics_County_History.csv')
	df = data.drop(len(data)-1)
	Null_fips = df.loc[df['county_name'].isnull(),'county_fips'].unique() # fix missing county name related to Valdez-Cordova, AK
	df.fillna({'county_name':'valdez-cordova, ak'}, inplace=True)
	df.rename(columns={'month_date_yyyymm':'date'}, inplace=True)
	df['date'] = pd.to_datetime(df['date'], format='%Y%m')
	df = df.drop_duplicates(subset=['date','county_name'])
	df = df.sort_values(['county_name', 'date']).reset_index(drop=True)

	return df

def calculate_roi(month):
	df = load_data()

	# remove counties with few listings
	df = df.loc[(df['total_listing_count'] >= 2)]

	# make sure all possible dates are present
	date_correct = (
		df
		.groupby('county_name')['date']
		.apply(lambda x: (min(x), max(x)))
		.apply(lambda x: pd.date_range(x[0], x[1], freq='MS'))
		.reset_index()
		.explode('date')
		.reset_index(drop=True)
	)

	# calculate roi
	df_ = date_correct.merge(df, left_on=['county_name','date'], right_on=['county_name','date'], how='left')
	df_['roi'] = ((df_.groupby('county_name')['median_listing_price'].shift(-month) - df_['median_listing_price'])
					/ df_['median_listing_price'] * 100)
	df_ = df_.dropna(subset='roi').reset_index(drop=True)
	df_['class'] = pd.cut(df_['roi'],
							bins=[min(df_['roi']), 5, max(df_['roi'])],
							labels=[-1, 1],
							include_lowest=True)

	# remove outliers
	for i in range(3,df_.shape[1]-1):
		z = np.abs(stats.zscore(df_.iloc[:,i]))
		outliers = np.where(z > 1.5)[0]
		df_.iloc[outliers][['roi']] # check outlier roi values
		df_ = df_.drop(outliers).reset_index(drop=True)

	return df_

class ROIModel(BaseEstimator, ClassifierMixin):
	def fit(self, X, y):
		self.estimator = HistGradientBoostingClassifier( # these best parameter values found by using GridSearchCV based on highest scores from sklearn.metrics.classification_report(y_test, y_pred)
					        l2_regularization=0.001,
					        learning_rate=0.1,
					        max_depth=300,
					        max_iter=200,
					        max_leaf_nodes=100,
					        min_samples_leaf=30
					        )
		self.estimator.fit(X, y)
		return self

	def predict(self, X):
		y_pred = self.estimator.predict(X)
		return y_pred

	def prep_train_data(self, month:int=12):
		df = calculate_roi(month)
		bad_features = ['roi','county_name','date','county_fips','quality_flag', 'class']
		X_data = df.drop(bad_features, axis=1)
		y_data = df['class']

		for train_idx, test_idx in ShuffleSplit(1, test_size=0.2, random_state=42).split(range(len(df))):
			X_train = X_data.iloc[train_idx]
			y_train = y_data.iloc[train_idx]
			X_test = X_data.iloc[test_idx]
			y_test = y_data.iloc[test_idx]

		return X_train, y_train, X_test, y_test

def model_input():
	df = load_data()
	d_last_date = df.groupby('county_name')['date'].max().reset_index()
	d_last_date['last_date_flag'] = 1
	df_ = d_last_date.merge(df, left_on=['county_name','date'], right_on=['county_name','date'], how='right')
	df_ = df_.dropna(subset='last_date_flag').reset_index(drop=True)

	return df_

def model_output(month):
	# fit model
	classifier = ROIModel()
	X_train, y_train, X_test, y_test = classifier.prep_train_data(month)
	classifier.fit(X_train, y_train)

	# predict
	df = model_input()
	bad_features = ['county_name','date','county_fips','quality_flag', 'last_date_flag']
	X = df.drop(bad_features, axis=1)
	y = classifier.predict(X)

	prediction = pd.DataFrame(data = y,
	              index = df['county_name'],
	              columns = ['y_pred'])

	return prediction

# m = 6 # months
# model_output(m).to_parquet(path='./Data/prediction_'+str(m), index=True)


import tensorflow as tf
from tensorflow import keras
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
from torchvision.utils import save_image
import torch
from tqdm import tqdm

mnist = input_data.read_data_sets("/tmp/data", one_hot=True)

# tf.enable_eager_execution()

batch_size = 100
noise_size = 64
total_step = 10000

def bce_loss(labels, predicts):
    return tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels, logits=predicts))

def get_noise():
    return np.random.normal(0, 1., size=[batch_size, noise_size]).astype(np.float32)

def G(z, re):
    with tf.variable_scope("gggg", reuse=re):
        out = keras.layers.Dense(256, activation=tf.nn.relu)(z)
        # out = keras.layers.Dense(512, activation=tf.nn.relu)(out)
        out = keras.layers.Dense(784, activation=tf.nn.tanh)(out)

    return out

def D(x, re):
    with tf.variable_scope("dddd", reuse=re):
        out = keras.layers.Dense(256, activation=tf.nn.relu)(x)
        # out = keras.layers.Dense(64, activation=tf.nn.relu)(out)
        out = keras.layers.Dense(1)(out)

    return out

x_data = tf.placeholder(tf.float32, [None, 784])
z_noise = tf.placeholder(tf.float32, [None, noise_size])

# case 1
# d_loss = tf.reduce_mean(D(G(z_noise, False), False)) - tf.reduce_mean(D(x_data, True))
# g_loss = - tf.reduce_mean(D(G(z_noise, True), True))

# case 2
fake_img = G(z_noise, False)
d_fake = D(fake_img, False)
d_data = D(x_data, True)

d_loss = bce_loss(tf.ones_like(d_data), d_data) + bce_loss(tf.zeros_like(d_fake), d_fake)
g_loss = bce_loss(tf.zeros_like(d_fake), d_fake)

fake_img_list = tf.reshape(fake_img, (batch_size, 1, 28, 28))

optimizer = tf.train.AdamOptimizer(0.0002)

t_vars = tf.trainable_variables()

d_var_list = [var for var in t_vars if "dddd" in var.name]
g_var_list = [var for var in t_vars if "gggg" in var.name]

d_train = optimizer.minimize(d_loss, var_list=d_var_list)
g_train = optimizer.minimize(g_loss, var_list=g_var_list)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

train_pbar = tqdm(total=total_step)

for step in range(total_step):
    train_pbar.update(1)
    batch_xs, _ = mnist.train.next_batch(batch_size)
    sample_noise = get_noise()

    d_error, _ = sess.run([d_loss, d_train],
                          feed_dict={
                              x_data: batch_xs,
                              z_noise: sample_noise
                          })

    g_error, _ = sess.run([g_loss, g_train],
                          feed_dict={
                              z_noise: sample_noise
                          })

    if (step + 1) % 100 == 0:
        train_pbar.set_description('d error {} g error {}'.format(d_error, g_error))

test_noise = get_noise()
result_img = sess.run(fake_img_list, feed_dict={
    z_noise: test_noise
})

print(result_img.shape)
result_tensor = torch.from_numpy(result_img)
save_image(result_tensor, 'result.png', normalize=True)


"""OpenAPI3 with flask
"""
import pytest
from flask import Flask, Response, jsonify, request
from flask.views import MethodView

from apiman.flask import Apiman

app = Flask(__name__)
apiman = Apiman(template="./examples/docs/dog_template.yml")
apiman.init_app(app)

# define data
DOGS = {1: {"id": 1, "name": "Ping", "age": 2}, 2: {"id": 2, "name": "Pong", "age": 1}}
# add schema
apiman.add_schema(
    "Dog",
    {
        "properties": {
            "id": {"description": "global unique", "type": "integer"},
            "name": {"type": "string"},
            "age": {"type": "integer"},
        },
        "type": "object",
        "required": ["id", "name", "age"],
    },
)

# define routes and schema(in doc string)
@apiman.from_dict(
    {
        "get": {
            "parameters": [
                {
                    "in": "path",
                    "name": "id",
                    "required": True,
                    "schema": {"type": "integer"},
                },
                {
                    "in": "query",
                    "name": "test_param1",
                    "required": True,
                    "schema": {"type": "string"},
                },
                {
                    "in": "header",
                    "name": "Test-Param2",
                    "required": True,
                    "schema": {"type": "string"},
                },
            ],
            "responses": {
                "200": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "age": {"type": "integer"},
                                    "id": {
                                        "description": "global unique",
                                        "type": "integer",
                                    },
                                    "name": {"type": "string"},
                                },
                                "required": ["id", "name", "age"],
                                "type": "object",
                            }
                        },
                    },
                    "description": "OK",
                },
                "404": {"description": "Not found"},
            },
            "summary": "Get single dog",
            "tags": ["dog"],
        }
    }
)
class DogView(MethodView):
    def get(self, id):
        """
        Normal annotation will be ignored
        """
        apiman.validate_request(request)
        return jsonify(DOGS[id])

    @apiman.from_yaml(
        """
        summary: Delete single dog
        tags:
        - dog
        parameters:
        - name: id
          in: path
          required: True
          schema:
            type: integer
        responses:
          "204":
            description: OK
          "404":
            description: Not found
        """
    )
    def delete(self, id):
        DOGS.pop(id)
        return Response(status=204)

app.add_url_rule("/dog/<int:id>", view_func=DogView.as_view(name="dog"))

# define doc by yaml or json file
@app.route("/dogs/", methods=["GET"])
@apiman.from_file("./examples/docs/dogs_get.yml")
def list_dogs():
    return jsonify(list(DOGS.values()))

@app.route("/dogs/", methods=["POST"])
@apiman.from_file("./examples/docs/dogs_post.json")
def create_dog():
    apiman.validate_request(request)
    dog = request.json
    DOGS[dog["id"]] = dog
    return jsonify(dog)

def test_app():
    client = app.test_client()
    spec = apiman.load_specification(app)
    apiman.validate_specification()
    assert client.get(apiman.config["specification_url"]).json == spec
    assert client.get(apiman.config["swagger_url"]).status_code == 200
    assert client.get(apiman.config["redoc_url"]).status_code == 200
    # --
    with pytest.raises(Exception):
        assert client.get("/dog/1") == 200
    with pytest.raises(Exception):
        assert client.get("/dog/1?test_param1=test") == 200
    assert (
        client.get(
            "/dog/1?test_param1=test", headers={"test_param2": "test"}
        ).status_code
        == 200
    )
    with pytest.raises(Exception):
        assert client.post("/dogs/", json={"id": 1, "name": "doge"}).status_code == 200
    with pytest.raises(Exception):
        assert (
            client.post(
                "/dogs/",
                data="age=1&id=2&name=3",
                headers={"Content-Type": "application/x-www-form-urlencoded"},
            ).status_code
            == 200
        )
    with pytest.raises(Exception):
        assert (
            client.post(
                "/dogs/",
                data="age=1&id=2&name=3",
                headers={"Content-Type": "multipart/form-data"},
            ).status_code
            == 200
        )
    with pytest.raises(Exception):
        assert (
            client.post(
                "/dogs/",
                data="""<?xml version="1.0" encoding="UTF-8"?> <data> <age>0</age> <id>0</id> <name>string</name> </data>""",
                headers={"Content-Type": "application/xml"},
            ).status_code
            == 200
        )
    assert (
        client.post("/dogs/", json={"id": 1, "name": "doge", "age": 3}).status_code
        == 200
    )

if __name__ == "__main__":
    app.run(debug=True)


def divisors(n):
	count = 1
	numbers = []
	while count < n:
		if n % count == 0:
			numbers = numbers + [count]
		count += 1
	return numbers

def sum_ints(numbers):
	sum = 0
	for number in numbers:
		sum += number
	return sum

def is_perfect(x):
	return x == sum_ints(divisors(x))

n = input("Enter n: ")
n = int(n)

#divisor = divisors(n)
#print(divisor)
#sum = sum_ints(divisor)
#print(sum)

perfect = is_perfect(n)
print(perfect)


import matplotlib.pyplot as plt
import numpy as np

def ellipse(x_param, a_param, c_param):
    return np.sqrt(np.sqrt(a_param ** 4 + 4 * x_param ** 2 * c_param ** 2) - x_param ** 2 - c_param ** 2)

print('Ellipse of Cassini: ')
print('sqrt(sqrt(a^4 + 4 * c^2 * x^2) - x^2 - c^2) ')

a = float(input('Enter parameter a: '))
c = float(input('Enter parameter c: '))

x = np.linspace(-4*c, 4*c, 666666)
y = []

for x_value in x:
    y_result = ellipse(x_value, a, c)
    y.append([y_result, -1 * y_result])

plt.plot(x, y)
plt.show()


"""
Faça um programa que receba um código numérico e um vetor de cinco posições de
números reais. Se o código for 0 (zero), termine o programa. Se o código for 1,
mostre o vetor na ordem direta. Se o código for 2, mostre o vetor na ordem inversa.
"""

v = []
y = 1

for n in range(1, 6):
    x = int(input("Informe um numero:"))
    v.append(x)

while y != 0:
    y = int(input("1- Mostrar vetor na ordem direta\n"
        +"2- Mostrar vetor na ordem inversa\n"
        +"0- Finalizar programa\n"
        +"Insira um codigo: "))

    if y == 1:
        print("----Ordem Direta----")
        print(v)
    elif y == 2:
        v.reverse()
        print("----Ordem Inversa----")
        print(v)
    elif y == 0:
        print("----Programa Finalizado----")
        exit(0)
    else:
        print("Codigo Invalido, insira um codigo valido!!!")


"""
Image recognition and categorization module using
transfer learning and unsupervised learning methods
"""
from io import BytesIO
import pickle
import requests
import pandas as pd
import numpy as np
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications import vgg16
from sklearn.cluster import MiniBatchKMeans

def input_processing(url):
    """
    Function to download and process the image input
    """
    try:
        response = requests.get(url)
        img = image.load_img(BytesIO(response.content), target_size=(48, 48))
        img_array = image.img_to_array(img)
    except Exception as exception_type:
        print(exception_type)
        img = image.load_img("empty.png", target_size=(48, 48))
        img_array = image.img_to_array(img)

    return img_array

def add_img_array(data):
    """
    Function to add the array to the pandas dataframe
    """
    data['img_array'] = data['url'].map(input_processing)
    data['predictions'] = data['img_array'].apply(apply_vgg)
    data.to_hdf('reddit_img_tl.h5', key='data')

model = vgg16.VGG16(include_top=False, weights="imagenet", input_shape=(48, 48, 3))
def apply_vgg(img):
    """
    Function to add the array to the pandas dataframe
    """
    x_img = np.expand_dims(img, axis=0)
    x_img = vgg16.preprocess_input(x_img)
    # Run the image through the deep neural network to make a prediction
    predictions = model.predict(x_img)

    return predictions

if __name__ == "__main__":
    try:
        print('try')
        topics_data = pd.read_hdf('./reddit_img_tl.h5', key='data')

    except Exception as exception_type:
        print("Error: %s" % exception_type)
        topics_data = pd.read_csv('../redditretriever/reddit.csv')
        add_img_array(topics_data)

    preds = topics_data['predictions']
    x_train = preds.values
    x_train = np.concatenate(x_train)
    x_train = x_train.reshape(len(x_train), -1)

    # Initialize and fit KMeans algorithm
    kmeans = MiniBatchKMeans(n_clusters=100)
    kmeans.fit(x_train)

    # record centroid values
    centroids = kmeans.cluster_centers_

    images = centroids.reshape(100, 1, 1, 512)
    y_pred_kmeans = kmeans.predict(x_train)
    pickle.dump(kmeans, open("save_tl.pkl", "wb"))
    topics_data['cat'] = pd.Series(y_pred_kmeans.astype(int), index=topics_data.index)
    topics_data.to_csv('reddit_img_labeled_tl.csv')


import copy
import random

import pygame.image

from Custum_Components.bullet_etalons import BulletEtalons
from Custum_Components.enemies.Zdenek import Zdenek
from Custum_Components.enemies.boss_budai import BossBudai
from Custum_Components.enemies.creeper import Creeper
from Custum_Components.enemies.klickova import Klickova
from Custum_Components.enemies.sykora import Sykora
from Custum_Components.weapon import Weapon
from game_object import GameObject
import numpy as np
from Custum_Components.box_collider import BoxCollider
from Custum_Components.enemy import Enemy
import Custum_Components.basic_enemy_weapon as enemy_weapons

def get_spawn_pos_basic_side():
    return np.array([random.choice([-100.0, 700.0]), random.uniform(200, 450)])

class EnemyEtalons:
    def __init__(self, speed, health_q):
        bullets = BulletEtalons().bullets

        jura_weapon = enemy_weapons.BasicWeapon(bullet=bullets["basic"], fire_rate=1.4 * speed)
        jura = GameObject(np.array([0.0, 0.0]),
                          components=[BoxCollider(), jura_weapon,
                                      Enemy(max_health=7 * health_q, speed=0.6 * speed)],
                          img=pygame.image.load('sprites/Jura.png'),
                          tag='Enemy')

        # Velich
        velich = GameObject(np.array([0.0, 0.0]),
                            components=[BoxCollider(), Enemy(max_health=1 * health_q, speed=speed)],
                            img=pygame.image.load('sprites/Velich.png'),
                            tag='Enemy')
        velich.get_component(Enemy).get_spawn_pos = lambda: np.array([-100, random.randrange(300, 550)])
        velich.rotation = [1, 0]

        velich2 = copy.deepcopy(velich)
        velich2.get_component(Enemy).get_spawn_pos = lambda: np.array([700, random.randrange(300, 550)])
        velich2.rotation = [-1, 0]

        lopocha = GameObject(np.array([0.0, 0.0]),
                            components=[BoxCollider(), Enemy(max_health=6 * health_q, speed=2 * speed)],
                            img=pygame.image.load('sprites/Lopocha.jpeg'),
                            tag='Enemy')

        # Hrabalova
        h_weapon = enemy_weapons.EnemyTripleWeapon(bullet=bullets["basic"], fire_rate=0.7 * speed)
        hrabalova = GameObject(np.array([0.0, 0.0]),
                               components=[BoxCollider(), Enemy(max_health=15 * health_q, speed=0.1 * speed), h_weapon],
                               img=pygame.image.load('sprites/Hrabalova.png'),
                               tag='Enemy')

        b_weapon1 = enemy_weapons.EnemyTripleWeapon(bullet=bullets["basic"], fire_rate=speed, offset=[60, 0])

        budai = GameObject(np.array([0.0, 0.0]),
                           components=[BoxCollider(),
                                       BossBudai(max_health=500 * health_q, speed=0.5 * speed, boss=True),
                                       b_weapon1],
                           img=pygame.image.load('sprites/budai.png'),
                           tag='Enemy')

        rasek_weapon = enemy_weapons.BasicWeapon(bullet=bullets["explosive"], fire_rate=0.4 * speed)
        rasek = GameObject(np.array([0.0, 0.0]),
                           components=[BoxCollider(), Enemy(max_health=7 * health_q, speed=0.5 * speed), rasek_weapon],
                           img=pygame.image.load('sprites/Rasek.png'),
                           tag='Enemy')

        herman_weapon = enemy_weapons.Weapon(bullet=bullets["zig_zag"], fire_rate=0.4 * speed)
        herman = GameObject(np.array([0.0, 0.0]),
                            components=[BoxCollider(), Enemy(max_health=7 * health_q, speed=0.5 * speed),
                                        herman_weapon],
                            img=pygame.image.load('sprites/Herman.png'),
                            tag='Enemy')

        jedlicka = GameObject(np.array([0.0, 0.0]),
                              components=[BoxCollider(), Creeper(max_health=15 * health_q, speed=1.0 * speed,
                                                                 get_spawn_pos=get_spawn_pos_basic_side)],
                              img=pygame.image.load('sprites/Jedlicka.png'),
                              tag='Enemy')

        klickova = GameObject(np.array([0.0, 0.0]),
                              components=[BoxCollider(),
                                          Klickova(max_health=400 * health_q, speed=1.0 * speed, boss=True)],
                              img=pygame.image.load('sprites/Jedlicka.png'),
                              tag='Enemy')
        zdenda_weapon = enemy_weapons.BasicWeapon(bullet=bullets["basic"], fire_rate=1.4 * speed)
        zdenda = GameObject(np.array([0.0, 0.0]),
                            components=[BoxCollider(), Zdenek(max_health=200 * health_q, speed=1.0 * speed, boss=True),
                                        zdenda_weapon],
                            img=pygame.image.load('sprites/Zdenek.png'),
                            tag='Enemy')

        sykora = GameObject(np.array([0.0, 0.0]),
                            components=[BoxCollider(), Sykora(max_health=300 * health_q, speed=1.0 * speed, boss=True)],
                            img=pygame.image.load('sprites/Sykora.png'),
                            tag='Enemy')

        vondra_weapon1 = Weapon(bullet=bullets["basic"], fire_rate=1.0 * speed, direction=[0.0, -1.0])
        vondra_weapon2 = Weapon(bullet=bullets["basic"], fire_rate=1.0 * speed, direction=[1.0, -1.0])
        vondra_weapon3 = Weapon(bullet=bullets["basic"], fire_rate=1.0 * speed, direction=[-1.0, -1.0])

        vondra_ = GameObject(np.array([0.0, 0.0]),
                             components=[BoxCollider(), Enemy(max_health=4 * health_q, speed=0.5 * speed),
                                         vondra_weapon1, vondra_weapon2, vondra_weapon3],
                             img=pygame.image.load('sprites/Vondra.png'),
                             tag='Enemy')

        self.enemies = {
            "Jura": jura,
            "Velich": velich,
            "Velich2": velich2,
            "Vondra": vondra_,
            "Hrabalova": hrabalova,
            "budai": budai,
            "Rasek": rasek,
            "Herman": herman,
            "Jedlicka": jedlicka,
            "Zdenda": zdenda,
            "Sykora": sykora,
            "Klickova": klickova,
            "Zelenka": None,
            "Studenkova": None,
            "Lopocha": lopocha
        }


"""
created  by  hzwlxy  at 2018/7/5 10:59
__author__: 西瓜哥
__QQ__ : 120235331
__Note__：
"""
from datetime import datetime, timedelta
from flask import (session, _request_ctx_stack, request, current_app)
from flask_login import LoginManager as  _loginManager

from flask_login.signals import user_accessed, session_protected, user_loaded_from_cookie
from flask_login.config import COOKIE_NAME, AUTH_HEADER_NAME, COOKIE_DURATION, COOKIE_SECURE, COOKIE_HTTPONLY
from flask_login.utils import decode_cookie, encode_cookie

from flask_login_multi import _get_user,_user_context_processor

SESSION_KEYS = set(['user_id', 'remember', 'id', 'fresh', 'next'])

class LoginManager(_loginManager):

    def init_app(self, app, add_context_processor=True):

        app.login_manager = self
        app.after_request(self._update_remember_cookie)

        self._login_disabled = app.config.get('LOGIN_DISABLED', False)

        if add_context_processor:
            app.context_processor(_user_context_processor)

    @property
    def _get_endpoint(self):
        blueprint = getattr(request, 'blueprint', None)
        if blueprint is None:
            return 'user'
        return blueprint

    def reload_user(self, user=None):
        ctx = _request_ctx_stack.top
        if user is None:
            user_id = session.get(self._get_endpoint + '_user_id')
            if user_id is None:
                setattr(ctx, self._get_endpoint, self.anonymous_user())
            else:
                if self.user_callback is None:
                    raise Exception(
                        "No user_loader has been installed for this "
                        "LoginManager. Refer to"
                        "https://flask-login.readthedocs.io/"
                        "en/latest/#how-it-works for more info.")
                # 根据endpoint来判断当前登录是用户还是管理员
                user = self.user_callback(user_id, self._get_endpoint)
                if user is None:
                    setattr(ctx, self._get_endpoint, self.anonymous_user())
                else:
                    setattr(ctx, self._get_endpoint, user)
        else:
            setattr(ctx, self._get_endpoint, user)

    def _load_user(self):
        user_accessed.send(current_app._get_current_object())
        config = current_app.config

        if config.get('SESSION_PROTECTION', self.session_protection):
            deleted = self._session_protection()
            if deleted:
                return self.reload_user()

        is_missing_user_id = (self._get_endpoint + '_user_id') not in session
        if is_missing_user_id:
            cookie_name = self._get_endpoint + '_' + config.get('REMEMBER_COOKIE_NAME', COOKIE_NAME)
            header_name = config.get('AUTH_HEADER_NAME', AUTH_HEADER_NAME)
            has_cookie = (cookie_name in request.cookies and
                          session.get('remember') != 'clear')

            if has_cookie:
                return self._load_from_cookie(request.cookies[cookie_name])
            elif self.request_callback:
                return self._load_from_request(request)
            elif header_name in request.headers:
                return self._load_from_header(request.headers[header_name])

        return self.reload_user()

    def _get_session_protection(self):
        app = current_app._get_current_object()
        return app.config.get('SESSION_PROTECTION', self.session_protection)

    def _session_protection(self):
        sess = session._get_current_object()
        ident = self._session_identifier_generator()
        app = current_app._get_current_object()
        mode = app.config.get('SESSION_PROTECTION', self.session_protection)

        # 用了endpoint区别之后，不能直接 用sess来判断session有没有值
        # 用sess.get(self._get_endpoint + '_user_id',None) 来判断当前用户session标志存不存在
        if sess.get(self._get_endpoint + '_user_id', None) and ident != sess.get(self._get_endpoint + '_id', None):
            if mode == 'basic' or sess.permanent:
                sess[self._get_endpoint + '_fresh'] = False
                session_protected.send(app)
                return False
            elif mode == 'strong':

                for k in SESSION_KEYS:
                    sess.pop(self._get_endpoint + '_' + k, None)
                sess[self._get_endpoint + '_remember'] = 'clear'
                session_protected.send(app)
                return True
        return False

    def _load_from_cookie(self, cookie):
        data = decode_cookie(cookie).split('||')
        user_id = data[0]
        mode = current_app._get_current_object().config.get('SESSION_PROTECTION', self.session_protection)
        if user_id is not None:
            session[self._get_endpoint + '_user_id'] = user_id
            session[self._get_endpoint + '_fresh'] = False
            if mode == 'strong':
                session[self._get_endpoint + '_id'] = data[1]

        self.reload_user()
        user = getattr(_request_ctx_stack.top, self._get_endpoint, None)

        if user is not None:
            app = current_app._get_current_object()
            user_loaded_from_cookie.send(app, user=_get_user())

    def _update_remember_cookie(self, response):

        if (self._get_endpoint + '_remember') not in session and current_app.config.get('REMEMBER_COOKIE_REFRESH_EACH_REQUEST'):
            session[self._get_endpoint + '_remember'] = 'set'

        if (self._get_endpoint + '_remember') in session:
            operation = session.pop((self._get_endpoint + '_remember'), None)

            if operation == 'set' and (self._get_endpoint + '_user_id') in session:
                self._set_cookie(response)
            elif operation == 'clear':
                self._clear_cookie(response)

        return response

    def _set_cookie(self, response):

        config = current_app.config
        cookie_name = self._get_endpoint + '_' + config.get('REMEMBER_COOKIE_NAME', COOKIE_NAME)
        domain = config.get('REMEMBER_COOKIE_DOMAIN')
        path = config.get('REMEMBER_COOKIE_PATH', '/')
        secure = config.get('REMEMBER_COOKIE_SECURE', COOKIE_SECURE)
        httponly = config.get('REMEMBER_COOKIE_HTTPONLY', COOKIE_HTTPONLY)

        if (self._get_endpoint + '_remember_seconds') in session:
            duration = timedelta(seconds=session[self._get_endpoint + '_remember_seconds'])
        else:
            duration = config.get('REMEMBER_COOKIE_DURATION', COOKIE_DURATION)

        # 用户id 和 浏览器加密信息 存入cookie
        temp = (str(session[self._get_endpoint + '_user_id']), str(session[self._get_endpoint + '_id']))
        data = encode_cookie('||'.join(temp))

        if isinstance(duration, int):
            duration = timedelta(seconds=duration)

        try:
            expires = datetime.utcnow() + duration
        except TypeError:
            raise Exception('REMEMBER_COOKIE_DURATION must be a ' +
                            'datetime.timedelta, instead got: {0}'.format(
                                duration))

        response.set_cookie(cookie_name,
                            value=data,
                            expires=expires,
                            domain=domain,
                            path=path,
                            secure=secure,
                            httponly=httponly)

    def _clear_cookie(self, response):
        config = current_app.config
        cookie_name = self._get_endpoint + '_' + config.get('REMEMBER_COOKIE_NAME', COOKIE_NAME)
        domain = config.get('REMEMBER_COOKIE_DOMAIN')
        path = config.get('REMEMBER_COOKIE_PATH', '/')
        response.delete_cookie(cookie_name, domain=domain, path=path)


class FSDJumpFactions:
    def __init__(self, Name, FactionState, Government, Influence, Happiness, MyReputation, PendingStates, RecovingStates, ActiveStates, SquadronFaction, HappiestSystem, HomeSystem):
        self.Name = Name
        self.FactionState = FactionState
        self.Government = Government
        self.Influence = Influence
        self.Happiness = Happiness
        self.MyReputation = MyReputation
        self.PendingStates = PendingStates
        self.RecovingStates = RecovingStates
        self.ActiveStates = ActiveStates
        self.SquadronFaction = SquadronFaction
        self.HappiestSystem = HappiestSystem
        self.HomeSystem = HomeSystem


from typing import BinaryIO, Optional, Union

from typing_extensions import Protocol

from .batch_factory import Batch, BatchFactory
from .episode import EpisodeManager
from .io import dump_memory, load_memory
from .item import Item
from .step import StepBuffer
from .step_collector import StepCollector
from .transition_buffer import TransitionBuffer
from .transition_factory import TransitionFactory

class KioxProtocol(Protocol):
    def collect(
        self,
        observation: Item,
        action: Item,
        reward: Item,
        terminal: Union[bool, float],
        timeout: Optional[bool] = None,
    ) -> None:
        """Stores experience tuple.

        Args:
            observation: observation.
            action: action.
            reward: reward.
            terminal: terminal flag.
            timeout: timeout flag.

        """

    def get_step_buffer_size(self) -> int:
        """Returns number of stored tuples.

        Returns:
            number of tuples.

        """

    def get_transition_buffer_size(self) -> int:
        """Returns number of stored transitions.

        Returns:
            number of transitions.

        """

    def clip_episode(self) -> None:
        """Clips active episode.

        This method should be called whenever the current episode ends for
        timeout.

        """

    def sample(self, batch_size: int) -> Batch:
        """Samples transitions and returns mini-batch.

        Args:
            batch_size: batch size.

        Returns:
            mini-batch.

        """

    def copy_from(self, kiox: "KioxProtocol") -> None:
        """Copies steps and transitions from another Kiox object.

        Args:
            kiox: source Kiox object.

        """

    def save(self, f: BinaryIO) -> None:
        """Saves data as HDF5.

        Args:
            f: I/O-like object.

        """

    def load(self, f: BinaryIO) -> None:
        """Loads HDF5 data.

        Args:
            f: I/O-like object.

        """

class Kiox(KioxProtocol):
    """Kiox class.

    This class takes a single stream of experiences.

    .. code-block:: python

        kiox = Kiox(FIFOTransitionBuffer(1000), SimpleTransitionFactory())

        # collect data
        env = gym.make("CartPole-v0")
        obs = env.reset()
        while True:
            action = np.random.randint(2)
            next_obs, reward, terminal, _ = env.step(action)
            kiox.collect(obs, action, reward, terminal)
            if terminal:
                break
            obs = next_obs

        # sample mini-batch
        batch = kiox.sample(32)

        # save data
        with open("data.h5", "wb") as f:
            kiox.save(f)

        # load data
        kiox2 = Kiox(FIFOTransitionBuffer(1000), SimpleTransitionFactory())
        with open("data.h5", "rb") as f:
            kiox2.load(f)

    Args:
        transition_buffer: TransitionBuffer object.
        transition_factory: TransitionFactory object.
        n_steps: step size for multi-step learning. This corresponds to TD(N).
        gamma: discounted factor. If ``n_steps=1``, this value does not make
            any difference.

    """

    _step_buffer: StepBuffer
    _episode_manager: EpisodeManager
    _transition_buffer: TransitionBuffer
    _transition_factory: TransitionFactory
    _batch_factory: BatchFactory
    _step_collector: StepCollector

    def __init__(
        self,
        transition_buffer: TransitionBuffer,
        transition_factory: TransitionFactory,
        n_steps: int = 1,
        gamma: float = 0.99,
    ):
        self._step_buffer = StepBuffer()
        self._transition_buffer = transition_buffer
        self._transition_factory = transition_factory
        self._episode_manager = EpisodeManager(
            step_buffer=self._step_buffer,
            transition_buffer=self._transition_buffer,
        )
        self._batch_factory = BatchFactory(
            step_buffer=self._step_buffer,
            transition_buffer=transition_buffer,
        )
        self._step_collector = StepCollector(
            episode_manager=self._episode_manager,
            transition_factory=transition_factory,
            n_steps=n_steps,
            gamma=gamma,
        )

    def collect(
        self,
        observation: Item,
        action: Item,
        reward: Item,
        terminal: Union[bool, float],
        timeout: Optional[bool] = None,
    ) -> None:
        terminal = float(terminal) if isinstance(terminal, bool) else terminal
        self._step_collector.collect(
            observation=observation,
            action=action,
            reward=reward,
            terminal=terminal,
            timeout=timeout,
        )

    def get_step_buffer_size(self) -> int:
        return self._step_buffer.size()

    def get_transition_buffer_size(self) -> int:
        return self._transition_buffer.size()

    def clip_episode(self) -> None:
        self._step_collector.clip_episode()

    def sample(self, batch_size: int) -> Batch:
        return self._batch_factory.sample(batch_size)

    def copy_from(self, kiox: KioxProtocol) -> None:
        assert isinstance(kiox, Kiox)
        for episode in kiox.episode_manager.episodes:
            steps = episode.steps
            episode_length = len(steps)
            for i, step in enumerate(steps):
                self.collect(
                    observation=step.observation,
                    action=step.action,
                    reward=step.reward,
                    terminal=step.terminal,
                    timeout=(i + 1) == episode_length,
                )

    def save(self, f: BinaryIO) -> None:
        dump_memory(f, self._episode_manager.episodes)

    def load(self, f: BinaryIO) -> None:
        load_memory(f, self._step_collector)

    @property
    def episode_manager(self) -> EpisodeManager:
        return self._episode_manager

    @property
    def transition_buffer(self) -> TransitionBuffer:
        return self._transition_buffer

    @property
    def transition_factory(self) -> TransitionFactory:
        return self._transition_factory


from .base import INSTALLED_APPS  # noqa: F401

# Minimal settings module to use Django's collectstatic command during Dockerfile build
# Bring in INSTALLED_APPS to find all Django's assets

# set DEBUG off
DEBUG = False

# must set some value in SECRET_KEY so that Django init can happen
SECRET_KEY = "temporary"

# must set default DATABASES key as well for Django init
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": "temporary"}}

# must set AUTH_USER_MODEL so Django init does not detect improper configuration
AUTH_USER_MODEL = "profile.User"

# finally, the actual staticfiles settings:
# location where static assets are saved in Docker image
STATIC_ROOT = "/usr/local/edd-static"
# URL where static assets will eventually get served; used in processing references
STATIC_URL = "/static/"
# do not need any hashing/manifest at this stage
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"


from flask import url_for, flash, redirect, current_app, render_template
from main import db
from main.models import Appointment, Holiday, Post
from flask_login import current_user
from main.users.utils import send_email

def send_email_accept(id):
    appointment = Appointment.query.filter(Appointment.id == id).first()
    #SELECT * FROM Appointment WHERE id = {id} LIMIT 1;
    send_email('[Smile Plaza] Booked Appointment',
               sender=current_app.config['ADMINS'][0],
               recipients=[appointment.user_email],
               text_body=render_template('email/appointment_status_accepted.txt',
                                         appointment=appointment))

def send_email_reject(id):
    appointment = Appointment.query.filter(Appointment.id == id).first()
    #SELECT * FROM Appointment WHERE id = {id} LIMIT 1;
    send_email('[Smile Plaza] Booked Appointment',
               sender=current_app.config['ADMINS'][0],
               recipients=[appointment.user_email],
               text_body=render_template('email/appointment_status_rejected.txt',
                                         appointment=appointment))

def send_email_cancel(id):
    appointment = Appointment.query.filter(Appointment.id == id).first()
    #SELECT * FROM Appointment WHERE id = {id} LIMIT 1;
    send_email('[Smile Plaza] Booked Appointment',
               sender=current_app.config['ADMINS'][0],
               recipients=[appointment.user_email],
               text_body=render_template('email/appointment_status_cancelled.txt',
                                         appointment=appointment))

def send_email_received(id):
    appointment = Appointment.query.filter(Appointment.id == id).first()
    #SELECT * FROM Appointment WHERE id = {id} LIMIT 1;
    send_email('[Smile Plaza] Booked Appointment',
               sender=current_app.config['ADMINS'][0],
               recipients=[appointment.user_email],
               text_body=render_template('email/appointment_status_pending.txt',
                                         appointment=appointment))

def accept_action(appointmentID):
    appointment = Appointment.query.filter(Appointment.id == appointmentID).first()
    #SELECT * FROM Appointment WHERE id = {appointmentID} LIMIT 1;
    appointment.action = "ACCEPTED"
    #UPDATE Appointment SET action='ACCEPTED' WHERE id={appointmentID};
    db.session.commit()

def reject_action(appointmentID):
    appointment = Appointment.query.filter(Appointment.id == appointmentID).first()
    #SELECT * FROM Appointment WHERE id = {appointmentID} LIMIT 1;
    appointment.action = "REJECTED"
    appointment.status = "CANCELLED"
    #UPDATE Appointment SET action='REJECTED', status='CANCELLED' WHERE id={appointmentID};
    db.session.commit()

def cancel_status(appointmentID):
    appointment = Appointment.query.filter(Appointment.id == appointmentID).first()
    #SELECT * FROM Appointment WHERE id = {appointmentID} LIMIT 1;
    appointment.status = "CANCELLED"
    #UPDATE Appointment SET action='REJECTED', status='CANCELLED' WHERE id={appointmentID};
    db.session.commit()

def finish_status(appointmentID):
    appointment = Appointment.query.filter(Appointment.id == appointmentID).first()
    #SELECT * FROM Appointment WHERE id = {appointmentID} LIMIT 1;
    appointment.status = "FINISHED"
    #UPDATE Appointment SET status = 'FINISHED' WHERE id = {appointmentID};

    db.session.commit()

def holiday_status(selected_date_utc):
    if current_user.is_authenticated:
        holiday = Holiday(date=selected_date_utc, isHoliday="HOLIDAY")
        db.session.add(holiday)
        #INSERT INTO Holiday (date) VALUES ('{selected_date_utc}');
        db.session.commit()

        post = Post(title="No Clinic", content=f"No clinic for {selected_date_utc}, all appointments are cancelled.",
                    author=current_user)
        db.session.add(post)
        #INSERT INTO Post (title, content, author_id) VALUES ('No Clinic', CONCAT('No clinic for ' , '{selected_date_utc}', ', all appointments are cancelled.'), {current_user_id});
        db.session.commit()

        appointments = Appointment.query.filter(Appointment.date == selected_date_utc).all()
        #SELECT * FROM Appointment WHERE date = '{selected_date_utc}';
        print(f"Appointment: {appointments}")
        for appointment in appointments:
            appointment.action = "REJECTED"
            appointment.status = "CANCELLED"
            #UPDATE Appointment SET action = 'REJECTED', status = 'CANCELLED' WHERE date = '{selected_date_utc}';
            db.session.commit()
            send_email_cancel(appointment.id)

def add_appointment_to_database(selected_date_utc, selected_time, selected_service):
    appointment = Appointment(user_id=current_user.id, user_name=current_user.username,
                              user_email=current_user.email, user_contact = current_user.contact,
                              service = selected_service, date=selected_date_utc, time=selected_time)
    db.session.add(appointment)
    '''
    INSERT INTO Appointment (user_id, user_name, user_email, user_contact, service, date, time)
    VALUES ('{current_user_id}', '{current_user_username}', '{current_user_email}', '{current_user_contact}',
    '{selected_service}', '{selected_date_utc}', '{selected_time}');
    '''
    db.session.commit()
    flash('Your appointment has been added.', 'success')
    return redirect(url_for('main.customer_announcement'))


from collections import defaultdict
class Graph:
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self,start,end):
        self.graph[start].append(end)

    def dfs(self,node,visited = {},out=[]):
        if not visited.get(node,None):
            out.append(node)
            visited[node] = True

        for nei in self.graph[node]:
            if not visited.get(nei,None):
                self.dfs(nei, visited, out)

g = Graph()
g.add_edge(0, 1)
g.add_edge(0, 2)
g.add_edge(2, 0)
g.add_edge(2, 4)
g.add_edge(0, 3)

visited = {}
out = []
g.dfs(0,visited,out)
print(out)


''' Задача Марка '''

import math
import random

e = float(input('Задайте погрешность: '))
a = float(input('Задайте начало интервала: '))
b = float(input('Задайте конец интервала: '))

fx0, fx1, fx2 = 0,0,0
x0, x1, x2 = 0,0,0
l = b - a

while e <= l:

    x0 = (a + b) / 2
    x1 = a + l/4
    x2 = b - l/4

    fx0 = math.sin(x0)
    fx1 = math.sin(x1)
    fx2 = math.sin(x2)

    if fx1 < fx0:

        b = x0

    elif fx2 < fx0:

        a = x0

    else: print('Ошибка')

    l = b - a

print(fx0, '- минимальное значение фукции при ', x0)

books/Задача марка.py

Задача марка.py


#!/usr/bin/python3

# ## {R2D2919B742E} ##
# ###########################################################################
# What if magic existed?
# What if a place existed where your every thought and dream come to life.
# There is only one catch: it has to be written down.
# Such a place exists, it is called programming.
#    - Scott Taylor Reph, RightThumb.com
# ###########################################################################
# ## {C3P0D40fAe8B} ##

import os
import sys
import time
# import simplejson as json
# from threading import Timer

##################################################
# construct registration

import _rightThumb._construct as __
appDBA = __.clearFocus( __name__, __file__ )
# appDBA = __name__
__.appReg = appDBA
def focus( parentApp='', childApp='', reg=True ):
	global appDBA
	f = __.appName( appDBA, parentApp, childApp )
	if reg:
		__.appReg = f
	return f
__.registeredApps.append(focus())

import _rightThumb._base3 as _
_.load()

##################################################

import _rightThumb._vars as _v
import _rightThumb._string as _str
# import _rightThumb._date as _date
# import _rightThumb._dir as _dir
# import _rightThumb._md5 as _md5
# import _rightThumb._mimetype as _mime

# import _rightThumb._auditCodeBase as _code
# _code = _.regImp( focus(), '_rightThumb._auditCodeBase' )

##################################################

from shutil import copyfile
# from lxml import html
# import requests
# import cssselect
# import sqlite3

##################################################

def appSwitches():
	_.switches.register('Input', '-i,-f,-file','file.txt')
	_.switches.register('Function', '-function')
	_.switches.register('ReplaceFile', '-replacefile')

_.appInfo[focus()] = {
	'file': 'replaceFunction.py',
	'description': 'Replaces an entire function with a replacement',
	'categories': [
						'file manipulation',
						'text manipulation',
				],
	'relatedapps': [],
	'prerequisite': [],
	'examples': [],
	'columns': [],
	}

_.appData[focus()] = {
	'start': time.time(),
	'uuid': '',
	'audit': [],
	'pipe': [],
	}

# epy replaceText
# epy insertText
# epy changeTextEnd
# epy moveText
# epy replaceFunction

_.appInfo[focus()]['relatedapps'].append('')
_.appInfo[focus()]['relatedapps'].append('p replaceText ?')
_.appInfo[focus()]['relatedapps'].append('p insertText ?')
_.appInfo[focus()]['relatedapps'].append('')
_.appInfo[focus()]['relatedapps'].append('p changeTextEnd ?')
_.appInfo[focus()]['relatedapps'].append('')
_.appInfo[focus()]['relatedapps'].append('p moveText ?')
_.appInfo[focus()]['relatedapps'].append('')
_.appInfo[focus()]['relatedapps'].append('p replaceFunction ?')

_.appInfo[focus()]['examples'].append('')
_.appInfo[focus()]['examples'].append('p replaceFunction -i insertText.py -replacefile %tmpf0% -function focus')
_.appInfo[focus()]['examples'].append('')
_.appInfo[focus()]['examples'].append('p f -in *.py + "def focus" -jn | p replaceFunction -replacefile %tmpf0% -function focus')
_.appInfo[focus()]['examples'].append('')

# _.appInfo[focus()]['columns'].append({'name': 'name', 'abbreviation': 'n'})

def registerSwitches( argvProcessForce=False ):
	global appDBA
	if not __.appReg == appDBA and appDBA in __.appReg:

		if not __name__ == '__main__':
			_.argvProcess = argvProcessForce
		else:
			_.argvProcess = True

		_.load()
		_.appInfo[__.appReg] = _.appInfo[appDBA]
		_.appData[__.appReg] = _.appData[appDBA]
	__.constructRegistration(_.appInfo[__.appReg]['file'],__.appReg)
	appSwitches()
	_.defaultScriptTriggers()

	_.switches.trigger('Input',_.myFileLocations)
		# trigger settings
	_.myFileLocation_Print = False

	# _.switches.trigger('Watched', _.txt2Date)
	# _.switches.trigger('Input',_.formatColumns)
	_.switches.process()

if not __name__ == '__main__':
	_.argvProcess = False
else:
	_.argvProcess = True

registerSwitches()

def fieldSet( switchName, switchField, switchValue, theFocus=False ):
	if not type( theFocus ) == bool:
		theFocus = theFocus
	_.switches.fieldSet( switchName, switchField, switchValue, theFocus )

def setPipeData(data):
	# _.appData[__.appReg]['pipe'] = list(data)
	if len(data) > 0:
		_.appData[__.appReg]['pipe'] = []
		for pd in data:
			pd = pd.replace('\n','')
			if not pd == '':
				_.appData[__.appReg]['pipe'].append(pd)

def pipeCleaner():
	if len( _.appData[__.appReg]['pipe'] ):
		if type( _.appData[__.appReg]['pipe'][0] ) == str:
			if not _.appData[__.appReg]['pipe'][0][0] in _str.safeChar:
				_.appData[__.appReg]['pipe'][0] = _.appData[__.appReg]['pipe'][0][1:]
			for i,pipeData in enumerate(_.appData[__.appReg]['pipe']):
				_.appData[__.appReg]['pipe'][i] = _.appData[__.appReg]['pipe'][i].replace('\n','')

_.appData[__.appReg]['pipe'] = False
if not sys.stdin.isatty():
	setPipeData( sys.stdin.readlines() )
	# _.appData[__.appReg]['pipe'] = sys.stdin.readlines()
	# pipeCleaner()

########################################################################################

########################################################################################
########################################################################################
# START

fileBackup = _.regImp( __.appReg, 'fileBackup' )
# fileBackup.switch( 'Silent' )
fileBackup.switch( 'isRunOnce' )
fileBackup.switch( 'DoNotSchedule' )

functionName = ''
replaceText = ''
def action():
	global functionName
	global replaceText

	# _.pr( _.switches.value('Input') )
	shouldRun = False

	if _.switches.isActive('Function'):
		shouldRun = True
		functionName = _.ci(_.switches.value('Function'))
		functionName = _str.cleanBE( functionName, ' ' )

	if _.switches.isActive('ReplaceFile'):
		if not os.path.isfile( _.switches.value('ReplaceFile') ):
			_.pr( 'Error: ReplaceFile' )
			sys.exit()
		else:
			shouldRun = True
			replaceText = _.getText( _.switches.value('ReplaceFile'), True )

	if len(functionName) == 0:
		confirm = input('Insert blank, run? ')
		if not 'y' in confirm.lower():
			sys.exit()

	if not shouldRun:
		_.pr( 'Error: Bad switch 1' )
		sys.exit()

	if not type( _.appData[__.appReg]['pipe'] ) == bool or _.switches.isActive('Input') and os.path.isfile( _.switches.value('Input') ):
		if type( _.appData[__.appReg]['pipe'] ) == bool:
			_.appData[__.appReg]['pipe'] = []
			_.appData[__.appReg]['pipe'].append( _.switches.value('Input') )

		files = _.appData[__.appReg]['pipe']
		for filename in files:
			if os.path.isfile( filename ):
				processFile(filename)
	else:
		_.pr( 'Error: No Files' )
		sys.exit()

def getTabs( line ):
	pre = ''
	for ch in str(line):
		if ch == ' ' or ch == '\t':
			pre += ch
		else:
			return pre
	return pre

def processFile( filename ):
	global functionName
	global replaceText
	replaceText = replaceText.replace( ';n', _v.slash+'n' )
	_.pr()
	_.pr('processing:', filename)
	fileBackup.switch( 'Input', filename )
	fileBackup.switch( 'Flag', 'pre replaceFunction' )
	recoveryFile = fileBackup.do( 'action' )

	file = _.getText( filename )

	newFile = []
	rows = []
	found = False
	done = False
	ri = 0
	noSpace = []
	blank = []
	comment_blank = []
	omit = []
	hasText = []

	for i,line in enumerate(file):
		line = line.replace( '\n', '' )
		blnk = line.replace( '\t', '' ).replace( ' ', '' )
		if blnk == '':
			comment_blank.append( i )
		else:
			if blnk.startswith( '#' ):
				comment_blank.append( i )
			elif not line[0] == ' ' and not line[0] == '\t':
				noSpace.append( i )

			if not blnk.startswith( '#' ):
				hasText.append( i )

	for i,line in enumerate(file):
		line = line.replace( '\n', '' )

		if line.startswith( 'def ' + functionName + '(' ):

			# for newline in replaceText:
			#     newFile.append( newline.replace( '\n', '' ) )

			newFile.append( replaceText )

			x = i
			xx = i

			loop = True
			while loop:
				xx+=1
				if xx in noSpace:
					xx-=1
					loop = False

			loop = True
			while loop:
				if xx in hasText:
					# _.pr( 'h', file[xx] )
					loop = False
					# xx+=1
				# elif xx in comment_blank:
					# _.pr( 'c', file[xx] )
					# loop = False
				else:
					xx-=1
			y = i
			while not y > xx:
				omit.append( y )
				y+=1

		if not i in omit:
			newFile.append( line )

	_.saveText( newFile, filename )

	fileBackup.switch( 'Input', filename )
	fileBackup.switch( 'Flag', 'replaceFunction' )
	recoveryFile = fileBackup.do( 'action' )

	if _.switches.isActive('Input'):

		keep=input('Keep changes? ')
		if 'n' in keep.lower():
			try:
				copyfile(recoveryFile, filename)
				_.pr( 'Undo successful' )
			except Exception as e:
				_.pr( 'Undo fail' )

########################################################################################
if __name__ == '__main__':
	action()


#-*- coding:utf8 -*-

"""
为show global status 中的statu提供一个与之对应的类，以方便使用
"""

from .base import StatuBase

class AbortedClients(StatuBase):
    """
    The number of connections that were aborted because the client died without closing the connection properly.
    """
    statu_name="Aborted_clients"
    statu_type="intger"

class AbortedConnects(StatuBase):
    """
    The number of failed attempts to connect to the MySQL server
    """
    statu_name="Aborted_connects"
    statu_type="intger"

class BinlogCacheDiskUse(StatuBase):
    """
    The number of transactions that used the temporary binary log cache but that exceeded the value of binlog_cache_size and used a temporary file to store statements from the transaction.
    The number of nontransactional statements that caused the binary log transaction cache to be written to disk is tracked separately in the Binlog_stmt_cache_disk_use status variable.
    """
    statu_name="Binlog_cache_disk_use"
    statu_type="intger"

class BinlogCacheUse(StatuBase):
    """
    The number of transactions that used the binary log cache.
    """
    statu_name="Binlog_cache_use"
    statu_type="intger"

class BinlogStmtCacheDiskUse(StatuBase):
    """
    The number of nontransaction statements that used the binary log statement cache but that exceeded the value of binlog_stmt_cache_size and used a temporary file to store those statements.
    """
    statu_name="Binlog_stmt_cache_disk_use"
    statu_type="intger"

class BinlogStmtCacheUse(StatuBase):
    """
    The number of nontransactional statements that used the binary log statement cache.
    """
    statu_name="Binlog_stmt_cache_use"
    statu_type="intger"

class BytesReceived(StatuBase):
    """
    The number of bytes received from all clients.
    """
    statu_name="Bytes_received"
    statu_type="byte"

class BytesSent(StatuBase):
    """
    The number of bytes sent to all clients.
    """
    statu_name="Bytes_sent"
    statu_type="byte"

class ComBegin(StatuBase):
    statu_name="Com_begin"

class ComCallProcedure(StatuBase):
    statu_name="Com_call_procedure"

class ComChangeMaster(StatuBase):
    statu_name="Com_change_master"

class ComCommit(StatuBase):
    statu_name="Com_commit"

class ComDelete(StatuBase):
    statu_name="Com_delete"

class ComDeleteMulti(StatuBase):
    statu_name="Com_delete_multi"

class ComInsert(StatuBase):
    statu_name="Com_insert"

class ComInsertSelect(StatuBase):
    statu_name="Com_insert_select"

class ComSelect(StatuBase):
    statu_name="Com_select"

class SelectFullJoin(StatuBase):
    """The number of joins that perform table scans because they do not use indexes.
    If this value is not 0, you should carefully check the indexes of your tables.
    """
    statu_name="Select_full_join"

class SelectFullRangeJoin(StatuBase):
    """The number of joins that used a range search on a reference table.
    """
    statu_name="Select_full_range_join"

class SelectRange(StatuBase):
    """The number of joins that used ranges on the first table. This is normally not a critical issue even if the value is quite large.
    """
    statu_name="Select_range"

class SelectRangeCheck(StatuBase):
    """The number of joins without keys that check for key usage after each row.
    If this is not 0, you should carefully check the indexes of your tables.
    """
    statu_name="Select_range_check"

class SelectScan(StatuBase):
    """The number of joins that did a full scan of the first table.
    """
    statu_name="Select_scan"

class ComUpdate(StatuBase):
    statu_name="Com_update"

class ComUpdateMulti(StatuBase):
    statu_name="Com_update_multi"

class Connections(StatuBase):
    """
    通过mysql-connector每获取一次这个值，这个值都会加1，这个返回与命令行执行得到的结果不同。
    """
    statu_name="Connections"
    statu_type="intger"

class CreatedTmpDiskTables(StatuBase):
    """
    The number of internal on-disk temporary tables created by the server while executing statements.
    If an internal temporary table is created initially as an in-memory table but becomes too large,
    MySQL automatically converts it to an on-disk table. The maximum size for in-memory temporary tables is the minimum
    of the tmp_table_size and max_heap_table_size values. If Created_tmp_disk_tables is large, you may want to increase
    the tmp_table_size or max_heap_table_size value to lessen the likelihood that internal temporary tables in memory will be
    converted to on-disk tables.You can compare the number of internal on-disk temporary tables created
    to the total number of internal temporary tables created by comparing the values of the Created_tmp_disk_tables and Created_tmp_tables variables.
    """
    statu_name="Created_tmp_disk_tables"

class CreatedTmpFiles(StatuBase):
    statu_name="Created_tmp_files"

class CreatedTmpTables(StatuBase):
    """
    The number of internal temporary tables created by the server while executing statements.
    You can compare the number of internal on-disk temporary tables created to the total number of internal temporary tables created by comparing the values of the Created_tmp_disk_tables and Created_tmp_tables variables.
    See also Section 8.4.4, “Internal Temporary Table Use in MySQL”.
    Each invocation of the SHOW STATUS statement uses an internal temporary table and increments
    the global Created_tmp_tables value.
    """
    statu_name="Created_tmp_tables"

class InnodbBufferPoolDumpStatus(StatuBase):
    statu_name="Innodb_buffer_pool_dump_status"
    statu_type="string"

class InnodbBufferPoolLoadStatus(StatuBase):
    statu_name="Innodb_buffer_pool_load_status"
    statu_type="string"

class InnodbBufferPoolResizeStatus(StatuBase):
    statu_name="Innodb_buffer_pool_resize_status"
    statu_type="string"

class InnodbBufferPoolBytesData(StatuBase):
    """
    The total number of bytes in the InnoDB buffer pool containing data.
    The number includes both dirty and clean pages.
    For more accurate memory usage calculations than with Innodb_buffer_pool_pages_data,
    when compressed tables cause the buffer pool to hold pages of different sizes.
    """
    statu_name="Innodb_buffer_pool_bytes_data"
    statu_type="byte"

class InnodbBufferPoolPagesData(StatuBase):
    """
    The number of pages in the InnoDB buffer pool containing data.
    The number includes both dirty and clean pages. When using compressed tables,
    the reported Innodb_buffer_pool_pages_data value may be larger than Innodb_buffer_pool_pages_total (Bug #59550).
    """
    statu_name="Innodb_buffer_pool_pages_data"

class InnodbBufferPoolPagesDirty(StatuBase):
    """
    The total current number of bytes held in dirty pages in the InnoDB buffer pool.
    For more accurate memory usage calculations than with Innodb_buffer_pool_pages_dirty,
    when compressed tables cause the buffer pool to hold pages of different sizes.
    """
    statu_name="Innodb_buffer_pool_pages_dirty"

class InnodbBufferPoolBytesDirty(StatuBase):
    """
    The current number of dirty pages in the InnoDB buffer pool.
    """
    statu_name="Innodb_buffer_pool_bytes_dirty"
    statu_type="byte"

class InnodbBufferPoolPagesFlushed(StatuBase):
    """
    The number of requests to flush pages from the InnoDB buffer pool.
    """
    statu_name="Innodb_buffer_pool_pages_flushed"

class InnodbBufferPoolPagesFree(StatuBase):
    """
    The number of free pages in the InnoDB buffer pool.
    """
    statu_name="Innodb_buffer_pool_pages_free"

class InnodbBufferPoolPagesMisc(StatuBase):
    """
    The number of pages in the InnoDB buffer pool that are busy because they have
    been allocated for administrative overhead, such as row locks or the adaptive hash
    index. This value can also be calculated as
    Innodb_buffer_pool_pages_total − Innodb_buffer_pool_pages_free − Innodb_buffer_pool_pages_data.
    When using compressed tables, Innodb_buffer_pool_pages_misc may report an out-of-bounds value (Bug #59550).
    """
    statu_name="Innodb_buffer_pool_pages_misc"

class InnodbBufferPoolPagesTotal(StatuBase):
    """
    The total size of the InnoDB buffer pool, in pages. When using compressed tables,
    the reported Innodb_buffer_pool_pages_data value may be larger
    than Innodb_buffer_pool_pages_total (Bug #59550)
    """
    statu_name="Innodb_buffer_pool_pages_total"

class InnodbBufferPoolReadAhead(StatuBase):
    """
    The number of pages read into the InnoDB buffer pool by the read-ahead background thread.
    """
    statu_name="Innodb_buffer_pool_read_ahead"

class InnodbBufferPoolReadAheadEvicted(StatuBase):
    """
    The number of pages read into the InnoDB buffer pool by the read-ahead background thread
    that were subsequently evicted without having been accessed by queries.
    """
    statu_name="Innodb_buffer_pool_read_ahead_evicted"

class InnodbBufferPoolReadRequests(StatuBase):
    """
    The number of logical read requests.
    """
    statu_name="Innodb_buffer_pool_read_requests"

class InnodbBufferPoolReads(StatuBase):
    """
    The number of logical reads that InnoDB could not satisfy from the buffer pool,
    and had to read directly from disk.
    """
    statu_name="Innodb_buffer_pool_reads"

class InnodbBufferPoolWaitFree(StatuBase):
    """
    Normally, writes to the InnoDB buffer pool happen in the background.
    When InnoDB needs to read or create a page and no clean pages are available,
    InnoDB flushes some dirty pages first and waits for that operation to finish.
    This counter counts instances of these waits. If innodb_buffer_pool_size has been set properly,
    this value should be small.
    """
    statu_name="Innodb_buffer_pool_wait_free"

class InnodbBufferPoolWriteRequests(StatuBase):
    """
    The number of writes done to the InnoDB buffer pool.
    """
    statu_name="Innodb_buffer_pool_write_requests"

class InnodbDataFsyncs(StatuBase):
    """
    The number of fsync() operations so far. The frequency of fsync() calls is influenced by the
    setting of the innodb_flush_method configuration option.
    """
    statu_name="Innodb_data_fsyncs"

class InnodbDataPendingFsyncs(StatuBase):
    """
    The current number of pending fsync() operations. The frequency of fsync() calls is influenced
    by the setting of the innodb_flush_method configuration option.
    """
    statu_name="Innodb_data_pending_fsyncs"

class InnodbDataPendingReads(StatuBase):
    """
    The current number of pending reads.
    """
    statu_name="Innodb_data_pending_reads"

class InnodbDataPendingWrites(StatuBase):
    """
    The current number of pending writes.
    """
    statu_name="Innodb_data_pending_writes"

class InnodbDataRead(StatuBase):
    """
    The amount of data read since the server was started (in bytes).
    """
    statu_name="Innodb_data_read"
    statu_type="byte"

class InnodbDataReads(StatuBase):
    """
    The total number of data reads (OS file reads).
    """
    statu_name="Innodb_data_reads"

class InnodbDataWrites(StatuBase):
    """
    The total number of data writes.
    """
    statu_name="Innodb_data_writes"

class InnodbDataWritten(StatuBase):
    """
    The amount of data written so far, in bytes.
    """
    statu_name="Innodb_data_written"
    statu_type="byte"

class InnodbDblwrPagesWritten(StatuBase):
    """
    The number of pages that have been written to the doublewrite buffer. See Section 14.12.1, “InnoDB Disk I/O”.
    """
    statu_name="Innodb_dblwr_pages_written"

class InnodbDblwrWrites(StatuBase):
    """
    The number of doublewrite operations that have been performed. See Section 14.12.1,
    “InnoDB DiskI/O”.
    """
    statu_name="Innodb_dblwr_writes"

class InnodbLogWaits(StatuBase):
    """
    The number of times that the log buffer was too small and a wait was required for it to be flushed before continuing.
    """
    statu_name="Innodb_log_waits"

class InnodbLogWriteRequests(StatuBase):
    """
    The number of write requests for the InnoDB redo log.
    """
    statu_name="Innodb_log_write_requests"

class InnodbLogWrites(StatuBase):
    """
    The number of physical writes to the InnoDB redo log file.
    """
    statu_name="Innodb_log_writes"

class InnodbOsLogFsyncs(StatuBase):
    """
    The number of fsync() writes done to the InnoDB redo log files.
    """
    statu_name="Innodb_os_log_fsyncs"

class InnodbOsLogPendingFsyncs(StatuBase):
    """
    The number of pending fsync() operations for the InnoDB redo log files.
    """
    statu_name="Innodb_os_log_pending_fsyncs"

class InnodbOsLogPendingWrites(StatuBase):
    """
    The number of pending writes to the InnoDB redo log files.
    """
    statu_name="Innodb_os_log_pending_writes"

class InnodbOsLogWritten(StatuBase):
    """
    The number of bytes written to the InnoDB redo log files.
    """
    statu_name="Innodb_os_log_written"

class InnodbPagesCreated(StatuBase):
    """
    The number of pages created by operations on InnoDB tables.
    """
    statu_name="Innodb_pages_created"

class InnodbPagesRead(StatuBase):
    """
    The number of pages read from the InnoDB buffer pool by operations on InnoDB tables.
    """
    statu_name="Innodb_pages_read"

class InnodbPagesWritten(StatuBase):
    """
    The number of pages written by operations on InnoDB tables.
    """
    statu_name="Innodb_pages_written"

class InnodbRowLockCurrentWaits(StatuBase):
    """
    The number of row locks currently being waited for by operations on InnoDB tables.
    """
    statu_name="Innodb_row_lock_current_waits"

class InnodbRowLockTime(StatuBase):
    """
    The total time spent in acquiring row locks for InnoDB tables, in milliseconds.
    """
    statu_name="Innodb_row_lock_time"

class InnodbRowLockTimeAvg(StatuBase):
    """
    The average time to acquire a row lock for InnoDB tables, in milliseconds.
    """
    statu_name="Innodb_row_lock_time_avg"

class InnodbRowLockTimeMax(StatuBase):
    """
    The maximum time to acquire a row lock for InnoDB tables, in milliseconds.
    """
    statu_name="Innodb_row_lock_time_max"

class InnodbRowLockWaits(StatuBase):
    """
    The number of times operations on InnoDB tables had to wait for a row lock.
    """
    statu_name="Innodb_row_lock_waits"

class InnodbRowsDeleted(StatuBase):
    """
    The number of rows deleted from InnoDB tables.
    """
    statu_name="Innodb_rows_deleted"

class InnodbRowsInserted(StatuBase):
    """
    The number of rows inserted into InnoDB tables.
    """
    statu_name="Innodb_rows_inserted"

class InnodbRowsRead(StatuBase):
    """
    The number of rows read from InnoDB tables.
    """
    statu_name="Innodb_rows_read"

class InnodbRowsUpdated(StatuBase):
    """
    The number of rows updated in InnoDB tables.
    """
    statu_name="Innodb_rows_updated"

class InnodbAvailableUndoLogs(StatuBase):
    """
    The number of times output from the SHOW ENGINE INNODB STATUS statement has been truncated.
    """
    statu_name="Innodb_available_undo_logs"

class OpenTableDefinitions(StatuBase):
    """
    The number of cached .frm files.
    """
    statu_name="Open_table_definitions"

class OpenTables(StatuBase):
    """
    The number of tables that are open.
    """
    statu_name="Open_tables"

class OpenedTableDefinitions(StatuBase):
    """
    The number of .frm files that have been cached.
    """
    statu_name="Opened_table_definitions"

class OpenedTables(StatuBase):
    """
    The number of tables that have been opened. If Opened_tables is big, your table_open_cache
    value is probably too small.
    """
    statu_name="Opened_Tables"

class TableOpenCacheOverflows(StatuBase):
    """
    The number of overflows for the open tables cache. This is the number of times,
    after a table is opened or closed, a cache instance has an unused entry and the size of the instance is larger
    than table_open_cache / table_open_cache_instances.
    """
    statu_name="Table_open_cache_overflows"

class ThreadsCached(StatuBase):
    """
    The number of threads in the thread cache.
    """
    statu_name="Threads_cached"

class ThreadsConnected(StatuBase):
    """
    The number of currently open connections.
    """
    statu_name="Threads_connected"

class ThreadsCreated(StatuBase):
    """
    The number of threads created to handle connections. If Threads_created is big,
    you may want to increase the thread_cache_size value. The cache miss rate can be calculated
    as Threads_created/Connections.
    """
    statu_name="Threads_created"

class ThreadsRunning(StatuBase):
    """
    The number of threads that are not sleeping.
    """
    statu_name="Threads_running"

class Uptime(StatuBase):
    """
    The number of seconds that the server has been up.
    """
    statu_name="Uptime"


import sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Font size and .tex background
params = {'text.usetex' : True,
          'font.size' : 15,
          'font.family' : 'lmodern'
          }
plt.rcParams.update(params)
fig = plt.figure()

# Find the experiment type
experiment_type = sys.argv[1]

truth = pd.read_csv('experiment-full/true-sin-wave.txt', delimiter=',').to_numpy()
param1 = pd.read_csv('experiment-full/sinwave-5.txt', delimiter=',').to_numpy()[:, 0]
param2 = pd.read_csv('experiment-full/sinwave-6.txt', delimiter=',').to_numpy()[:, 0]
param3 = pd.read_csv('experiment-full/sinwave-7.txt', delimiter=',').to_numpy()[:, 0]
param4 = pd.read_csv('experiment-full/sinwave-8.txt', delimiter=',').to_numpy()[:, 0]
param5 = pd.read_csv('experiment-full/sinwave-100.txt', delimiter=',').to_numpy()[:, 0]

data = np.array([param5, param1, param2, param3, param4])
#parameters = [ 0.001, 0.005, 0.05, 0.08 ]
parameters = [100, 500, 1000, 2000, 3000]
#parameters = [0.01, 0.02, 0.06, 0.1]
color_palette = ['royalblue', 'darkorange', 'crimson', 'limegreen', 'cyan']
xs = np.linspace(0, 900, len(truth))

for i in range(len(data)):
    plt.plot(xs, data[i], label='{} = {}'.format(experiment_type, parameters[i]), alpha=0.7, c=color_palette[i])

plt.plot(xs, truth[:, 0], label="Ground Truth", color='black', linewidth=2.0)

plt.ylabel('X-coordinate')
plt.xlabel('Time [s]')
plt.xlim(left=0)
plt.ylim(bottom=min(data.flatten()))
plt.title('True Movement vs. Predicted Movement Along X-Axis')
plt.legend(loc=2, prop={'size': 12})

# Save the file
fig.set_size_inches(7.2, 5)
plt.savefig('report-plots/svg/sinwave-{experiment}.svg'.format(experiment=experiment_type), dpi=1000, bbox_inches='tight')
plt.show()


"""
Character LSTM implementation (matches https://arxiv.org/pdf/1805.01052.pdf)
"""

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

class CharacterLSTM(nn.Module):
    def __init__(self, num_embeddings, d_embedding, d_out, char_dropout=0.0, **kwargs):
        super().__init__()

        self.d_embedding = d_embedding
        self.d_out = d_out

        self.lstm = nn.LSTM(
            self.d_embedding, self.d_out // 2, num_layers=1, bidirectional=True
        )

        self.emb = nn.Embedding(num_embeddings, self.d_embedding, **kwargs)
        self.char_dropout = nn.Dropout(char_dropout)

    def forward(self, chars_packed, valid_token_mask):
        inp_embs = nn.utils.rnn.PackedSequence(
            self.char_dropout(self.emb(chars_packed.data)),
            batch_sizes=chars_packed.batch_sizes,
            sorted_indices=chars_packed.sorted_indices,
            unsorted_indices=chars_packed.unsorted_indices,
        )

        _, (lstm_out, _) = self.lstm(inp_embs)
        lstm_out = torch.cat([lstm_out[0], lstm_out[1]], -1)

        # Switch to a representation where there are dummy vectors for invalid
        # tokens generated by padding.
        res = lstm_out.new_zeros(
            (valid_token_mask.shape[0], valid_token_mask.shape[1], lstm_out.shape[-1])
        )
        res[valid_token_mask] = lstm_out
        return res

class RetokenizerForCharLSTM:
    # Assumes that these control characters are not present in treebank text
    CHAR_UNK = "\0"
    CHAR_ID_UNK = 0
    CHAR_START_SENTENCE = "\1"
    CHAR_START_WORD = "\2"
    CHAR_STOP_WORD = "\3"
    CHAR_STOP_SENTENCE = "\4"

    def __init__(self, char_vocab):
        self.char_vocab = char_vocab

    @classmethod
    def build_vocab(cls, sentences):
        char_set = set()
        for sentence in sentences:
            if isinstance(sentence, tuple):
                sentence = sentence[0]
            for word in sentence:
                char_set |= set(word)

        # If codepoints are small (e.g. Latin alphabet), index by codepoint
        # directly
        highest_codepoint = max(ord(char) for char in char_set)
        if highest_codepoint < 512:
            if highest_codepoint < 256:
                highest_codepoint = 256
            else:
                highest_codepoint = 512

            char_vocab = {}
            # This also takes care of constants like CHAR_UNK, etc.
            for codepoint in range(highest_codepoint):
                char_vocab[chr(codepoint)] = codepoint
            return char_vocab
        else:
            char_vocab = {}
            char_vocab[cls.CHAR_UNK] = 0
            char_vocab[cls.CHAR_START_SENTENCE] = 1
            char_vocab[cls.CHAR_START_WORD] = 2
            char_vocab[cls.CHAR_STOP_WORD] = 3
            char_vocab[cls.CHAR_STOP_SENTENCE] = 4
            for id_, char in enumerate(sorted(char_set), start=5):
                char_vocab[char] = id_
            return char_vocab

    def __call__(self, words, space_after="ignored", return_tensors=None):
        if return_tensors != "np":
            raise NotImplementedError("Only return_tensors='np' is supported.")

        res = {}

        # Sentence-level start/stop tokens are encoded as 3 pseudo-chars
        # Within each word, account for 2 start/stop characters
        max_word_len = max(3, max(len(word) for word in words)) + 2
        char_ids = np.zeros((len(words) + 2, max_word_len), dtype=int)
        word_lens = np.zeros(len(words) + 2, dtype=int)

        char_ids[0, :5] = [
            self.char_vocab[self.CHAR_START_WORD],
            self.char_vocab[self.CHAR_START_SENTENCE],
            self.char_vocab[self.CHAR_START_SENTENCE],
            self.char_vocab[self.CHAR_START_SENTENCE],
            self.char_vocab[self.CHAR_STOP_WORD],
        ]
        word_lens[0] = 5
        for i, word in enumerate(words, start=1):
            char_ids[i, 0] = self.char_vocab[self.CHAR_START_WORD]
            for j, char in enumerate(word, start=1):
                char_ids[i, j] = self.char_vocab.get(char, self.CHAR_ID_UNK)
            char_ids[i, j + 1] = self.char_vocab[self.CHAR_STOP_WORD]
            word_lens[i] = j + 2
        char_ids[i + 1, :5] = [
            self.char_vocab[self.CHAR_START_WORD],
            self.char_vocab[self.CHAR_STOP_SENTENCE],
            self.char_vocab[self.CHAR_STOP_SENTENCE],
            self.char_vocab[self.CHAR_STOP_SENTENCE],
            self.char_vocab[self.CHAR_STOP_WORD],
        ]
        word_lens[i + 1] = 5

        res["char_ids"] = char_ids
        res["word_lens"] = word_lens
        res["valid_token_mask"] = np.ones_like(word_lens, dtype=bool)

        return res

    def pad(self, examples, return_tensors=None):
        if return_tensors != "pt":
            raise NotImplementedError("Only return_tensors='pt' is supported.")
        max_word_len = max(example["char_ids"].shape[-1] for example in examples)
        char_ids = torch.cat(
            [
                F.pad(
                    torch.tensor(example["char_ids"]),
                    (0, max_word_len - example["char_ids"].shape[-1]),
                )
                for example in examples
            ]
        )
        word_lens = torch.cat(
            [torch.tensor(example["word_lens"]) for example in examples]
        )
        valid_token_mask = nn.utils.rnn.pad_sequence(
            [torch.tensor(example["valid_token_mask"]) for example in examples],
            batch_first=True,
            padding_value=False,
        )

        char_ids = nn.utils.rnn.pack_padded_sequence(
            char_ids, word_lens, batch_first=True, enforce_sorted=False
        )
        return {
            "char_ids": char_ids,
            "valid_token_mask": valid_token_mask,
        }


"""
@作者: egon老湿
@微信:18611453110
@专栏: https://zhuanlan.zhihu.com/c_1189883314197168128
"""
# 如何得到自定义的迭代器：
# 在函数内一旦存在yield关键字，调用函数并不会执行函数体代码
# 会返回一个生成器对象，生成器即自定义的迭代器
def func():
    print('第一次')
    yield 1
    print('第二次')
    yield 2
    print('第三次')
    yield 3
    print('第四次')

# g=func()
# print(g)
# 生成器就是迭代器
# g.__iter__()
# g.__next__()

# 会触发函数体代码的运行，然后遇到yield停下来，将yield后的值
# 当做本次调用的结果返回
# res1=g.__next__()
# print(res1)
#
#
# res2=g.__next__()
# print(res2)
#
# res3=g.__next__()
# print(res3)
#
# res4=g.__next__()

# len('aaa') # 'aaa'.__len__()

# next(g)    # g.__next__()
# iter(可迭代对象)     # 可迭代对象.__iter__()

# 应用案列
def my_range(start,stop,step=1):
    # print('start...')
    while start < stop:
        yield start
        start+=step
    # print('end....')

# g=my_range(1,5,2) # 1 3
# print(next(g))
# print(next(g))
# print(next(g))

for n in my_range(1,7,2):
    print(n)

# 总结yield：
# 有了yield关键字，我们就有了一种自定义迭代器的实现方式。yield可以用于返回值，但不同于return，函数一旦遇到return就结束了，而yield可以保存函数的运行状态挂起函数，用来返回多次值

2函数和模块/函数编程纯小白都能学会/day18-生成器/代码/04 生成器.py


import sys, os
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),os.path.pardir))
from .dependencies import *
from .draw_figure import figure
import numpy as np
from .adjust_plots import set_plot

###########################################################
######  Histogram
###########################################################

def hist(graph,
         x, bins=20, ax=None,
         orientation='horizontal',
         edgecolor='k', facecolor='lightgray',
         c=None,
         lw=0.3,
         xlabel='', ylabel='count', title='',
         normed=False,
         fig_args={}, axes_args={}):

    hist, be = np.histogram(x, bins=bins, density=normed)

    if c is not None:
        facecolor = c
        lw = 0

    if ax is None:
        fig, ax = graph.figure(**fig_args)
    else:
        fig = plt.gcf()

    if orientation=='vertical':
        ax.barh(.5*(be[1:]+be[:-1]), hist, height=be[1]-be[0],
                edgecolor=edgecolor, facecolor=facecolor, lw=lw)
    elif orientation=='horizontal':
        ax.bar(.5*(be[1:]+be[:-1]), hist, width=be[1]-be[0],
                edgecolor=edgecolor, facecolor=facecolor, lw=lw)

    if 'xlabel' not in axes_args:
        axes_args['xlabel'] = xlabel
    if 'ylabel' not in axes_args:
        axes_args['ylabel'] = ylabel

    graph.set_plot(ax, **axes_args)
    if title!='':
        graph.title(ax, title)

    return fig, ax

if __name__=='__main__':

    from .my_graph import graphs
    mg = graphs('screen')
    fig, ax = hist(mg, np.random.randn(100), xlabel='some value')
    mg.show()


"contains class for persons"
#--------------------------------------------------------------------------------------------------#
import logging
import math
import time
import person

class Group:
    "class for handling a crowd of persons"
    def __init__(self):
        self.person_instances = []
        self.logger = logging.getLogger('training_logger')
        self.person_counter = 0

    def next_frame_aging(self, frame_count):
        "ages each person by one and de-lists 'done' persons"
        persons_temp =[]
        for person_instance in self.person_instances:
            person_instance.age_one(frame_count)  # age every person each frame
            if person_instance.done is False:
                persons_temp.append(person_instance)
                self.logger.debug('next_frame_aging(): person_id %s was aged by one, but is not '\
                    'too old, i.e. is still part of person_instances', person_instance.person_id)
        self.person_instances = persons_temp

    def get_closest_person(self, contour_centroid_xt_new, contour_centroid_yt_new):
        "selects the closest person. This is algorithm can still be improved on: Think of a "\
        "situation where two centroids are to be matched to two persons. both are within the "\
        "new_person_x_thresholds, but the one that is closest to person 1 should actually be "\
        "fitted to person 2, and the valid 'leftover' centroid, should be assigend to person 1"
        distances = []
        closest_person_id = None
        # sort persons by age, look which contours are within their new_person_thresholds and
        # assign the cluster to this person
        for person_instance in self.person_instances:
            person_instance_distance = math.sqrt(\
                (person_instance.contour_centroid_xt - contour_centroid_xt_new)**2
                + (person_instance.contour_centroid_yt - contour_centroid_yt_new)**2
            )
            # introduce additional pull if person is of age
            person_instance_distance =max(0, person_instance_distance \
                - min(person_instance.age * 2, 75))
            distances.append((person_instance.person_id, person_instance_distance))
        try:
            closest_person_id = min(distances, key = lambda t: t[1])[0]
        except ValueError:
            pass

        self.logger.debug("closest person to contour centroids (%s,%s) is personID %s "\
            ,  contour_centroid_xt_new, contour_centroid_yt_new, closest_person_id)
        return closest_person_id

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

    def calculate_cluster_person_distance_list(self, cluster_instances, parameter_space_instance):
        """calculates distances from clusters to persons. If no person is in reach, a new person is
        created and assigned"""
        self.logger.debug("calculate_cluster_person_distance_list(): creating"\
            "cluster_person_distance_list...")
        cluster_person_distance_list = []
        for cluster_instance in cluster_instances:
            one_person_within_threshold = False

            for person_instance in self.person_instances:
                distance = int(math.sqrt(\
                    (person_instance.contour_centroid_xt - cluster_instance.centroid_x)**2
                    + (person_instance.contour_centroid_yt - cluster_instance.centroid_y)**2))
                self.logger.debug("calculate_cluster_person_distance_list(): person_instance"\
                    ".person_id %s and cluster_instance.cluster_id %s have distance %s"\
                    , person_instance.person_id, cluster_instance.cluster_id, distance)
                if distance < parameter_space_instance.new_person_horizontal_threshold:
                    cluster_person_distance_list.append([ cluster_instance.cluster_id\
                        , person_instance.person_id, distance])
                    self.logger.debug("calculate_cluster_person_distance_list(): appended to "\
                        "cluster_person_distance_list: %s, %s, %s "\
                        , person_instance.person_id, cluster_instance.cluster_id, distance)
                    one_person_within_threshold = True

            if one_person_within_threshold is False:
                person_instance = person.MyPerson(self.person_counter\
                    , cluster_instance.centroid_x, cluster_instance.centroid_y\
                    , parameter_space_instance.person_age_threshold)
                self.logger.debug("calculate_cluster_person_distance_list(): no existing person in"\
                    "reach, created a new person: person_counter %s, cluster_id %s,  y %s, x %s"\
                    , str(self.person_counter), str(cluster_instance.cluster_id)\
                    ,  str(cluster_instance.centroid_x), str(cluster_instance.centroid_y))
                self.person_instances.append(person_instance)
                self.person_counter += 1
                distance = 0
                cluster_person_distance_list.append([cluster_instance.cluster_id\
                    , person_instance.person_id, distance])

        return cluster_person_distance_list

    def person_to_cluster_assignment(self, cluster_person_distance_list):
        "resolves matching: every person to one contour within thresholds.For those with more than"\
        "one contour at choice, let persons with one choice choose first. then go through the"\
        "persons with more than one choice and assign the closest cluster form the clusters that"\
        " are still available "
        free_clusters_set = set([ x[0] for x in cluster_person_distance_list ])
        free_persons_set = set([ x[1] for x in cluster_person_distance_list ])
        person_to_cluster_assignmen_list = [] # reset person_to_cluster_assignment
        # first iteration:
        self.logger.debug("person_to_cluster_assignment(): free_clusters_set = %s "\
            ", free_persons_set = %s starting first iteration to assign clusters to persons..."\
            , free_clusters_set, free_persons_set)
        self.person_instances.sort(key=lambda x: x.age, reverse=False)
        for person_instance in self.person_instances:
            prospects = [ x for x in cluster_person_distance_list if x[1] \
                == person_instance.person_id]
            self.logger.debug("person_id %s has the following prospective clusters: %s" \
                ,person_instance.person_id, prospects)
            if len(prospects) == 1 and prospects[0][0] in free_clusters_set:
                person_to_cluster_assignmen_list.append([person_instance.person_id\
                    , prospects[0][0]])
                free_clusters_set.remove(prospects[0][0])
                free_persons_set.remove(prospects[0][1])
                self.logger.debug("cluster_id %s is assigned to person_id %s,because person_id has"\
                    "exactly one cluster in reach",  prospects[0][0], person_instance.person_id )

        self.logger.debug("lenth cluster_person_distance_list is %s before removing assinged "\
            "clusters", len(cluster_person_distance_list))
        cluster_person_distance_list_temp = []
        for item in cluster_person_distance_list:
            if item[0] in free_clusters_set and item[1] in free_persons_set:
                cluster_person_distance_list_temp.append(item)
        cluster_person_distance_list = cluster_person_distance_list_temp
        self.logger.debug("lenth cluster_person_distance_list is %s after removing assinged "\
            "clusters", len(cluster_person_distance_list))

        if len(cluster_person_distance_list) == 0:
            return person_to_cluster_assignmen_list

        # second iteration:
        self.logger.debug("starting second iteration to assign clusters to persons...")
        self.person_instances.sort(key=lambda x: x.age, reverse=False)
        for person_instance in self.person_instances:
            if person_instance.person_id in free_persons_set:
                prospects = [ x for x in cluster_person_distance_list if x[1] \
                    == person_instance.person_id]
                if len(prospects) == 0:
                    self.logger.debug("person_id %s has no prospects in second iteration. "\
                        "continuing to next person", person_instance.person_id)
                    continue
                self.logger.debug("person_id %s has the following prospects : %s (from "\
                    "cluster_person_distance_list)", person_instance.person_id, prospects)
                prospect_min = min(prospects, key = lambda t: t[2])
                self.logger.debug("person_id %s has the following min-prospect : %s (from "\
                    "cluster_person_distance_list)", person_instance.person_id, prospect_min)

                person_to_cluster_assignmen_list.append([person_instance.person_id\
                    , prospect_min[0]])
                free_clusters_set.remove(prospect_min[0])
                free_persons_set.remove(prospect_min[1])
                self.logger.debug("person_to_cluster_assignment(): free_clusters_set = %s, "\
                    "free_persons_set = %s in second iteration after removal"\
                    , free_clusters_set, free_persons_set)
                self.logger.debug("lenth cluster_person_distance_list is %s before removing "\
                    "assinged clusters", len(cluster_person_distance_list))
                cluster_person_distance_list_temp = []
                for item in cluster_person_distance_list:
                    if item[0] in free_clusters_set and item[1] in free_persons_set:
                        cluster_person_distance_list_temp.append(item)
                cluster_person_distance_list = cluster_person_distance_list_temp
                self.logger.debug("lenth cluster_person_distance_list is %s after removing "\
                    "assinged clusters", len(cluster_person_distance_list))

        # there can be person_instances without cluster, and also cluster without person instance.
        if len(free_clusters_set) > 0:
            self.logger.debug("clusters %s are unassigned after completion of assignment" \
                , free_clusters_set)
        return person_to_cluster_assignmen_list

    def runner2(self, cluster_instances, parameter_space_instance, ai_db,cnt_up, cnt_down\
        , frame_count):
        "makeover of the legendary runner "
        cluster_person_distance_list = self.calculate_cluster_person_distance_list(\
            cluster_instances, parameter_space_instance)
        person_to_cluster_assignmen_list = self.person_to_cluster_assignment(\
            cluster_person_distance_list)

        for person_cluster in person_to_cluster_assignmen_list:
            person_instance = [x for x in self.person_instances if x.person_id \
                == person_cluster[0]][0]
            cluster_instance = [x for x in cluster_instances if x.cluster_id \
                == person_cluster[1]][0]

            person_instance.update_coords(cluster_instance.centroid_x, cluster_instance.centroid_y)
            person_instance.update_age(parameter_space_instance.age_reset_down_thres\
                , parameter_space_instance.age_reset_up_thres)
            person_instance.update_thrust()

            self.logger.info("matched person to cluster: Person ID: %s | cluster_id %s | "\
                "frame_count %s | P(x/y): (%s / %s) | thrust_absolute: %s | thrust_binary %s | "\
                "age %s  ", str(person_instance.person_id), str(cluster_instance.cluster_id)\
                , str(frame_count), str(cluster_instance.centroid_x)\
                , str(cluster_instance.centroid_y)\
                , str(person_instance.thrust_absolute), str(person_instance.thrust_binary)\
                , str(person_instance.age))

            if person_instance.crossing_up(parameter_space_instance.thrust_abs_crossing_threshold\
                , parameter_space_instance.thrust_bin_crossing_threshold) is True:
                cnt_up += 1
                change_up_or_down = 1
                person_instance.has_crossed_up = True
                # reset thrust
                person_instance.thrust_absolute = 0
                person_instance.thrust_binary = 0

                #  write message into db
                capacity, latest_person_count, direction \
                    = ai_db.get_current_data()
                latest_person_count = max(latest_person_count \
                    + change_up_or_down * direction, 0)
                ai_db.set_current_data(capacity, latest_person_count, direction)

                # logging
                self.logger.info("ID: %s crossed going up at %s " \
                    , str(person_instance.get_id()), str(time.strftime("%c")))
                self.logger.debug("current person count: %s" \
                    ,  str(latest_person_count))
                #self.logger_reporting.info("%s;%s;",  str(change_up_or_down * direction) \
                #    ,str(latest_person_count) )

            if person_instance.crossing_down(parameter_space_instance.thrust_abs_crossing_threshold\
                , parameter_space_instance.thrust_bin_crossing_threshold) is True:
                cnt_down += 1
                change_up_or_down = -1
                person_instance.has_crossed_down = True
                # reset thrust
                person_instance.thrust_absolute = 0
                person_instance.thrust_binary = 0

                # write message into db
                capacity, latest_person_count, direction \
                    = ai_db.get_current_data()
                latest_person_count = max(latest_person_count \
                    + change_up_or_down * direction, 0)
                ai_db.set_current_data(capacity, latest_person_count, direction)

                #logging
                self.logger.info("ID: %s crossed going down at %s " \
                    , str(person_instance.get_id()), str(time.strftime("%c")))
                self.logger.debug("current person count: %s "\
                    , str(latest_person_count))
                #self.logger_reporting.info("%s;%s;", str(change_up_or_down * direction) \
                #    , str(latest_person_count))
        return cnt_up, cnt_down

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