from pyjokes import get_joke
import random
import os

class Chatbot:

    def __init__(self, bot_name='Bot', user='user'):
        self.name = bot_name
        self.user = user
        # Define a function in a function
        def hello():
            print('Hello, my name is {}'.format(self.name))
        # Call the function we just defined
        hello()

    def decor_func(some_func):
        '''
            Decorator to print
            'bot_name says:' and
            'user says:' when executing a feature
        '''
        def wrapper_func(self):
            print('{} says: '.format(self.name), end='')
            some_func(self)
            print('{} says: '.format(self.user), end='')
        return wrapper_func

    @decor_func
    def greetings(self):
        ''' Feature : bot says "Hi" '''
        print('Hi {}!! How may I help you?'.format(self.user))

    @decor_func
    def motivate_me(self):
        ''' Feature : bot tells you a motivational quote '''
        try:
            with open('quotes.txt', 'r') as file:
                quotes = file.read()
                quotes = quotes.split('\n')
                print(random.choice(quotes))
        except:
            print('Sorry, something went wrong.')

    @decor_func
    def jokes(self):
        ''' Feature : bot tells you a joke '''
        try:
            print(get_joke())
        except:
            print('Sorry, something went wrong.')

    @decor_func
    def features(self):
        ''' Feature: lists features of bot '''
        print('Currently I can only tell you jokes, motivate you and tell you about my features.')

    # COMMAND DICTIONARY
    ## map_words_to_command
    my_dict = {
        'greeting,hello,hey,hi': greetings,
        'fun,bored,bore,joke': jokes,
        'inspire,motivate,sad,feeling down': motivate_me,
        'do, feature': features,
        'bye, goodbye, night, sleep, get lost': 'lets exit!'
    }

    def process(self, input):
        '''
            Takes input and uses my_dict to map it to feature(function) for output
        '''
        input_string = input.lower()

        for key,value in Chatbot.my_dict.items():
            words = key.split(',')
            for word in words:
                if word in input_string:
                    return value
        return Chatbot.features

    def deploy(self, run=True):
        '''
            Input => Process => Output => Repeat
        '''
        while(run):
            print('{} says: '.format(self.user), end='')
            cmd = input()
            exec = self.process(cmd)
            if isinstance(exec, str):
                print('Good Bye!')
                os._exit(1)
            else:
                exec(self)

my_bot = Chatbot('Jarvis', 'Akshat')
my_bot.deploy()


import logging
import xascraper.database
import abc

class StatusMixin(metaclass=abc.ABCMeta):

	# Abstract class (must be subclassed)
	__metaclass__ = abc.ABCMeta

	@abc.abstractmethod
	def pluginName(self):
		return None

	@abc.abstractmethod
	def db(self):
		return None

	def __init__(self):
		super().__init__()

		self.log = logging.getLogger("Main.%s.StatusMgr" % self.pluginName)

	def updateValue(self, sitename, key, value):

		with self.db.context_sess() as sess:
			row = sess.query(self.db.ScraperStatus)                  \
				.filter(self.db.ScraperStatus.site_name == sitename) \
				.scalar()

			if not row:
				row = self.db.ScraperStatus(site_name=sitename)
				sess.add(row)

			if key == 'nextRun':
				row.next_run = value
			elif key == 'prevRun':
				row.prev_run = value
			elif key == 'prevRunTime':
				row.prev_run_time = value
			elif key == 'isRunning':
				row.is_running = value
			else:
				self.log.error("Unknown key to update: '%s' -> '%s'", key, value)

			sess.commit()

	def getValue(self, sitename, key):

		with self.db.context_sess() as sess:
			row = sess.query(self.db.ScraperStatus)                  \
				.filter(self.db.ScraperStatus.site_name == sitename) \
				.scalar()

			if not row:
				row = self.db.ScraperStatus(site_name=sitename)
				sess.add(row)

			if key == 'nextRun':
				ret = row.next_run
			elif key == 'prevRun':
				ret = row.prev_run
			elif key == 'prevRunTime':
				ret = row.prev_run_time
			elif key == 'isRunning':
				ret = row.is_running
			else:
				self.log.error("Unknown key to fetch: '%s'", key)

			sess.commit()

		return ret

	def updateNextRunTime(self, name, timestamp):
		self.updateValue(name, "nextRun", timestamp)

	def updateLastRunStartTime(self, name, timestamp):
		self.updateValue(name, "prevRun", timestamp)

	def updateLastRunDuration(self, name, timeDelta):
		self.updateValue(name, "prevRunTime", timeDelta)

	def updateRunningStatus(self, name, state):
		self.updateValue(name, "isRunning", state)

	def getRunningStatus(self, name):
		return self.getValue(name, "isRunning")

class StatusResetter(StatusMixin):

	db = xascraper.database
	pluginName = None

	def __init__(self):
		super().__init__()
		self.log = logging.getLogger("Main.StatusMgr")

	def reset_all_plugins_run_state(self):
		with self.db.context_sess() as sess:
			rows = sess.query(self.db.ScraperStatus).all()
			for row in rows:
				if row.is_running:
					self.log.info("Resetting run-state flag for %s", row.site_name)
					row.is_running = False
					sess.commit()

	def reset_specific_plugin_run_state(self, plugin_name):
		self.log.info("Resetting run state for plugin '%s'", plugin_name)

		with self.db.context_sess() as sess:
			row = sess.query(self.db.ScraperStatus).filter(self.db.ScraperStatus.site_name == plugin_name).scalar()
			if not row:
				self.log.error("No plugin found for plugin name '%s'", plugin_name)
				return

			if row.is_running:
				self.log.info("Plugin %s is flagged as running. Clearing flag.", row.site_name)
				row.is_running = False
				sess.commit()
			else:
				self.log.warning("Plugin %s is flagged as not running already. Nothing to do!", row.site_name)


#!/usr/bin/env python
# encoding: utf-8
'''
@File  : 030_search_web_phone_number.py
@Date  : 2021/11/6 1:08
@Author: Cxs
@Email: Cxs1103@163.com
@Desc  :
'''

import re

pattern = r"1[3-9]\d{9}"

with open('./datas/030_web_phone_number') as fin:
    for line in fin:
        results = re.findall(pattern, line)
        for result in results:
            print(result)


import pickle
import sys
import pandas as pd
import numpy as np
import glob
import pickle
import matplotlib.pyplot as plt
import math
from scipy.stats import mode
import time

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import Dataset, TensorDataset

device = torch.device("cuda")
start_time = time.perf_counter()

class CustomTensorDataset(Dataset):
    def __init__(self, tensors, transform=None):
        #assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors)
        self.tensors = tensors
        self.transform = transform

    def __getitem__(self, index):
        train_service_traj = torch.tensor(self.tensors[0][index][1],dtype=torch.float32)
        train_seek_traj = torch.tensor(self.tensors[0][index][0],dtype=torch.float32)
        train_feat = torch.tensor(self.tensors[0][index][2],dtype=torch.float32)
        test_service_traj = torch.tensor(self.tensors[1][index][1],dtype=torch.float32)
        test_seek_traj = torch.tensor(self.tensors[1][index][0],dtype=torch.float32)
        test_feat = torch.tensor(self.tensors[1][index][2],dtype=torch.float32)

        y = self.tensors[2][index]

        return (train_seek_traj, train_service_traj, train_feat), (test_seek_traj, test_service_traj, test_feat), y

    def __len__(self):
        return len(self.tensors[0])

#Create Dataset for pytorch training

num_sub_traj_seek = 70

#define your model
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.rnn_seek = nn.RNN(4,2,batch_first=True)
        self.rnn_service = nn.RNN(4,2,batch_first=True)
        self.similarity = nn.CosineSimilarity(dim=1, eps=1e-6)
        self.sig = nn.Sigmoid()
        self.fc2 = nn.Sequential(
            nn.Linear(2*num_sub_traj_seek+2*num_sub_traj_seek+5,1)
        )

    def forward(self, train_seek, train_service, train_features, test_seek, test_service, test_features):
        train_seek_rearranged = train_seek.permute(1,0,2,3)
        train_service_rearranged = train_service.permute(1,0,2,3)
        test_seek_rearranged = test_seek.permute(1,0,2,3)
        test_service_rearranged = test_service.permute(1,0,2,3)

        train_seek_output = [self.rnn_seek(cell)[1][0] for cell in train_seek_rearranged]
        train_service_output = [self.rnn_service(cell)[1][0] for cell in train_service_rearranged]
        test_seek_output = [self.rnn_seek(cell)[1][0] for cell in test_seek_rearranged]
        test_service_output = [self.rnn_service(cell)[1][0] for cell in test_service_rearranged]

        train_input_tensor = torch.cat(train_service_output+[train_features],axis=1)
        train_input_tensor = torch.cat(train_seek_output+[train_input_tensor],axis=1)

        test_input_tensor = torch.cat(test_service_output+[test_features],axis=1)
        test_input_tensor = torch.cat(test_seek_output+[test_input_tensor],axis=1)
        difference = abs(train_input_tensor - test_input_tensor)
        difference = self.fc2(difference)
        return (1 - self.sig(difference)).flatten()

def processs_data(traj_1, traj_2):
    traj1_train = process_traj(traj_1)
    traj2_train = process_traj(traj_2)
    return [traj1_train, traj2_train]

def process_traj(traj):
    max_longitude = 114.51741
    min_longitude = 113.258
    max_latitude = 22.90
    min_latitude = 22.4704

    for i in range(len(traj)):
        if traj[i][1] > max_latitude:
            np.delete(traj, i)
        elif traj[i][0] > max_longitude:
            np.delete(traj, i)
        elif traj[i][1] < min_latitude:
            np.delete(traj, i)
        elif traj[i][0] < min_longitude:
            np.delete(traj, i)

    num_sub_traj_seek = 70
    sequence_length_seek = 400
    num_sub_traj_service = 70
    sequence_length_service = 200
    num_layers = 1

    longitude_distance = max_longitude - min_longitude
    latitude_distance = max_latitude - min_latitude

    def find_cell(traj):
        x = math.floor((traj[1]-min_latitude) / (latitude_distance / 500.0))
        y = math.floor((traj[0]-min_longitude) / (longitude_distance / 500.0))
        return [x, y]

    def calculate_distance(lat1, lat2, long1, long2):
        return math.sqrt(pow(lat2 - lat1, 2) + pow(long2 - long1, 2))

    def calculate_time(date1, date2):
        hours = int(date2[11:13]) - int(date1[11:13])
        mins = int(date2[14:16]) - int(date1[14:16])
        secs = int(date2[17:19]) - int(date1[17:19])
        return hours*60*60 + mins*60 + secs

    def get_hour(date1):
        return int(date1[11:13])

    def calculate_speed(lat1, lat2, long1, long2, date1, date2):
        time = calculate_time(date1, date2)
        if time != 0:
            return calculate_distance(lat1, lat2, long1, long2) / time
        return 0

    flag = traj[0][3]
    sub_traj = []
    last_sub_traj = []
    cell_traj = []
    cell_traj_seek = []
    cell_traj_service = []
    grid_array_spec = []
    first_time = traj[0][4]
    last_time = []
    distance = 0
    past_cell = []

    for point in traj:
        if point[3] != flag:
            if len(sub_traj) > 2:
                if flag == 0:
                    cell_traj_seek.append(sub_traj)
                else:
                    cell_traj_service.append(sub_traj)
                last_sub_traj = sub_traj
                sub_traj = []
            elif last_sub_traj != []:
                if flag == 0:
                    cell_traj_service.remove(last_sub_traj)
                else:
                    cell_traj_seek.remove(last_sub_traj)
                sub_traj = last_sub_traj
            else:
                sub_traj = []
            flag = point[3]
        cell = find_cell(point)
        grid_array_spec.append(cell)
        speed = 0
        if past_cell != []:
            speed = calculate_speed(past_cell[0], cell[0], past_cell[1], cell[1], point[4], last_time)
        features = [cell[0], cell[1], get_hour(point[4]), speed]
        sub_traj.append(features)
        last_time = point[4]
        past_cell = [cell[0], cell[1]]
        cell = []
    if len(sub_traj) > 2:
        if flag == 0:
            cell_traj_seek.append(sub_traj)
        else:
            cell_traj_service.append(sub_traj)
    grid_array = grid_array_spec

    training_grids_seek = cell_traj_seek
    training_grids_service = cell_traj_service

    def find_mode_cell(grid):
        x_mode, counts = mode(np.array(grid))
        return np.array(x_mode)[0]

    def average_distances(seek_traj, service_traj):
        seeking_distances = []
        service_distances = []

        for sub_traj in seek_traj:
            distance = 0
            last_cell = sub_traj[0]
            for cell in sub_traj:
                if cell != last_cell:
                    distance = distance + 1
                    last_cell = cell
            seeking_distances.append(distance)

        for sub_traj in service_traj:
            distance = 0
            last_cell = sub_traj[0]
            for cell in sub_traj:
                if cell != last_cell:
                    distance = distance + 1
                    last_cell = cell
            service_distances.append(distance)

        avg_seeking = 0
        avg_service = 0
        if len(seeking_distances) != 0:
            avg_seeking = sum(seeking_distances) / len(seeking_distances)
        if len(service_distances) != 0:
            avg_service = sum(service_distances) / len(service_distances)
        return [avg_seeking, avg_service]

    avg_seeking, avg_service = average_distances(training_grids_seek, training_grids_service)
    longitude_cell, latitude_cell = find_mode_cell(grid_array)
    feature = [longitude_cell, latitude_cell, avg_seeking, avg_service, len(training_grids_service)]
    features = feature

    # This goes through each sub-trajectory and pads it as necessary
    while len(training_grids_seek) > num_sub_traj_seek:
        training_grids_seek.remove(training_grids_seek[len(training_grids_seek)-1])
    while len(training_grids_seek) < num_sub_traj_seek:
        training_grids_seek.append(training_grids_seek[np.random.randint(len(training_grids_seek))])
    for sub_traj in training_grids_seek:
        while len(sub_traj) > sequence_length_seek:
            sub_traj.remove(sub_traj[len(sub_traj)-1])
        while len(sub_traj) < sequence_length_seek:
            sub_traj.append(sub_traj[len(sub_traj)-1])

    while len(training_grids_service) > num_sub_traj_service:
        training_grids_service.remove(training_grids_service[len(training_grids_service)-1])
    while len(training_grids_service) < num_sub_traj_service:
        training_grids_service.append([[-1,-1,0,0]])
    for sub_traj in training_grids_service:
        while len(sub_traj) > sequence_length_service:
            sub_traj.remove(sub_traj[len(sub_traj)-1])
        while len(sub_traj) < sequence_length_service:
            sub_traj.append(sub_traj[len(sub_traj)-1])

    training = [training_grids_seek, training_grids_service, features]

    return training

def check_accuracy(testing, loader, model):
    if testing:
        print("Checking accuracy on test data")
    else:
        print("Checking accuracy on training data")

    num_correct = 0
    num_samples = 0
    model.eval()

    with torch.no_grad():
        for x1, x2, y in loader:
            train_seek_traj = x1[0].to(device)
            train_service_traj = x1[1].to(device)
            train_feat = x1[2].to(device)
            test_seek_traj = x2[0].to(device)
            test_service_traj = x2[1].to(device)
            test_feat = x2[2].to(device)
            labels = y.to(device)
            scores = model(train_seek_traj, train_service_traj, train_feat, test_seek_traj, test_service_traj, test_feat)
            scores[scores > 0.5] = 1
            scores[scores <= 0.5] = 0
            predictions = scores
            num_correct += (predictions == labels).sum()
            num_samples += predictions.size(0)

            print(f'Label: {labels}')
            print(f'Prediction: {predictions}')

        print(f'Got {num_correct} / {num_samples} with accuracy \ {float(num_correct)/float(num_samples)*100:.2f}')

    model.train()

def run(data, model):
    trainset = CustomTensorDataset(tensors=([data[0]], [data[1]], torch.tensor([2],dtype=torch.float)))
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=1, shuffle=True)

    scores = []
    model.eval()
    with torch.no_grad():
        for x1, x2, y in trainloader:
            train_seek_traj = x1[0].to(device)
            train_service_traj = x1[1].to(device)
            train_feat = x1[2].to(device)
            test_seek_traj = x2[0].to(device)
            test_service_traj = x2[1].to(device)
            test_feat = x2[2].to(device)
            labels = y.to(device)
            scores = model(train_seek_traj, train_service_traj, train_feat, test_seek_traj, test_service_traj, test_feat)
            scores = model(train_seek_traj, train_service_traj, train_feat, test_seek_traj, test_service_traj, test_feat)
            scores[scores > 0.5] = 1
            scores[scores <= 0.5] = 0
    model.train()
    return scores[0].item()

filename = "validate_set.pkl"
training = pickle.load( open(filename, "rb") )
#print(len(training[0]))
filename = "validate_label.pkl"
labels = pickle.load( open(filename, "rb") )

net = Net().to(device)
net.load_state_dict(torch.load("final_model.pth"))#, model_3.pth   #final_model_83.pth"))
train = []
test = []

predictions = []

for pairing in training:
    data = processs_data(pairing[0], pairing[1])
    prediction = run(data, net)
    predictions.append(prediction)
    train.append(data[0])
    test.append(data[1])

print(predictions)

testset = CustomTensorDataset(tensors=(train, test, torch.tensor(labels,dtype=torch.float)))
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=True)

check_accuracy(True, testloader, net)

end_time = time.perf_counter()
difference = (end_time-start_time) / 60
print(f"Training took {difference:0.4f} minutes")


import turtle

window = turtle.getscreen()
t = turtle.Turtle()

t.ht()
turtle.ht()

turtle.title("წარწერა turtle ეკრანზე")
turtle.setup(1200, 600)

t.pen(pencolor='magenta')

# t.write("Hello, there!..", font=('calibri', 40, 'italic underline bold'))

t.up()
t.goto(0, 200)
t.down()

t.write("მოგესალმებით ყველას! დღეს 28 იანვარია...",
        font=('calibri', 40, 'italic underline bold'),
        align='center')

# ================
turtle.exitonclick()


import csv, os
from os.path import dirname, abspath, join, normpath
from Weapon_Stock_Rates import *
from Amram_Utilities import *
from service_period import *
from wildcard_items_list import *

def Get_Aircraft_Weapon_Stocks(UI, aircraft, airwing, current_year):
    """
    Get_Aircraft_Weapon_Stocks(aircraft, airwing, item_dict, current_year):
    Iterates over loadouts an aircraft possesses, and returns the complete list
    of items this aircraft can use, filtered for the current date.
    """
    aircraft_weapon_list = {}
    designation = airwing[aircraft]['designation']
    for launcher in airwing[aircraft]['launchers']:
        for item in airwing[aircraft]['launchers'][launcher]:
            if '*' in item:
                #its a wildcard!
                items = expand_wildcard(item, Wild_Items)
            else:
                items = [item]
            for item2 in items:
                role_ratio = stock_rate(UI, aircraft, item2)
                if role_ratio > 0:
                    qty = float(airwing[aircraft]['launchers'][launcher][item])
                    item_mass = float(UI.QueryDatabase(determine_item_table(UI, item2),item2,'Weight_kg').GetString(0))
                    item_qty = role_ratio * qty
                    item_mass = item_mass * item_qty
                    if item2 in aircraft_weapon_list:
                        aircraft_weapon_list[item2] += item_qty
                    else:
                        aircraft_weapon_list[item2] = item_qty
                else:
                    aircraft_weapon_list[item2] = 0
    return aircraft_weapon_list

def check_limits(UI, stocks):
    """
    check_limits(UI, stocks):
    totals and returns the total quantity of items, and the total mass of those items.
    """
    mass = 0
    qty = 0
    volume = 0
    if type(stocks) == type({}):
        for item in stocks:
            if item != 'mass':
                item_qty = float(stocks[item])
                if item_qty < 1:
                    item_qty = 1
                else:
                    item_qty = int(item_qty)
                qty += item_qty
                if item == 'Fuel':
                    item_mass = 1.0
                    item_volume = 0.32906
                else:
                    table = determine_item_table(UI, item)
                    item_mass = float(UI.QueryDatabase(table,item,'Weight_kg').GetRow(0).GetString(0))
                    item_volume = UI.QueryDatabase(table,item,'Volume_m3').GetRow(0).GetString(0)
                    if item_volume == '':
                        item_volume = 0.0
                    else:
                        item_volume = float(UI.QueryDatabase(table,item,'Volume_m3').GetRow(0).GetString(0))
                mass += item_mass * item_qty
                volume += item_volume * item_qty
    else:
        for line in stocks:
            item = line[1]
            item_qty = int(line[2])
            if item_qty < 1:
                item_qty = 1
            else:
                item_qty = int(item_qty)
            qty += item_qty
            if item == 'Fuel':
                item_mass = 1.0
                item_volume = 0.32906
            else:
                table = determine_item_table(UI, item)
                item_mass = float(UI.QueryDatabase(table,item,'Weight_kg').GetRow(0).GetString(0))
                item_volume = float(UI.QueryDatabase(table,item,'Volume_m3').GetRow(0).GetString(0))
            mass += item_mass * item_qty
            volume += item_volume * item_qty
    return qty, mass, volume

def Get_Weapon_Service_Mod(item, year, date1, date2):
    """
    Get_Weapon_Service_Mod(item, year, date1, date2):
    provides a multiplier for stock rates based upon the current year and weapon service period.

    Results in increased stock int he middile of a service period,
    dwindling stock at the end, and low stock at the beginning
    """
    if date2 >= year >= date1:
        #we're in service now
        mod1a = (year - date1 + 2) / 6  #entering service modifier
        mod1b = (date2 - year) / 4  #exiting service modifier
        mod2a = (year - date1) / 100
        mod2b = 0

        if mod1a > 0 and mod1a < mod1b:
            mod1 = mod1a
        elif mod1b > 0 and mod1a > mod1b:
            mod1 = mod1b
        else:
            mod1 = 0
        if mod1 > 1:
            mod1 = 1

        if mod2a > 0 and mod2a < 0.1:
            mod2 = mod2a
        elif mod2a >= 0.1:
            mod2 = 0.1
        else:
            mod2 = 0
        mod = mod1 + mod2
    else:
        mod = 0
    if mod < 0:
        mod = 0
    return mod

def Get_Own_Stock(UI, unit, current_year, country):
    """
    Get_Own_Stock(unit, current_year):
    determines an appropriate loadout, and the stock needed to reload it, returns the results.
    """
    table = determine_unit_table(UI, unit)
    #configure launcher loadout too based on this data.
    load_item = ''
    own_stock_list = {}
    loadout_entry = {}
    own_launchers = UI.QueryDatabase('platform_launcher', unit, 'LauncherId, LauncherClass, IsReloadable')
    for launcher_num in xrange(own_launchers.Size()):
        if own_launchers.GetRow(launcher_num).GetString(0) != "Error":
            LauncherId = own_launchers.GetRow(launcher_num).GetString(0)
            LauncherClass = own_launchers.GetRow(launcher_num).GetString(1)
            Reloadable = int(own_launchers.GetRow(launcher_num).GetString(2))
            Launcher_Config = UI.GetCompatibleItemList(launcher_num)
            launcher_items = {}
            wild_names = []
            for item_x in xrange(Launcher_Config.Size()):
                #item = Launcher_Config.GetRow(item_x).GetString(0)
                item = Launcher_Config.GetString(item_x)
                #item may be a wildcard, check for that now!
                if '*' in item:
                    #wildcard
                    wild_names.append(item)
                    wild_list = expand_wildcard(item, Wild_Items)
                else:
                    wild_list = [item]
                for item in wild_list:
                    if country in servicekit:
                        if item in servicekit[country]:
                            date1 = float(servicekit[country][item]['Entry'])
                            date2 = float(servicekit[country][item]['Exit'])
                            service_mod = Get_Weapon_Service_Mod(item, current_year, date1, date2)
                        else:
                            date1 = 2999
                            date2 = 1900
                            service_mod = 0
                    else:
                        table = determine_item_table(UI, item)
                        date1 = float(UI.QueryDatabase(table,item,'InitialYear').GetRow(0).GetString(0))
                        date2 = float(UI.QueryDatabase(table,item,'FinalYear').GetRow(0).GetString(0))
                        if table in ['fueltank']:
                            service_mod = 1
                        else:
                            service_mod = Get_Weapon_Service_Mod(item, current_year, date1, date2)

                    if not date1 > current_year and not date2 < current_year:
                        qty = float(UI.GetItemCapacityForLauncher(launcher_num, item)) * service_mod
                        launcher_items[item] = qty

            #keep the item with the highest stock value, load that for now
            #need to make something better for choosing stock to load.
            high_val = 0
            has_load_item = False
            for item in launcher_items:
                if launcher_items[item] > high_val:
                    high_val = launcher_items[item]
                    load_item = item
                    has_load_item = True

            #build reload stock list
            is_wild = False
            for wild_name in wild_names:
                if wild_name in load_item:
                    #then we were a wildcard in the launcher config, not the full name, so lookup the wildcard name
                    is_wild = True
                    for item_x in xrange(Launcher_Config.Size()):
                        item = Launcher_Config.GetString(item_x)
                        if item == wild_name:
                            load_item_qty = int(UI.GetItemCapacityForLauncher(launcher_num, item))
                            break
                    break
            if not is_wild:
                for item_x in xrange(Launcher_Config.Size()):
                    item = Launcher_Config.GetString(item_x)
                    if item == load_item:
                        load_item_qty = int(UI.GetItemCapacityForLauncher(launcher_num, item))
                        break

            if has_load_item:
                #build loadout list
                loadout_entry[launcher_num] = [load_item, load_item_qty]
                #Add stock if reloadable
                if Reloadable:
                    stock_lvl = {'torpedo':4,'ballistic':5,'missile':3}
                    stock = stock_lvl.get(determine_item_table(UI, load_item),5)
                    qty = float(load_item_qty) * stock
                    if load_item in own_stock_list:
                        own_stock_list[load_item] += qty
                    else:
                        own_stock_list[load_item] = qty

    return own_stock_list, loadout_entry

def airwing_stock(UI, airwing, current_year, country):
    """
    airwing_stock(airwing, item_dict, current_year, country):
    iterates over all the present aircraft, and compiles a list of all the items needed and their quantities.
    Returns the resulting dictionary.
    """
    airwing_stock = {}
    for aircraft in airwing:
        airwing_qty = airwing[aircraft]['count']
        aircraft_weapon_list = Get_Aircraft_Weapon_Stocks(UI, aircraft, airwing, current_year)
        for item in aircraft_weapon_list:
            if item in airwing_stock:
                airwing_stock[item] += float(aircraft_weapon_list[item]) * airwing_qty
            else:
                airwing_stock[item] = float(aircraft_weapon_list[item]) * airwing_qty
    for item in airwing_stock:
        if country in servicekit:
            if item in servicekit[country]:
                date1 = float(servicekit[country][item]['Entry'])
                date2 = float(servicekit[country][item]['Exit'])
                service_mod = Get_Weapon_Service_Mod(item, current_year, date1, date2)
            else:
                service_mod = 0
        else:
            table = determine_item_table(UI, item)
            date1 = float(UI.QueryDatabase(table,item,'InitialYear').GetString(0))
            date2 = float(UI.QueryDatabase(table,item,'FinalYear').GetString(0))
            if table in ['fueltank']:
                service_mod = 1
            else:
                service_mod = Get_Weapon_Service_Mod(item, current_year, date1, date2)
        airwing_stock[item] *= service_mod
    return airwing_stock

def generate_airwing(UI):
    """
    generate_airwing(UI):
    itemises the present child aircraft for use in finding needed stocks.
    """
    airwing = {}
    FP = UI.GetFlightPortInfo()
    for n in xrange(FP.GetUnitCount()):
        UIn = FP.GetUnitPlatformInterface(n)
        name = UIn.GetPlatformClass()
        if name in airwing:
            airwing[name]['count'] += 1
        else:
            airwing[name] = {}
            airwing[name]['count'] = 1
            if UIn.HasThrottle():
                table = 'air'
            else:
                table = 'simpleair'

            aircraft_data = UI.QueryDatabase(table,name, 'InitialYear, FinalYear, FuelCapacity_kg, Weight_kg, MaxTakeoffWeight_kg, Designation').GetRow(0)
            if aircraft_data.GetString(0) != 'Error' and aircraft_data.Size() == 6:
                airwing[name]['date1'] = aircraft_data.GetString(0)
                airwing[name]['date2'] = aircraft_data.GetString(1)
                airwing[name]['fuelcap'] = aircraft_data.GetString(2)
                airwing[name]['mass'] = aircraft_data.GetString(3)
                airwing[name]['MTOW'] = aircraft_data.GetString(4)
                airwing[name]['designation'] = aircraft_data.GetString(5)

                airwing[name]['payload'] = float(airwing[name]['MTOW']) - float(airwing[name]['mass']) - float(airwing[name]['fuelcap'])

                #replace dependence on data_dict with QueryDatabase when able to perform multi-line lookup
                airwing[name]['launchers'] = {}

                #own_launchers = UI.QueryDatabase('platform_launcher', name, 'LauncherClass')
                for launcher_num in xrange(UIn.GetLauncherCount()):
                    airwing[name]['launchers'][launcher_num] = {}
                    try:
                        Reloadable = int(own_launchers.GetRow(launcher_num).GetString(2))
                    except:
                        Reloadable = 0
                    launcher_items = UIn.GetCompatibleItemList(launcher_num)
                    #Launcher_Config = UI.QueryDatabase('launcher_configuration',LauncherClass,'ChildClass, ChildCapacity')
                    wild_names = []
                    for item_x in xrange(launcher_items.Size()):
                        item = launcher_items.GetString(item_x)
                        #iterate through launcher names and append items
                        qty = UIn.GetItemCapacityForLauncher(launcher_num, item)
                        airwing[name]['launchers'][launcher_num][item] = qty
    return airwing

def GetMagClasses(UI, magname):
    class1 = UI.QueryDatabase('stores',magname,'Class1').GetRow(0).GetString(0).split(';')
    class2 = UI.QueryDatabase('stores',magname,'Class2').GetRow(0).GetString(0).split(';')
    class3 = UI.QueryDatabase('stores',magname,'Class3').GetRow(0).GetString(0).split(';')
    class4 = UI.QueryDatabase('stores',magname,'Class4').GetRow(0).GetString(0).split(';')
    classlist = []
    for itemlist in [class1, class2, class3, class4]:
        for item in itemlist:
            if item not in classlist and item != '':
                classlist.append(item)
    return classlist

def get_mag_stock_mod(UI, mag, mag_items, mag_weight, mag_volume, mag_weight_limit, mag_item_limit, mag_volume_limit):
    if mag_weight > 0:
        weight_mod = (0.95 * mag_weight_limit) / mag_weight
    else:
        weight_mod = 4.29e9
    if mag_items > 0:
        qty_mod = mag_item_limit / mag_items
    else:
        qty_mod = 4.29e9
    if mag_volume > 0:
        volume_mod = mag_volume_limit / mag_volume
    else:
        volume_mod = 4.29e9

    return min(weight_mod, qty_mod, volume_mod)

def MagGenerator(UI):
    """
    MagGenerator(UI):
    Takes a date, and in return will load the launchers, and stock the magazines with date appropriate gear.

    This is not group capable, nothing prevents calling it from a group capable handler.
    """
    BB = UI.GetBlackboardInterface()
    SM = UI.GetScenarioInterface()
    mag_date = SM.GetScenarioDateAsString()
    current_year = DateString_DecimalYear(mag_date)

    launcher_count = UI.GetLauncherCount()

    unit = UI.GetPlatformClass()
    name = UI.GetPlatformName()
    UI.DisplayMessage('Configuring %s for year %0.3f' % (name, current_year))
    set_mag_items = float(4.29e9)
    set_mag_tonnage = float(4.29e9)
    if BB.KeyExists('MagTonnage'):
        set_mag_tonnage = float(BB.ReadMessage('MagTonnage')) * 1000
        if UI.HasFlightPort():
            FP = UI.GetFlightPortInfo()
            set_mag_tonnage *= FP.GetUnitCount()
    elif BB.KeyExists('MagItems'):
        set_mag_items = float(BB.ReadMessage('MagItems'))
    elif not UI.IsSurface():
        #how did we even get here?
        return
    plat_setup = {}

    if UI.QueryDatabase('platform_magazine',unit,'MagazineClass').GetRow(0).GetString(0) != 'Error':
        airwing = generate_airwing(UI)
        #get our country:
        if UI.IsSurface():
            table = 'ship'
        elif UI.IsGroundVehicle() or UI.IsFixed():
            table = 'ground'
        country = UI.QueryDatabase(table, unit, 'Country').GetRow(0).GetString(0)
        mag_info = UI.QueryDatabase('platform_magazine', unit, 'MagazineId, MagazineClass')
        magazines = {}
        magazines['limited'] = {}
        magazines['unlimited'] = {}
        all_items = UI.GetMagazineItems()
        for mag in xrange(mag_info.Size()):
            magname = mag_info.GetRow(mag).GetString(1)
            mag_id = mag_info.GetRow(mag).GetString(0)
            classes = GetMagClasses(UI, magname)
            if classes == []:
                magazines['unlimited'][mag_id] = magname
            else:
                magazines['limited'][mag_id] = magname

        airwing_stock_list = airwing_stock(UI, airwing, current_year, country)
        if launcher_count > 0:
            own_stock_list, loadout_entry = Get_Own_Stock(UI, unit, current_year, country)

        #split stock lists into magazine assignments.
        mag_assignments = {}
        assigned_items = []

        #limited magazine stock
        for mag in magazines['limited']:
            magname = magazines['limited'][mag]
            classes = GetMagClasses(UI, magname)
            mag_assignments[mag] = {}
            mag_assignments[mag]['Max Items'] = UI.QueryDatabase('stores',magname,'Capacity').GetRow(0).GetString(0)
            mag_assignments[mag]['Max Weight'] = UI.QueryDatabase('stores',magname,'MaxWeight_kg').GetRow(0).GetString(0)
            mag_assignments[mag]['Max Volume'] = UI.QueryDatabase('stores',magname,'MaxVolume_m3').GetRow(0).GetString(0)
            mag_assignments[mag]['items'] = {}
            for item in airwing_stock_list:
                if item in classes:
                    #then we put it here.
                    mag_assignments[mag]['items'][item] = airwing_stock_list[item]
                    assigned_items.append(item)
            if launcher_count > 0:
                for item in own_stock_list:
                    if item in classes:
                        #then we put it here.
                        mag_assignments[mag]['items'][item] = own_stock_list[item]
                        assigned_items.append(item)
        #unlimited magazine stock
        for mag in magazines['unlimited']:
            magname = magazines['unlimited'][mag]
            mag_assignments[mag] = {}
            if BB.KeyExists('MagTonnage'):
                mag_assignments[mag]['Max Weight'] = set_mag_tonnage
            else:
                mag_assignments[mag]['Max Weight'] = UI.QueryDatabase('stores',magname,'MaxWeight_kg').GetRow(0).GetString(0)
            if BB.KeyExists('MaxItems'):
                mag_assignments[mag]['Max Items'] = set_mag_items
            else:
                mag_assignments[mag]['Max Items'] = UI.QueryDatabase('stores',magname,'Capacity').GetRow(0).GetString(0)
            if BB.KeyExists('MaxVolume'):
                mag_assignments[mag]['Max Volume'] = set_mag_volume
            else:
                mag_assignments[mag]['Max Volume'] = UI.QueryDatabase('stores',magname,'MaxVolume_m3').GetRow(0).GetString(0)
            mag_assignments[mag]['items'] = {}
            for item in airwing_stock_list:
                if item not in assigned_items:
                    #then we put it here.
                    mag_assignments[mag]['items'][item] = airwing_stock_list[item]
            if launcher_count > 0:
                for item in own_stock_list:
                    if item not in assigned_items:
                        #then we put it here.
                        mag_assignments[mag]['items'][item] = own_stock_list[item]
        #stock assigned, check for over qty, or over weight
        mag_stock_mod = {}
        for mag in mag_assignments:
            mag_weight_limit = float(mag_assignments[mag]['Max Weight'])
            mag_item_limit = float(mag_assignments[mag]['Max Items'])
            mag_volume_limit = float(mag_assignments[mag]['Max Volume'])
            for n in xrange(all_items.Size()):
                item = all_items.GetString(n)
                qty = UI.GetMagazineIdQuantity(item, int(mag))
                if qty > 0:
                    mag_assignments[mag]['items'][item] = qty
            mag_items, mag_weight, mag_volume = check_limits(UI, mag_assignments[mag]['items'])
            if float(mag_weight_limit) == 0:  mag_weight_limit = float(4.29e9)
            if float(mag_item_limit)   == 0:  mag_item_limit = float(4.29e9)
            if float(mag_volume_limit) == 0:  mag_volume_limit = float(4.29e9)

            if mag in magazines['unlimited']:
                mag_weight_limit = min(mag_weight_limit, set_mag_tonnage)
                mag_item_limit = min(mag_weight_limit, set_mag_items)

            mag_stock_mod[mag] = get_mag_stock_mod(UI, mag, mag_items, mag_weight, mag_volume, mag_weight_limit, mag_item_limit, mag_volume_limit)
        mag_loads = {}
        #begin creating the magazine entry lines
        for mag_num in mag_assignments:
            stock_mod = mag_stock_mod[mag_num]
            for item in mag_assignments[mag_num]['items']:
                item_table = determine_item_table(UI, item)
                if item_table in ['fueltank']:
                    item_qty = int(mag_assignments[mag_num]['items'][item])
                else:
                    item_qty = int(mag_assignments[mag_num]['items'][item] * stock_mod)
                if item_qty < 1:
                    item_qty = 0
                if 'Nuclear' in UI.QueryDatabase(item_table,item,'DamageModel').GetRow(0).GetString(0) and not BB.KeyExists('MagGenAllowNukes'):
                    item_qty = 0
#                if launcher_count > 0:
#                    if item in own_stock_list and item_qty < own_stock_list[item]:
#                        item_qty += int(own_stock_list[item])
                if item_qty > 0:
                    try:
                        mag_loads[mag_num][item] = item_qty
                    except KeyError:
                        mag_loads[mag_num] = {item:item_qty}
        #set magazine
        stocked = {}
        for magazine in sorted(mag_loads.keys()):
            UI.SetMagazineEmpty(int(magazine))
            for item in mag_loads[magazine]:
                qty = int(mag_loads[magazine][item])
                UI.AddItemToMagazine(item, qty)
                stocked[item]=qty

    elif launcher_count > 0:
        own_stock_list, loadout_entry = Get_Own_Stock(unit, unit_dict, current_year)
    else:
        #no magazine to store items, no launchers to configure either, wtf are we doing?  Terminate now.
        return

    loads = []
    if launcher_count > 0:
        for launcher_num in loadout_entry:
            item = loadout_entry[launcher_num][0]
            item_qty = loadout_entry[launcher_num][1]
            loadline = (launcher_num, item, item_qty)
            loads.append(loadline)
        plat_setup['launcher_content'] = loads

        #set loadout
        for line in sorted(loads):
            Lnum = int(line[0])
            item = line[1]
            UI.LoadLauncher(Lnum, item)
    #tonnage = 0
    #for mag in mag_loads:
    #    tonnage += check_limits(UI, mag_loads[mag])[1]/1000
    tonnage = check_limits(UI, stocked)[1]/1000
    UI.DisplayMessage('%0.1f tons of munitions provided to <%d> %s (%s)' % (tonnage, UI.GetPlatformId(), UI.GetPlatformName(), unit))

def stock_rate(UI, aircraft, item):
    qty = 0
    sortie = 0
    item_table = determine_item_table(UI, item)

    if UI.QueryDatabase('air', aircraft, 'InitialYear').GetRow(0).GetString(0) != 'Error':
        unit_role = UI.QueryDatabase('air', aircraft,'Designation').GetRow(0).GetString(0)
    else:
        unit_role = UI.QueryDatabase('simpleair', aircraft,'Designation').GetRow(0).GetString(0)

    try:
        sortie = int(sorties[unit_role])
    except KeyError:
        return 0

    if item_table == 'cm':
        qty = cm.get(unit_role,2)
    elif item_table == 'fueltank':
        qty = tank.get(unit_role,1)
    elif item_table == 'sonobuoy':
        qty = buoy.get(unit_role,0)
    elif item_table == 'ballistic':
        if 'Nuclear' in UI.QueryDatabase(item_table,item,'DamageModel').GetRow(0).GetString(0):
            qty = nuke_bomb.get(unit_role,0)
        elif UI.QueryDatabase(item_table,item,'BallisticType').GetRow(0).GetString(0) == '5':  #rockets
            qty = rockets.get(unit_role,0)
        elif (UI.QueryDatabase(item_table,item,'BallisticType').GetRow(0).GetString(0) == '0' or
            UI.QueryDatabase(item_table,item,'BallisticType').GetRow(0).GetString(0) == '2'):  #gun round, autocannon round
            qty = gun.get(unit_role,1)
        elif UI.QueryDatabase(item_table,item,'BallisticType').GetRow(0).GetString(0) == '1':  #unguided bomb
            if UI.QueryDatabase('torpedo',UI.QueryDatabase('ballistic',item,'Payload').GetRow(0).GetString(0),'weight_kg').GetRow(0).GetString(0) != 'Error':
                if UI.QueryDatabase('torpedo',item,'ClassificationId').GetRow(0).GetString(0) == '138':  #mine
                    qty = mine_bomb.get(unit_role,0)
                elif UI.QueryDatabase('torpedo',item,'WeaponType').GetRow(0).GetString(0) == '2':
                    qty = DC.get(unit_role,0)
            mass = float(UI.QueryDatabase(item_table, item,'Weight_kg').GetRow(0).GetString(0))
            if mass < 125:
                qty = ib_125.get(unit_role,0)
            elif mass < 250:
                qty = ib_250.get(unit_role,0)
            elif mass < 500:
                qty = ib_500.get(unit_role,0)
            elif mass < 750:
                qty = ib_750.get(unit_role,0)
            elif mass < 1000:
                qty = ib_1000.get(unit_role,0)
            elif mass < 2000:
                qty = ib_2000.get(unit_role,0)
            elif mass < 3000:
                qty = ib_3000.get(unit_role,0)
        elif UI.QueryDatabase(item_table,item,'BallisticType').GetRow(0).GetString(0) == '3':  #guided bomb
            mass = float(UI.QueryDatabase(item_table, item,'Weight_kg').GetRow(0).GetString(0))
            if mass < 125:
                qty = gb_125.get(unit_role,0)
            elif mass < 250:
                qty = gb_250.get(unit_role,0)
            elif mass < 500:
                qty = gb_500.get(unit_role,0)
            elif mass < 750:
                qty = gb_750.get(unit_role,0)
            elif mass < 1000:
                qty = gb_1000.get(unit_role,0)
            elif mass < 2000:
                qty = gb_2000.get(unit_role,0)
    elif item_table == 'torpedo':
        if UI.QueryDatabase(item_table,item,'WeaponType').GetRow(0).GetString(0) == '1':
            qty = torpedo.get(unit_role,0)
        elif UI.QueryDatabase(item_table,item,'WeaponType').GetRow(0).GetString(0) == '2':
            qty = DC.get(unit_role,0)
        else:
            qty = mine.get(unit_role,0)
    elif item_table == 'missile':
        if 'Nuclear' in UI.QueryDatabase(item_table,item,'DamageModel').GetRow(0).GetString(0):
            qty = nuke_mis.get(unit_role,0)
        else:
            targets = bin(int(UI.QueryDatabase(item_table,item,'targetFlags').GetRow(0).GetString(0)))[2:]
            surface = int(targets[-1])
            if len(targets) > 1:
                air = int(targets[-2])
            else:
                air = 0
            if len(targets) > 2:
                land = int(targets[-3])
            else:
                land = 0
            if len(targets) > 3:
                missile = int(targets[-4])
            else:
                missile = 0
            if len(targets) > 4:
                sub = int(targets[-5])
            else:
                sub = 0

            mass = float(UI.QueryDatabase(item_table, item,'Weight_kg').GetRow(0).GetString(0))

            if air:
                range_km = float(UI.QueryDatabase(item_table, item,'MaxRange_km').GetRow(0).GetString(0))
                year = float(UI.QueryDatabase(item_table, item,'InitialYear').GetRow(0).GetString(0))
                year -= 1950
                if UI.QueryDatabase('optical', UI.QueryDatabase(item_table, item,'SensorClass').GetRow(0).GetString(0),'Cost').GetRow(0).GetString(0) != 'Error':  #its ir
                    short_ir = year / 5 * 0.08 * 16
                    medium_ir = year / 5 * 0.08 * 24
                    long_ir = year / 5 * 0.08 * 32

                    if range_km < short_ir:
                        qty = ir_sraam.get(unit_role,0)
                    elif range_km < medium_ir:
                        qty = ir_mraam.get(unit_role,0)
                    elif range_km < long_ir:
                        qty = ir_lraam.get(unit_role,0)
                    else:
                        qty = ir_vlraam.get(unit_role,0)
                elif UI.QueryDatabase('esm', UI.QueryDatabase(item_table, item,'SensorClass').GetRow(0).GetString(0),'Cost').GetRow(0).GetString(0) != 'Error':  #its esm
                    qty = ir_vlraam.get(unit_role,0)  #just using the longest of the actives for now.
                else:  #its radar
                    short_radar = year / 5.0 * 0.08 * 50.0
                    medium_radar = year / 5.0 * 0.08 * 100.0
                    long_radar = year / 5.0 * 0.08 * 200.0
                    very_long_radar = year / 5.0 * 0.08 * 200.0
                    semiactive = int(UI.QueryDatabase('radar', UI.QueryDatabase(item_table, item,'SensorClass').GetRow(0).GetString(0),'IsSemiactive').GetRow(0).GetString(0))
                    if range < short_radar:
                        if semiactive:
                            qty = sr_sraam.get(unit_role,0)
                        else:
                            qty = ar_sraam.get(unit_role,0)
                    elif range < medium_radar:
                        if semiactive:
                            qty = sr_mraam.get(unit_role,0)
                        else:
                            qty = ar_mraam.get(unit_role,0)
                    elif range < long_radar:
                        if semiactive:
                            qty = sr_lraam.get(unit_role,0)
                        else:
                            qty = ar_lraam.get(unit_role,0)
                    else:
                        if semiactive:
                            qty = sr_vlraam.get(unit_role,0)
                        else:
                            qty = ar_vlraam.get(unit_role,0)
            elif UI.QueryDatabase('esm', UI.QueryDatabase(item_table, item,'SensorClass').GetRow(0).GetString(0),'Cost').GetRow(0).GetString(0) != 'Error':  #its esm
                if mass < 50:
                    qty = usarm.get(unit_role,0)
                elif mass < 150:
                    qty = vsarm.get(unit_role,0)
                elif mass < 400:
                    qty = sarm.get(unit_role,0)
                elif mass < 1000:
                    qty = arm.get(unit_role,0)
                elif mass > 1000:
                    qty = larm.get(unit_role,0)
                elif mass > 2500:
                    qty = vlarm.get(unit_role,0)
            elif surface and land:
                if mass < 50:
                    qty = usagsm.get(unit_role,0)
                elif mass < 150:
                    qty = vsagsm.get(unit_role,0)
                elif mass < 400:
                    qty = sagsm.get(unit_role,0)
                elif mass < 1000:
                    qty = agsm.get(unit_role,0)
                elif mass > 1000:
                    qty = lagsm.get(unit_role,0)
                elif mass > 2500:
                    qty = vlagsm.get(unit_role,0)
            elif surface:
                if mass < 50:
                    qty = usasm.get(unit_role,0)
                elif mass < 150:
                    qty = vsasm.get(unit_role,0)
                elif mass < 400:
                    qty = sasm.get(unit_role,0)
                elif mass < 1000:
                    qty = asm.get(unit_role,0)
                elif mass > 1000:
                    qty = lasm.get(unit_role,0)
                elif mass > 2500:
                    qty = vlasm.get(unit_role,0)
            elif land:
                if mass < 50:
                    qty = usagm.get(unit_role,0)
                elif mass < 150:
                    qty = vsagm.get(unit_role,0)
                elif mass < 400:
                    qty = sagm.get(unit_role,0)
                elif mass < 1000:
                    qty = agm.get(unit_role,0)
                elif mass > 1000:
                    qty = lagm.get(unit_role,0)
                elif mass > 2500:
                    qty = vlagm.get(unit_role,0)

    #return float(sortie) * float(qty)
    return float(qty)


from collections import namedtuple

import matplotlib.pyplot as plt
import matplotlib as mpl
import peakutils
import numpy as np

from ..base import Base

class spec(Base):
    def plot(
        self,
        dset="m",
        thres=0.01,
        min_dist=5,
        xmin=0,
        xmax=40,
        c=0,
    ):
        def get_peaks(x, y):
            Peak = namedtuple("Peak", "idx freq amp")
            idx = peakutils.indexes(y, thres=thres, min_dist=min_dist)
            peak_amp = [y[i] for i in idx]
            freqs = [x[i] for i in idx]
            return [Peak(i, f, a) for i, f, a in zip(idx, freqs, peak_amp)]

        def plot_spectra(ax, x, y, peaks):
            ax.plot(x, y)
            for _, freq, amp in peaks:
                ax.text(
                    freq,
                    amp + 0.03 * max(y),
                    f"{freq:.2f}",
                    # fontsize=5,
                    rotation=90,
                    ha="center",
                    va="bottom",
                )
            ax.set_title(self.m.sim_name)
            ax.spines["top"].set_visible(False)
            ax.spines["right"].set_visible(False)

        def plot_modes(axes, f):
            for ax in axes.flatten():
                ax.cla()
                ax.set(xticks=[], yticks=[])
            mode = self.m.get_mode("m", f)[0]
            extent = [
                0,
                mode.shape[1] * self.m.dx * 1e9,
                0,
                mode.shape[0] * self.m.dy * 1e9,
            ]
            for c in range(3):
                abs_arr = np.abs(mode[:, :, c])
                phase_arr = np.angle(mode[:, :, c])
                axes[0, c].imshow(
                    abs_arr,
                    cmap="inferno",
                    # vmin=0,
                    # vmax=mode_list_max,
                    norm=mpl.colors.LogNorm(vmin=5e-3),
                    extent=extent,
                    interpolation="None",
                    aspect="equal",
                )
                axes[1, c].imshow(
                    phase_arr,
                    aspect="equal",
                    cmap="hsv",
                    vmin=-np.pi,
                    vmax=np.pi,
                    interpolation="None",
                    extent=extent,
                )
                axes[2, c].imshow(
                    phase_arr,
                    aspect="equal",
                    alpha=abs_arr / abs_arr.max(),
                    cmap="hsv",
                    vmin=-np.pi,
                    vmax=np.pi,
                    interpolation="nearest",
                    extent=extent,
                )

        def get_spectrum():
            x = self.m.fft.m.freqs[:]
            y = self.m.fft.m.max[:, c]
            x1 = np.abs(x - xmin).argmin()
            x2 = np.abs(x - xmax).argmin()
            return x[x1:x2], y[x1:x2]

        fig = plt.figure(constrained_layout=True, figsize=(15, 6))
        gs = fig.add_gridspec(1, 2)
        ax_spec = fig.add_subplot(gs[0, 0])
        x, y = get_spectrum()
        peaks = get_peaks(x, y)
        plot_spectra(ax_spec, x, y, peaks)
        axes_modes = gs[0, 1].subgridspec(3, 3).subplots()
        vline = ax_spec.axvline(10, ls="--", lw=0.8, c="#ffb86c")
        # plot_modes(axes_modes, peaks[0].freq)

        def onclick(event):
            if event.inaxes == ax_spec:
                f = 10
                if event.button.name == "RIGHT":
                    freqs = [p.freq for p in peaks]
                    f = freqs[(np.abs(freqs - event.xdata)).argmin()]
                else:
                    f = event.xdata
                vline.set_data([f, f], [0, 1])
                plot_modes(axes_modes, f)
                fig.canvas.draw()

        fig.canvas.mpl_connect("button_press_event", onclick)
        return fig, ax_spec, axes_modes


def get_params(mem, pos):
    a=mem[mem[pos+1]]
    b=mem[mem[pos+2]]
    c=mem[pos+3]
    return (a,b,c)

with open("input.txt", "rt") as f:
    memO = [int(x) for x in f.read().split(',')]

    for n in range(99):
        for v in range(99):
            mem = memO[:]
            mem[1] = n
            mem[2] = v
            pos=0
            while mem[pos]!=99:
                opcode=mem[pos]
                a,b,c = get_params(mem, pos)
                if opcode==1:
                    mem[c]=a+b
                elif opcode==2:
                    mem[c]=a*b
                else:
                    raise ValueError(f"Bad opcode: {opcode}")
                pos+=4

            if mem[0] == 19690720:
                print(100 * n + v)
                exit()
    print("oops")


from django.urls import path
from cart.views import CartAddView, CartShowView, CartUpdateView, CartDeleteView

app_name = 'cart'
urlpatterns = [
    path('add', CartAddView.as_view(), name='add'),
    path('show', CartShowView.as_view(), name='show'),
    path('update', CartUpdateView.as_view(), name='update'),
    path('delete', CartDeleteView.as_view(), name ='delete'),
]


import cv2

FRONT_fACE_PATH = 'Cascades/haarcascade_frontalface_alt2.xml'
PROFILE_FACE_PATH = 'Cascades/haarcascade_profileface.xml'

'''人脸检测的相关类'''

class FaceDetector:
    detect_count = 0
    __cascades = []
    __last_detect_faces = []

    # 初始化
    def __init__(self):
        self.__cascades.append(cv2.CascadeClassifier(FRONT_fACE_PATH))
        self.__cascades.append(cv2.CascadeClassifier(PROFILE_FACE_PATH))

    # 合并重叠人脸
    def __merge_faces(self, front_faces, profile_faces):
        if len(front_faces) == 0:
            return profile_faces

        if len(profile_faces) == 0:
            return front_faces

        res = front_faces.copy().tolist()

        for profile in profile_faces:
            overlap = False

            for front in front_faces:
                # 如果和其中一个矩形有重叠，就continue
                if self.__is_overlap(front, profile):
                    overlap = True
                    break

            # 如果没有重叠，就把这个前脸加入
            if not overlap:
                res.append(profile)

        return res

        # 判断是否重叠

    # 判断是否重叠
    def __is_overlap(self, rect1, rect2):
        l1, t1, w1, h1 = rect1
        l2, t2, w2, h2 = rect2
        (l1, t1, w1, h1) = (l1 * 2, t1 * 2, w1 * 2, h1 * 2)
        (l2, t2, w2, h2) = (l2 * 2, t2 * 2, w2 * 2, h2 * 2)

        r1 = l1 + w1
        b1 = t1 + h1

        r2 = l2 + w2
        b2 = t2 + h2

        res = False

        res = res | (b1 < t2 & r1 < l2)
        res = res | (b1 < t2 & l1 > r2)
        res = res | (t1 > b2 & r1 < l2)
        res = res | (t1 > b2 & l1 > r2)

        res = not res
        return res

    # 获取人脸坐标
    def detect_faces(self, raw_img):
        self.detect_count = (self.detect_count + 1) % 4
        count = self.detect_count

        if count != 0:
            return self.__last_detect_faces

        gray = cv2.cvtColor(raw_img, cv2.COLOR_BGR2GRAY)
        frame = cv2.resize(gray, (0, 0), fx=0.5, fy=0.5)

        faces = []
        cascades = self.__cascades

        faces_1 = cascades[0].detectMultiScale(frame, scaleFactor=1.2, minNeighbors=2, minSize=(16, 16))
        faces_2 = cascades[1].detectMultiScale(frame, scaleFactor=1.2, minNeighbors=3, minSize=(16, 16))

        faces = self.__merge_faces(faces_1, faces_2)
        self.__last_detect_faces = faces
        return faces


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

Module to find features in non diferentiable clouds

Created on Tue Apr 27 15:24:01 2021

@author: hernando

"""

import numpy             as np

import clouds.utils      as cu

#import scipy.ndimage     as ndimg

#import scipy.sparse.csgraph as scgraph

#import collections
#import functools
#import operator

#import clouds.ridges     as ridges
#import tables            as tb

#from collections import namedtuple

#
#  get elements
#

#--- Filters

def edge_filter(img        : np.array,
                steps      : tuple = None,
                mask       : np.array = None,
                hard       : bool = True,
                perc       : float = 100):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)
    egrad, edir, _    = _gradient(bins, mask, cells, enes)
    efil   = mask.flatten()
    if (hard):
        efil              = _edge_filter(bins, mask, cells, egrad, edir)

    nfil        = np.full(shape, False, dtype = bool)
    ngrad       = np.zeros(shape)
    nfil [mask] = efil
    ngrad[mask] = egrad

    cut0  = np.percentile(egrad[efil], 100 - perc)
    umask = ngrad > cut0
    nfil [~umask] = False

    #nfil, _ = np.histogramdd(cells, bins, weights = efil)
    return nfil, ngrad

def ridge_filter(img   : np.array,
                 steps : tuple = None,
                 perc  : float = 100,
                 hard: bool = True,
                 mask  : np.array = None):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)
    egrad, edir, _    = _gradient(bins, mask, cells, enes)

    xfil        = mask.flatten()
    rv, _, _, _ = _curvature_transverse(bins, mask, cells, enes, edir)

    if (hard):
        xfil, rv = _ridge_filter(bins, mask, cells, enes, edir)

    xfil = xfil if hard else mask.flatten()

    nfil       = np.full(shape, False, dtype = bool)
    nval       = np.zeros(shape)
    nfil[mask] = xfil
    nval[mask] = rv

    cut0  = np.percentile(rv, perc)
    umask = nval <= cut0
    nfil [~umask] = False

    return nfil, nval

def ridge_lambda_filter(img   : np.array,
                        steps : tuple = None,
                        perc  : float = 100,
                        hard : bool = True,
                        mask  : np.array = None):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask

    egrad, edir = gradient     (img, steps, mask)
    mcur , mdir = min_curvature(img, steps, mask)

    xfil = mask & (mcur < 0)
    if (hard):
        xfil = (xfil) & (np.isclose(np.sum(edir * mdir, axis = 0), 0))

    if (np.sum(xfil) > 0):
        cut0  = np.percentile(mcur[xfil], perc)
        xfil = (xfil) & (mcur < cut0)

    nfil = np.full(shape, False)
    nfil[xfil] = True

    return nfil, mcur

def node_filter(img   : np.array,
                steps : tuple = None,
                mask  : np.array = None):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask
    bins, cells, enes = _cells(img, steps, mask = mask)
    egrad, _, _       = _gradient(bins, mask, cells, enes)

    isnode  = np.isclose(egrad, 0)

    nfil, _ = np.histogramdd(cells, bins, weights = isnode)

    return nfil.astype(bool)

def blob_filter(img : np.array,
                steps = None,
                mask  = None,
                extended = False):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask
    lap  = laplacian(img, steps, mask, extended)
    umask = (mask) & (-lap >0)
    nfil = node_filter(-lap, steps, mask = umask)

    #bins, mask, cells, enes = mask(img, steps, mask = mask)
    #lap                     = _laplacian(bins, mask, cells, enes, extended = extended)

    #nlap, _  = np.histogramdd(cells, bins, weights = -lap)
    #nfil     = node_filter(nlap, steps)

    return nfil

#--- math objects

def gradient(img   : np.array,
             steps : tuple = None,
             mask  : np.array = None):

    ndim  = img.ndim
    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask
    bins, cells, enes = _cells(img, steps, mask = mask)

    egrad, edir, _ =  _gradient(bins, mask, cells, enes)

    ngrad = np.zeros(shape)
    ngrad[mask] = egrad

    ndir = np.zeros((ndim,) + img.shape)
    for i in range(ndim):
        ndir[i, mask] = edir[:, i]

    return ngrad, ndir

# def grad_vector(ngrad, ndir, steps):

#     ndim  = ndir.shape[0]
#     steps = np.ones(ndim) if steps is None else steps

#     vdir  = np.zeros(ndir.shape)
#     for i in range(ndim): vdir[i] = steps[i] * ndir[i]
#     norma = np.sqrt(np.sum(vdir * vdir, axis = 0))
#     norma[np.isclose(norma, 0)] = 1

#     grad = np.zeros(ndir.shape)
#     for i in range(ndim):
#         grad[i] = ngrad * vdir[i]/norma
#     return grad

def curvature(img, edir, steps = None, mask = None):

    mask  = np.full(img.shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)

    curv        =  _curvature(bins, mask, cells, enes, edir)
    #ncurv       = np.zeros(img.shape)
    #ncurv[mask] = curv
    ncurv, _ = np.histogramdd(cells, bins, weights = curv)

    return ncurv

def laplacian(img, steps = None, mask = None, extended = False):

    mask  = np.full(img.shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)
    lap               = _laplacian(bins, mask, cells, enes, extended = extended)

    nlap, _ = np.histogramdd(cells, bins, weights = lap)

    return nlap

def min_curvature_transverse(img, steps = None, mask = None):

    mask = np.full(img.shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)

def curvature_transverse(img, edir, steps = None, mask = None):

    mask = np.full(img.shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)
    #size = len(enes)
    #ndim = img.ndim
    #xdir = np.zeros((size, ndim))
    #for i in range(ndim): xdir[:, i] = edir[i, mask]
    xdir = edir
    curv, _, _, _  = _curvature_transverse(bins, mask, cells, enes, xdir)
    ncurv, _ = np.histogramdd(cells, bins, weights = curv)

    return ncurv

def min_curvature(img, steps = None, mask = None):

    mask = np.full(img.shape, True) if mask is None else mask

    bins, cells, enes = _cells(img, steps, mask = mask)
    #size = len(enes)
    #ndim = img.ndim
    #xdir = np.zeros((size, ndim))
    #for i in range(ndim): xdir[:, i] = edir[i, mask]
    curv, edir  = _min_curvature(bins, mask, cells, enes)

    ndim  = img.ndim
    shape = img.shape
    ncurv = np.zeros(shape)
    ncurv[mask] = curv
    ndir  = np.zeros( (ndim,) + shape)
    for i in range(ndim): ndir[i][mask] = edir[i]

    return ncurv, ndir

#----- internal

def _bins(img, steps = None, x0 = None):

    ndim  = img.ndim
    shape = img.shape
    steps = np.ones(ndim)  if steps is None else steps
    x0s   = np.zeros(ndim) if x0    is None else x0

    ibins = [np.linspace(0, n, n + 1) for n in shape]
    bins  = [x0 + step * ibin for x0, step, ibin in zip(x0s, steps, ibins)]

    return bins

def _steps(bins):
    steps  = np.array([ibin[1] - ibin[0] for ibin in bins])
    return steps

def _scells(img, bins, mask):

    ndim      = img.ndim
    icells    = cu.to_coors(np.argwhere(mask))
    enes      = img[mask]
    centers   = [cu.ut_centers(ibin) for ibin in bins]
    cells     = [centers[i][icells[i]] for i in range(ndim)]

    return cells, enes

def _cells(img, steps = None, x0 = None, mask = None):

    ndim = img.ndim

    #mask      = img > mask
    mask      = np.full(img.shape, True) if mask is None else mask
    icells    = cu.to_coors(np.argwhere(mask))
    enes      = img[mask]
    #nsize     = len(enes)
    #kids      = np.arange(nsize).astype(int)

    bins      = _bins(img, steps, x0)
    centers   = [cu.ut_centers(ibin) for ibin in bins]
    cells     = [centers[i][icells[i]] for i in range(ndim)]

    # ISSUE: do we need icells, then ibins?
    return bins, cells, enes

# def _dene(bins, mask, cells, enes):

#     ndim, size   = len(cells), len(enes)
#     steps        = _steps(bins)
#     ids          = np.arange(size)

#     potential, _ = np.histogramdd(cells, bins, weights = enes)
#     kid, _       = np.histogramdd(cells, bins, weights = ids)

#     nn_dir       = np.zeros(potential.shape + (ndim,))
#     nn_potential = np.zeros(potential.shape)
#     nn_kid       = np.copy(kid)

#     #moves = get_moves_updown(ndim)
#     for move in moves(ndim):

#        #vmove = steps * move
#        # mmove = np.sqrt(np.sum(vmove * vmove))

#         coors_next         = [cells[i] + steps[i] * move[i] for i in range(ndim)]
#         potential_next, _  = np.histogramdd(coors_next, bins, weights = enes)
#         kid_next, _        = np.histogramdd(coors_next, bins, weights = ids)

#         sel_next           = potential_next > nn_potential
#         sel                = (mask) & (sel_next)

#         nn_potential[sel]  = potential_next[sel]
#         nn_kid[sel]        = kid_next[sel]
#         for i in range(ndim):
#             nn_dir[sel, i] = -move[i]

#     epot  = nn_potential[mask] - potential[mask]
#     edir  = nn_dir[mask, :]
#     epath = nn_kid[mask]

#     return epot, edir, epath

def _gradient(bins, mask, cells, enes):

    ndim, size   = len(cells), len(enes)
    steps        = _steps(bins)
    ids          = np.arange(size)

    potential, _ = np.histogramdd(cells, bins, weights = enes)
    kid, _       = np.histogramdd(cells, bins, weights = ids)

    nn_dir       = np.zeros(potential.shape + (ndim,))
    nn_potential = np.copy(potential)
    nn_egrad     = np.zeros(potential.shape)
    nn_kid       = np.copy(kid)

    #moves = get_moves_updown(ndim)
    for move in moves(ndim):

        vmove = steps * move
        mmove = np.sqrt(np.sum(vmove * vmove))

        coors_next         = [cells[i] + steps[i] * move[i] for i in range(ndim)]
        potential_next, _  = np.histogramdd(coors_next, bins, weights = enes)
        kid_next, _        = np.histogramdd(coors_next, bins, weights = ids)
        egrad_next         = (potential_next - potential)/mmove

        sel_next           = potential_next > nn_potential
        sel                = (mask) & (sel_next)

        nn_potential[sel]  = potential_next[sel]
        nn_egrad[sel]      = egrad_next[sel]
        nn_kid[sel]        = kid_next[sel]
        for i in range(ndim):
            nn_dir[sel, i] = -move[i]

    egrad = nn_egrad[mask]
    edir  = nn_dir[mask, :]
    epath = nn_kid[mask].astype(int)

    return egrad, edir, epath

# def _gradient_bin(bins, mask, cells, enes):

#     ndim  = len(cells)
#     size  = len(cells[0])
#     steps = _steps(bins)
#     print('steps ', steps)
#     ids   = np.arange(size)

#     potential, _ = np.histogramdd(cells, bins, weights = enes)
#     kids, _      = np.histogramdd(cells, bins, weights = ids)

#     nn_potential = np.copy(potential)
#     nn_grad      = np.zeros(potential.shape)
#     nn_dir       = np.zeros(potential.shape + (ndim,))
#     nn_kids      = np.copy(kids) .astype(int)

#     #moves = get_moves_updown(ndim)
#     for i, move in enumerate(moves(ndim)):

#         vmove  = np.array([steps[i] * move[i] for i in range(ndim)])
#         vmode  = np.sqrt(np.sum(vmove * vmove))
#         coors_next         = [cells[i] + steps[i] * move[i] for i in range(ndim)]
#         potential_next, _  = np.histogramdd(coors_next, bins, weights = enes)
#         kids_next, _       = np.histogramdd(coors_next, bins, weights = ids)

#         sel_pot_next       = potential_next > nn_potential
#         sel                = (mask) & (sel_pot_next)

#         nn_potential[sel]  = potential_next [sel]
#         #nn_move     [sel]  = i
#         nn_grad     [sel]  = (potential_next[sel] - potential[sel])/vmode
#         nn_kids     [sel]  = kids_next      [sel]
#         for i in range(ndim):
#             nn_dir[sel, i] = -move[i]

#     egrad = nn_grad[mask]
#     epath = nn_kids[mask]
#     edir  = nn_dir[mask, :]
#     #emove = nn_move[mask]

#     return egrad, edir, epath

def _curvature(bins, mask, cells, enes, edir):

    ndim         = len(cells)
    steps        = _steps(bins)

    vmove        = steps * edir
    vmag2        = np.sum(vmove * vmove)

    potential, _ = np.histogramdd(cells, bins, weights = enes)
    shape        = potential.shape
    mcurve       = np.zeros(shape)

    for sign in (-1, +1):
        coors_next        = [cells[i] + sign * vmove[i] for i in range(ndim)]
        potential_next, _ = np.histogramdd(coors_next, bins, weights = enes)

        sel             = (mask)
        mcurve   [sel] +=  (potential_next[sel] - potential[sel])/vmag2

    curve = mcurve[mask]/2
    return curve

def _laplacian(bins, mask, cells, enes, extended = False):

    ndim, size = len(cells), len(cells[0])
    lap        = np.zeros(size)
    moves      = moves_face(ndim) if extended else moves_axis(ndim)
    for move in moves:
        icur = _curvature(bins, mask, cells, enes, move)
        lap += icur
    return lap

def _curvature_transverse(bins, mask, cells, enes, edir):

    ndim,size    = len(cells), len(cells[0])

    potential, _ = np.histogramdd(cells, bins, weights = enes)
    shape        = potential.shape
    nn_curvemin  = np.zeros(shape)
    nn_curvemax  = np.zeros(shape)
    nn_curve     = np.zeros(shape)

    edir  = edir * np.ones ((size, ndim)) if (edir.ndim == 1) else edir
    #print(edir.shape)
    direction = [np.histogramdd(cells, bins, weights = edir[:, i])[0] \
                 for i in range(ndim)]

    curves = [] # temporal holder to return all the curves
    for move in moves_face(ndim):

        mcur      = _curvature(bins, mask, cells, enes, move)
        mcurve, _ = np.histogramdd(cells, bins, weights = mcur)

        vdot              = np.zeros(shape)
        for i in range(ndim):
            vdot += direction[i] * move[i]
        sel_transv = np.isclose(vdot, 0)

        mcurvesel = (mask) & (sel_transv)

        nn_curve[mcurvesel] += mcurve[mcurvesel]
        curves.append(mcurve)

        sel        = (mcurvesel) & (mcurve < nn_curvemin)
        nn_curvemin[sel] = mcurve[sel]

        sel        = (mcurvesel) & (mcurve > nn_curvemax)
        nn_curvemax[sel] = mcurve[sel]

    curve    = nn_curve   [mask]
    curvemin = nn_curvemin[mask]
    curvemax = nn_curvemax[mask]

    return curve, curvemin, curvemax, curves

def _min_curvature(bins, mask, cells, enes):

    ndim         = len(cells)
    potential, _ = np.histogramdd(cells, bins, weights = enes)
    shape        = potential.shape
    nn_mincurve  = np.zeros(shape)
    nn_edir      = np.zeros((ndim,) + shape)

    for move in moves_face(ndim):

        mcur      = _curvature(bins, mask, cells, enes, move)
        mcurve, _ = np.histogramdd(cells, bins, weights = mcur)

        sel_mincv = mcurve < nn_mincurve
        sel       = (mask) & (sel_mincv)

        nn_mincurve[sel]  = mcurve[sel]

        for i in range(ndim):
            nn_edir[i, sel] = move[i]

    mincurve = nn_mincurve[mask]
    edir     = [nn_edir[i][mask] for i in range(ndim)]

    return mincurve, edir

#  Internal filters

def _edge_filter(bins, mask, cells, egrad, edir):

    ndim         = len(cells)
    steps        = [ibin[1] - ibin[0] for ibin in bins]

    vgrad, _     =  np.histogramdd(cells, bins, weights = egrad)
    vdir         = [edir[:, i] for i in range(ndim)]

    sel          = np.full(vgrad.shape, True)

    for sign in (-1, 1):
        cells_next   = [cells[i] + sign * steps[i] * vdir[i] for i in range(ndim)]
        vgrad_next,_ = np.histogramdd(cells_next, bins, weights = egrad)
        isel         = vgrad_next < vgrad
        sel          = (sel) & (isel)

    edge = sel[mask]

    return edge

def _ridge_filter(bins, mask, cells, enes, edir):

    ndim, size = len(cells), len(cells[0])

    vcur, _, _, _ = _curvature_transverse(bins, mask, cells, enes, edir)

    ridge   = np.full(size, True, dtype = bool)
    ncurv   = np.full(size, 0)
    ncurv   = vcur

    for move in moves_face(ndim):
        #if (np.sum(move) <= 0): continue
        #print(move)
        dmove = np.zeros((size, ndim), dtype = int)
        for i in range(ndim):
            dmove[:, i] = move[i]
        #print(dmove.shape)
        acur, _, _, _ = _curvature_transverse(bins, mask, cells, enes, dmove)

        sel         = acur < vcur
        ridge[sel]  = False
        ncurv[sel]  = ncurv[sel]

    sel        = vcur >= 0
    ridge[sel] = False

    return ridge, ncurv

# def normal_laplacian(bins, mask, cells, enes, sigma = 1, steps = None, extended = True):

#     ndim   = len(cells)
#     steps  = np.ones(ndim) if steps is None else np.array(steps)
#     sigmas = sigma / steps
#     #print(sigmas)
#     img, _  = np.histogramdd(cells, bins, weights = enes)
#     simg   = ndimg.gaussian_filter(img, sigmas)
#     wenes  = simg[mask]
#     #lap  = sigma * ndimg.laplace(simg)
#     lap    = sigma * laplace(bins, mask, cells, wenes, extended = extended)
#     return lap

# xsigmas = np.linspace(0.2, 2, 10)

# def blob_filter(bins, mask, cells, weights, sigmas = (1,), extended = True):

#     size    = len(cells[0])
#     nsigmas = len(sigmas)
#     steps   = _steps(bins)

#     img, _  = np.histogramdd(cells, bins, weights = weights)

#     nlaps = np.zeros((size, nsigmas))
#     msigmas = np.zeros(size)
#     mlap    = np.zeros(size)
#     hasmax  = np.full(size, False)
#     for i, sigma in enumerate(sigmas):
#         nlap   = - normal_laplacian(bins, mask, cells, weights, sigma, steps, extended)
#         sel    = nlap > mlap
#         mlap   [sel] = nlap[sel]
#         usel   = (nlap > 0) & (nlap < mlap)
#         hasmax[usel] = True
#         msigmas[sel] = 1.8 * sigma
#         nlaps[:, i]  = nlap

#     return msigmas, mlap, hasmax, nlaps

#
#--- Utilities
#

# def ut_scale(values, a = 0, b = 1):

#     xmin, xmax = np.min(values), np.max(values)
#     scale  = (values - xmin)/(xmax - xmin)
#     return scale

# def ut_centers(xs : np.array) -> np.array:
#     return 0.5* ( xs[1: ] + xs[: -1])

# def arstep(x, step, delta = False):
#     delta = step/2 if delta else 0.
#     return np.arange(np.min(x) - delta, np.max(x) + step + delta, step)

# def to_coors(vs):
#     ndim = len(vs[0])
#     xs = [np.array([vi[i] for vi in vs]) for i in range(ndim)]
#     return xs

# def ut_sort(values, ids, reverse = True):

#     vals_ = sorted(zip(values, ids), reverse = reverse)
#     vals  = np.array([v[0] for v in vals_])
#     kids  = np.array([v[1] for v in vals_])
#     return vals, kids

#   Moves
#   Todo: convert them into kernels?
#--------------

def movei(i, ndim):
    ei    = np.zeros(ndim, dtype = int)
    ei[i] = 1
    return ei

def moves(ndim):

    u0 = np.zeros(ndim)
    def u1(idim):
        ui1 = np.zeros(ndim)
        ui1[idim] = 1
        return ui1.astype(int)

    vs = (u0, u1(0), -1 * u1(0))
    for idim in range(1, ndim):
        us = (u0, u1(idim), -1 * u1(idim))
        vs = [(vi + ui).astype(int) for vi in vs for ui in us]
    vs.pop(0)

    return vs

def moves_face(ndim):

    #for i in range(ndim):
    vis = moves(ndim)
    vos = []
    for i in range(ndim):
        for vi in vis:
            if (np.sum(vi[:i] * vi[:i]) == 0) & (vi[i] == 1): vos.append(vi)
    return vos

def moves_pos(ndim):
    movs = moves(ndim)
    _ok  = lambda x: np.sum([vx >= 0 for vx in x]) == ndim
    movs = [mov for mov in movs if _ok(mov)]
    return movs

def moves_axis(ndim):
    movs = moves(ndim)
    _ok = lambda x: (np.sum(x*x) <= 1) & (np.sum(x) == 1)
    movs = [mov for mov in movs if _ok(mov)]
    return movs

#
#  Path Utilites
#

def get_path(kid, epath):
    path = []
    while epath[kid] != kid:
        path.append(kid)
        kid = epath[kid]
    path.append(kid)
    return path

def get_path_from_link(kid0, kid1, epath):
    path1 = get_path(kid0, epath)
    path2 = get_path(kid1, epath)
    path1.reverse()
    path = path1 + path2
    return path

def get_path_to_path(kid, epath, path):
    ipath  = []
    while not np.isin(kid, path):
        ipath.append(kid)
        kid_next = epath[kid]
        if (kid_next == kid): return []
        kid = kid_next
    ipath.append(kid)
    return ipath

#
#  Topology
#

def cells_selection(cells, sel):
    return [cell[sel] for cell in cells]

def get_segment(cells, kids):
    """ Fron a list of local IDs returns a segment to plot
    inputs:
        cells: tuple(array), m-dim tuple with n-size array with the cells' cordinates positions
        kids: tuple(int), list of the ID to generate the segment
    """
    ndim = len(cells)
    segment = [np.array([float(cells[i][kid]) for kid in kids]) for i in range(ndim)]
    return segment

#  debugging
#----------

def _edge_filter_hard(img       : np.array,
                      steps     : tuple = None,
                      perc      : float = 80,
                      mask      : np.array = None):

    shape = img.shape
    mask  = np.full(shape, True) if mask is None else mask

    bins, cells, enes  = _cells(img, steps, mask = mask)
    egrad, edir, epath = _gradient(bins, mask, cells, enes)

    size = len(enes)
    kid  = np.arange(size).astype(int)
    xfil = egrad[epath] < egrad[kid]
    for k in np.argwhere(kid == True):
        ok = np.max(egrad[epath == k]) < egrad[k]
        xfil[k] = ok

    nfil        = np.full(shape, False, dtype = bool)
    ngrad       = np.zeros(shape)
    nfil [mask] = xfil
    ngrad[mask] = egrad

    #nfil, _ = np.histogramdd(cells, bins, weights = efil)
    return nfil, ngrad

#---- Analysis

# def analysis(df, name = 'e'):

#     true = df.istrue.values
#     ext  = df.isext .values
#     cells_types = (name + 'isnode', name +'isborder',
#                    name + 'ispass', name +'isridge', 'iscore')

#     dat = {}
#     for itype in cells_types:
#         vals  = df[itype].values
#         ntot  = np.sum(vals)
#         yes   = vals & true
#         noes  = vals & (~true)
#         nyes  = np.sum(yes)
#         nnoes = np.sum(noes)
#         isext = np.sum(vals & ext)
#         eff   = float(nyes/ntot) if ntot >0 else -1
#         dat[name+itype+'_success']  = nyes
#         dat[name+itype+'_extreme']  = isext
#         dat[name+itype+'_failures'] = nnoes
#         dat[name+itype+'_eff']      = eff
#     return dat


from PyDSS.ProfileManager.base_definitions import BaseProfileManager, BaseProfile
from PyDSS.ProfileManager.common import PROFILE_TYPES
from PyDSS.exceptions import InvalidParameter
from PyDSS.common import DATE_FORMAT
from datetime import datetime
import pandas as pd
import numpy as np
import datetime
import h5py
import copy
import os

class ProfileManager(BaseProfileManager):

    def __init__(self,  sim_instance, solver, options, logger, **kwargs):
        super(ProfileManager, self).__init__(sim_instance, solver, options, logger, **kwargs)
        self.Objects = kwargs["objects"]
        if os.path.exists(self.basepath):
            self.logger.info("Loading existing h5 store")
            self.store = h5py.File(self.basepath, "r+")
        else:
            self.logger.info("Creating new h5 store")
            self.store = h5py.File(self.basepath, "w")
            for profileGroup in PROFILE_TYPES.names():
                self.store.create_group(profileGroup)
        self.setup_profiles()
        return

    def setup_profiles(self):
        self.Profiles = {}
        for group, profileMap in self.mapping.items():
            if group in self.store:
                grp = self.store[group]
                for profileName, mappingDict in profileMap.items():
                    if profileName in grp:
                        objects = {x['object']: self.Objects[x['object']] for x in mappingDict}
                        self.Profiles[f"{group}/{profileName}"] = Profile(
                            self.sim_instance,
                            grp[profileName],
                            objects,
                            self.solver,
                            mappingDict,
                            self.logger,
                            **self.kwargs
                        )
                    else:
                        self.logger.warning("Group {} \ data set {} not found in the h5 store".format(
                            group, profileName
                        ))
            else:
                self.logger.warning("Group {} not found in the h5 store".format(group))
        return

    def create_dataset(self, dname, pType, data ,startTime, resolution, units, info):
        grp = self.store[pType]
        if dname not in grp:
            dset = grp.create_dataset(
                dname,
                data=data,
                shape=(len(data),),
                maxshape=(None,),
                chunks=True,
                compression="gzip",
                compression_opts=4,
                shuffle=True
            )
            self.createMetadata(
                dset, startTime, resolution, data, units, info
            )
        else:
            self.logger.error('Dataset "{}" already exists in group "{}".'.format(dname, pType))
            raise Exception('Dataset "{}" already exists in group "{}".'.format(dname, pType))

    def add_from_arrays(self, data, name, pType, startTime, resolution, units="", info=""):
        r, c = data.shape
        if r > c:
            for i in range(c):
                d = data[:, i]
                dname = name if i==0 else "{}_{}".format(name, i)
                self.create_dataset(dname=dname, pType=pType, data=d, startTime=startTime, resolution=resolution,
                                    units=units, info=info)
        else:
            for i in range(r):
                d = data[i, :]
                dname = name if i==0 else "{}_{}".format(name, i)
                self.create_dataset(dname=dname, pType=pType, data=d, startTime=startTime, resolution=resolution,
                                    units=units, info=info)
        return

    def add_profiles_from_csv(self, csv_file, name, pType, startTime, resolution_sec=900, units="",
                              info=""):
        data = pd.read_csv(csv_file).values
        self.add_profiles(data, name, pType, startTime, resolution_sec=resolution_sec, units=units, info=info)

    def add_profiles(self, data, name, pType, startTime, resolution_sec=900, units="", info=""):
        if type(startTime) is not datetime.datetime:
            raise InvalidParameter("startTime should be a python datetime object")
        if pType not in PROFILE_TYPES.names():
            raise InvalidParameter("Valid values for pType are {}".format(PROFILE_TYPES.names()))
        if data:
            self.add_from_arrays(data, name, pType, startTime, resolution_sec, units=units, info=info)
        self.store.flush()
        return

    def createMetadata(self, dSet, startTime, resolution, data, units, info):
        metadata = {
            "sTime": str(startTime),
            "eTime": str(startTime + datetime.timedelta(seconds=resolution*len(data))),
            "resTime": resolution,
            "npts": len(data),
            "min": min(data),
            "max": max(data),
            "mean": np.mean(data),
            "units": units,
            "info": info,
        }
        for key, value in metadata.items():
            if isinstance(value, str):
                value = np.string_(value)
            dSet.attrs[key] = value
        return

    def remove_profile(self, profile_type, profile_name):
        return

    def update(self):
        results = {}
        for profileaName, profileObj in self.Profiles.items():
            result = profileObj.update()
            results[profileaName] = result
        return results

class Profile(BaseProfile):

    DEFAULT_SETTINGS = {
        "multiplier": 1,
        "normalize": False,
        "interpolate": False
    }

    def __init__(self, sim_instance, dataset, devices, solver, mapping_dict, logger, **kwargs):
        super(Profile, self).__init__(sim_instance, dataset, devices, solver, mapping_dict, logger, **kwargs)
        self.valueSettings = {x['object']: {**self.DEFAULT_SETTINGS, **x} for x in mapping_dict}

        self.bufferSize = kwargs["bufferSize"]
        self.buffer = np.zeros(self.bufferSize)
        self.profile = dataset
        self.neglectYear = kwargs["neglectYear"]
        self.Objects = devices

        self.attrs = self.profile.attrs
        self.sTime = datetime.datetime.strptime(self.attrs["sTime"].decode(), DATE_FORMAT)
        self.eTime = datetime.datetime.strptime(self.attrs["eTime"].decode(), '%Y-%m-%d %H:%M:%S.%f')
        self.simRes = solver.GetStepSizeSec()
        self.Time = copy.deepcopy(solver.GetDateTime())
        return

    def update_profile_settings(self):
        return

    def update(self, updateObjectProperties=True):
        self.Time = copy.deepcopy(self.solver.GetDateTime())
        if self.Time < self.sTime or self.Time > self.eTime:
            value = 0
            value1 = 0
        else:
            dT = (self.Time - self.sTime).total_seconds()
            n = int(dT / self.attrs["resTime"])
            value = self.profile[n]
            dT2 = (self.Time - (self.sTime + datetime.timedelta(seconds=int(n * self.attrs["resTime"])))).total_seconds()
            value1 = self.profile[n] + (self.profile[n+1] - self.profile[n]) * dT2 / self.attrs["resTime"]
        if updateObjectProperties:
            for objName, obj in self.Objects.items():
                if self.valueSettings[objName]['interpolate']:
                    value = value1
                mult = self.valueSettings[objName]['multiplier']
                if self.valueSettings[objName]['normalize']:
                    valueF = value / self.attrs["max"] * mult
                else:
                    valueF = value * mult
                obj.SetParameter(self.attrs["units"].decode(), valueF)
        return value


#para pruebas:

t = int(input())
for tt in range(t):
	(n, p1, w1, m, k, a, b, c, d) = map(int, input().split())
	ps = [p1]
	ws = [w1]
	for i in range(1, n):
		pi = ((a*ps[i-1] + b) % m) +1
		ps.append(pi)
		wi = ((c*ws[i-1] + d) % k) +1
		ws.append(wi)
	print(ps)
	print(ws)


#!/usr/bin/env python3

# Created by: Matthew Meech
# Created on: Nov 2021
# This program is a Choose your own adventure game

def main():
    # process & output

    # input
    answer = input("Would you like to become a millionaire? (yes/no): ")
    print("")

    # input and output (if... elif... else... )
    if answer == "yes":
        answer = input(
            "\n\nGREAT, well let's get started. First you have to choose from three professions."
            "(thief/adventurer/shopkeeper): "
        )

        if answer == "thief":
            answer = input(
                "\n\nSo you have chosen the life of crime, your first task will be to rob a fine silk store."
                "would you like to steal mulberry silk, or golden laced silk (mulberry/gold): "
            )

            if answer == "mulberry":
                answer = input(
                    "\n\nyou successfully steal the mulberry due to low security and made $5000. "
                    " Your next heist will be at a fine Ore store called goldstone. "
                    " You have the choice of stealing gold, diamonds, or the mystery vault (gold/diamonds/vault): "
                )

                if answer == "gold":
                    print(
                        "\n\nyou take all the gold and make a run for it, you get away and hide in the garbage suitable place for a thief, "
                        " But this does not change the fact that you just got away with the gold!"
                        " you ended up stealing $10 000 and were too scared to keep stealing with your ending profit of $15 000. | ENDING #1 $15 000 | "
                    )

                elif answer == "diamonds":
                    print(
                        "\n\nyou took the diamonds and ran but tripped over your shoelaces "
                        " fall and die from the impact on the ground | GAME OVER | cause of death SLOTH | "
                    )

                elif answer == "vault":
                    print(
                        "\n\nyou get to the vault and open it with your master lock picking skills. You are surprised to see jadeite, "
                        "one of the most expensive gemstones. You act fast and take the jadeite stones and run out the door. "
                        " You later find out that the jadeite is worth $500 000 dollars and this encourages you to keep stealing. "
                        " you become a world-class thief stealing millions of dollars every year. | ENDING #2 $505 000 |  "
                    )

                else:
                    print("\n\ninvaild answer you lose!")

            elif answer == "gold":
                print(
                    "\n\nyou got caught stealing the silk due to the high security. | GAME OVER | cause of death GREAD | "
                )

            else:
                print("\n\ninvaild answer you lose!")

        elif answer == "adventurer":
            answer = input(
                "\n\nso you have chosen the life of an explorer, "
                " now you must pick a bounty you have a choice of fighting slime, or a gorilla. (slime/gorilla): "
            )

            if answer == "slime":
                answer = input(
                    "\n\nyou miraculosuoy take down the slime and complete the bounty. "
                    " You claim $3000 from the bounty and are ready for your next mission. "
                    " for your next mission you have the choice of either finding and killing a group of bandits "
                    "exploring the forbidden forest or trying to take down the legendary BLUE MAMMOTH(forest/bandits/BLUE): "
                )

                if answer == "bandits":
                    print(
                        "\n\nyou sneak up on the group of bandits and go for a takedown on their leader, "
                        " you fail horribly and get beaten to death by the gang | GAME OVER | cause of death PRIDE | "
                    )

                elif answer == "forest":
                    print(
                        "\n\nyou traverse into the forest and find yourself lost when you stumble upon a big X marks the spot. "
                        " You dig it up and find a chest. You take the chest to your house and open it. Gold, gems, and artifacts "
                        " that could be priceless are what fill the chest. after this, "
                        " you decide to stop while you're ahead and quit being an adventurer | ENDING #3 $??? ??? ??? + $3000 | "
                    )

                elif answer == "BLUE":
                    print(
                        "\n\nyou travel far to the top of the blue mountain where you find a sleeping BLUE MAMMOTH!?!? "
                        " You are about to kill it when all of the sudden you realize how cute it is. "
                        " You befriend the legendary monster and go on many adventures with it. "
                        " You gain the nickname kaya and become a legendary adventurer | ENDING #4 BLUE MAMMOTH + $3000| "
                    )

                else:
                    print("\n\ninvaild answer you lose!")

            elif answer == "gorilla":
                answer = input(
                    "\n\nyou get overwhelmed by the gorilla and get brutally "
                    " torn and ripped apart. | GAME OVER | cause of death WARTH | "
                )

            else:
                print("\n\ninvalid answer you lose!")

        elif answer == "shopkeeper":
            answer = input(
                "\n\nso you wanna be the wolf of wall street well guess what it isn't that easy. "
                " First, you will choose what you would like to base you shop around, "
                " your options consist of two things ores or being a blacksmith (ores/blacksmith ): "
            )

            if answer == "blacksmith":
                answer = input(
                    "\n\nyou make your new blacksmith shop and instantly get customers. "
                    " Now you are faced with the challenge of selling swords, shields or armor (swords/shields/armor) "
                )

                if answer == "swords":
                    print(
                        "\n\nyou start selling swords and they take off. "
                        " One day you are walking around your shop when one of the swords falls off the wall and... "
                        " startles you which leads to you dying of shock R.I.P | GAME OVER | cause of death you are just a wimp |: "
                    )

                elif answer == "shields":
                    print(
                        "\n\nyou start selling shields and at first it's slow but soon picks up a bit. "
                        " One day you sell a shield to a man/woman named Addison. "
                        " Their shield later saves them in battle and they fall in love with you and become your husband/wife. "
                        " You and your spouse open a new little shop that sells shields named protectors. | ENDING #5 LOVE + $3000 | "
                    )

                elif answer == "armor":
                    answer = input(
                        "\n\nyou stock your shelves with armor which sell super fast due to the high demand of armor in your village. "
                        " you gain enough money to expand into swords and shields as well. "
                        " Your shop becomes world-class and you have "
                        " made yourself a multimillion dollar business. | ENDING #6 Multimillion-dollar business + 3000$ | "
                    )

                else:
                    print("\n\ninvaild answer you lose!")

            elif answer == "ores":
                answer = input(
                    "\n\nyou picked ores but there is a bigger and better ores shop in "
                    " town called goldstone which put you out of business.  | GAME OVER | cause of death COVETOUSNESS | "
                )

            else:
                print("\n\ninvaild answer you lose!")

        else:
            print("\n\ninvalid answer you lose!")

    elif answer == "no":
        print(
            "\nwhy did you even click run I guess money isn't always the answer (easter egg ending #7)"
        )
    else:
        print("\ninvalid answer you lose!")

    print("\nDone.")

if __name__ == "__main__":
    main()