# Задайте список.
# Напишите программу, которая определит, присутствует ли в заданном списке
# строк некое число.

num = 123
elem = [123, '234', 123, '567']

def check_number(num, elem):
    for e in elem:
        if e == num:
            return True

if check_number(num, elem):
    print(f'число {num} присутствует в списке')

else:
    print(f'числа {num} в списке нет')

# 2 var

list_ = ['qwe', '2,4', '3', '45']

def is_num(str_):
    if str_.count(',') > 1:
        return False
    elif str_.startswith(','):
        return False

    for i in str_:
        if not i in '0123456789,':
            return False
    return True

for i in list_:
    if is_num(i):
        print(i)


import graph as g
import aco

def main():
	# Data read
	points = g.dataRead() # Point is a list with 'Point' instances, and it represents all the points in the space.
	graph = g.buildGraph(points) # N is the index of the imaginary point
	g.calculateDensity(points, graph) # Each point has a density, based in the distance of the nearests neighbors.

	for t in range(1, aco.ITERATIONS + 1):
		p_medians = aco.chooseMedians(points, graph)
		aco.buildSolution(p_medians, points, graph)
		s_q = aco.solutionQuality(points, graph)
		aco.saveBestSolution(s_q, points, graph)
		aco.updatePheromones(s_q, p_medians, points, graph)
		aco.resetCapacity(points)

	aco.printBestSolution()

main()


import logging
from typing import List, Optional, Any

from pymongo import MongoClient
from pymongo.collection import Collection

from sched_slack_bot.data.schedule_access import ScheduleAccess
from sched_slack_bot.model.schedule import Schedule

logger = logging.getLogger(__name__)

class MongoScheduleAccess(ScheduleAccess):
    def __init__(
        self, mongo_url: str, port: Optional[str] = None, db_name: str = "sched-slack-bot", collection_name: str = "schedules"
    ):
        self._client: MongoClient[dict[str, Any]] = MongoClient(host=mongo_url, port=int(port) if port is not None else port)
        self._db_name = db_name
        self._collection_name = collection_name

    @property
    def _collection(self) -> Collection[dict[str, Any]]:
        return self._client.get_database(name=self._db_name).get_collection(name=self._collection_name)

    def get_available_schedules(self) -> List[Schedule]:
        return [Schedule.from_json(json=s) for s in self._collection.find({})]

    def save_schedule(self, schedule: Schedule) -> None:
        logger.info(f"Saving schedule with id {schedule.id}")
        self._collection.insert_one(schedule.as_json())

    def delete_schedule(self, schedule_id: str) -> None:
        logger.info(f"Deleting schedule with id {schedule_id}")
        self._collection.delete_one({"id": schedule_id})

    def update_schedule(self, schedule_id_to_update: str, new_schedule: Schedule) -> None:
        logger.info(f"Updating schedule with id {schedule_id_to_update}")

        update = new_schedule.as_json()
        self._collection.replace_one(filter={"id": schedule_id_to_update}, replacement=update)

    def get_schedule(self, schedule_id: str) -> Optional[Schedule]:
        logger.info(f"Getting schedule with id {schedule_id}")

        found_schedule = self._collection.find_one({"id": schedule_id})

        if found_schedule is None:
            return None

        return Schedule.from_json(json=found_schedule)


import json
import random
import os
from scipy import stats
import tensorflow as tf
from config.cvae_config import CVAECongfig
from config.cvrnn_config import CVRNNCongfig
from config.lstm_prediction_config import LSTMPredictConfig
from config.stats_encoder_config import EncoderConfig
from support.embedding_tools import plot_embeddings, dimensional_reduction, aggregate_positions_within_cluster, \
    get_player_cluster
from support.model_tools import get_model_and_log_name, get_data_name, validate_games_player_id, \
    validate_games_embedding

def illustrate_embeddings(encoder_values, player_index_list, player_basic_info_dir):
    position_list = get_player_cluster(player_index_list=player_index_list,
                                       player_basic_info_dir=player_basic_info_dir, clutser_type='pindex')
    dr_embedding = dimensional_reduction(encoder_values, dr_method='TSNE')
    plot_embeddings(data=dr_embedding, cluster_number=position_list)

    pass

def significance_test(testing_target, testing_objects):
    # testing_target = testing_target[:, :128]
    for testing_object in testing_objects:
        a = testing_target.flatten()
        b = testing_object.flatten()
        results = stats.ttest_rel(testing_target[:, :128].flatten(), testing_object[:, :128].flatten())
        print(results)
    return

if __name__ == '__main__':
    local_test_flag = False
    # model_type = 'cvrnn'
    model_type_all = ['cvrnn', 'cvae', 'vhe', 'encoder']
    model_number = 1801
    player_info = ''
    # embed_mode = '_'
    os.environ["CUDA_VISIBLE_DEVICES"] = "1"

    player_basic_info_dir = '../sport_resource/ice_hockey_201819/player_info_2018_2019.json'
    game_date_dir = '../sport_resource/ice_hockey_201819/game_dates_2018_2019.json'
    player_box_score_dir = '../sport_resource/ice_hockey_201819/Scale_NHL_players_game_summary_201819.csv'
    data_store_dir = "/Local-Scratch/oschulte/Galen/Ice-hockey-data/2018-2019/"
    dir_games_all = os.listdir(data_store_dir)
    selected_game_index = random.sample(range(0, len(dir_games_all)), 5)
    testing_dir_games_all = [dir_games_all[index] for index in selected_game_index]

    all_type_embedding = []

    for model_type in model_type_all:

        if model_type == 'cvrnn':
            embed_mode = '_embed_random'
            predicted_target = '_PlayerLocalId_predict_nex_goal'
            player_id_cluster_dir = '../sport_resource/ice_hockey_201819/local_player_id_2018_2019.json'
            icehockey_cvrnn_config_path = "../environment_settings/icehockey_cvrnn{0}_config{1}{2}.yaml".format(
                predicted_target, player_info, embed_mode)
            icehockey_model_config = CVRNNCongfig.load(icehockey_cvrnn_config_path)

        elif model_type == 'cvae':
            predicted_target = '_PlayerLocalId_predict_next_goal'  # playerId_
            player_id_cluster_dir = '../sport_resource/ice_hockey_201819/local_player_id_2018_2019.json'
            icehockey_config_path = "../environment_settings/icehockey_cvae_lstm{0}_config{1}.yaml".format(
                predicted_target, player_info)
            icehockey_model_config = CVAECongfig.load(icehockey_config_path)

        elif model_type == 'vhe':
            predicted_target = '_PlayerLocalId_predict_next_goal'  # playerId_
            player_id_cluster_dir = '../sport_resource/ice_hockey_201819/local_player_id_2018_2019.json'
            icehockey_config_path = "../environment_settings/icehockey_vhe_lstm{0}_config{1}.yaml".format(
                predicted_target, player_info)
            icehockey_model_config = CVAECongfig.load(icehockey_config_path)

        elif model_type == 'encoder':
            predicted_target = '_PlayerLocalId_predict_next_goal'
            player_id_cluster_dir = '../sport_resource/ice_hockey_201819/local_player_id_2018_2019.json'
            icehockey_encoder_config_path = "../environment_settings/" \
                                            "icehockey_stats_lstm_encoder{0}" \
                                            "_config{1}.yaml".format(predicted_target, player_info)
            icehockey_model_config = EncoderConfig.load(icehockey_encoder_config_path)
        else:
            raise ValueError("uknown model catagoery {0}".format(model_type))

        saved_network_dir, log_dir = get_model_and_log_name(config=icehockey_model_config,
                                                            model_catagoery=model_type,
                                                            running_number=0)

        # data_name = get_data_name(icehockey_model_config, model_category, model_number)

        print(model_type + '_' + str(model_number) + player_info)

        if local_test_flag:
            data_store_dir = "/Users/liu/Desktop/Ice-hokcey-data-sample/feature-sample"
        else:
            data_store_dir = icehockey_model_config.Learn.save_mother_dir \
                             + "/oschulte/Galen/Ice-hockey-data/2018-2019/"

        all_embedding, \
        all_player_index = validate_games_embedding(config=icehockey_model_config,
                                                    data_store_dir=data_store_dir,
                                                    dir_all=testing_dir_games_all,
                                                    player_basic_info_dir=player_basic_info_dir,
                                                    game_date_dir=game_date_dir,
                                                    player_box_score_dir=player_box_score_dir,
                                                    model_number=model_number,
                                                    player_id_cluster_dir=player_id_cluster_dir,
                                                    saved_network_dir=saved_network_dir,
                                                    model_category=model_type,
                                                    sess_nn=None)
        all_type_embedding.append(all_embedding)

    significance_test(testing_target=all_type_embedding[0], testing_objects=all_type_embedding[1:])

    # illustrate_embeddings(encoder_values=all_embedding,
    #                       player_index_list=all_player_index,
    #                       player_basic_info_dir=player_basic_info_dir)


"""
Simple demo of reading Temperature using a Pt100 sensor with the help of a
Raspbbery Pi and the ADS1115 AD controller.
Author: Christos Karapanagiotis
"""

import time
import csv
# Import the ADS1x15 module.
import Adafruit_ADS1x15
import board
import busio
import inspect

GAIN = 8
#The gain defines the voltage range:
#  Gain = 2/3   --> +/-6.144V
#  Gain = 1     --> +/-4.096V
#  Gain = 2     --> +/-2.048V
#  Gain = 4     --> +/-1.024V
#  Gain = 8     --> +/-0.512V
#  Gain = 16    --> +/-0.256V

GAIN_MAP = {
    2/3 : 6.144,
    1 : 4.096,
    2: 2.048,
    4 : 1.024,
    8 : 0.512,
    16 : 0.256
}

class PT100:
    def __init__(self) -> None:
        #Import the conversion table
        self.conv_list = None
        with open("/home/motion/Desktop/flir/tools/pt100/pt100.csv") as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            conv_list = list(csv_reader)
            self.conv_list = list(list(map(float,i)) for i in conv_list)

        self.adc = Adafruit_ADS1x15.ADS1115()

        self.temperature = None

    def show_me(self):
        # Print nice channel column headers.
        print(f"[{self.__class__.__name__}] Temperature : {self.temperature}°C")

    def find_nearest(self,list_,ref_resist):
        """
        find the element in a list which is closest to a reference value
        """
        resist = list(list_[i][1] for i in range(len(list_)))
        nearest_value = min(resist, key=lambda x:abs(x-ref_resist))
        list_index = resist.index(nearest_value)
        temperature = list_[list_index][0]

        return temperature

    def read_temp(self):
        # Main loop.
            # Read all the ADC channel values in a list.
        values = [0]*2
        for i in range(2):
            # Read the specified ADC channel using the previously set gain value.
            values[i] = self.adc.read_adc(i, gain=GAIN)/32767 *GAIN_MAP[GAIN] * 1000

            # Note you can also pass in an optional data_rate parameter that controls
            # the ADC conversion time (in samples/second). Each chip has a different
            # set of allowed data rate values, see datasheet Table 9 config register
            # DR bit values.
            #values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
            # Each value will be a 12 or 16 bit signed integer value depending on the
            # ADC (ADS1015 = 12-bit, ADS1115 = 16-bit).

        # print(f"Voltage in :{values[0]} | voltage out {values[1]}")
        R3 = 100 * (1 / ((values[0]/values[1])-1))
        self.temperature = self.find_nearest(self.conv_list, R3) - 8.5
        return float(self.temperature)

if __name__=="__main__":
    temp = PT100()
    while True:
        print(f"[{temp.read_temp()}]")
        time.sleep(1)


class Tool(object):

    # 使用赋值语句定义类属性，记录所有工具对象的数量
    count = 0

    @classmethod
    def show_tool_count(cls):

        print("工具对象的数量 %d" % cls.count)

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

        # 让类属性的值+1
        Tool.count += 1

# 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")

# 调用类方法
Tool.show_tool_count()


import torch
from PIL import Image
from torchvision import transforms
from models.joinmbt import JoinMbt

torch.backends.cudnn.deterministic = True

if __name__ == '__main__':
    device = 'cpu'
    checkpoint = torch.load('checkpoint_600.pth.tar', map_location=device)
    print(checkpoint["state_dict"].keys())

    net = JoinMbt(192, 192).to(device).eval()
    net.load_state_dict(checkpoint["state_dict"])

    img = Image.open('kodim18.png').convert('RGB')
    x = transforms.ToTensor()(img).unsqueeze(0).to(device)

    with torch.no_grad():
        # codec
        out = net.compress(x, 'foo')
        rec = net.decompress('foo')
        rec = transforms.ToPILImage()(rec['x_hat'].clamp(0, 1).squeeze().cpu())
        rec.save('./images/codec.png', format="PNG")

        # inference
        out = net(x)
        rec = out['x_hat'].clamp(0, 1)
        rec = transforms.ToPILImage()(rec.squeeze().cpu())
        rec.save('./images/infer.png', format="PNG")

        print('saved in ./images')


# -*- coding: utf-8 -*-
from adapter.grgsm.bursts import BurstFilter
from core.plugin.interface import plugin, PluginBase, cmd, arg, subcmd

@plugin(name="Burstfile Plugin", description="Provides functionality for filtering burst files")
class BurstfilePlugin(PluginBase):
    @cmd(name="bursts", description="Provides functionality for filtering burst files.", parent=True)
    def bursts(self, args):
        pass

    @arg("-a", action="store", dest="after", type=int,
         help="Allow only framenumbers greater than or equal the specified one")
    @arg("-b", action="store", dest="before", type=int,
         help="Allow only framenumbers less than or equal the specified one")
    @arg("-t", action="store", dest="timeslot", type=int, help="Allow only bursts on the specified timeslot")
    @arg("-s", action="store", dest="subslot", type=int, help="Allow only bursts on the specified subslot")
    @arg("-d", action="store", dest="remove_dummy", type=bool, default=False, help="Remove dummy bursts")
    @arg("input_burst_file", action="store_path", help="The source burst file")
    @arg("output_burst_file", action="store_path", help="The destination burst file")
    @subcmd(name="filter", help="Filter bursts with provided criteria.", parent="bursts")
    def filter(self, args):
        block = BurstFilter(args.input_burst_file, args.output_burst_file, args.after, args.before, args.timeslot,
                            args.subslot, args.remove_dummy)
        block.start()
        block.wait()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('database', '0001_initial'),
    ]

    operations = [
        migrations.AlterField(
            model_name='resource',
            name='resource_image',
            field=models.ImageField(upload_to=b'', verbose_name=b'\xd0\x98\xd0\xb7\xd0\xbe\xd0\xb1\xd1\x80\xd0\xb0\xd0\xb6\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 \xd1\x80\xd0\xb5\xd1\x81\xd1\x83\xd1\x80\xd1\x81\xd0\xb0'),
        ),
        migrations.AlterField(
            model_name='resource',
            name='resource_name',
            field=models.CharField(max_length=200, verbose_name=b'\xd0\x9d\xd0\xb0\xd0\xb7\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5 \xd1\x80\xd0\xb5\xd1\x81\xd1\x83\xd1\x80\xd1\x81\xd0\xb0'),
        ),
        migrations.AlterField(
            model_name='resourcenode',
            name='node_image',
            field=models.ImageField(default=None, upload_to=b'database', null=True, verbose_name=b'\xd0\x98\xd0\xb7\xd0\xbe\xd0\xb1\xd1\x80\xd0\xb0\xd0\xb6\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5 \xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd1\x87\xd0\xbd\xd0\xb8\xd0\xba\xd0\xb0', blank=True),
        ),
        migrations.AlterField(
            model_name='resourcenode',
            name='node_location',
            field=models.TextField(verbose_name=b'\xd0\x9c\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xbd\xd0\xb0\xd1\x85\xd0\xbe\xd0\xb6\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5'),
        ),
        migrations.AlterField(
            model_name='resourcenode',
            name='node_name',
            field=models.CharField(max_length=200, verbose_name=b'\xd0\x98\xd1\x81\xd1\x82\xd0\xbe\xd1\x87\xd0\xbd\xd0\xb8\xd0\xba \xd1\x80\xd0\xb5\xd1\x81\xd1\x83\xd1\x80\xd1\x81\xd0\xb0'),
        ),
        migrations.AlterField(
            model_name='resourcenode',
            name='node_respawn_time',
            field=models.IntegerField(verbose_name=b'\xd0\x92\xd1\x80\xd0\xb5\xd0\xbc\xd1\x8f \xd1\x80\xd0\xb5\xd1\x81\xd0\xbf\xd0\xb0\xd1\x83\xd0\xbd\xd0\xb0'),
        ),
        migrations.AlterField(
            model_name='resourcenode',
            name='node_yield',
            field=models.FloatField(verbose_name=b'\xd0\x9a\xd0\xbe\xd0\xbb\xd0\xb8\xd1\x87\xd0\xb5\xd1\x81\xd1\x82\xd0\xb2\xd0\xbe'),
        ),
    ]


import npyscreen
from openfoodfacts.view.buttons import (
    SearchButton,
    FavoritesButton,
    ResetDBButton,
    ExitButton,
)

class MainForm(npyscreen.FormBaseNew):
    """This form in the main form of the TUI.
    It displays the main menu.
    """

    def create(self):

        self.search_btn = self.add(SearchButton, name="Rechercher un produit")

        self.nextrely += 1
        self.favorites_btn = self.add(
            FavoritesButton, name="Produits enregistrés"
        )

        self.nextrely += 3
        self.reinit_btn = self.add(
            ResetDBButton, name="Réinitilaliser la base de données"
        )

        self.exitButton = self.add(ExitButton, name="Quit", relx=-12, rely=-3)


from random import randint

scores = {"neighbor": 0, "player": 0}

class Board:
    """
    main board setting of size, player's name, numbers of bad seeds,
    board type(player's board or neighbor's). Has methods for
    adding bad seeds and guesses and print the board
    """
    def __init__(self, size, num_bad_seeds, name, type):
        self.size = size
        self.board = [[". " for x in range(size)] for y in range(size)]
        self.num_bad_seeds = num_bad_seeds
        self.name = name
        self.type = type
        self.guess_place = []
        self.add_place = []
        self.rand_place = []

    def print(self):
        """
        print the board
        """
        for row in self.board:
            print(" ".join(row))

    def add_seeds(self):
        """
        Use while loop to add random and non-repeating coordinate (bad seeds)
        in both garden. Print a symbol ! on player side while computer side is
        hidden. Note: in test version, both side are shown. After tested, will
        add "if self.type == "player":"in front of the last line
        (last line indent).
        """
        while len(self.add_place) < self.num_bad_seeds:
            add_row = randint(0, self.size-1)
            add_col = randint(0, self.size-1)
            add_coord = [add_row, add_col]
            if add_coord not in self.add_place:
                self.add_place.append([add_row, add_col])
                if self.type == "player":
                    self.board[add_row][add_col] = "# "

    def my_guess(self):
        """
        The outer while loop includes two sub while loop which promp player
        to make a guess row and col, and validate the both.
        Then in outer loop, outside the subloops to validate the guess
        coordinat, if it's not already guessed, then move on to hit or miss
        part which is outside the outer loop. if hit, shown as $ and increment
        the score. If miss shown as x.
        """
        num = self.size-1

        while True:
            str1 = "Guess a number between 0 and"
            str2 = "Hei, you are in my garage!"
            str3 = "come back to my garden."
            str4 = "Your number must be between 0 and"
            str5 = "You dig that place already neighbor,"
            while True:
                print("\nPlease guess a row number:")
                try:
                    guess_row = int(input(f"{str1} {num}\n"))
                    if guess_row <= num:
                        break
                    elif guess_row > num:
                        print(f"\n{str2} \n{str3}\n{str4} {num}.")
                except ValueError:
                    print("\nYou can only enter a interger number!")

            while True:
                print("\nPlease guess a column number:")
                try:
                    guess_col = int(input(f"{str1} {num}\n"))
                    if guess_col <= num:
                        break
                    elif guess_col > num:
                        print(f"\n{str2} \n{str3}\n{str4} {num}.")
                except ValueError:
                    print("\nYou can only enter a interger number!")

            guess_coord = [guess_row, guess_col]
            if guess_coord in self.guess_place:
                print(f"{str5} \nplease choose a different spot.")
            else:
                break

        guess_coord = [guess_row, guess_col]
        self.guess_place.append(guess_coord)
        if guess_coord in self.add_place:
            self.board[guess_row][guess_col] = "$ "
            print("\nYou got it! Now your neighbor can plant flowers.")
            scores["player"] += 1
        else:
            self.board[guess_row][guess_col] = "X "
            print("\nYou missed, don't give up, keep going!")

    def neighbor_rand_guess(self):
        """
        Through a while loop, computer makes random non-repeating coordinate.
        Outside the loop, if the coordinate hit, print $ and increment score.
        Otherwise print X
        """
        while True:
            rand_row = randint(0, self.size-1)
            rand_col = randint(0, self.size-1)
            rand_coord = [rand_row, rand_col]
            if rand_coord not in self.rand_place:
                self.rand_place.append([rand_row, rand_col])
                break
        if rand_coord in self.add_place:
            self.board[rand_row][rand_col] = "$ "
            print("\nYour neighbor got it! Now you can plant flowers.")
            scores["neighbor"] += 1
        else:
            self.board[rand_row][rand_col] = "X "
            print("\nYour neighbor missed, but she/he will keep going!")

def new_game():
    """
    Starts a new game. Sets the board size and numbers of bad seeds,
    resets the scores and print the baords and random bad seeds.
    Use while loop to start the game, player guesses and computer
    make random coord.Game will automatic stop when one side's score
    reach the number of bad seeds. Then winner will be announced and
    this round game over.
    """
    size = 4
    num_bad_seeds = 3
    scores["neighbor"] = 0
    scores["player"] = 0
    print("-" * 20)
    str6 = "Welcom! You and your neighbor will help each other"
    str7 = "to dig out bad seeds from your garden!"
    str8 = "Your garden size is"
    print(f"\n{str6} \n{str7} \nIsn't that exciting!")
    print(f"{str8} {size}. \nNumber of bad seeds is {num_bad_seeds}")
    print("Top left coner is row: 0, col: 0")
    print("-" * 20)
    play_name = input("Please enter your name:\n")
    print("-" * 20)

    neighbor_board = Board(size, num_bad_seeds, "neighbor", type="neighbor")
    player_board = Board(size, num_bad_seeds, play_name, type="player")

    print("\nneighbor's garden")
    print()
    neighbor_board.add_seeds()
    neighbor_board.print()
    print(f"\n{play_name}'s garden")
    print()
    player_board.add_seeds()
    player_board.print()

    while True:

        neighbor_board.my_guess()
        my_score = scores["player"]
        print(f"Your current score is: {my_score}")
        print("\nYour neighbor's garden")
        neighbor_board.print()

        player_board.neighbor_rand_guess()
        neighbor_score = scores["neighbor"]
        print(f"Her/his current score is: {neighbor_score}")
        print(f"\n{play_name}'s garden")
        player_board.print()

        if scores["player"] == num_bad_seeds or scores["neighbor"] == num_bad_seeds:
            break

    str9 = "In this round you win! But he/she is not sad at all."
    str10 = "In fact, he/she will bring you a big bucket of icecream!"
    str11 = "But your garden will be prettier, so it's win_win!"
    print("\nGame Over!")
    if my_score > neighbor_score:
        print(f"{str9} \n{str10}")
    elif my_score == neighbor_score:
        print("In this round you are even!")
    elif my_score < neighbor_score:
        print(f"In this round your neighber win! \n{str11}")

def game_round():
    """
    Player will be asked for another round. when yes start a new game.
    when no exit the game.
    """
    while True:
        new_game()
        a = input("\nWould you like another round? any key or n\n")
        a = a.lower()
        if a != "n":
            continue
        elif a == "n":
            break

game_round()


import gc
import os
import time
import unittest
from datetime import datetime
from getpass import getuser
from sys import version_info

from gevent import sleep, spawn, Timeout as GTimeout
from ssh2.exceptions import SocketSendError, SocketRecvError

from pssh.clients.native import SSHClient, ParallelSSHClient
from pssh.clients.native.tunnel import LocalForwarder, TunnelServer, FORWARDER
from pssh.config import HostConfig
from pssh.exceptions import ProxyError
from .base_ssh2_case import PKEY_FILENAME, PUB_FILE
from ..embedded_server.openssh import OpenSSHServer

class TunnelTest(unittest.TestCase):
    server = None

    @classmethod
    def setUpClass(cls):
        _mask = int('0600') if version_info <= (2,) else 0o600
        os.chmod(PKEY_FILENAME, _mask)
        cls.port = 2225
        cls.cmd = 'echo me'
        cls.resp = u'me'
        cls.user_key = PKEY_FILENAME
        cls.user_pub_key = PUB_FILE
        cls.user = getuser()
        cls.proxy_host = '127.0.0.9'
        cls.proxy_port = cls.port + 1
        cls.server = OpenSSHServer(listen_ip=cls.proxy_host, port=cls.proxy_port)
        cls.server.start_server()

    @classmethod
    def tearDownClass(cls):
        cls.server.stop()

    def test_forwarder(self):
        forwarder = LocalForwarder()
        forwarder.daemon = True
        forwarder.start()
        forwarder.started.wait()
        client = SSHClient(
            self.proxy_host, port=self.proxy_port, pkey=self.user_key)
        forwarder.enqueue(client, self.proxy_host, self.port)
        forwarder.out_q.get()
        self.assertTrue(len(forwarder._servers) > 0)
        forwarder.shutdown()

    def test_tunnel_server(self):
        remote_host = '127.0.0.8'
        remote_server = OpenSSHServer(listen_ip=remote_host, port=self.port)
        remote_server.start_server()
        try:
            client = SSHClient(
                remote_host, port=self.port, pkey=self.user_key,
                num_retries=1,
                proxy_host=self.proxy_host,
                proxy_pkey=self.user_key,
                proxy_port=self.proxy_port,
            )
            output = client.run_command(self.cmd)
            _stdout = list(output.stdout)
            self.assertListEqual(_stdout, [self.resp])
            self.assertEqual(remote_host, client.host)
            self.assertEqual(self.port, client.port)
        finally:
            remote_server.stop()

    def test_proxy_pkey_bytes_data(self):
        remote_host = '127.0.0.8'
        remote_server = OpenSSHServer(listen_ip=remote_host, port=self.port)
        remote_server.start_server()
        with open(self.user_key, 'rb') as fh:
            pkey_data = fh.read()
        try:
            client = ParallelSSHClient(
                [remote_host], port=self.port, pkey=pkey_data,
                num_retries=1,
                proxy_host=self.proxy_host,
                proxy_pkey=pkey_data,
                proxy_port=self.proxy_port,
            )
            output = client.run_command(self.cmd)
            _stdout = list(output[0].stdout)
            self.assertListEqual(_stdout, [self.resp])
            self.assertEqual(remote_host, output[0].host)
            self.assertEqual(self.port, client.port)
        finally:
            remote_server.stop()

    # The purpose of this test is to exercise
    # https://github.com/ParallelSSH/parallel-ssh/issues/304
    def test_tunnel_server_reconn(self):
        remote_host = '127.0.0.8'
        remote_server = OpenSSHServer(listen_ip=remote_host, port=self.port)
        remote_server.start_server()

        reconn_n = 20       # Number of reconnect attempts
        reconn_delay = .1    # Number of seconds to delay between reconnects
        try:
            for _ in range(reconn_n):
                client = SSHClient(
                    remote_host, port=self.port, pkey=self.user_key,
                    num_retries=1,
                    proxy_host=self.proxy_host,
                    proxy_pkey=self.user_key,
                    proxy_port=self.proxy_port,
                )
                output = client.run_command(self.cmd)
                client.wait_finished(output)
                self.assertEqual(remote_host, client.host)
                self.assertEqual(self.port, client.port)
                client.disconnect()
                FORWARDER._cleanup_servers()
                time.sleep(reconn_delay)
                gc.collect()
        finally:
            remote_server.stop()

    def test_tunnel_server_same_port(self):
        remote_host = '127.0.0.7'
        remote_server = OpenSSHServer(listen_ip=remote_host, port=self.proxy_port)
        remote_server.start_server()
        try:
            client = SSHClient(
                remote_host, port=self.proxy_port, pkey=self.user_key,
                num_retries=1,
                retry_delay=.1,
                proxy_host=self.proxy_host,
            )
            output = client.run_command(self.cmd)
            _stdout = list(output.stdout)
            self.assertListEqual(_stdout, [self.resp])
            self.assertEqual(remote_host, client.host)
            self.assertEqual(self.proxy_port, client.port)
        finally:
            remote_server.stop()

    def test_tunnel_parallel_client(self):
        hosts = ['127.0.0.1%s' % (d,) for d in range(5)]
        servers = [OpenSSHServer(listen_ip=_host, port=self.port) for _host in hosts]
        for server in servers:
            server.start_server()
        hosts_5 = [hosts[0], hosts[1], hosts[2], hosts[3], hosts[4]]
        try:
            client = ParallelSSHClient(hosts_5, port=self.port, pkey=self.user_key,
                                       proxy_host=self.proxy_host,
                                       proxy_pkey=self.user_key,
                                       proxy_port=self.proxy_port,
                                       num_retries=1,
                                       )
            start = datetime.now()
            output = client.run_command(self.cmd)
            end = datetime.now()
            dt_5 = end - start
            client = ParallelSSHClient(hosts, port=self.port, pkey=self.user_key,
                                       proxy_host=self.proxy_host,
                                       proxy_pkey=self.user_key,
                                       proxy_port=self.proxy_port,
                                       num_retries=1,
                                       )
            start = datetime.now()
            output = client.run_command(self.cmd)
            end = datetime.now()
            dt_10 = end - start
            dt = dt_10.total_seconds() / dt_5.total_seconds()
            # self.assertTrue(dt < 2)
            client.join(output)
            self.assertEqual(len(hosts), len(output))
            for i, host_out in enumerate(output):
                _stdout = list(host_out.stdout)
                self.assertListEqual(_stdout, [self.resp])
                self.assertEqual(hosts[i], host_out.host)
        finally:
            for server in servers:
                server.stop()

    def test_tunnel_parallel_client_part_failure(self):
        hosts = ['127.0.0.11', '127.0.0.12', '127.0.0.13']
        servers = [OpenSSHServer(listen_ip=_host, port=self.port) for _host in hosts]
        servers[0].start_server()
        try:
            client = ParallelSSHClient(hosts, port=self.port, pkey=self.user_key,
                                       proxy_host=self.proxy_host,
                                       proxy_pkey=self.user_key,
                                       proxy_port=self.proxy_port,
                                       num_retries=1,
                                       retry_delay=.1,
                                       )
            output = client.run_command(self.cmd, stop_on_errors=False)
            client.join(output)
            self.assertEqual(len(hosts), len(output))
            self.assertTrue(output[1].exception is not None)
            self.assertTrue(output[2].exception is not None)
            self.assertListEqual(list(output[0].stdout), [self.resp])
        finally:
            for server in servers:
                server.stop()

    def test_tunnel_parallel_client_running_fail(self):
        hosts = ['127.0.0.11', '127.0.0.12', '127.0.0.13']
        servers = [OpenSSHServer(listen_ip=_host, port=self.port) for _host in hosts]
        for server in servers:
            server.start_server()
        try:
            client = ParallelSSHClient(hosts, port=self.port, pkey=self.user_key,
                                       proxy_host=self.proxy_host,
                                       proxy_pkey=self.user_key,
                                       proxy_port=self.proxy_port,
                                       num_retries=1,
                                       retry_delay=.1,
                                       )
            output = client.run_command(self.cmd)
            client.join(output)
            for server in (servers[1], servers[2]):
                server.stop()
                server.server_proc.communicate()
            client._host_clients[(1, hosts[1])].disconnect()
            client._host_clients[(2, hosts[2])].disconnect()
            output = client.run_command(self.cmd, stop_on_errors=False)
            client.join(output)
            self.assertEqual(len(hosts), len(output))
            self.assertTrue(output[1].exception is not None)
            self.assertTrue(output[2].exception is not None)
            self.assertListEqual(list(output[0].stdout), [self.resp])
        finally:
            for server in servers:
                server.stop()

    def test_tunnel_host_config(self):
        hosts = ['127.0.0.11', '127.0.0.12']
        servers = [OpenSSHServer(listen_ip=_host, port=self.port) for _host in hosts]
        for server in servers:
            server.start_server()
        host_config = [
            HostConfig(proxy_host=self.proxy_host,
                       proxy_port=self.proxy_port,
                       proxy_pkey=self.user_key),
            HostConfig(proxy_host='127.0.0.155',
                       proxy_port=123),
            ]
        client = ParallelSSHClient(hosts, port=self.port, pkey=self.user_key,
                                   host_config=host_config, num_retries=1)
        output = client.run_command(self.cmd, stop_on_errors=False)
        client.join(output)
        self.assertIsInstance(output[1].exception, ProxyError)
        self.assertTrue(output[0].exception is None)
        stdout = list(output[0].stdout)
        self.assertListEqual(stdout, [self.resp])

    def test_proxy_error(self):
        client = ParallelSSHClient([self.proxy_host], port=self.port, pkey=self.user_key,
                                   proxy_host='127.0.0.155',
                                   proxy_port=123,
                                   num_retries=1)
        output = client.run_command(self.cmd, stop_on_errors=False)
        client.join(output)
        self.assertIsInstance(output[0].exception, ProxyError)

    def test_proxy_bad_target(self):
        self.assertRaises(
            SocketRecvError, SSHClient,
            '127.0.0.155', port=self.proxy_port, pkey=self.user_key,
            proxy_host=self.proxy_host, proxy_port=self.proxy_port,
            num_retries=1,
        )

    def test_forwarder_exit(self):
        def _start_server():
            raise Exception

        forwarder = LocalForwarder()
        forwarder.daemon = True
        forwarder.start()
        forwarder.started.wait()
        client = SSHClient(
            self.proxy_host, port=self.proxy_port, pkey=self.user_key)
        forwarder.enqueue(client, self.proxy_host, self.port)
        forwarder.out_q.get()
        self.assertTrue(len(forwarder._servers) > 0)
        client.sock.close()
        client.disconnect()
        forwarder._cleanup_servers()
        self.assertEqual(len(forwarder._servers), 0)
        forwarder._start_server = _start_server
        forwarder.enqueue(client, self.proxy_host, self.port)
        sleep(.1)

    def test_socket_channel_error(self):
        class SocketError(Exception):
            pass
        class ChannelFailure(object):
            def read(self):
                raise SocketRecvError
            def write(self, data):
                raise SocketSendError
            def eof(self):
                return False
            def close(self):
                return
        class Channel(object):
            def __init__(self):
                self._eof = False
            def read(self):
                return 5, b"asdfa"
            def write(self, data):
                return 0, len(data)
            def eof(self):
                return self._eof
            def close(self):
                return
        class Socket(object):
            def recv(self, num):
                return b"asdfaf"
            def close(self):
                return
        class SocketFailure(object):
            def sendall(self, data):
                raise SocketError
            def recv(self, num):
                raise SocketError
            def close(self):
                return
        class SocketEmpty(object):
            def recv(self, num):
                return b""
            def close(self):
                return
        client = SSHClient(
            self.proxy_host, port=self.proxy_port, pkey=self.user_key)
        server = TunnelServer(client, self.proxy_host, self.port)
        let = spawn(server._read_forward_sock, SocketEmpty(), Channel())
        let.start()
        sleep(.01)
        self.assertRaises(SocketSendError, server._read_forward_sock, Socket(), ChannelFailure())
        self.assertRaises(SocketError, server._read_forward_sock, SocketFailure(), Channel())
        self.assertRaises(SocketError, server._read_channel, SocketFailure(), Channel())
        self.assertRaises(SocketRecvError, server._read_channel, Socket(), ChannelFailure())
        channel = Channel()
        _socket = Socket()
        source_let = spawn(server._read_forward_sock, _socket, channel)
        dest_let = spawn(server._read_channel, _socket, channel)
        channel._eof = True
        self.assertIsNone(server._wait_send_receive_lets(source_let, dest_let, channel))
        let.kill()

    def test_server_start(self):
        _port = 1234
        class Server(object):
            def __init__(self):
                self.started = False
                self.listen_port = _port
        server = Server()
        forwarder = LocalForwarder()
        let = spawn(forwarder._get_server_listen_port, None, server)
        let.start()
        sleep(.01)
        server.started = True
        sleep(.01)
        with GTimeout(seconds=1):
            port = forwarder.out_q.get()
        self.assertEqual(port, _port)


import os

from mlearning import coco, util

from tests import config
from tests.base import BaseTestCase

TEST_IMAGES = [
    {'id': 1, 'height': 450, 'width': 600, 'file_name': '1.jpg'},
    {'id': 2, 'height': 450, 'width': 600, 'file_name': '2.jpg'},
]

TEST_CATEGORIES = [
    {'supercategory': 'license', 'id': 1, 'name': 'license'},
    {'supercategory': 'car', 'id': 2, 'name': 'car'},
]

TEST_ANNOTATIONS = [{
    'area': None,
    'bbox': [179, 252, 29, 28],
    'category_id': 1,
    'id': 1,
    'image_id': 1,
    'iscrowd': 0,
    'segmentation': [[178, 252, 209, 258, 208, 280, 179, 274]]
},{
    'area': None,
    'bbox': [158, 137, 373, 182],
    'category_id': 2,
    'id': 2,
    'image_id': 1,
    'iscrowd': 0,
    'segmentation': [[
        254,
        180,
        313,
        142,
        407,
        133,
        476,
        139,
        519,
        174,
        529,
        187,
        530,
        226,
        510,
        270,
        484,
        270,
        396,
        298,
        379,
        317,
        345,
        319,
        327,
        305,
        281,
        306,
        164,
        282,
        153,
        237,
        184,
        204]]
},{
    'area': None,
    'bbox': [124, 68, 423, 375],
    'category_id': 2,
    'id': 3,
    'image_id': 2,
    'iscrowd': 0,
    'segmentation': [[
        184, 155, 245, 68, 379, 76, 404, 91, 439, 145, 470, 147,
        474, 163, 453, 174, 525, 275, 528, 315, 546, 350, 518, 409,
        443, 441, 228, 437, 130, 392, 117, 335, 129, 281, 143, 224]]
},{
    'area': None,
    'bbox': [291, 386, 105, 44],
    'category_id': 1,
    'id': 4,
    'image_id': 2,
    'iscrowd': 0,
    'segmentation': [[298, 386, 394, 391, 388, 428, 292, 427]]
}]

class AnnotationTests(BaseTestCase):

    def setUp(self):
        self.ann = coco.Annotation(
            path=os.path.join(config.PROJECT_DIR, 'tests/data'))

    def test_init(self):
        assert os.path.isdir(self.ann.ann_path)
        assert self.ann.ann_path == \
            os.path.join(config.PROJECT_DIR, 'tests/data/annotations')
        assert self.ann.image_path == \
            os.path.join(config.PROJECT_DIR, 'tests/data/images')
        assert self.ann.output_path == \
            os.path.join(config.PROJECT_DIR, 'tests/data/output')

    def test_all(self):
        ret = self.ann.all()

        assert isinstance(ret, dict)
        assert len(ret) == 5
        # info
        assert isinstance(ret['info'], dict)
        # images
        assert isinstance(ret['images'], list)
        assert ret['images'] == TEST_IMAGES
        # licenses
        assert isinstance(ret['licenses'], list)
        # annotations
        assert isinstance(ret['annotations'], list)
        assert ret['annotations'] == TEST_ANNOTATIONS
        # categories
        assert isinstance(ret['categories'], list)
        assert ret['categories'] == TEST_CATEGORIES

    def test_generate(self):
        # rm file file if present
        output_path = os.path.join(config.OUTPUT_DIR, 'annotations.json')
        if os.path.isfile(output_path):
            os.remove(output_path)
        assert not os.path.isfile(output_path)

        self.ann.generate(output_path)

        assert os.path.isfile(output_path)
        data = util.load_json(output_path)
        assert data == self.ann.all()
        # cleanup file when done
        os.remove(output_path)

    def test_list_annotations(self):
        raw_ret = [
            os.path.join(config.ANNOTATIONS_DIR, '1.json'),
            os.path.join(config.ANNOTATIONS_DIR, '2.json'),
        ]

        ret = self.ann.list_annotations()

        assert ret == raw_ret

    def test_get_categories(self):
        raw_ret = TEST_CATEGORIES

        ret = self.ann.get_categories()

        assert ret == raw_ret

    def test_get_images(self):
        raw_ret = TEST_IMAGES

        ret = self.ann.get_images()

        assert ret == raw_ret

    def test_get_image_ann(self):
        raw_ret = {'id': 1, 'height': 450, 'width': 600, 'file_name': '1.jpg'}
        path = os.path.join(config.ANNOTATIONS_DIR, '1.json')

        ret = self.ann.get_image_ann(path)

        assert ret == raw_ret

    def test_get_annotation_bbox(self):
        labelme_bb = [[290, 386], [397, 433]]
        raw_ret = [290, 386, 107,  47]

        ret = self.ann.get_annotation_bbox(labelme_bb)

        assert ret == raw_ret

    def test_get_label_to_category_id_map(self):
        raw_ret = {
            'license': 1,
            'car': 2
        }

        ret = self.ann.get_label_to_category_id_map()

        assert ret == raw_ret

    def test_get_segmentation(self):
        labelme_seg = [[178, 252], [209, 258], [208, 280], [179, 274]]
        raw_ret = [[178, 252, 209, 258, 208, 280, 179, 274]]

        ret = self.ann.get_segmentation(labelme_seg)

        assert ret == raw_ret

    def test_get_annotations(self):
        raw_ret = TEST_ANNOTATIONS

        ret = self.ann.get_annotations()

        assert ret == raw_ret

    def test_get_imageid_to_imageann(self):
        ret = self.ann.get_imageid_to_imageann()

        assert isinstance(ret, dict)
        assert ret == {
            1: TEST_IMAGES[0],
            2: TEST_IMAGES[1]
        }

    def test_get_imageid_to_ann(self):
        ret = self.ann.get_imageid_to_ann()

        assert isinstance(ret, dict)
        assert ret == {
            1: TEST_ANNOTATIONS[:2],
            2: TEST_ANNOTATIONS[2:]
        }

    def test_get_image_ids(self):
        ret = self.ann.get_image_ids()

        assert ret == [1, 2]

    def test_get_category_id_to_name(self):
        ret = self.ann.get_category_id_to_name()

        assert ret == {
            1: 'license',
            2: 'car'
        }


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

def solve():
    n = int(input())
    s = input()
    el, wl = [0]*n, [0]*n
    ec, wc = 0, 0
    for i in range(n):
        if s[n - 1 - i] == 'E':
            ec += 1
        if s[i] == 'W':
            wc += 1
        el[n - 1 - i] = ec
        wl[i] = wc

    ans = n - 1
    for i in range(n):
        if i == 0:
            ans = min(ans, el[i + 1])
        elif i == n - 1:
            ans = min(ans, wl[i - 1])
        else:
            ans = min(ans, wl[i - 1] + el[i + 1])
    print(max(0, ans))

if __name__=="__main__":
    solve()


#!/usr/bin/env python3

# the Cartesian product
from itertools import product

import sys
import copy

##############################################################################
class Automaton:
    '''Represents an automaton'''

    ###########################################
    def __init__(self):
        '''__init__(self)

Constructor.
'''
        self.startStates = []
        self.acceptStates = []
        self.transitions = []

    ###########################################
    def clearAcceptStates(self):
        '''clearAcceptStates() -> Automaton

Clear accepting states of an automaton.
'''
        result = Automaton()
        result.startStates = self.startStates[:]
        result.transitions = self.transitions[:]
        result.acceptStates = []

        return result

    ###########################################
    def clearStartStates(self):
        '''clearStartStates() -> Automaton

Clear starting states of an automaton.
'''
        result = Automaton()
        result.startStates = []
        result.transitions = self.transitions[:]
        result.acceptStates = self.acceptStates[:]

        return result

    ###########################################
    def getTgtState(trans):
        '''getTgtState(trans) -> State

Retrieve the target state of a transition.
'''
        if len(trans) == 2:
            return trans[1]
        elif len(trans) == 3:
            return trans[2]
        elif len(trans) == 4:
            return trans[3]
        else:
            raise Exception("Internal error")

    ###########################################
    def getSrcState(trans):
        '''getSrcState(trans) -> State

Retrieve the source state of a transition.
'''
        return trans[0]

    ###########################################
    def getSymbol(trans):
        '''getSymbol(trans) -> Symbol

Get the symbol in an automaton transition.
'''
        assert len(trans) == 3
        return trans[1]

    ###########################################
    def getSymbol1(trans):
        '''getSymbol1(trans) -> Symbol

Get the first symbol in a transducer transition.
'''
        assert len(trans) == 4
        return trans[1]

    ###########################################
    def getSymbol2(trans):
        '''getSymbol2(trans) -> Symbol

Get the second symbol in a transducer transition.
'''
        assert len(trans) == 4
        return trans[2]

    ###########################################
    def isEpsilonTrans(trans):
        '''isEpsilonTrans(trans) -> Bool

Determine an epsilon transition.
    '''
        return len(trans) == 2

    ###########################################
    def makeEpsTrans(src, tgt):
        '''makeTrans(src, tgt) -> transition

Makes an epsilon transition.
'''
        return (src, tgt)

    ###########################################
    def makeTrans(src, symbol, tgt):
        '''makeTrans(src, symbol, tgt) -> transition

Makes a transition.
'''
        return (src, symbol, tgt)

    ###########################################
    def makeTransTransd(src, symbol1, symbol2, tgt):
        '''makeTrans(src, symbol1, symbol2, tgt) -> transition

Makes a transducer transition.
'''
        return (src, symbol1, symbol2, tgt)

    ###########################################
    def singleStartState(self, name):
        '''singleStartState(self, name) -> Automaton

Make a single start state called name, using epsilon transitions to go to the
original start states.
'''
        result = self
        startingStates = result.startStates[:]

        result.clearStartStates()
        result.startStates = [name]
        for state in startingStates:
            result.addTrans(transition = Automaton.makeEpsTrans(name, state))

        return result

    ###########################################
    def postTrans(self, state):
        '''postTrans(self, state) -> [transitions]

A list of transitions leaving state.
'''
        return list(filter(lambda trans: Automaton.getSrcState(trans) == state,
            self.transitions))

    ###########################################
    def preTrans(self, state):
        '''preTrans(self, state) -> [transitions]

A list of transitions entering state.
'''
        return list(filter(lambda trans: Automaton.getTgtState(trans) == state,
            self.transitions))

    ###########################################
    def addTrans(self, src = None, symb = None, tgt = None, transition = None):
        '''addTrans(self, src, symb, tgt)

Add a new transition src --symb--> tgt.
'''
        if transition is None:
            assert (src is not None) and (symb is not None) and (tgt is not None)
            self.transitions.append(Automaton.makeTrans(src, symb, tgt))
        else:
            assert (src is None) and (symb is None) and (tgt is None)
            self.transitions.append(transition)

    ###########################################
    def addTransTransd(self, src = None, symb1 = None, symb2 = None, tgt = None,
        transition = None):
        '''addTrans(self, src, symb1, symb2, tgt)

Add a new transition src --symb1/symb2--> tgt.
'''
        if transition is None:
            assert ((src is not None) and (symb1 is not None) and (symb2 is not None) and
                (tgt is not None))
            self.transitions.append(Automaton.makeTransTransd(src, symb1, symb2, tgt))
        else:
            assert (src is None) and (symb1 is None) and (symb2 is None) and (tgt is None)
            self.transitions.append(transition)

    ###########################################
    def addTransitions(self, transitions):
        '''addTransitions(transitions)

Adds a set of transitions into the automaton.
'''
        self.transitions.extend(transitions)

    ###########################################
    def appendAut(self, aut):
        '''appendAut(self, aut) -> Automaton

Append aut to the automaton. That is, keep the original starting state and add all transitions and accepting states from aut.
'''
        result = self
        result.transitions += aut.transitions
        result.acceptStates += aut.acceptStates

        return result

    ###########################################
    def flattenProductStateNames(self):
        '''flattenProductStateNames(self) -> Automaton

Flatten names of states of a product automaton.
'''
        def flattenProdState(prodState):
            return prodState[0] + "X" + prodState[1]

        # result = Automaton()
        # result.startStates = list(map(flattenProdState, self.startStates))
        # result.acceptStates = list(map(flattenProdState, self.acceptStates))
        #
        # # hey, without list(..), I get only an ierator
        # result.transitions = list(map(lambda trans: (
        #         flattenProdState(trans[0]), # src state
        #         trans[1],                   # symbol
        #         flattenProdState(trans[2])  # tgt state
        #     ), self.transitions))

        result = self.renameStates(flattenProdState)
        return result

    ###########################################
    def generalIntersection(autLhs, autRhs, funSymMatch, funDetSymb):
        '''generalIntersection(autLhs, autRhs, funSymMatch, funDetSymb) -> Automaton

Performs a general intersection of autLhs and autRhs, such that symbols are
matched using the funSymMatch predicate.  The symbol of a new transition is then
determined using funDetSymb.  Generates only reachable transitions and states.
'''
        print('generalIntersection: warning: ignoring epsilon transitions', file=sys.stderr)

        result = Automaton()
        newStartStates = list(product(autLhs.startStates, autRhs.startStates))
        result.startStates = newStartStates[:]
        result.acceptStates = []
        allAcceptStates = list(product(autLhs.acceptStates, autRhs.acceptStates))

        worklist = newStartStates[:]
        processed = set(newStartStates)

        while not (len(worklist) == 0):
            (lhs, rhs) = worklist.pop(0)

            for (_, symbLhs, tgtStateLhs) in autLhs.postTrans(lhs):
                for (_, symbRhs, tgtStateRhs) in autRhs.postTrans(rhs):
                    # go over all transitions from lhs and rhs
                    if (funSymMatch(symbLhs, symbRhs)):
                        # if the symbols match
                        newState = (tgtStateLhs, tgtStateRhs)
                        if newState not in processed:
                            worklist.append(newState)
                            processed.add(newState)
                            if newState in allAcceptStates:
                                result.acceptStates.append(newState)

                        result.addTrans(transition = Automaton.makeTrans(
                                (lhs, rhs),
                                funDetSymb(symbLhs, symbRhs),
                                newState
                            ))

        return result.flattenProductStateNames()

    ###########################################
    def intersection(autLhs, autRhs):
        '''intersection(self, autLhs, autRhs) -> Automaton

Performs a standard intersection of two automata using a product construction.
'''
        return Automaton.generalIntersection(autLhs, autRhs,
            lambda x, y: x == y,
            lambda x, y: x)

    ###########################################
    def renameStates(self, funcRem):
        '''renameStates(self, funcRem) -> Automaton

Rename states of the automaton using funcRem.
'''
        result = Automaton()

        result.startStates = list(map(funcRem, self.startStates))
        result.acceptStates = list(map(funcRem, self.acceptStates))

        ##############################################
        def sodomizeTrans(trans):                    #
            if len(trans) == 2:                      #
                return (                             #
                    funcRem(trans[0]),               #
                    funcRem(trans[1])                #
                )                                    #
            if len(trans) == 3:                      #
                return (                             #
                    funcRem(trans[0]),               #
                    trans[1],                        #
                    funcRem(trans[2])                #
                )                                    #
            elif len(trans) == 4:                    #
                return (                             #
                    funcRem(trans[0]),               #
                    trans[1],                        #
                    trans[2],                        #
                    funcRem(trans[3])                #
                )                                    #
            else:                                    #
                raise Exception("Internal error")    #
        ##############################################

        result.transitions = list(map(sodomizeTrans, self.transitions))

        return result

    ###########################################
    def removeUseless(self):
        '''removeUseless(self) -> Automaton

Removes useless (forward and backward) states from the automaton.
'''
        result = Automaton()
        result.startStates = []
        result.acceptStates = []

        # keep only forward reachable states
        worklist = self.startStates[:]
        processed = set(self.startStates)

        while not (len(worklist) == 0):
            state = worklist.pop(0)

            if state in self.acceptStates:
                result.acceptStates.append(state)

            for trans in self.postTrans(state):
                # go over all transitions _from_ state
                tgtState = Automaton.getTgtState(trans)

                if tgtState not in processed:
                    worklist.append(tgtState)
                    processed.add(tgtState)

        # keep only backward reachable states
        worklist = result.acceptStates[:]
        bwdProcessed = set(result.acceptStates)

        while not (len(worklist) == 0):
            state = worklist.pop(0)

            if state in self.startStates:
                result.startStates.append(state)

            for trans in self.preTrans(state):
                # go over all transitions _to_ state
                srcState = Automaton.getSrcState(trans)

                if srcState in processed and srcState not in bwdProcessed:
                    # if srcState is forward-useful and not backward-processed yet
                    worklist.append(srcState)
                    bwdProcessed.add(srcState)

                result.addTrans(transition = trans)

        return result

    ###########################################
    def removeEpsilon(self):
        '''removeEpsilon(self) -> Automaton

Removes epsilon transitions from the automaton.
'''
        result = copy.deepcopy(self)

        eClosure = {}
        eTransitions = list(filter(lambda trans: Automaton.isEpsilonTrans(trans),
            result.transitions))

        while len(eTransitions) > 0:
            trans = eTransitions.pop()
            result.transitions.remove(trans)
            (src, tgt) = (Automaton.getSrcState(trans), Automaton.getTgtState(trans))

            if tgt in result.acceptStates:
                result.acceptStates.append(src)

            for nextTrans in result.postTrans(tgt):
                if Automaton.isEpsilonTrans(nextTrans):
                    newTrans = (src, Automaton.getTgtState(nextTrans))
                    result.addTrans(transition = newTrans)
                    eTransitions.append(newTrans)
                else:
                    newTrans = (src, Automaton.getSymbol(nextTrans),
                        Automaton.getTgtState(nextTrans))
                    result.addTrans(transition = newTrans)

        return result

    ###########################################
    def toTransducer(self):
        '''toTransducer(self) -> Automaton

Transforms an automaton into a transducer encoding the identity relation.
'''
        result = self.mapTrans(lambda trans:
            (
                trans[0],
                trans[1],
                trans[1],
                trans[2]
            ))

        return result

    ###########################################
    def packTransdToAutomaton(self):
        '''toAutomaton(self) -> Automaton

Transforms a transducer into an automaton by packing the two symbols inside a
transition to a pair.
'''
        ##############################################
        def packer(trans):                           #
            if len(trans) == 2:                      #
                return trans                         #
            elif len(trans) == 4:                    #
                return (                             #
                    trans[0],                        #
                    (trans[1], trans[2]),            #
                    trans[3]                         #
                )                                    #
            else:                                    #
                raise Exception("Internal error")    #
        ##############################################

        result = self.mapTrans(packer)
        return result

    ###########################################
    def unpackAutomatonToTransd(self):
        '''toAutomaton(self) -> Automaton

Transforms an automaton with pairs on edges into a transducer by unpacking the pair.
'''
        ##############################################
        def unpacker(trans):                         #
            if len(trans) == 2:                      #
                return trans                         #
            elif len(trans) == 3:                    #
                return (                             #
                    trans[0],                        #
                    trans[1][0],                     #
                    trans[1][1],                     #
                    trans[2]                         #
                )                                    #
            else:                                    #
                raise Exception("Internal error")    #
        ##############################################

        result = self.mapTrans(unpacker)
        return result

    ###########################################
    def filterTrans(self, pred):
        '''filterTrans(self, pred) -> Automaton

Filters transitions of automaton with respect to the predicate pred.
'''
        result = Automaton()
        result.startStates = self.startStates[:]
        result.acceptStates = self.acceptStates[:]
        result.transitions = list(filter(pred, self.transitions))
        return result

    ###########################################
    def mapTrans(self, mapper):
        '''mapTrans(self, mapper) -> Automaton

Maps transitions w.r.t. mapper.
'''
        result = Automaton()
        result.startStates = self.startStates[:]
        result.acceptStates = self.acceptStates[:]
        result.transitions = list(map(mapper, self.transitions))
        return result

    ###########################################
    def transdAutAutProd(transd, aut1, funMatch1, funDet1, aut2, funMatch2, funDet2):
        '''transdAutAutProd(transd, aut1, funMatch1, funDet1, aut2, funMatch2, funDet2) -> Automaton

Peform a ternarny product of a transducer transd with automata aut1 and aut2,
such that aut1 matches to the first tape of trands and aut2 matches on the
second tape of transd.  funMatch1 and funMatch2 are used to determine whether
the symbols of transd and aut1 and aut2 respectively match.  funDet1 and
funDet2 are used to determine the symbol in the result.
'''
        result = Automaton()

        result.startStates = list(product(
            transd.startStates,
            aut1.startStates,
            aut2.startStates))

        result.acceptStates = []
        allAcceptStates = list(product(
            transd.acceptStates,
            aut1.acceptStates,
            aut2.acceptStates))

        worklist = result.startStates[:]
        processed = set(result.startStates)

        while not (len(worklist) == 0):
            (lhs, st1, st2) = worklist.pop(0)

            for lhsTrans in transd.postTrans(lhs):
                if Automaton.isEpsilonTrans(lhsTrans):
                    # for epsilon transitions
                    newState = (Automaton.getTgtState(lhsTrans), st1, st2)
                    if newState not in processed:
                        worklist.append(newState)
                        processed.add(newState)
                        if newState in allAcceptStates:
                            result.acceptStates.append(newState)

                    # insert an epsilon transition
                    newTrans = (
                            (lhs, st1, st2),
                            newState
                        )
                    result.addTrans(transition = newTrans)
                else:
                    # for ordinary transitions
                    (_, symbLhs1, symbLhs2, tgtStateLhs) = lhsTrans

                    for (_, symbAut1, tgtState1) in aut1.postTrans(st1):
                        if (funMatch1(symbLhs1, symbAut1)):
                            for (_, symbAut2, tgtState2) in aut2.postTrans(st2):
                                if (funMatch2(symbLhs2, symbAut2)):
                                    # go over all matching transitions from
                                    # lhs, st1, and st2

                                    # target product state
                                    newState = (tgtStateLhs, tgtState1, tgtState2)

                                    if newState not in processed:
                                        worklist.append(newState)
                                        processed.add(newState)
                                        if newState in allAcceptStates:
                                            result.acceptStates.append(newState)

                                    # insert an ordinary transition
                                    newTrans = (
                                            (lhs, st1, st2),
                                            funDet1(symbLhs1, symbAut1),
                                            funDet2(symbLhs2, symbAut2),
                                            newState
                                        )
                                    result.addTrans(transition = newTrans)

        ################################################################
        def stateSodomizer(stTuple):                                   #
            assert len(stTuple) == 3                                   #
            return stTuple[0] + "X" + stTuple[1] + "X" + stTuple[2]    #
        ################################################################

        result = result.renameStates(stateSodomizer)

        return result

    ###########################################
    def union(self, rhs):
        '''union(self, rhs) -> Automaton

Unites the automaton with automaton rhs.
'''
        result = Automaton()

        print('union: check whether the automata are disjoint first!', file=sys.stderr)
        result.startStates = self.startStates + rhs.startStates
        result.acceptStates = self.acceptStates + rhs.acceptStates
        result.transitions = self.transitions + rhs.transitions

        return result

    ###########################################
    def autUnion(lhs, rhs):
        '''autUnion(lhs, rhs) -> Automaton

Unites the automaton lhs with rhs.
'''
        return lhs.union(rhs)

    ###########################################
    def exportToDot(self):
        '''exportToDot(self) -> String

Export the automaton to the dot format.
'''
        result = ""
        result += "digraph {\n"
        result += "\"__init\" [shape=point];\n"

        for stState in self.startStates:
            result += "\"__init\" -> \"" + stState + "\";\n"

        for accState in self.acceptStates:
            result += "\"" + accState + "\" [shape=doublecircle];\n"

        for trans in self.transitions:
            result += "  \"" + Automaton.getSrcState(trans)
            result += "\" -> \"" + Automaton.getTgtState(trans)
            result += "\" [label=\""

            if len(trans) == 2:
                result += 'epsilon'
            elif len(trans) == 3:
                result += Automaton.getSymbol(trans)
            elif len(trans) == 4:
                result += Automaton.getSymbol1(trans)
                result += "/"
                result += Automaton.getSymbol2(trans)
            else:
                raise Exception("Internal error")

            result += "\"];\n"

        result += "}\n"
        return result

    ###########################################
    def __str__(self):
        '''__str__(self) -> String

Transforms automaton into a string.
'''
        output = ""
        output += "init: "
        first = True
        for state in self.startStates:
            if not first:
                output += ", "

            output += state
            first = False

        output += ";\n"

        for trans in self.transitions:
            if len(trans) == 2:
                output += trans[0] + " -> " + trans[1] + ";\n"
            elif len(trans) == 3:
                output += trans[0] + " -> " + trans[2] + " " + trans[1] + ";\n"
            elif len(trans) == 4:
                output += trans[0] + " -> " + trans[3] + " " + trans[1] + "/" + trans[2] + ";\n"
            else:
                raise Exception("Internal error")

        output += "accepting: "
        first = True
        for state in self.acceptStates:
            if not first:
                output += ", "

            output += state
            first = False

        output += ";\n"

        return output

###############################################################################
if __name__ == '__main__':
    print("Library module")


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

from random import choice, randrange as rand
import matplotlib.pyplot as plt
import copy

##
# Dimensions du labyrinthe
width = 20
height = 20

##
# Constantes servant à décrire les directions des passages
N, S, E, W  = 1, 2, 4, 8
IN          = 0x10
FRONTIER    = 0x20
OPPOSITE    = {E: W, W: E, S: N, N: S}

##
# Structures de données
grid = [([0] * width) for _ in range(height)]
frontier = set()

##
# Méthodes utilitaires
def add_frontier(x, y):
    if (x >= 0 and y >= 0 and y < len(grid)
            and x < len(grid[y]) and grid[y][x] == 0):
        grid[y][x] |= FRONTIER
        frontier.add((x, y))

def mark(x, y):
    grid[y][x] |= IN
    add_frontier(x-1, y)
    add_frontier(x+1, y)
    add_frontier(x, y-1)
    add_frontier(x, y+1)

def neighbors(x, y):
    if x > 0 and (grid[y][x-1] & IN):
        yield (x-1, y)
    if x + 1 < len(grid[y]) and (grid[y][x+1] & IN):
        yield (x+1, y)
    if y > 0 and (grid[y-1][x] & IN):
        yield (x, y-1)
    if y + 1 < len(grid) and (grid[y+1][x] & IN):
        yield (x, y+1)

def direction(fx, fy, tx, ty):
    return {(fx < tx): E,
            (fx > tx): W,
            (fy < ty): S,
            (fy > ty): N}[True]

def is_empty(cell):
    return cell == 0 or cell == FRONTIER

def display_plt():
    plt.text(2,5*height-2,'D')
    plt.text(5*width-3,2,'A')
    for y, row in enumerate(grid):
        for x, cell in enumerate(row):
            if cell&N==0:
                plt.plot([5*x,5*x+5],[5*height-(5*y),5*height-(5*y)],'b')
            if cell&S==0:
                plt.plot([5*x,5*x+5],[5*height-(5*y+5),5*height-(5*y+5)],'b')
            if cell&E==0:
                plt.plot([5*x+5,5*x+5],[5*height-(5*y+5),5*height-(5*y)],'b')
            if cell&W==0:
                plt.plot([5*x,5*x],[5*height-(5*y+5),5*height-(5*y)],'b')
    plt.axis('equal')

def choice_dir(x,y):
    list_dir=[N,S,E,W]
    for test in parcours:
        if test[0]==(x,y):
            if test[1] in list_dir:
                list_dir.remove(test[1])
    return(list_dir)

def generation_grille():
    mark(rand(width), rand(height))
    while frontier:
        ##
        # Choix d'un voisin à la frontière
        x, y = choice(list(frontier))
        frontier.remove((x, y))
        nx, ny = choice(list(neighbors(x, y)))

        ##
        # Création d'un passage
        dir = direction(x, y, nx, ny)
        grid[y][x] |= dir
        grid[ny][nx] |= OPPOSITE[dir]

        mark(x, y)

        ## DEBUG :
        # print("frontier =", frontier)
        # print("(%d, %d) -> (%d, %d)" % (x, y, nx, ny))
        # display_maze()
        # input("Appuyez sur Entree pour continuer")

def test_grille():
    i=0
    x,y=0,0
    parcours=[]
    grid_parcours = [([0] * width) for _ in range(height)]
    grid_parcours[0][0]=1
    while (x,y)!=(width-1,height-1):
        test_case=(grid[y][x]&N)+(grid[y][x]&S)+(grid[y][x]&E)+(grid[y][x]&W)
        if test_case in [N,S,E,W]:
            banni.append([x,y,test_case])
        i+=1
        parcours.append([x,y])
        idee=choice([N,S,E,W])
        if idee==E and grid[y][x]&E!=0 and (x+1,y) not in banni:
            x+=1
        elif idee==S and grid[y][x]&S!=0 and (x,y+1) not in banni:
            y+=1
        elif idee==W and grid[y][x]&W!=0 and (x-1,y) not in banni:
            x+=-1
        elif idee==N and grid[y][x]&N!=0 and (x,y-1) not in banni:
            y+=-1
        grid_parcours[y][x]=1
    parcours.append([x,y])
    #plt.scatter([5*ban[0]+2.5 for ban in banni],[5*height-(5*ban[1]+2.5) for ban in banni])
    return(parcours)

def mise_a_jour_grille():
    for ban in banni[1:]:
        if [ban[0],ban[1]] not in traite and (ban[0],ban[1])!=(0,0):
            if ban[2]==N and ban[1]>0:
                traite.append([ban[0],ban[1]])
                grid[ban[1]][ban[0]] +=- ban[2]
                grid[ban[1]-1][ban[0]] +=- OPPOSITE[ban[2]]
            elif ban[2]==S and ban[1]<height-1:
                traite.append([ban[0],ban[1]])
                grid[ban[1]][ban[0]] +=- ban[2]
                grid[ban[1]+1][ban[0]] +=- OPPOSITE[ban[2]]
            if ban[2]==E and ban[0]<width-1:
                traite.append([ban[0],ban[1]])
                grid[ban[1]][ban[0]] +=- ban[2]
                grid[ban[1]][ban[0]+1] +=- OPPOSITE[ban[2]]
            if ban[2]==W and ban[0]>0:
                traite.append([ban[0],ban[1]])
                grid[ban[1]][ban[0]] +=- ban[2]
                grid[ban[1]][ban[0]-1] +=- OPPOSITE[ban[2]]

plt.figure('Initial')

generation_grille()
grid_init=copy.deepcopy(grid)
display_plt()

for i in range(50):
    print('Essai '+str(i))
    banni=[]
    parcours=test_grille()
    if i in [0]:
        plt.figure('Essai '+str(i))
        plt.plot([5*par[0]+2.5 for par in parcours],[5*height-(5*par[1]+2.5) for par in parcours],'r')
        display_plt()
    traite=[]
    mise_a_jour_grille()

plt.figure('Final')
grid=copy.deepcopy(grid_init)
display_plt()
plt.plot([5*par[0]+2.5 for par in parcours],[5*height-(5*par[1]+2.5) for par in parcours],'r')

plt.show()


from decimal import Decimal
from django.http import JsonResponse
from django.shortcuts import render_to_response, render, get_object_or_404
from django.middleware import csrf
from django.views.generic import DetailView, ListView, FormView

from deal.models import Deal
from utils.decorators.permission import perm_required
from mlm.forms import ManagerCreateAgentForm
from mlm.models import AgentPayment
from mlm.views.mlm_agent import MLMAgentView
from utils.remote_forms.forms import RemoteForm

class MLMCabinetManagerView(MLMAgentView):

    @perm_required('mlm.mlm_manager')
    def dispatch(self, request, *args, **kwargs):
        self.manager = request.user.person.mlm_agent
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(dict(
            title='Личный кабинет менеджера',
            month_set=self.month_set,
            permissions=self.permissions
        ))
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data()
        context.update(
            child_agents=self.get_child_agents()
        )
        if self.request.GET.get('debug'):
            return render_to_response('debug.jinja2', locals())
        return JsonResponse(context, safe=False)

class MLMCabinetManagerInviteView(ListView):
    permissions = []
    manager = None
    count = 0
    total = Decimal('0.00')

    @perm_required('mlm.mlm_manager')
    def dispatch(self, request, *args, **kwargs):
        self.model = Deal
        self.permissions = ['view']
        self.manager = request.user.person.mlm_agent
        return super().dispatch(request, *args, **kwargs)

    def get_queryset(self):
        queryset = self.model.objects.filter(mlm_agent=self.manager, step__name='done', cost__gt=0)
        return queryset.distinct()

    def get_items(self):
        items = []
        _queryset = self.get_queryset()
        self.count = _queryset.count()
        for item in _queryset:
            bonus = round(item.cost / 100 * self.manager.level_1, 2)
            self.total += bonus
            items.append(dict(
                id=item.id,
                cost=item.cost,
                start_datetime=item.start_datetime.strftime('%Y.%m.%d'),
                bonus=bonus
            ))
        return items

    def get(self, request, *args, **kwargs):
        if 'view' not in self.permissions:
            return JsonResponse(dict(answer='No permissions'), safe=False)

        context = dict(
            permissions=self.permissions,
            items=self.get_items(),
            count=self.count,
            total=self.total,
            headers=[
                dict(order=None, text='#', value='id'),
                dict(order=None, text='День сделки', value='start_datetime'),
                dict(order=None, text='Стоимость', value='cost'),
                dict(order=None, text='Начислено', value='bonus'),
            ]
        )
        if request.GET.get('debug'):
            from django.shortcuts import render_to_response
            return render_to_response('debug.jinja2', locals())

        return JsonResponse(context)

class MLMCabinetManagerPaymentsView(ListView):
    permissions = []
    manager = None
    count = 0
    total = Decimal('0.00')

    @perm_required('mlm.mlm_manager')
    def dispatch(self, request, *args, **kwargs):
        self.model = AgentPayment
        self.permissions = ['view']
        self.manager = request.user.person.mlm_agent
        return super().dispatch(request, *args, **kwargs)

    def get_queryset(self):
        queryset = self.model.objects.filter(agent=self.manager)
        return queryset.distinct()

    def get_items(self):
        items = []
        _queryset = self.get_queryset()
        self.count = _queryset.count()
        for item in _queryset:
            self.total += item.cost
            items.append(dict(
                id=item.id,
                cost=item.cost,
                created_at=item.created_at.strftime('%Y.%m.%d'),
            ))
        return items

    def get(self, request, *args, **kwargs):
        if 'view' not in self.permissions:
            return JsonResponse(dict(answer='No permissions'), safe=False)

        context = dict(
            permissions=self.permissions,
            items=self.get_items(),
            count=self.count,
            total=self.total,
            headers=[
                dict(order=None, text='#', value='id'),
                dict(order=None, text='День выплаты', value='created_at'),
                dict(order=None, text='Выплата', value='cost'),
            ]
        )
        if request.GET.get('debug'):
            from django.shortcuts import render_to_response
            return render_to_response('debug.jinja2', locals())

        return JsonResponse(context)

class MLMCabinetManagerCreateAgentView(FormView):
    form_class = ManagerCreateAgentForm
    action = None
    manager = None
    permissions = []

    @perm_required('mlm.mlm_manager')
    def dispatch(self, request, *args, **kwargs):
        self.action = kwargs.get('action')
        self.manager = request.user.person.mlm_agent
        self.permissions = ['view', 'add', 'change']
        return super().dispatch(request, *args, **kwargs)

    def get_form(self, form_class=None):
        if self.request.POST:
            self.request.POST._mutable = True
            self.request.POST['manager'] = self.manager
            print('self.request.POST', self.request.POST)
            return self.form_class(self.request.POST)
        return self.form_class()

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            form.save()
            return JsonResponse(dict(
                # form=form,
                message=dict(type='success', text='Сохранено'),
            ))
        return JsonResponse(dict(
            form=dict(errors=form.errors)
        ))

    def get_context_data(self, **kwargs):
        context = dict(
            title='Регистрация партнера',
            csrf_token=csrf.get_token(self.request),
            # form=self.get_form(),
            form=RemoteForm(self.get_form(), csrf_token=csrf.get_token(self.request)).as_dict(),
            permissions=self.permissions
        )
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data()
        return JsonResponse(context)


# coding: utf-8

import collections

aa = ("홍길동", 21, "남")
bb = ("강복녀", 23, "여")

for n in [aa, bb]:
    print('%s, %d, %s' %n)

Person = collections.namedtuple("Person", 'name age gender')

aa = Person(name="홍길동", age="25", gender="남")
bb = Person(name="강길녀", age="21", gender="여")

for n in [aa, bb]:
    print('%s는 %s세, %s입니다.' %n)


import numpy as np
from same_seeds import same_seeds

same_seeds(2)
np.set_printoptions(suppress=True, precision=5)

def LUP_inv(m):
    eps = 1e-3
    n = m.shape[0]
    L = np.mat(np.eye(n), dtype=float)
    P = np.mat(np.eye(n), dtype=float)
    U = np.mat(m.copy())
    for i in range(n):
        swap_line = np.argmax(abs(U[i:, i])) + i
        if swap_line != i:
            P[[i, swap_line]] = P[[swap_line, i]]
            U[[i, swap_line]] = U[[swap_line, i]]
            if i > 0:
                L[[i, swap_line], :i] = L[[swap_line, i], :i]

        if abs(U[i, i]) < eps:
            print("LUP: There is no non-zero pivot!")
            return np.zeros(1)
        if abs(U[i, i] - 1.0) < eps:
            L[i + 1:, i] = U[i + 1:, i]
        else:
            L[i + 1:, i] = U[i + 1:, i] / U[i, i]
        U[i + 1:, :] = U[i + 1:, :] - L[i + 1:, i] * U[i, :]

    E1 = np.mat(np.eye(n))  # 这个E1用来求U的逆
    for i in range(n - 1, -1, -1):
        if abs(U[i, i] - 1.0) > eps:
            # 对角元单位化
            E1[i, :] = E1[i, :] / U[i, i]
            # U[i, :] = U[i, :] / U[i, i]

        E1[:i, :] = E1[:i, :] - U[:i, i] * E1[i, :]
        # U[:i, :] = U[:i, :] - U[:i, i] * U[i, :]

    # 当然，我们还可以来求一下下三角阵L的逆
    E2 = np.mat(np.eye(n))
    for i in range(n):
        E2[i + 1:, :] = E2[i + 1:, :] - L[i + 1:, i] * E2[i, :]
        # L[i + 1:, :] = L[i + 1:, :] - L[i + 1:, i] * L[i, :]

    return np.array(E1 * E2 * P)

if __name__ == "__main__":
    # A = np.mat(np.random.randn(4, 4))
    A = np.array([[1, 2, 3, 4],  # for test
                        [2, 3, 1, 5],
                        [3, 1, 2, 6],
                        [1, 3, 2, 6]], dtype=float)
    X = LUP_inv(A)
    print(A @ X)


import warnings

import matplotlib.pyplot as plt
import numpy as np
import pytorch_lightning as pl
import torch
from scipy.linalg import LinAlgWarning
from sklearn.decomposition import PCA

from nlb_tools.evaluation import (
    bits_per_spike,
    eval_psth,
    speed_tp_correlation,
    velocity_decoding,
)

plt.switch_backend("Agg")

def get_tensorboard_summary_writer(loggers):
    """Gets the TensorBoard SummaryWriter from a logger
    or logger collection to allow writing of images.

    Parameters
    ----------
    loggers : obj or list[obj]
        An object or list of loggers to search for the
        SummaryWriter.

    Returns
    -------
    torch.utils.tensorboard.writer.SummaryWriter
        The SummaryWriter object.
    """
    logger_list = loggers if isinstance(loggers, list) else [loggers]
    for logger in logger_list:
        if isinstance(logger, pl.loggers.tensorboard.TensorBoardLogger):
            return logger.experiment
    else:
        return None

def batch_fwd(model, batch):
    """Performs the forward pass for a given model and data batch.

    Parameters
    ----------
    model : pl.LightningModule
        The model to pass data through.
    batch : tuple[torch.Tensor]
        A tuple of batched input tensors.

    Returns
    -------
    tuple[torch.Tensor]
        A tuple of batched output tensors.
    """
    input_data, recon_data, *other_input, behavior = batch
    input_data = input_data.to(model.device)
    other_input = [oi.to(model.device) for oi in other_input]
    return model.forward(input_data, *other_input)

class RasterPlotCallback(pl.Callback):
    """Plots validation spiking data side-by-side with
    inferred rates and logs to tensorboard. Heldin/heldout
    and observed/forward distinctions are indicated by
    dividing lines.
    """

    def __init__(self, batch_fwd=batch_fwd, n_samples=2, log_every_n_epochs=20):
        """Initializes the callback.

        Parameters
        ----------
        batch_fwd: func, optional
            A function that takes a model and a batch of data and
            performs the forward pass, returning the model output.
            May be useful if your model requires specialized I/O.
        n_samples : int, optional
            The number of samples to plot, by default 2
        log_every_n_epochs : int, optional
            The frequency with which to plot and log, by default 20
        """
        self.batch_fwd = batch_fwd
        self.n_samples = n_samples
        self.log_every_n_epochs = log_every_n_epochs

    def on_validation_epoch_end(self, trainer, pl_module):
        """Logs plots at the end of the validation epoch.

        Parameters
        ----------
        trainer : pytorch_lightning.Trainer
            The trainer currently handling the model.
        pl_module : pytorch_lightning.LightningModule
            The model currently being trained.
        """
        if (trainer.current_epoch % self.log_every_n_epochs) != 0:
            return
        # Check for the TensorBoard SummaryWriter
        writer = get_tensorboard_summary_writer(trainer.loggers)
        if writer is None:
            return
        # Get data samples
        dataloader = trainer.datamodule.val_dataloader()
        batch = next(iter(dataloader))
        input_data, recon_data, *_ = batch
        # Compute data sizes
        _, steps_tot, neur_tot = recon_data.shape
        batch_size, steps_obs, neur_in = input_data.shape
        # Compute model output
        rates, *_ = self.batch_fwd(pl_module, batch)
        # Convert data to numpy arrays
        recon_data = recon_data.detach().cpu().numpy()
        rates = rates.detach().cpu().numpy()
        # Create subplots
        fig, axes = plt.subplots(
            self.n_samples, 2, sharex=True, sharey=True, figsize=(10, 10)
        )
        for i, ax_row in enumerate(axes):
            for ax, array in zip(ax_row, [recon_data, rates]):
                ax.imshow(array[i].T)
                ax.vlines(steps_obs, 0, neur_tot, color="coral")
                ax.hlines(neur_in, 0, steps_tot, color="coral")
                ax.set_xlim(0, steps_tot)
                ax.set_ylim(0, neur_tot)
        plt.tight_layout()
        # Log the plot to tensorboard
        writer.add_figure("raster_plot", fig, trainer.global_step)

class TrajectoryPlotCallback(pl.Callback):
    """Plots the top-3 PC's of the latent trajectory for
    all samples in the validation set and logs to tensorboard.
    """

    def __init__(self, batch_fwd=batch_fwd, log_every_n_epochs=100):
        """Initializes the callback.

        Parameters
        ----------
        batch_fwd: func, optional
            A function that takes a model and a batch of data and
            performs the forward pass, returning the model output.
            May be useful if your model requires specialized I/O.
        log_every_n_epochs : int, optional
            The frequency with which to plot and log, by default 100
        """
        self.batch_fwd = batch_fwd
        self.log_every_n_epochs = log_every_n_epochs

    def on_validation_epoch_end(self, trainer, pl_module):
        """Logs plots at the end of the validation epoch.

        Parameters
        ----------
        trainer : pytorch_lightning.Trainer
            The trainer currently handling the model.
        pl_module : pytorch_lightning.LightningModule
            The model currently being trained.
        """
        # Skip evaluation for most epochs to save time
        if (trainer.current_epoch % self.log_every_n_epochs) != 0:
            return
        # Check for the TensorBoard SummaryWriter
        writer = get_tensorboard_summary_writer(trainer.loggers)
        if writer is None:
            return
        # Get the validation dataset
        val_dataloader = trainer.datamodule.val_dataloader()
        input_data, recon_data, *_ = trainer.datamodule.valid_data
        # Pass data through the model
        latents = [self.batch_fwd(pl_module, batch)[1] for batch in val_dataloader]
        latents = torch.cat(latents).detach().cpu().numpy()
        # Reduce dimensionality if necessary
        n_samp, n_step, n_lats = latents.shape
        if n_lats > 3:
            latents_flat = latents.reshape(-1, n_lats)
            pca = PCA(n_components=3)
            latents = pca.fit_transform(latents_flat)
            latents = latents.reshape(n_samp, n_step, 3)
            explained_variance = np.sum(pca.explained_variance_ratio_)
        else:
            explained_variance = 1.0
        # Create figure and plot trajectories
        fig = plt.figure(figsize=(10, 10))
        ax = fig.add_subplot(111, projection="3d")
        for traj in latents:
            ax.plot(*traj.T, alpha=0.2, linewidth=0.5)
        ax.scatter(*latents[:, 0, :].T, alpha=0.1, s=10, c="g")
        ax.scatter(*latents[:, -1, :].T, alpha=0.1, s=10, c="r")
        ax.set_title(f"explained variance: {explained_variance:.2f}")
        plt.tight_layout()
        # Log the plot to tensorboard
        writer.add_figure("trajectory_plot", fig, trainer.global_step)

class EvaluationCallback(pl.Callback):
    """Computes and logs all evaluation metrics for the Neural Latents
    Benchmark to tensorboard. These include `co_bps`, `fp_bps`,
    `behavior_r2`, `psth_r2`, and `tp_corr`.
    """

    def __init__(
        self, batch_fwd=batch_fwd, log_every_n_epochs=20, decoding_cv_sweep=False
    ):
        """Initializes the callback.

        Parameters
        ----------
        batch_fwd: func, optional
            A function that takes a model and a batch of data and
            performs the forward pass, returning the model output.
            May be useful if your model requires specialized I/O.
        log_every_n_epochs : int, optional
            The frequency with which to plot and log, by default 100
        decoding_cv_sweep : bool, optional
            Whether to run a cross-validated hyperparameter sweep to
            find optimal regularization values, by default False
        """
        self.batch_fwd = batch_fwd
        self.log_every_n_epochs = log_every_n_epochs
        self.decoding_cv_sweep = decoding_cv_sweep

    def on_validation_epoch_end(self, trainer, pl_module):
        """Logs plots at the end of the validation epoch.

        Parameters
        ----------
        trainer : pytorch_lightning.Trainer
            The trainer currently handling the model.
        pl_module : pytorch_lightning.LightningModule
            The model currently being trained.
        """
        # Skip evaluation for most epochs to save time
        if (trainer.current_epoch % self.log_every_n_epochs) != 0:
            return
        # Get entire validation dataset from dataloader
        input_data, recon_data, *_, behavior = trainer.datamodule.valid_data
        recon_data = recon_data.detach().cpu().numpy()
        behavior = behavior.detach().cpu().numpy()
        # Get model predictions for the entire validation dataset
        val_dataloader = trainer.datamodule.val_dataloader()
        # Pass the data through the model
        rates = [self.batch_fwd(pl_module, batch)[0] for batch in val_dataloader]
        rates = torch.cat(rates).detach().cpu().numpy()
        # Compute co-smoothing bits per spike
        _, n_obs, n_heldin = input_data.shape
        heldout = recon_data[:, :n_obs, n_heldin:]
        rates_heldout = rates[:, :n_obs, n_heldin:]
        co_bps = bits_per_spike(rates_heldout, heldout)
        pl_module.log("nlb/co_bps", max(co_bps, -1.0))
        # Compute forward prediction bits per spike
        forward = recon_data[:, n_obs:]
        rates_forward = rates[:, n_obs:]
        fp_bps = bits_per_spike(rates_forward, forward)
        pl_module.log("nlb/fp_bps", max(fp_bps, -1.0))
        # Get relevant training dataset from datamodule
        *_, train_behavior = trainer.datamodule.train_data
        train_behavior = train_behavior.detach().cpu().numpy()
        # Get model predictions for the training dataset
        train_dataloader = trainer.datamodule.train_dataloader(shuffle=False)
        train_rates = [
            self.batch_fwd(pl_module, batch)[0] for batch in train_dataloader
        ]
        train_rates = torch.cat(train_rates).detach().cpu().numpy()
        # Get firing rates for observed time points
        rates_obs = rates[:, :n_obs]
        train_rates_obs = train_rates[:, :n_obs]
        # Compute behavioral decoding performance
        if "dmfc_rsg" in trainer.datamodule.hparams.dataset_name:
            tp_corr = speed_tp_correlation(heldout, rates_obs, behavior)
            pl_module.log("nlb/tp_corr", tp_corr)
        else:
            with warnings.catch_warnings():
                # Ignore LinAlgWarning from early in training
                warnings.filterwarnings("ignore", category=LinAlgWarning)
                behavior_r2 = velocity_decoding(
                    train_rates_obs,
                    train_behavior,
                    trainer.datamodule.train_decode_mask,
                    rates_obs,
                    behavior,
                    trainer.datamodule.valid_decode_mask,
                    self.decoding_cv_sweep,
                )
            pl_module.log("nlb/behavior_r2", max(behavior_r2, -1.0))
        # Compute PSTH reconstruction performance
        if hasattr(trainer.datamodule, "psth"):
            psth = trainer.datamodule.psth
            cond_idxs = trainer.datamodule.valid_cond_idxs
            jitter = trainer.datamodule.valid_jitter
            psth_r2 = eval_psth(psth, rates_obs, cond_idxs, jitter)
            pl_module.log("nlb/psth_r2", max(psth_r2, -1.0))


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

result = pd.read_csv("data/source/PVProfile1440.csv",
                     sep=";", decimal=".")

result.index = result.index.astype(int)
result.sort_index()

fig, ax = plt.subplots(1, 1)

y = ['pv_output_power_kw']

result.plot(kind='line', y=y,
            ax=ax, legend=True, lw=2)

ax.xaxis.set_label_text("Time step[min]")
ax.yaxis.set_label_text("Generated power [kW]")
ax.set_title("Solar PV generation")

ax.grid()

dir_path = "graphs/source/en"
file_path = "{}/pv.png".format(dir_path)
os.makedirs(dir_path, exist_ok=True)
fig.savefig(file_path)


import random

bag_list = [1, 1, 1, 1, 1, 1, 2, 2, 3, 3]

bag_dict = {
    '1': ['Bag of Lightness', 'Objects placed in the bag weigh 1/10 their normal weight. Can carry up to 2D6*100'
                              ' encumbrance points. See manual.', 'AN', '43'],
    '2': ['Bag of Middenheim', 'Like a Bag of Lightness, but it can carry (2D6+3)*100 encumbrance points, and is'
                               ' resistant'
                               ' to fire and water. See manual.', 'AN', '43'],
    '3': ['Bag of Resource', 'Once per day, the bearer can retrieve the necessary materials for a single spell.', 'AN',
          '43']
}

# this function picks a random object
# from the list, then takes the information from
# the corresponding dictionary
# entry.

# the randomness added on the ifs is for
# sub-classes or specifics
# within a given magic item

def pick_bag():
    choice = str(random.choice(bag_list))
    chosen_object = bag_dict[choice]
    object_id = choice
    name = chosen_object[0]
    description = chosen_object[1]
    source = chosen_object[2]
    page = chosen_object[3]
    if object_id == '1':
        roll = (random.randint(1, 6)+random.randint(1, 6))
        name += ': '+str((roll+6)*100)+' encumbrance'
    elif object_id == '2':
        roll = (random.randint(1, 6)+random.randint(1, 6))
        name += ': '+str((roll+3)*100)+' encumbrance'
    final_object = [object_id, name, description, source, page]
    return final_object