"""D."""
import asyncio
import time

async def task1():
    """Task1."""
    await asyncio.sleep(0.5)

async def task2():
    """Task2."""
    await asyncio.sleep(0.5)

async def task3():
    """Task3."""
    await asyncio.sleep(10)

async def handler(name):
    """Handle."""
    # task1
    total = 0
    start = time.time()

    print('{}--task1 0.5s'.format(name))
    await task1()
    finish = time.time() - start
    total += finish
    print('{}--task1 realtime {}s'.format(name, finish))

    # task2
    start = time.time()
    print('{}--task1 0.5s'.format(name))
    await task2()
    finish = time.time() - start
    total += finish
    print('{}--task2 realtime {}s'.format(name, finish))

    # task3
    start = time.time()
    print('{}--task1 10s'.format(name))
    await task3()
    finish = time.time() - start
    total += finish
    print('{}--task3 realtime {}s'.format(name, finish))

    print('{} done for {} seconds'.format(name, 11))

def main():
    """Main."""
    # Generate timings task
    total_sleep = 11 * 3

    # Wait.
    start = time.time()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(handler('handler-{}'.format(1)),
                                           handler('handler-{}'.format(2)),
                                           handler('handler-{}'.format(3))))
    total = time.time() - start
    loop.close()

    print('====')
    print('3 handler done in parallel for {} seconds'.format(total))
    print('total sleep time: {} seconds'.format(total_sleep))

if __name__ == '__main__':
    main()


# !/usr/bin python3
# -*- coding: utf-8 -*-
from app.settings import PATH

def return_diyepg():
    filename = PATH / "assets/diychannel.txt"
    if filename.is_file():
        with open(filename, "r", encoding="utf-8") as f:
            return f.read()
    return ""

if __name__ == '__main__':
    a = return_diyepg()
    print(a)


import numpy as np
from scipy.stats import skew

from lcc.stars_processing.utilities.base_descriptor import BaseDescriptor
from lcc.utils.data_analysis import to_ekvi_PAA

class SkewnessDescr(BaseDescriptor):

    """
    SkewnessDescr describes stars by skewness

    Attributes
    ----------
    bins : int, NoneType
        Dimension of reduced light curve. If it is `None` whole curve is taken.

    absolute : bool
        Absolute value of skewness is taken if it is `True`
    """
    LABEL = "Skewness"
    LC_NEEDED = True

    def __init__(self, bins=None, absolute=False):
        """
        Parameters
        ----------
        bins : int, NoneType
            Dimension of reduced light curve. If it is `None` whole curve is taken.

        absolute : bool
            Absolute value of skewness is taken if it is True
        """
        self.bins = bins
        self.absolute = absolute

    def getFeatures(self, star):
        """
        Get skewness

        Parameters
        -----------
        star : lcc.entities.star.Star object
            Star to process

        Returns
        -------
        float
            Skewness of the investigated star
        """
        lc = star.lightCurve
        if self.bins:
            _, mags = to_ekvi_PAA(lc.time, lc.mag, self.bins)
        else:
            mags = lc.mag
        sk = skew(mags)

        if self.absolute:
            sk = abs(sk)
        return sk


from src.unitxt import add_to_catalog
from src.unitxt.metrics import NER
from src.unitxt.test_utils.metrics import test_metric

metric = NER()
# Test1 single line single class
# 0.1 simple case, multi examples
predictions = [[("Amir", "Person"), ("Yaron", "Person")], [("Ran", "Person"), ("Yonatan", "Person")]]
references = [[("Yaron", "Person"), ("Ran", "Person")], [("Yonatan", "Person")]]
# precision = 1/2, recall 1/2
# Precision = 1/2, Recall = 1/1,
# total precision = 2/4, recall = 2/3
# F1 = 2 * 1/2 * 2/3 / (1/2 + 2/3) = 0.57
instance_targets = [
    {"f1_Person": 0.5, "f1_macro": 0.5, "f1_micro": 0.5, "score": 0.5},
    {"f1_Person": 0.67, "f1_macro": 0.67, "f1_micro": 0.67, "score": 0.67},
]
global_target = {"f1_Person": 0.57, "f1_macro": 0.57, "f1_micro": 0.57, "score": 0.57}

outputs = test_metric(
    metric=metric,
    predictions=predictions,
    references=references,
    instance_targets=instance_targets,
    global_target=global_target,
)

# 1.1 simple case
predictions = [[("Amir", "Person"), ("Yaron", "Person")]]
references = [[("Yaron", "Person"), ("Ran", "Person"), ("Yonatan", "Person")]]
# Precision = 1/2, Recall = 1/3, F1 = 2 * 1/2 * 1/3 / (1/2 + 1/3) = 0.4
instance_targets = [{"f1_Person": 0.4, "f1_macro": 0.4, "f1_micro": 0.4, "score": 0.4}]
global_target = {"f1_Person": 0.4, "f1_macro": 0.4, "f1_micro": 0.4, "score": 0.4}

outputs = test_metric(
    metric=metric,
    predictions=predictions,
    references=references,
    instance_targets=instance_targets,
    global_target=global_target,
)
# 1.2 more then one instance of an element
predictions = [[("Amir", "Person"), ("Yaron", "Person"), ("Yaron", "Person")]]
references = [[("Yaron", "Person"), ("Ran", "Person"), ("Yonatan", "Person")]]
# Precision = 1/3, Recall = 1/3, F1 = 2 * 1/3 * 1/3 / (1/3 + 1/3) = 0.333333
instance_targets = [{"f1_Person": 0.33, "f1_macro": 0.33, "f1_micro": 0.33, "score": 0.33}]
global_target = {"f1_Person": 0.33, "f1_macro": 0.33, "f1_micro": 0.33, "score": 0.33}

outputs = test_metric(
    metric=metric,
    predictions=predictions,
    references=references,
    instance_targets=instance_targets,
    global_target=global_target,
)
# 1.3 class with no predictions
predictions = [[]]
references = [[("Yaron", "Person"), ("Ran", "Person"), ("Yonatan", "Person")]]
# Precision = 0/0=(by def for prediction)=1, Recall = 0/3, F1 = 2 * 1 * 0 / (1 + 0) = 0
instance_targets = [{"f1_Person": 0.0, "f1_macro": 0.0, "f1_micro": 0.0, "score": 0.0}]
global_target = {"f1_Person": 0.0, "f1_macro": 0.0, "f1_micro": 0.0, "score": 0.0}

outputs = test_metric(
    metric=metric,
    predictions=predictions,
    references=references,
    instance_targets=instance_targets,
    global_target=global_target,
)
# 1.4 multi classes multi examples
predictions = [
    [
        ("Dalia", "Person"),
        ("Amir", "Person"),
        ("Yaron", "Person"),
        ("Ramat-Gan", "Location"),
        ("Ramat-Gan", "Location"),
        ("IBM", "Org"),
        ("CIA", "Org"),
        ("FBI", "Org"),
    ]
]
references = [
    [
        ("Amir", "Person"),
        ("Yaron", "Person"),
        ("Dalia", "Person"),
        ("Naftali", "Person"),
        ("Ramat-Gan", "Location"),
        ("Givataaim", "Location"),
    ]
]
# Person: Precision = 3/3, Recall = 3/4, F1 = 2 * 1 * 0.75 / (1 + 0.75) = 0.8571
# Location: Precision = 1/2, Recall = 1/2, F1 = 0.5
# Person: Precision = 0/3, Recall = 0/0 = 1(!), F1 = 0
instance_targets = [
    {"f1_Person": 0.86, "f1_Location": 0.5, "f1_Org": 0.0, "f1_macro": 0.45, "f1_micro": 0.57, "score": 0.57},
]
global_target = {
    "f1_Org": 0.0,
    "f1_Person": 0.86,
    "f1_Location": 0.5,
    "f1_macro": 0.45,
    "f1_micro": 0.57,
    "score": 0.57,
}

outputs = test_metric(
    metric=metric,
    predictions=predictions,
    references=references,
    instance_targets=instance_targets,
    global_target=global_target,
)

add_to_catalog(metric, "metrics.ner", overwrite=True)


from flask import current_app

from api_gpt.services.constants import CHATGPT_MODEL, DEFAULT_MAX_TOKENS
from api_gpt.services.openai_request import get_openai_response_string
from api_gpt.workflows.notification_context import NotificationContext

GENERATE_DEBRIEF_ACTIONS_SYSTEM_PROMPT = ""
with open("api_gpt/nlp/debrief/prompts/generate_action_system_prompts.txt") as f1:
    try:
        GENERATE_DEBRIEF_ACTIONS_SYSTEM_PROMPT = f1.read()
    except Exception as e:
        current_app.logger.debug("failed in reading enerate_action_system_prompts", e)

def generate_action_dict(context: NotificationContext) -> dict:
    default_actions_dict = {
        "Reply positively": "Reply positively",
        "Reply negatively": "Reply negatively",
    }
    system_prompt = GENERATE_DEBRIEF_ACTIONS_SYSTEM_PROMPT
    snippet = context.email_dict["content"]
    if len(snippet) >= 2000:
        snippet = snippet[:2000]
    debrief_context = context.context.replace("\n", " ")
    user_prompt = f"Context: {debrief_context}\nSubject: {context.email_dict['subject']}\nFrom: {context.email_dict['from']}\nContent: {snippet}\nActions: "

    response = get_openai_response_string(
        CHATGPT_MODEL, 100, system_prompt, user_prompt
    )
    # current_app.logger.debug('#### user_prompt : ', user_prompt)
    # current_app.logger.debug('#### response : ', response)
    if response is None or ("ignore" in response.lower() and len(response) <= 10):
        return default_actions_dict
    ret = {}
    for action in response.split("|"):
        action = action.replace(".", "").strip()
        # $ # [ ] /
        # action = action.replace('#', '')
        # action = action.replace('$', '')
        # action = action.replace('[', '')
        # action = action.replace(']', '')
        action = action.replace("/", "")
        action = action.strip()
        if (
            action.lower() == "none"
            or action.lower() == "ignore"
            or action.lower().startswith("ignore")
        ):
            continue
        ret[action] = action
    # current_app.logger.debug(f'ret : {ret}, len(ret): {len(ret)}')
    if len(ret) == 0:
        return default_actions_dict
    return ret


from enum import Enum
from tools.plan import Plan
from tools.newtonRaphson import find_root
import itertools

# Maintenance
HEALTH_THRESHOLD = {
    'EnvironmentalHouse': 41,
    'Other': 41
}

# Building
REQ_MAX_VACANCIES = 5
REQ_MIN_HOUSING_QUEUE = 14
MAX_RESIDENCES = 16
OPENER = [] # TODO
BUILDING_PRIORITY = ['LuxuryResidence', 'HighRise', 'Cabin', 'EnvironmentalHouse', 'ModernApartments', 'Apartments']
BASE_BUILD_PRIORITY = 4.0 # how many buildings are better than a utility, needs rethinking
MAX_BUILDINGS = {
    'LuxuryResidence': 1,
    'Cabin': 1,
    'HighRise': 1,
    'EnvironmentalHouse': 1,
    'ModernApartments': 11,
    'Apartments': 30
}

# Utilities
MAX_UTILITIES = {
    'Mall': 1,
    'Park': 2,
    'WindTurbine': 1
}

# Energy
DEG_PER_EXCESS_MWH = 0.75
DEG_PER_POP = 0.04

FORECAST_DAYS = 5
TEMP_TARGET = 21.0
TEMP_TOO_LOW = 19.5
TEMP_TOO_HIGH = 22.5
ENERGY_CHANGE_THRESHOLD = 1.0

DERIVATIVE_NUM_DAYS = 5
H = 0.01

class Urgency(Enum):
    NO = 0
    MINOR_ADJUST_ENERGY = 1
    CONSTRUCTION = 2
    UPGRADE = 3
    BUILD = 4
    MAJOR_ADJUST_ENERGY = 5
    MAINTENANCE = 6
    def __gt__(self, other):
        if self.__class__ is other.__class__:
            return self.value > other.value
        return NotImplemented

memory = {}
def reset_memory():
    global memory
    memory = {
        'planned_buildings': [],
        'planned_utilities': [],
        'temperature': []
    }

def manhattan(u, v):
    return abs(v[0] - u[0]) + abs(v[1] - u[1])

def setup(game):
    reset_memory()
    state = game.game_state

    # if map square is occupied
    def is_occupied(position):
        if state.map[position[0]][position[1]] != 0:
            return True
        for residence in state.residences:
            if position == (residence.X, residence.Y):
                return True
        for utility in state.utilities:
            if position == (utility.X, utility.Y):
                return True
        return False

    # buildable spots, this assume square maps
    buildable_spots = list(filter(lambda p: not is_occupied(p), list(itertools.product(range(len(state.map)), range(len(state.map))))))

    # score area for building based on available utility effects
    def score(pos, planned_utilities):
        stuff = set()
        for utility in state.utilities:
            for name in game.get_blueprint(utility.building_name).effects:
                effect = game.get_effect(name)
                if manhattan(pos, (utility.X, utility.Y)) <= effect.radius:
                    stuff.add(effect.name)
        for utility_position, utility_name in planned_utilities:
            for effect_name in game.get_blueprint(utility_name).effects:
                if manhattan(pos, utility_position) <= game.get_effect(effect_name).radius:
                    stuff.add(effect_name)
        return len(stuff)

    # find all the sites for buildings with associated score
    def scored_buildable_positions(utilities):
        sites = {}
        for pos in buildable_spots:
            occupied = False
            for utility_position, _ in utilities:
                if pos == utility_position:
                    occupied = True
                    break
            if not occupied:
                for utility in state.utilities:
                    if pos == (utility.X, utility.Y):
                        occupied = True
                        break
            if not occupied:
                sites[pos] = score(pos, utilities)
        return sites

    # true if building is available on this map
    def building_is_available(building_name):
        for building in state.available_residence_buildings:
            if building_name == building.building_name:
                return True
        for building in state.available_utility_buildings:
            if building_name == building.building_name:
                return True
        return False

    def residences_to_build():
        return max(0, MAX_RESIDENCES - len(state.residences))

    # plan utilities
    def planned_utilities():
        # score the map for usable utilities
        def utility_score(utilities):
            sites = scored_buildable_positions(utilities)
            total = sum([v for k, v in sorted(sites.items(), key=lambda item: item[1], reverse=True)][:residences_to_build()])
            for residence in state.residences:
                total += score((residence.X, residence.Y), utilities)
            return total

        # try to add utility_name utility to the list of utilities
        def place(utility_name, utilities):
            occupied = [p for p, _ in utilities]
            # plan
            best_utilities = utilities
            best_score = utility_score(best_utilities)
            for pos in buildable_spots:
                if pos in occupied:
                    continue
                total = utility_score(utilities + [(pos, utility_name)])
                if total > best_score:
                    best_score = total
                    best_utilities = utilities + [(pos, utility_name)]
            return best_utilities

        # prepare to plan utilities
        utility_queue = []
        for building_name in filter(building_is_available, ['Mall', 'WindTurbine', 'Park']):
            # figure out how many utilities to plan
            count = MAX_UTILITIES[building_name] - len(list(filter(lambda b: building_name == b.building_name, state.utilities)))
            utility_queue += [building_name] * max(0, count)
        # plan utilities
        utilities = []
        for utility_name in utility_queue:
            utilities = place(utility_name, utilities)
        return utilities

    # get the best buildingsites in order
    def planned_buildings(utilities):
        sites = scored_buildable_positions(utilities)
        positions = [k for k, v in sorted(sites.items(), key=lambda item: item[1], reverse=True)][:residences_to_build()]
        build_queue = []
        for building_name in filter(building_is_available, BUILDING_PRIORITY):
            # figure out how many buildings to plan
            count = MAX_BUILDINGS[building_name] - len(list(filter(lambda b: building_name == b.building_name, state.residences)))
            build_queue += [building_name] * max(0, count)
        build_queue = build_queue[:len(positions)]
        return list(zip(positions, build_queue))

    utilities = planned_utilities()
    memory['planned_utilities'] = utilities
    memory['planned_buildings'] = planned_buildings(utilities)

def take_turn(game):
    memory['temperature'].append(game.game_state.current_temp)
    plans = [Plan(Urgency.NO, 0.0).wait()] + find_build(game) + find_construction(game) + find_utilities(game) + find_upgrades(game) + find_maintenance(game) + find_adjust_energy(game)
    max(plans).do(game)

def find_build(game):
    state = game.game_state
    # always continue construction
    plans = []
    for residence in state.residences:
        if residence.build_progress < 100:
            plans.append(Plan(Urgency.BUILD, 0.0).build((residence.X, residence.Y)))
    return plans

def available_buildings(state):
    output = []
    for b in state.available_residence_buildings:
        if state.turn > b.release_tick:
            output.append(b.building_name)
    return output

def find_construction(game):
    state = game.game_state
    plans = []
    # new construction?
    available = available_buildings(state)
    vacancies = sum([game.get_blueprint(residence.building_name).max_pop - residence.current_pop for residence in state.residences])
    bad_time = state.housing_queue < REQ_MIN_HOUSING_QUEUE or vacancies > REQ_MAX_VACANCIES
    priority = 1
    for entry in memory['planned_buildings']:
        position, building_name = entry
        if building_name not in available:
            continue
        bp = game.get_blueprint(building_name)
        score = BASE_BUILD_PRIORITY - 0.01*priority
        plan = Plan(Urgency.CONSTRUCTION, score).construction(position, building_name).forget_entry(memory, 'planned_buildings', entry)
        if bad_time or state.funds < bp.cost:
            plan = Plan(Urgency.CONSTRUCTION, score).wait()
        plans.append(plan)
        priority += 1
    return plans

def find_utilities(game):
    state = game.game_state
    def score(pos, bp):
        val = 0
        for residence in state.residences:
            for effect_name in bp.effects:
                effect = game.get_effect(effect_name)
                if manhattan(pos, (residence.X, residence.Y)) <= effect.radius:
                    val += 1
        return val
    plans = []
    for entry in memory['planned_utilities']:
        position, building_name = entry
        bp = game.get_blueprint(building_name)
        if (state.funds >= bp.cost) and state.turn >= bp.release_tick:
            plans.append(Plan(Urgency.CONSTRUCTION, score(position, bp)).construction(position, building_name).forget_entry(memory, 'planned_utilities', entry))
    return plans

def find_upgrades(game):
    state = game.game_state
    plans = []
    upgrades = {}
    if state.funds > 30000:
        upgrades = {
            'Apartments': ['SolarPanel', 'Playground', 'Caretaker'],
            'ModernApartments': ['SolarPanel', 'Playground', 'Caretaker', 'Charger'],
            'EnvironmentalHouse': ['Insulation'],
            'LuxuryResidence': ['SolarPanel', 'Caretaker', 'Regulator', 'Playground'],
            'Cabin': [],
            'HighRise': ['Caretaker', 'Playground']
        }
    for residence in state.residences:
        if residence.building_name in upgrades:
            for priority, name in enumerate(upgrades[residence.building_name]):
                upgrade = next((upgrade for upgrade in state.available_upgrades if upgrade.name == name), None)
                if upgrade is not None and name not in residence.effects and state.funds >= upgrade.cost:
                    score = 10.0 - priority
                    plans.append(Plan(Urgency.UPGRADE, score).upgrade((residence.X, residence.Y), name).remember_count(memory, 'upgrade', name))
    return plans

def find_maintenance(game):
    state = game.game_state
    plans = []
    for residence in state.residences:
        threshold = HEALTH_THRESHOLD['Other']
        if residence.building_name in HEALTH_THRESHOLD:
            threshold = HEALTH_THRESHOLD[residence.building_name]
        if residence.health < threshold:
            plans.append(Plan(Urgency.MAINTENANCE, 100.0 - residence.health).maintenance((residence.X, residence.Y)))
    return plans

def temperatureDerivative():
    t = memory["temperature"]
    if len(t) == 0 or len(t) == 1:
        return 0.0
    elif len(t) < DERIVATIVE_NUM_DAYS:
        return (t[-1] - t[0]) / (len(t) - 1)
    return (t[-1] - t[-DERIVATIVE_NUM_DAYS]) / (DERIVATIVE_NUM_DAYS - 1)

def new_temp(energy_in, base_energy, indoor_temperature, outdoor_temperature, current_pop, emissivity):
    return indoor_temperature + (energy_in - base_energy) * DEG_PER_EXCESS_MWH + DEG_PER_POP * current_pop - (indoor_temperature - outdoor_temperature) * emissivity

def find_adjust_energy(game):
    def get_energy_need(residence, outside_temp):
        bp = game.get_residence_blueprint(residence.building_name)
        emissivity = bp.emissivity
        for name in residence.effects:
            if name == 'Insulation':
                emissivity *= 0.6
        def indoor_temp_forecast(energy_in):
            temp = residence.temperature
            o_dt = temperatureDerivative()
            for i in range(FORECAST_DAYS):
                o_at_t = outside_temp + (i + 1) * o_dt
                temp = new_temp(energy_in, bp.base_energy_need, temp, o_at_t, residence.current_pop, emissivity)
            return temp
        f = lambda energy_in: TEMP_TARGET - indoor_temp_forecast(energy_in)
        energy = find_root(f, residence.effective_energy_in, H)
        return max(bp.base_energy_need, energy)
    state = game.game_state
    plans = []
    for residence in state.residences:
        need = get_energy_need(residence, state.current_temp)
        urgency = Urgency.MINOR_ADJUST_ENERGY
        if residence.temperature < TEMP_TOO_LOW or residence.temperature > TEMP_TOO_HIGH:
            urgency = Urgency.MAJOR_ADJUST_ENERGY
        change = abs(need - residence.requested_energy_in)
        score = change * residence.current_pop
        if change > ENERGY_CHANGE_THRESHOLD:
            plans.append(Plan(urgency, score).adjust_energy((residence.X, residence.Y), need))
    return plans


# Perse Coding Team Challenge
# Round 1 Sample Paper
# Attempt by Mr Raymond Chng
# Question 9

def getChar():
    cha = input()
    if (cha == "<") or (cha == "+") or (cha == "&") or (cha == ">"):
        return cha
    else:
        print("You have entered an invalid operation.")
        print("Please try again:")
        cha = getChar()
    return cha
startStep = getChar()
dance = "<+&><+&>"
for i in range(4):
    if dance[i] != startStep:
        dance = dance + dance[i]
    else:
        print(dance[i::])


#CTI-110
#P2T1-Sales Prediction
#Evita Reyes
#February 14, 2018
#

total_sales = float(input('Enter the projected amount of total sales: '))
profit = total_sales * 0.23
print ('The annual profit is $', format(profit,',.2f'))


'''
Let's break down Calvin's financial transactions step by step:

1. **Starting Balance:** $1,598.47
2. **Direct Deposit:** +$517.62 (to be received at 5 pm)
3. **House Payment:** -$494.90 (automatic deduction)
4. **Online Payments (next morning):**
   - Payment 1: -$506.70
   - Payment 2: -$264.07
5. **Minimum Desired Balance:** $1,500.00 (to avoid a low balance penalty)

Now, let's calculate how much money Calvin needs to transfer to his account to ensure he maintains a balance of at least $1,500.00:

\[
\text{Balance After Direct Deposit} = \text{Starting Balance} + \text{Direct Deposit}
\]

\[
\text{Balance After House Payment} = \text{Balance After Direct Deposit} - \text{House Payment}
\]

\[
\text{Balance After Online Payments} = \text{Balance After House Payment} - \text{Payment 1} - \text{Payment 2}
\]

Calvin needs to transfer an amount to reach or exceed the Minimum Desired Balance. Let's calculate this:

\[
\text{Transfer Amount} = \text{Balance After Online Payments} - \text{Minimum Desired Balance}
\]

Here's the Python code to calculate this:
'''
# Given values
starting_balance = 1598.47
direct_deposit = 517.62
house_payment = 494.90
online_payment_1 = 506.70
online_payment_2 = 264.07
min_desired_balance = 1500.00

# Calculate balances
balance_after_direct_deposit = starting_balance + direct_deposit
balance_after_house_payment = balance_after_direct_deposit - house_payment
balance_after_online_payments = balance_after_house_payment - online_payment_1 - online_payment_2

# Calculate transfer amount
transfer_amount = max(0, min_desired_balance - balance_after_online_payments)

# Output rounded to the nearest cent
print("Calvin needs to transfer:", round(transfer_amount, 2))

'''
This code calculates the amount Calvin needs to transfer to avoid a low balance penalty and ensures the answer is rounded to the nearest cent.
python3 business_math_quiz2.py
'''


from torch import nn
import torch
import math
from dgl.nn.functional import edge_softmax
import dgl.function as fn
from models.diffuser_utils import *
from models.utils import *
class DiffuserSelfOutput(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.dense = nn.Linear(config.hidden_size, config.hidden_size)
        self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
        self.dropout = nn.Dropout(config.hidden_dropout_prob)

    def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
        hidden_states = self.dense(hidden_states)
        hidden_states = self.dropout(hidden_states)
        hidden_states = self.LayerNorm(hidden_states + input_tensor)
        return hidden_states

class DiffuserAttention(nn.Module):
    def __init__(self, config, layer_id=0):
        super().__init__()
        self.self = DiffuserSelfAttention(config, layer_id)
        self.output = DiffuserSelfOutput(config)

    def forward(
        self,
        hidden_states,
        g=None,
        attention_mask=None,
        layer_head_mask=None,
        is_index_masked=None,
        is_index_global_attn=None,
        is_global_attn=None,
        output_attentions=False,
    ):

        self_outputs = self.self(
            hidden_states,
            g=g,
            attention_mask=attention_mask,
            layer_head_mask=layer_head_mask,
            is_index_masked=is_index_masked,
            is_index_global_attn=is_index_global_attn,
            is_global_attn=is_global_attn,
            output_attentions=output_attentions,
        )
        attn_output = self.output(self_outputs[0], hidden_states)
        outputs = (attn_output,) + self_outputs[1:]
        return outputs

class DiffuserSelfAttention(nn.Module):
    def __init__(self, config, layer_id):
        super().__init__()
        if config.hidden_size % config.num_attention_heads != 0:
            raise ValueError(
                f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "
                f"heads ({config.num_attention_heads})"
            )
        self.num_heads = config.num_attention_heads
        self.head_dim = int(config.hidden_size / config.num_attention_heads)
        self.embed_dim = config.hidden_size

        self.query = nn.Linear(config.hidden_size, self.embed_dim)
        self.key = nn.Linear(config.hidden_size, self.embed_dim)
        self.value = nn.Linear(config.hidden_size, self.embed_dim)

        self.dropout = config.attention_probs_dropout_prob

        self.layer_id = layer_id
        attention_window = config.attention_window[self.layer_id]
        assert (
            attention_window % 2 == 0
        ), f"`attention_window` for layer {self.layer_id} has to be an even value. Given {attention_window}"
        assert (
            attention_window > 0
        ), f"`attention_window` for layer {self.layer_id} has to be positive. Given {attention_window}"

    def forward(
        self,
        hidden_states,
        g=None,
        attention_mask=None,
        layer_head_mask=None,
        is_index_masked=None,
        is_index_global_attn=None,
        is_global_attn=None,
        output_attentions=False,
    ):
        hidden_states = hidden_states.transpose(0, 1) #(N,B,HD)
        # attention_mask (B,N)
        # project hidden states
        query_vectors = self.query(hidden_states)
        key_vectors = self.key(hidden_states)
        value_vectors = self.value(hidden_states)   # (N,B,HD)

        seq_len, batch_size, embed_dim = hidden_states.size()
        assert (
            embed_dim == self.embed_dim
        ), f"hidden_states should have embed_dim = {self.embed_dim}, but has {embed_dim}"

        # normalize query
        query_vectors /= math.sqrt(self.head_dim)

        query_vectors = query_vectors.view(seq_len, batch_size, self.num_heads, self.head_dim).transpose(0, 1) # (B,N,H,D)
        key_vectors = key_vectors.view(seq_len, batch_size, self.num_heads, self.head_dim).transpose(0, 1) # (B,N,H,D)
        value_vectors = value_vectors.view(seq_len, batch_size, self.num_heads, self.head_dim).transpose(0, 1) #B,N,H,D

        bool_mask = (attention_mask>=0 )
        g = g.local_var()
        g.ndata["mask"] = bool_mask.reshape(-1).unsqueeze(-1)        #BN,1
        g.ndata['q'] =  query_vectors.reshape(-1, self.num_heads, self.head_dim) #BN,H,D
        g.ndata['k'] =  key_vectors.reshape(-1, self.num_heads, self.head_dim) #BN,H,D
        g.ndata['v'] =  value_vectors.reshape(-1, self.num_heads, self.head_dim) #BN,H,D

        g.apply_edges(fn.u_dot_v('k', 'q', 'score'))   #score: [E,H,1]
        g.apply_edges(mask_attention_score)   #kq
        e = g.edata.pop('score')
        g.edata['score'] = edge_softmax(g, e)
        g.edata['score']= nn.functional.dropout(g.edata['score'], p=self.dropout, training=self.training)

        g.ndata["h"] = g.ndata["v"]
        alpha = 0.1
        for _ in range(5):
            g.update_all(fn.u_mul_e('h', 'score', 'm'), fn.sum('m', 'h'))
            g.apply_nodes(lambda nodes: {'h' : (1.0 - alpha) * nodes.data['h'] + alpha * nodes.data['v']})
            g.ndata['h']= nn.functional.dropout(g.ndata['h'], p=self.dropout, training=self.training)

        attn_output = g.ndata['h'] #BN,H,D
        attn_output = attn_output.reshape(batch_size, seq_len,  self.num_heads, self.head_dim) # B,N,H,D
        assert attn_output.size() == (batch_size, seq_len, self.num_heads, self.head_dim), "Unexpected size"
        attn_output = attn_output.transpose(0, 1).reshape(seq_len, batch_size, embed_dim).contiguous()
        outputs = (attn_output.transpose(0, 1),) # Seq,B,D

        return outputs + (global_attn_probs,) if (is_global_attn and output_attentions) else outputs


"""Defines the DANN model (Domain Adversarial Neural Network)"""

from math import exp

import torch
import torch.nn as nn
from torchvision.models import alexnet

from domain_adapt.nn.layers import ReverseGradient

# ----------------------------------------------------------------------------------------------------------------------
# Training utilities for DANN
# ----------------------------------------------------------------------------------------------------------------------

def train_dann_epoch(model, src_loader, tgt_loader, criterion, optimizer, device, da_scale):
    """Train a DANN model for one epoch

    Parameters
    ----------
    model: DANN
    src_loader: DataLoader
    tgt_loader: DataLoader
    criterion: callable
    optimizer: Optimizer
    device: torch.device
    da_scale: float
    """
    model = model.train()
    for (src_images, src_labels), (tgt_images, _) in zip(src_loader, tgt_loader):
        src_images = src_images.to(device)
        src_labels = src_labels.to(device)
        tgt_images = tgt_images.to(device)

        n_src = len(src_images)
        src_domains = torch.ones(n_src, dtype=torch.int64).to(device)

        n_tgt = len(tgt_images)
        tgt_domains = torch.zeros(n_tgt, dtype=torch.int64).to(device)

        optimizer.zero_grad()
        out_src_label, out_src_domain, out_tgt_domain = model(src_images, tgt_images, da_scale)
        loss_src_label = criterion(out_src_label, src_labels)
        loss_src_domain = criterion(out_src_domain, src_domains)
        loss_tgt_domain = criterion(out_tgt_domain, tgt_domains)
        loss = loss_src_label + loss_src_domain + loss_tgt_domain
        loss.backward()
        optimizer.step()

# ----------------------------------------------------------------------------------------------------------------------
# Models and layers
# ----------------------------------------------------------------------------------------------------------------------

def pretrained_alexnet():
    """Prepares an AlexNet feature extractor pre-trained on ImageNet

    Note: The final fc8 layer is removed from the network, resulting in a 4096-dim output.

    Returns
    -------
    nn.Module
    """
    model = alexnet(pretrained=True)
    model.classifier = nn.Sequential(*[child for child in list(model.classifier.children())[:6]])
    return model

class LabelClassifier(nn.Module):
    """Default label classifier architecture for the DANN model

    Parameters
    ----------
    num_classes: int
    input_dim: int, optional
    hidden_dim: int, optional
    """

    def __init__(self, num_classes, input_dim=4096, hidden_dim=1024):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, hidden_dim)
        self.fc3 = nn.Linear(hidden_dim, num_classes)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

class DomainClassifier(nn.Module):
    """Default domain classifier architecture for the DANN model

    Parameters
    ----------
    input_dim: int, optional
    hidden_dim: int, optional
    """

    def __init__(self, input_dim=4096, hidden_dim=1024):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, hidden_dim)
        self.fc3 = nn.Linear(hidden_dim, 2)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

class DANN(nn.Module):
    """Domain Adversarial Neural Network

    Parameters
    ----------
    feature_nn: nn.Module
        The feature extractor neural network
    label_nn: nn.Module
        The label classifier neural network
    domain_nn: nn.Module
        The domain classifier neural network
    """

    def __init__(self, feature_nn, label_nn, domain_nn):
        super().__init__()
        self.feature_nn = feature_nn
        self.label_nn = label_nn
        self.domain_nn = domain_nn
        self.reverse_grad = ReverseGradient()

    def retrieve_model(self):
        """Concatenates the feature extractor and the label classifier

        This should be used when domain adaptation has been applied and the resulting model needs to be retrieved.

        Returns
        -------
        nn.Module
        """
        return nn.Sequential(self.feature_nn, self.label_nn)

    def forward(self, x_src, x_tgt, da_scale):
        """

        Parameters
        ----------
        x_src: torch.Tensor
            The source batch tensor
        x_tgt: torch.Tensor
            The target batch tensor
        da_scale: float, optional
            The scaling factor for the gradient reversal layer (default = 1)

        Returns
        -------
        tuple[torch.Tensor]
            A tuple containing the pre-softmax scores for the label classifier (only source) and the domain classifier
            (both source and target)
        """
        # get the source and target features
        src_features = self.feature_nn(x_src)
        tgt_features = self.feature_nn(x_tgt)

        # get the pre-softmax source label scores
        out_src_label = self.label_nn(src_features)

        # pass both source and target features through a gradient reversal layer
        src_features_reversed = self.reverse_grad(src_features, da_scale)
        tgt_features_reversed = self.reverse_grad(tgt_features, da_scale)

        # get the pre-softmax source and target domain scores
        out_src_domain = self.domain_nn(src_features_reversed)
        out_tgt_domain = self.domain_nn(tgt_features_reversed)

        return out_src_label, out_src_domain, out_tgt_domain

# ----------------------------------------------------------------------------------------------------------------------
# Define the schedulers
# ----------------------------------------------------------------------------------------------------------------------

class LRScheduler:
    """Learning rate scheduler

    This class defines the learning rate scheduler used in the DANN paper.

    Parameters
    ----------
    max_epochs: int
    init_lr: float, optional
    alpha: float, optional
    beta: float, optional
    """

    def __init__(self, max_epochs, init_lr=0.01, alpha=10, beta=0.75):
        self.max_epochs = max_epochs
        self.lr_0 = init_lr
        self.alpha = alpha
        self.beta = beta

    def __call__(self, epoch):
        """Calculates the new learning rate given the epoch index

        Parameters
        ----------
        epoch: int
            The integer index of the current epoch

        Returns
        -------
        float
        """
        p = epoch / self.max_epochs
        lr_p = self.lr_0 / ((1 + self.alpha * p) ** self.beta)
        return lr_p

class DAScheduler:
    """The domain adaptation hyperparameter scheduler

     This hyperparamter controls scales the domain regularization loss.
     The value is initialized at zero and gradually changed to one.

     Parameters
     ----------
     max_epochs: int
     gamma: float
     """

    def __init__(self, max_epochs, gamma=10):
        self.max_epochs = max_epochs
        self.gamma = gamma

    def __call__(self, epoch):
        """Calculates the new domain adaptation parameter value given the epoch index

        Parameters
        ----------
        epoch: int

        Returns
        -------
        float
        """
        p = epoch / self.max_epochs
        lambda_p = (2 / (1 + exp(-self.gamma * p))) - 1
        return lambda_p


import streamlit as st
import pandas as pd
import numpy as np
#import importlib
#cv2 = importlib.import_module("opencv-python-headless")
#import `opencv-python-headless' as cv2
#from PIL import Image
#import io

from keras.preprocessing.image import ImageDataGenerator
#from keras.utils import load_img, img_to_array
from keras.models import Sequential, load_model, Model
#from keras.layers import Conv2D, MaxPooling2D
#from keras.layers import Activation, Dropout, Flatten, Dense, GlobalAveragePooling2D
#from keras import backend as K
#from keras.callbacks import ModelCheckpoint
#from keras import regularizers

from keras.applications.resnet import ResNet50, preprocess_input
import cv2

def change_to_bw(bytes_data, calibration_value):
  #im_gray = Image.frombytes('L', (3000,3000), bytes_data, 'raw')

  im_gray = cv2.imdecode(np.frombuffer(bytes_data, np.uint8), cv2.IMREAD_GRAYSCALE)
  (thresh, im_bw) = cv2.threshold(im_gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
  thresh += calibration_value
  im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
  #im_bw = np.array(im_bw)

  return(im_bw, thresh)

st.title('Jetaire Dust Detection')

modelpath='./model_current_best.h5'
model = load_model(modelpath)
images_dir = './imgs/'
normed_dims = (500,500)

uploaded_file = st.file_uploader("Upload an image", type=['png','jpg'])

if uploaded_file is None:
    CALIBRATION_VALUE = -35
else:
    bytes_data = uploaded_file.read()
    CALIBRATION_VALUE= st.slider('Enter a calibration value', -70, 0, -35)

    col1, col2= st.columns(2)
    with col1:
        st.subheader("Original")
        st.image(bytes_data)

    with col2:
        st.subheader("Processed")
        (image_bw,thres)=change_to_bw(bytes_data, CALIBRATION_VALUE)
        cv2.imwrite('./imgs/0/curr_image.jpg', image_bw)
        st.image(image_bw)

    test_datagen = ImageDataGenerator(dtype='float32',
                                preprocessing_function = preprocess_input)

    test_generator = test_datagen.flow_from_directory(
        images_dir,
        target_size=normed_dims,
        batch_size=1,
        shuffle=False,
        #class_mode='binary'
        class_mode="categorical"
        )

    test_generator.reset()
    X_te, y_te = test_generator.next()

    res = model.predict(np.expand_dims(X_te[0], axis = 0))

    cat_percentages = np.array([0, 25, 50, 100])
    y_percentage = res.dot(cat_percentages)

    color = 'red'
    if y_percentage[0] < 25:
        color = 'green'

    st.header(f'Dust percentage: :{color}[{round(y_percentage[0],2)}%]')


# присутствие внутри полигона

from cmath import atan

from base.const import GREEN, RED, BLACK, BLUE, MEDIA
from base.point import Point
from base.show import Show

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

class Polygon:
    p = []
    e = 0.0001

    url = MEDIA + 'area/'

    # ---------------------------
    # точка внутри полигона

    def find(self, q):
        if len(self.p) < 3:
            return False
        s = 0

        c = self.p[-1]
        b = Point(c.x - q.x, c.y - q.y)

        for c in self.p:
            a = Point(c.x - q.x, c.y - q.y)

            d = b.x * a.y - a.x * b.y
            xy = a.x * b.x + a.y * b.y

            s += atan((b.x * b.x + b.y * b.y - xy) / d)
            s += atan((a.x * a.x + a.y * a.y - xy) / d)

            b = a

        return abs(s) > self.e

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

    def show(self, show):
        for q in self.p:
            show.r(q)

        show.polygon(self.p, BLACK)
        for q in self.p:
            show.point(q, BLUE)

    # ---------------------------
    # тестовое отображение

    def take(self):
        self.p = []
        for q in open(self.url + 'polygon.txt'):
            x, y = q[:-1].split('\t')
            self.p.append(Point(float(x), float(y)))

        p = []

        for q in open(self.url + 'points.txt'):
            x, y = q[:-1].split('\t')
            p.append(Point(float(x), float(y)))

        return p

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

    def demo(self):
        print('polygon')

        show = Show(self.url + 'map.jpg')
        p = self.take()

        for q in p:
            t = GREEN if self.find(q) else RED
            q.show(show, t)

        self.show(show)
        show.save(self.url + 'polygon.jpg')
        exit()


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

"""
@author: Li Tian
@contact: 694317828@qq.com
@software: pycharm
@file: keywords_search.py
@time: 2018/8/1 20:37
@desc: 查找文件中的关键字 是否存在关键字
"""

import os

def keyswords_search(keyword, file_path):
    """
    根据文件路径寻找该文件路径下的.py文件中会不会有关键字
    :param keyword: 关键字
    :param file_path: 文件路径
    :return: 含有关键字的文件名
    """

    file_name = []
    time_show = 1
    for root, dirs, files in os.walk(file_path):
        # print('******************************************************************************************')
        # print('当前目录路径：' + str(root))  # 当前目录路径
        # print('当前路径下所有子目录：' + str(dirs))  # 当前路径下所有子目录
        # print('当前路径下所有非目录子文件：' + str(files))  # 当前路径下所有非目录子文件

        for i in files:
            houzhui = os.path.splitext(i)[1]
            if houzhui == '.py':
                with open(root + '/' + i, 'r', encoding='UTF-8') as f:
                    contents = f.readlines()
                    # print(contents)
                    for cont in contents:
                        if keyword in cont:
                            print('***********************************************************'
                                  '***********************************************************'
                                  '***********************************************************')
                            print('\n关键字第' + str(time_show) + '次出现在文件：' + root + '/' + i)
                            time_show += 1
                            print('出现的语句为：' + cont.strip() + '\n')
                            file_name.append(root + '/' + i)
    print('-----------------------------------结果显示---------------------------------------')
    print('包含关键字【' + keyword + '】的文件有：')
    for j in file_name:
        print('        ' + j)

def main():
    keyword = 'text'
    file_path = 'C:/Users/Administrator/Desktop/Python WorkSpace'
    keyswords_search(keyword, file_path)

if __name__ == '__main__':
    main()


'''
Created on 29.08.2012

@author: michi
'''
import logging

from PyQt4.QtCore import QObject, QAbstractItemModel, QAbstractListModel, \
    pyqtSignal, QVariant, Qt, QString
from PyQt4.QtGui import QTabBar, QIcon
from ems.qt4.util import variant_to_pyobject

class TabBarConnector(QObject):

    modelColumnChanged = pyqtSignal(int)
    currentTabDataChanged = pyqtSignal(QVariant)

    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self._model = None
        self._tabBar = None
        self._modelColumn = 0
        self._tabDataColumn = None

    def modelColumn(self):
        return self._modelColumn

    def setModelColumn(self, column, initialConnect=True):
        if column == self._modelColumn:
            return
        if not isinstance(column, int):
            raise TypeError("modelColumn has to be instance of int")
        self._modelColumn = column

    def tabDataColumn(self):
        return self._tabDataColumn

    def setTabDataColumn(self, column):
        self._tabDataColumn = column

    def tabBar(self):
        return self._tabBar

    def setTabBar(self, tabBar, initialConnect=True):
        if self._tabBar is tabBar:
            return

        if not isinstance(tabBar, QTabBar):
            raise TypeError("tabBar has to be instance of QTabBar")
        self._tabBar = tabBar

    def model(self):
        return self._model

    def setModel(self, model, initialConnect=True):
        if self._model is model:
            return

        if not isinstance(model, QAbstractItemModel):
            raise TypeError("model has to be instance of QAbstractItemModel")
        self._model = model

        self._model.dataChanged.connect(self.onDataChanged)
        self._model.modelReset.connect(self.onModelReset)
        self._model.rowsInserted.connect(self.onRowsInserted)
        self._model.rowsMoved.connect(self.onRowsMoved)
        self._model.rowsRemoved.connect(self.onRowsRemoved)

    def connectModel2TabBar(self, model=None, tabBar=None):
        if model is None:
            if self._model is None:
                raise TypeError("No model assigned. Pass a model or set one by setModel()")
        else:
            self.setModel(model, False)

        if tabBar is None:
            if self._tabBar is None:
                raise TypeError("No tabbar assigned. Pass a QTabBar or set one by setTabBar()")
        else:
            self.setTabBar(tabBar, False)

        self.onModelReset()

    def onDataChanged(self, topLeft, bottomRight):
        for row in range(topLeft.row(), bottomRight.row()+1):
            for col in range(topLeft.column(), bottomRight.column()+1):
                if col == self._modelColumn:
                    self._updateTabText(row)
                    self._updateTabToolTip(row)
                if col == self._tabDataColumn:
                    self._updateTabData(row)
                if col == self._model.enabledFlagColumn():
                    self._updateTabEnabledState(row)

    def onModelReset(self):
        for i in range(self._tabBar.count()):
            self._tabBar.removeTab(i)

        for row in range(self._model.rowCount()):
            title = variant_to_pyobject(self._model.index(row,
                                                          self._modelColumn).
                                        data(Qt.DisplayRole))
            icon = variant_to_pyobject(self._model.index(row,
                                                          self._modelColumn).
                                        data(Qt.DecorationRole))
            if isinstance(icon, QIcon):
                self._tabBar.addTab(icon, QString.fromUtf8(title))
            else:
                self._tabBar.addTab(QString.fromUtf8(title))

            self._updateTabEnabledState(row)
            self._updateTabToolTip(row)
            self._updateTabData(row)

    def _updateTabEnabledState(self, row):
        flags = self._model.flags(self._model.index(row, self._modelColumn))
        self._tabBar.setTabEnabled(row, bool(int(flags) & int(Qt.ItemIsEnabled)))

    def _updateTabText(self, row):
        title = variant_to_pyobject(self._model.index(row,
                                                          self._modelColumn).
                                        data(Qt.DisplayRole))
        self._tabBar.setTabText(QString.fromUtf8(title))

    def _updateTabToolTip(self, row):
        toolTip = variant_to_pyobject(self._model.index(row, self._modelColumn)
                                      .data(Qt.ToolTipRole))
        if toolTip:
            self._tabBar.setTabToolTip(row, QString.fromUtf8(toolTip))

    def _updateTabData(self, row):
        if self._tabDataColumn is not None:
            tabData = self._model.index(row, self._tabDataColumn).data(Qt.DisplayRole)
            if tabData:
                self._tabBar.setTabData(row, tabData)

    def onRowsInserted(self, parent, start, end):
        pass

    def onRowsMoved(self, sourceParent, sourceStart, sourceEnd, destinationParent,
                  destinationRow):
        logging.getLogger(__name__).debug("onRowsMoved")

    def onRowsRemoved(self, parent, start, end):
        logging.getLogger(__name__).debug("onRowsRemoved")


from tkinter import filedialog
from tkinter import *

class ParentWindow(Frame):
    def __init__ (self,master):
        Frame.__init__ (self)

        self.master = master
        self.master.resizable(width=False, height=False)
        self.master.geometry('{}x{}'.format(600, 350))
        self.master.title('Drill 123')
        self.master.config(bg='lightgray')

        self.lblDisplay1 = Label(self.master,text='Please select a file directory: ', font=("Helvetica", 12), fg='black', bg='lightgray')
        self.lblDisplay1.grid(row=0, column=0,padx=(30,0), pady=(30,0))

        self.lblDisplay2 = Label(self.master,text='', font=("Helvetica", 12), fg='black', bg='lightgray')
        self.lblDisplay2.grid(row=3, column=0,padx=(30,0), pady=(30,0))

        self.btnSelect = Button(self.master, text="Select Folder", width=10, height=2, command=self.select)
        self.btnSelect.grid(row=1, column=1,padx=(0,0), pady=(30,0), sticky=NW)

        self.btnCancel = Button(self.master, text="Cancel", width=10, height=2, command=self.cancel)
        self.btnCancel.grid(row=2, column=1,padx=(0,90), pady=(30,0), sticky=NW)

    def select(self):
        dir = filedialog.askdirectory()
        self.lblDisplay2.config(text='{}'.format(dir))

    def cancel(self):
        self.master.destroy()

if __name__ == "__main__":
    root = Tk()
    App = ParentWindow(root)
    root.mainloop()


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

# # LSTM on Cosine Wave

# The goal of this project is to train an LSTM (Long Short-Term Memory) model to predict the next values in a cosine wave time series. The LSTM model will learn to capture the underlying patterns and dependencies in the data and generate accurate predictions.

# # Importing Libraries

# These are just a few examples of popular Python libraries. You can import any other library using the same import statement followed by the library name or alias:
#
# NumPy: for numerical operations and array manipulation
#
# Pandas: for data manipulation and analysis
#
# Matplotlib: for creating visualizations
#
# Scikit-learn: for machine learning algorithms

# In[2]:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

get_ipython().run_line_magic('matplotlib', 'inline')

# # Generating Data Sequence

# To generate a data sequence for the cosine wave, you can use the numpy library in Python.

# In[4]:

x = np.linspace(0, 50, 501)
y = np.cos(x)

# In[5]:

x

# In[6]:

y

# # Data Visualization

#
# To visualize the generated data sequence representing a cosine wave, you can use the matplotlib library in Python.

# In[19]:

plt.plot(x, y)

# In[7]:

x.shape, y.shape

# # Creating Dataframe

# In[9]:

dataframe = pd.DataFrame(data = y,
                         index = x,
                         columns = ['Cosine'])

# In[10]:

dataframe.head()

# In[11]:

dataframe.tail()

# Calculating the test index for a given dataset taking the test percentage is 0.1 (10%), we can perform the following ways:

# In[12]:

test_precent = 0.1

# In[13]:

len(dataframe)*test_precent

# In[15]:

test_point = np.round(len(dataframe)*test_precent)

# In[16]:

test_point

# In[17]:

test_index = int(len(dataframe) - test_point)

# In[18]:

test_index

# # Splitting Dataset

# Splitting a dataset refers to the process of dividing a given dataset into two or more subsets for training and evaluation purposes. The most common type of split is between the training set and the testing (or validation) set. This division allows us to assess the performance of a machine learning model on unseen data and evaluate its generalization capabilities.
#
# Train-Test Split: This is the most basic type of split, where the dataset is divided into a training set and a testing set. The training set is used to train the machine learning model, while the testing set is used to evaluate its performance. The split is typically done using a fixed ratio, such as 80% for training and 20% for testing.

# In[20]:

train_data = dataframe.iloc[:test_index]
test_data = dataframe.iloc[test_index:]

# In[21]:

train_data

# In[22]:

test_data

# In[23]:

train_data.shape, test_data.shape

# # Scaling Dataset

# Scaling is a preprocessing technique used in machine learning to transform the input features to a similar scale. It is often necessary because features can have different units, ranges, or magnitudes, which can affect the performance of certain algorithms. Scaling ensures that all features contribute equally to the learning process and prevents features with larger values from dominating those with smaller values.

# MinMaxScaler is a popular scaling technique used in data preprocessing. It scales the features to a specified range, typically between 0 and 1.

# In[24]:

from sklearn.preprocessing import MinMaxScaler

# In[25]:

scaler = MinMaxScaler()

# In[26]:

scaler.fit(train_data)

# In[27]:

scaled_train = scaler.transform(train_data)
scaled_test = scaler.transform(test_data)

# In[28]:

scaled_train

# In[29]:

scaled_test

# # Timeseries Generator

# In time series analysis, a common approach is to use a time series generator to generate batches of sequential data for training recurrent neural networks (RNNs) or other time-based models. This allows you to efficiently process and train models on large time series datasets. Here's an example of how you can create a time series generator using the TimeseriesGenerator calss.

# In[30]:

from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator

# In[32]:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM
from tensorflow.keras.callbacks import EarlyStopping

# Early stopping is a technique commonly used in machine learning projects, including those involving neural networks such as LSTM, to prevent overfitting and determine the optimal number of training iterations. It allows you to monitor the model's performance during training and stop the training process when the model starts to show signs of overfitting or when further training is unlikely to improve the model's performance.

# In[33]:

early_stop = EarlyStopping(monitor='val_loss',patience=2)

# In[34]:

length = 49
generator = TimeseriesGenerator(scaled_train,scaled_train,
                               length=length,batch_size=1)

validation_generator = TimeseriesGenerator(scaled_test,scaled_test,
                                          length=length,batch_size=1)

# In[35]:

n_features = 1

# # Building Model

# Creating a deep learning model involves defining the architecture and structure of the neural network, specifying the layers, and configuring the parameters for training.

# In[36]:

model = Sequential()
model.add(LSTM(49, input_shape = (length, n_features)))
model.add(Dense(1))

# # Compiling Model

# Compiling the model in deep learning involves configuring essential components that define how the model will be trained.

# In[37]:

model.compile(optimizer = 'adam', loss = 'mse')

# # Training Model

# Training the model in deep learning involves the process of iteratively updating the model's parameters (weights and biases) based on the provided training data to minimize the loss function and improve the model's performance

# In[38]:

model.fit_generator(generator, epochs = 10,
                    validation_data = validation_generator,
                    callbacks = [early_stop])

# In[39]:

model.save('model_cosine_wave.h5')

# # Learning Curve for x-Test Data

# The learning curve is a plot that shows how the loss and accuracy of a model change during training. It provides insights into how well the model is learning from the training data and how it generalizes to unseen data. The learning curve typically shows the training and validation loss/accuracy on the y-axis and the number of epochs on the x-axis. By analyzing the learning curve, you can identify if the model is overfitting (high training loss, low validation loss) or underfitting (high training and validation loss). It is a useful tool for monitoring and evaluating the performance of machine learning models.

# In[40]:

loss = pd.DataFrame(model.history.history)

# In[41]:

loss.head()

# In[42]:

loss.plot()

# # Predicting On x-Test Data

# In[44]:

prediction = []
evaluation_batch = scaled_train[-length:]
current_batch = evaluation_batch.reshape(1, length, n_features)
for i in range (len(test_data)):
    current_prediction = model.predict(current_batch)[0]
    prediction.append(current_prediction)
    current_batch = np.append(current_batch[:, 1:, :], [[current_prediction]], axis = 1)

# In[45]:

prediction = scaler.inverse_transform(prediction)

# In[46]:

prediction

# In[47]:

test_data['Prediction'] = prediction

# In[48]:

test_data.head()

# # Predicted x-Test Value And Actual Value

# In[49]:

test_data.plot(figsize = (12, 5))

# # Predicting For Full Dataframe

# In[50]:

full_scaler = MinMaxScaler()

# In[51]:

full_data_scale = scaler.transform(dataframe)
length = 50
generator = TimeseriesGenerator(full_data_scale, full_data_scale, length=length, batch_size=1)
model = Sequential()
model.add(LSTM(50, input_shape=(length, n_features)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.fit_generator(generator,epochs=6)

# In[52]:

model.save('model_full_cosine.h5')

# In[53]:

losses = pd.DataFrame(model.history.history)

# In[54]:

losses.head()

# In[55]:

losses.plot()

# In[57]:

prediction = []
evaluation_batch = full_data_scale[-length:]
current_batch = evaluation_batch.reshape(1, length, n_features)
for i in range (len(test_data)):
    current_prediction = model.predict(current_batch)[0]
    prediction.append(current_prediction)
    current_batch = np.append(current_batch[:, 1:, :], [[current_prediction]], axis = 1)

# In[58]:

prediction = scaler.inverse_transform(prediction)

# In[60]:

prediction

# # Predicted Value Along With Actual Value

# In[61]:

prediction_index = np.arange(50.1,55.1,step=0.1)

# In[63]:

plt.plot(dataframe.index,dataframe['Cosine'])
plt.plot(prediction_index,prediction)

# # Thanks !

RNN on CosineWave/LSTM On Cosine Wave.py


#Libraries
import numpy as np
import matplotlib.pyplot as plt
import math

#Mean aerodynamic chord
def MAC_part(cr, ct, sweep, b):
    #MAC
    y = 2/3 * (cr + ct - (cr*ct)/(cr+ct))
    #offset from that parts root on quarter chord
    off_x = (b/2/(ct-cr))*(y-ct)
    off_y = cr*0.25-ct*0.25 + np.tan(sweep)*off_x
    return y, off_x, off_y

def listgenerator(cri,cti,cro,cto,sweepi,sweepo,bi,bo):
    MACi, off_x_i, off_y_i = MAC_part(cri,cti,sweepi,bi)
    MACo, off_x_o, off_y_o = MAC_part(cro, cto, sweepo, bo)

    MAC_list = np.array([MACi,MACo])
    S_list = np.array(([(cri+cti)/2*bi,(cro+cto)/2*bo]))
    x_list = np.array(([off_x_i,bi+off_x_o]))
    return MAC_list,S_list,x_list

def MAC_aircraft(cri,cti,cro,cto,sweepi,sweepo,bi,bo):#Make sure to use numpy array
    MAC_list,S_list,x_list=listgenerator(cri, cti, cro, cto, sweepi, sweepo, bi, bo)
    MAC = np.sum((MAC_list*S_list))/np.sum(S_list)
    x_quarter = np.sum(x_list)/np.sum(S_list)
    return MAC, x_quarter

'''INPUT'''
cri=0
cti=0
cro=0
cto=0
sweepi=0
sweepo=0
bi=0
bo=0
'''CALCULATION'''
print(MAC_aircraft(cri,cti,cro,cto,sweepi,sweepo,bi,bo))


#! /usr/bin/env python
#---------------------------------------------------------------------------------------
# configure.py: Athena++ configuration script in python. Original version by CJW.
#
# When configure.py is run, it uses the command line options and default settings to
# create custom versions of the files Makefile and src/defs.hpp from the template files
# Makefile.in and src/defs.hpp.in repspectively.
#
# The following options are implememted:
#   -h  --help        help message
#   --prob=name       use src/pgen/name.cpp as the problem generator
#   --coord=choice    use choice as the coordinate system
#   --eos=choice      use choice as the equation of state
#   --flux=choice     use choice as the Riemann solver
#   --order=choice    use choice as the spatial reconstruction algorithm
#   --fint=choice     use choice as the hydro time-integration algorithm
#   --exe=name        name of the executable file
#   -b                enable magnetic fields
#   -s                enable special relativity
#   -g                enable general relativity
#   -t                enable interface frame transformations for GR
#   -debug            enable debug flags (-g -O0); override other compiler options
#   -mpi              enable parallelization with MPI
#   -omp              enable parallelization with OpenMP
#   -hdf5             enable HDF5 output (requires the HDF5 library)
#   -netcdf           enable NETCDF output (requires the NETCDF library)
#   --hdf5_path=path  path to HDF5 libraries (requires the HDF5 library)
#   --netcdf_path=path path to NETCDF libraries (requires the NETCDF library)
#   --cxx=choice      use choice as the C++ compiler
#   --ccmd=choice     use choice as the command to call the C++ compiler
#---------------------------------------------------------------------------------------

# Modules
import argparse
import glob
import re

# Set template and output filenames
makefile_input = 'Makefile.in'
makefile_output = 'Makefile'
defsfile_input = 'src/defs.hpp.in'
defsfile_output = 'src/defs.hpp'

#--- Step 1. Prepare parser, add each of the arguments ---------------------------------
parser = argparse.ArgumentParser()

# --prob=[name] argument
pgen_directory = 'src/pgen/'
# set pgen_choices to list of .cpp files in src/pgen/
pgen_choices = glob.glob(pgen_directory + '*.cpp')
# remove 'src/pgen/' prefix and '.cpp' extension from each filename
pgen_choices = [choice[len(pgen_directory):-4] for choice in pgen_choices]
parser.add_argument('--prob',
    default='shock_tube',
    choices=pgen_choices,
    help='select problem generator')

# --coord=[name] argument
parser.add_argument('--coord',
    default='cartesian',
    choices=['cartesian','cylindrical','spherical_polar','spherical_latlon',
      'minkowski','sinusoidal',
        'tilted','schwarzschild','kerr-schild'],
    help='select coordinate system')

# --eos=[name] argument
parser.add_argument('--eos',
    default='adiabatic',
    choices=['adiabatic','isothermal', 'shallow_water', 'heterogeneous'],
    help='select equation of state')

# --flux=[name] argument
parser.add_argument('--flux',
    default='default',
    choices=['default','hlle','hllc','hlld','roe','llf'],
    help='select Riemann solver')

# --order=[name] argument
parser.add_argument('--order',
    default='plm',
    choices=['plm', 'weno3'],
    help='select spatial reconstruction algorithm')

# --fint=[name] argument
parser.add_argument('--fint',
    default='vl2',
    choices=['vl2', 'rk2'],
    help='select hydro time-integration algorithm')

# --particle=[num] argument
parser.add_argument('--particle',
    default='00',
    choices=map(lambda x: '0'+hex(x)[2:], range(0, 16)) \
          + map(lambda x: hex(x)[2:], range(16, 256)),
    help='request the number of real and integer particle data')

# --component=[num] argument
parser.add_argument('--comp',
    default='10',
    choices= map(lambda x: hex(x)[2:], range(16, 256)),
    help='request the number of components in hydro eos')

# --main=[name] argument
parser.add_argument('--main',
    default='dynamics',
    choices=['dynamics', 'radiation'],
    help='name of the main source file')

# --exe=[name] argument
parser.add_argument('--exe',
    default='athena',
    help='name of the executable file')

# -b argument
parser.add_argument('-b',
    action='store_true',
    default=False,
    help='enable magnetic field')

# -s argument
parser.add_argument('-s',
    action='store_true',
    default=False,
    help='enable special relativity')

# -g argument
parser.add_argument('-g',
    action='store_true',
    default=False,
    help='enable general relativity')

# -t argument
parser.add_argument('-t',
    action='store_true',
    default=False,
    help='enable interface frame transformations for GR')

# -debug argument
parser.add_argument('-debug',
    action='store_true',
    default=False,
    help='enable debug flags; override other compiler options')

# -mpi argument
parser.add_argument('-mpi',
    action='store_true',
    default=False,
    help='enable parallelization with MPI')

# -omp argument
parser.add_argument('-omp',
    action='store_true',
    default=False,
    help='enable parallelization with OpenMP')

# -hdf5 argument
parser.add_argument('-hdf5',
    action='store_true',
    default=False,
    help='enable HDF5 Output')

# -netcdf argument
parser.add_argument('-netcdf',
    action='store_true',
    default=False,
    help='enable NETCDF Output')

# -disort argument
parser.add_argument('-disort',
    action='store_true',
    default=False,
    help='enable DISORT radiative transfer model')

# --hdf5_path argument
parser.add_argument('--hdf5_path',
    type=str,
    default='',
    help='path to HDF5 libraries')

# --netcdf_path argument
parser.add_argument('--netcdf_path',
    type=str,
    default='',
    help='path to NETCDF libraries')

# --disort_path argument
parser.add_argument('--disort_path',
    type=str,
    default='thirdparty/cdisort-2.1.3a',
    help='path to DISORT libraries')

# --cxx=[name] argument
parser.add_argument('--cxx',
    default='g++',
    choices=['g++','icc','cray','bgxl'],
    help='select C++ compiler')

# --ccmd=[name] argument
parser.add_argument('--ccmd',
    type=str,
    default=None,
    help='override for command to use to call C++ compiler')

# Parse command-line inputs
args = vars(parser.parse_args())

#--- Step 2. Test for incompatible arguments -------------------------------------------

# Set default flux; HLLD for MHD, HLLC for hydro, HLLE for isothermal hydro or any GR
if args['flux'] == 'default':
  if args['g']:
    args['flux'] = 'hlle'
  elif args['b']:
    args['flux'] = 'hlld'
  elif args['eos'] == 'isothermal':
    args['flux'] = 'hlle'
  elif args['eos'] == 'shallow_water':
    args['flux'] = 'roe'
  elif args['eos'] == 'heterogeneous':
    args['flux'] = 'roe'
  else:
    args['flux'] = 'hllc'

# Check Riemann solver compatibility
if args['flux'] == 'hllc' and args['eos'] == 'isothermal':
  raise SystemExit('### CONFIGURE ERROR: HLLC flux cannot be used with isothermal EOS')
if args['flux'] == 'hllc' and args['b']:
  raise SystemExit('### CONFIGURE ERROR: HLLC flux cannot be used with MHD')
if args['flux'] == 'hlld' and not args['b']:
  raise SystemExit('### CONFIGURE ERROR: HLLD flux can only be used with MHD')
if args['flux'] != 'roe' and args['eos'] == 'shallow_water':
  raise SystemExit('### CONFIGURE ERROR: ShallowWater model only be used with Roe flux')
if args['flux'] != 'roe' and args['eos'] == 'heterogeneous':
  raise SystemExit('### CONFIGURE ERROR: Heterogeneous model only be used with Roe flux')

# Check relativity
if args['s'] and args['g']:
  raise SystemExit('### CONFIGURE ERROR: ' \
      + 'GR implies SR; the -s option is restricted to pure SR')
if args['t'] and not args['g']:
  raise SystemExit('### CONFIGURE ERROR: Frame transformations only apply to GR')
if args['g'] and not args['t'] and args['flux'] not in ('llf','hlle'):
  raise SystemExit('### CONFIGURE ERROR: Frame transformations required for ' + args['flux'])
if args['g'] and args['coord'] in ('cartesian','cylindrical','spherical_polar',
  'spherical_latlon'):
  raise SystemExit('### CONFIGURE ERROR: ' \
      + 'GR cannot be used with ' + args['coord'] + ' coordinates')
if not args['g'] and args['coord'] not in ('cartesian','cylindrical','spherical_polar',
    'spherical_latlon'):
  raise SystemExit('### CONFIGURE ERROR: ' \
      + args['coord'] + ' coordinates only apply to GR')
if args['eos'] == 'isothermal':
  if args['s'] or args['g']:
    raise SystemExit('### CONFIGURE ERROR: '\
        + 'Isothermal EOS is incompatible with relativity')
  if args['s'] or args['g']:
    raise SystemExit('### CONFIGURE ERROR: '\
        + 'ShallowWater EOS is incompatible with relativity')

#--- Step 3. Set definitions and Makefile options based on above arguments -------------

# Prepare dictionaries of substitutions to be made
definitions = {}
makefile_options = {}
makefile_options['LOADER_FLAGS'] = ''

# --prob=[name] argument
definitions['PROBLEM'] = makefile_options['PROBLEM_FILE'] = args['prob']

# --coord=[name] argument
definitions['COORDINATE_SYSTEM'] = makefile_options['COORDINATES_FILE'] = args['coord']

# --eos=[name] argument
definitions['EQUATION_OF_STATE'] = makefile_options['EOS_FILE'] = args['eos']

# legacy defnition of NON_BAROTROPIC_EOS
if args['eos'] == 'adiabatic':
  definitions['NON_BAROTROPIC_EOS'] = '1'
elif args['eos'] == 'heterogeneous':
  definitions['NON_BAROTROPIC_EOS'] = '1'
elif args['eos'] == 'shallow_water':
  definitions['NON_BAROTROPIC_EOS'] = '0'
elif args['eos'] == 'isothermal':
  definitions['NON_BAROTROPIC_EOS'] = '0'

# set number of hydro variables for adiabatic/isothermal
ngas = int(args['comp'][0], 16)
ncloud = int(args['comp'][1], 16)
if args['eos'] == 'adiabatic':
  definitions['NHYDRO_VARIABLES'] = '5'
if args['eos'] == 'isothermal':
  definitions['NHYDRO_VARIABLES'] = '4'
if args['eos'] == 'shallow_water':
  definitions['NHYDRO_VARIABLES'] = '4'
if args['eos'] == 'heterogeneous':
  definitions['NHYDRO_VARIABLES'] = str(4 + ngas + ncloud)

# --flux=[name] argument
definitions['RSOLVER'] = makefile_options['RSOLVER_FILE'] = args['flux']

# --order=[name] argument
definitions['RECONSTRUCT'] = makefile_options['RECONSTRUCT_FILE'] = args['order']

# --fint=[name] argument
definitions['HYDRO_INTEGRATOR'] = makefile_options['HYDRO_INT_FILE'] = args['fint']

# --particle=[num] argument
definitions['NREAL_PARTICLE_DATA'] = str(int(args['particle'][0], 16))
definitions['NINT_PARTICLE_DATA']  = str(int(args['particle'][1], 16))

# --comp=[num] argument
definitions['NGAS_VARIABLES'] = str(ngas)
definitions['NCOMP_VARIABLES'] = str(ngas + ncloud)

# --exe=[name] argument
definitions['EXE_NAME'] = makefile_options['EXE_NAME'] = args['exe']

# --main=[name] argument
definitions['MAIN_NAME'] = makefile_options['MAIN_NAME'] = 'main_' + args['main']

# -b argument
# set variety of macros based on whether MHD/hydro or adi/iso are defined
if args['b']:
  definitions['MAGNETIC_FIELDS_ENABLED'] = '1'
  makefile_options['EOS_FILE'] += '_mhd'
  definitions['NFIELD_VARIABLES'] = '3'
  makefile_options['RSOLVER_DIR'] = 'mhd/'
  if args['flux'] == 'hlle' or args['flux'] == 'llf' or args['flux'] == 'roe':
    makefile_options['RSOLVER_FILE'] += '_mhd'
  if args['eos'] == 'adiabatic':
    definitions['NWAVE_VALUE'] = '7'
  else:
    definitions['NWAVE_VALUE'] = '6'
    if args['flux'] == 'hlld':
      makefile_options['RSOLVER_FILE'] += '_iso'
else:
  definitions['MAGNETIC_FIELDS_ENABLED'] = '0'
  makefile_options['EOS_FILE'] += '_hydro'
  definitions['NFIELD_VARIABLES'] = '0'
  if args['eos'] == 'shallow_water' or args['eos'] == 'heterogeneous':
    makefile_options['RSOLVER_DIR'] = './'
  else:
    makefile_options['RSOLVER_DIR'] = 'hydro/'
  if args['eos'] == 'adiabatic':
    definitions['NWAVE_VALUE'] = '5'
  elif args['eos'] == 'isothermal':
    definitions['NWAVE_VALUE'] = '4'
  elif args['eos'] == 'shallow_water':
    definitions['NWAVE_VALUE'] = '4'
    makefile_options['RSOLVER_FILE'] += '_shallow_water'
  elif args['eos'] == 'heterogeneous':
    definitions['NWAVE_VALUE'] = str(ngas + ncloud + 4)
    makefile_options['RSOLVER_FILE'] += '_heterogeneous'

# -s, -g, and -t arguments
definitions['RELATIVISTIC_DYNAMICS'] = '1' if args['s'] or args['g'] else '0'
definitions['GENERAL_RELATIVITY'] = '1' if args['g'] else '0'
definitions['FRAME_TRANSFORMATIONS'] = '1' if args['t'] else '0'
if args['s']:
  makefile_options['EOS_FILE'] += '_sr'
  makefile_options['RSOLVER_FILE'] += '_rel'
if args['g']:
  makefile_options['EOS_FILE'] += '_gr'
  makefile_options['RSOLVER_FILE'] += '_rel'
  if not args['t']:
    makefile_options['RSOLVER_FILE'] += '_no_transform'

# --cxx=[name] argument
if args['cxx'] == 'g++':
  definitions['COMPILER_CHOICE'] = 'g++'
  definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'g++'
  makefile_options['PREPROCESSOR_FLAGS'] = ''
  makefile_options['COMPILER_FLAGS'] = '-O3'
  makefile_options['LINKER_FLAGS'] = ''
  makefile_options['LIBRARY_FLAGS'] = ''
if args['cxx'] == 'icc':
  definitions['COMPILER_CHOICE'] = 'icc'
  definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'icc'
  makefile_options['PREPROCESSOR_FLAGS'] = ''
  makefile_options['COMPILER_FLAGS'] = '-O3 -xhost -ipo -inline-forceinline'
  makefile_options['LINKER_FLAGS'] = ''
  makefile_options['LIBRARY_FLAGS'] = ''
if args['cxx'] == 'cray':
  definitions['COMPILER_CHOICE'] = 'cray'
  definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'CC'
  makefile_options['PREPROCESSOR_FLAGS'] = ''
  makefile_options['COMPILER_FLAGS'] = '-O3 -h aggress -h vector3 -hfp3'
  makefile_options['LINKER_FLAGS'] = '-hwp -hpl=obj/lib'
  makefile_options['LIBRARY_FLAGS'] = '-lm'
if args['cxx'] == 'bgxl':
  # suppressed messages:
  #   1500-036:  nostrict option can change semantics
  #   1540-1401: pragma (simd) not recognized
  definitions['COMPILER_CHOICE'] = 'bgxlc++'
  definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'bgxlc++'
  makefile_options['PREPROCESSOR_FLAGS'] = ''
  makefile_options['COMPILER_FLAGS'] = \
      '-O3 -qstrict -qlanglvl=extended -qsuppress=1500-036 -qsuppress=1540-1401'
  makefile_options['LINKER_FLAGS'] = ''
  makefile_options['LIBRARY_FLAGS'] = ''

# -debug argument
if args['debug']:
  definitions['DEBUG'] = 'DEBUG'
  if args['cxx'] == 'g++' or args['cxx'] == 'icc':
    makefile_options['COMPILER_FLAGS'] = '-O0 -g'
  if args['cxx'] == 'cray':
    makefile_options['COMPILER_FLAGS'] = '-O0'
  if args['cxx'] == 'bgxl':
    makefile_options['COMPILER_FLAGS'] = '-O0 -g -qlanglvl=extended'
else:
  definitions['DEBUG'] = 'NOT_DEBUG'

# -mpi argument
if args['mpi']:
  definitions['MPI_OPTION'] = 'MPI_PARALLEL'
  if args['cxx'] == 'g++' or args['cxx'] == 'icc':
    definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'mpicxx'
  if args['cxx'] == 'cray':
    makefile_options['COMPILER_FLAGS'] += ' -h mpi1'
  if args['cxx'] == 'bgxl':
    definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = 'mpixlcxx'
else:
  definitions['MPI_OPTION'] = 'NOT_MPI_PARALLEL'

# -omp argument
if args['omp']:
  definitions['OPENMP_OPTION'] = 'OPENMP_PARALLEL'
  if args['cxx'] == 'g++':
    makefile_options['COMPILER_FLAGS'] += ' -fopenmp'
  if args['cxx'] == 'icc':
    makefile_options['COMPILER_FLAGS'] += ' -openmp'
  if args['cxx'] == 'cray':
    makefile_options['COMPILER_FLAGS'] += ' -homp'
  if args['cxx'] == 'bgxl':
    # use thread-safe version of compiler
    definitions['COMPILER_COMMAND'] += '_r'
    makefile_options['COMPILER_COMMAND'] += '_r'
    makefile_options['COMPILER_FLAGS'] += ' -qsmp'
else:
  definitions['OPENMP_OPTION'] = 'NOT_OPENMP_PARALLEL'
  if args['cxx'] == 'cray':
    makefile_options['COMPILER_FLAGS'] += ' -hnoomp'
  if args['cxx'] == 'icc':
    # suppressed messages:
    #   3180: pragma omp not recognized
    makefile_options['COMPILER_FLAGS'] += ' -diag-disable 3180'

# -hdf5 argument
if args['hdf5']:
  definitions['HDF5_OPTION'] = 'HDF5OUTPUT'
  if args['hdf5_path'] != '':
    makefile_options['PREPROCESSOR_FLAGS'] += '-I%s/include' % args['hdf5_path']
    makefile_options['LINKER_FLAGS'] += '-L%s/lib' % args['hdf5_path']
  if args['cxx'] == 'g++' or args['cxx'] == 'icc' or args['cxx'] == 'cray':
    makefile_options['LIBRARY_FLAGS'] += ' -lhdf5'
  if args['cxx'] == 'bgxl':
    makefile_options['PREPROCESSOR_FLAGS'] += \
        ' -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_BSD_SOURCE' \
        + ' -I/soft/libraries/hdf5/1.10.0/cnk-xl/current/include' \
        + ' -I/bgsys/drivers/ppcfloor/comm/include'
    makefile_options['LINKER_FLAGS'] += \
        ' -L/soft/libraries/hdf5/1.10.0/cnk-xl/current/lib' \
        + ' -L/soft/libraries/alcf/current/xl/ZLIB/lib'
    makefile_options['LIBRARY_FLAGS'] += ' -lhdf5 -lz -lm'
else:
  definitions['HDF5_OPTION'] = 'NO_HDF5OUTPUT'

# -netcdf argument
if args['netcdf']:
  definitions['NETCDF_OPTION'] = 'NETCDFOUTPUT'
  if args['netcdf_path'] != '':
    makefile_options['PREPROCESSOR_FLAGS'] += '-I%s/include' % args['netcdf_path']
    makefile_options['LINKER_FLAGS'] += '-L%s/lib' % args['netcdf_path']
  if args['cxx'] == 'g++' or args['cxx'] == 'icc' or args['cxx'] == 'cray':
    makefile_options['LIBRARY_FLAGS'] += ' -lnetcdf'
else:
  definitions['NETCDF_OPTION'] = 'NO_NETCDFOUTPUT'

# -disort argument
if args['disort']:
  definitions['USE_DISORT'] = 'USE_DISORT'
  makefile_options['PREPROCESSOR_FLAGS'] += '-I%s' % args['disort_path']
  makefile_options['LINKER_FLAGS'] += '-L%s' % args['disort_path']
  if args['cxx'] == 'g++' or args['cxx'] == 'icc' or args['cxx'] == 'cray':
    makefile_options['LIBRARY_FLAGS'] += ' -lcdisort'
else:
  definitions['USE_DISORT'] = 'NO_DISORT'

# --ccmd=[name] argument
if args['ccmd'] is not None:
  definitions['COMPILER_COMMAND'] = makefile_options['COMPILER_COMMAND'] = args['ccmd']

# Assemble all flags of any sort given to compiler
definitions['COMPILER_FLAGS'] = ' '.join([makefile_options[opt+'_FLAGS'] for opt in \
    ['PREPROCESSOR','COMPILER','LINKER','LIBRARY']])

#--- Step 4. Create new files, finish up -----------------------------------------------

# Terminate all filenames with .cpp extension
makefile_options['PROBLEM_FILE'] += '.cpp'
makefile_options['COORDINATES_FILE'] += '.cpp'
makefile_options['EOS_FILE'] += '.cpp'
makefile_options['RSOLVER_FILE'] += '.cpp'
makefile_options['RECONSTRUCT_FILE'] += '.cpp'
makefile_options['HYDRO_INT_FILE'] += '.cpp'

# Read templates
with open(defsfile_input, 'r') as current_file:
  defsfile_template = current_file.read()
with open(makefile_input, 'r') as current_file:
  makefile_template = current_file.read()

# Make substitutions
for key,val in definitions.items():
  defsfile_template = re.sub(r'@{0}@'.format(key), val, defsfile_template)
for key,val in makefile_options.items():
  makefile_template = re.sub(r'@{0}@'.format(key), val, makefile_template)

# Write output files
with open(defsfile_output, 'w') as current_file:
  current_file.write(defsfile_template)
with open(makefile_output, 'w') as current_file:
  current_file.write(makefile_template)

# Finish with diagnostic output
print('Your Athena++ distribution has now been configured with the following options:')
print('  Problem generator:       ' + args['prob'])
print('  Coordinate system:       ' + args['coord'])
print('  Equation of state:       ' + args['eos'])
print('  Components:              ' + args['comp'])
print('  Riemann solver:          ' + args['flux'])
print('  Reconstruction method:   ' + args['order'])
print('  Hydro integrator:        ' + args['fint'])
print('  Particle data:           ' + args['particle'])
print('  Main source file name    ' + 'main_' + args['main'])
print('  Executable name:         ' + args['exe'])
print('  Magnetic fields:         ' + ('ON' if args['b'] else 'OFF'))
print('  Special relativity:      ' + ('ON' if args['s'] else 'OFF'))
print('  General relativity:      ' + ('ON' if args['g'] else 'OFF'))
print('  Frame transformations:   ' + ('ON' if args['t'] else 'OFF'))
print('  Debug flags:             ' + ('ON' if args['debug'] else 'OFF'))
print('  Linker flags:            ' + makefile_options['LINKER_FLAGS'] + ' ' \
    + makefile_options['LIBRARY_FLAGS'])
print('  MPI parallelism:         ' + ('ON' if args['mpi'] else 'OFF'))
print('  OpenMP parallelism:      ' + ('ON' if args['omp'] else 'OFF'))
print('  HDF5 output:             ' + ('ON' if args['hdf5'] else 'OFF'))
print('  NETCDF output:           ' + ('ON' if args['netcdf'] else 'OFF'))
print('  DISORT radiation model:  ' + ('ON' if args['disort'] else 'OFF'))
print('  Compiler:                ' + args['cxx'])
print('  Compilation command:     ' + makefile_options['COMPILER_COMMAND'] + ' ' \
    + makefile_options['PREPROCESSOR_FLAGS'] + ' ' + makefile_options['COMPILER_FLAGS'])


# Implementing doubly linked list
class Node:
  def __init__(self, value):
    self.prev = None
    self.next = None
    self.data = value

class DoublyLinkedList:
  def __init__(self):
    # intially list is empty
    self.head = None
    # to maintain the count of nodes
    self.n = 0

  # Insertion Operations
  # Insert at first/head (insert at head => .prepend())
  def insert_at_first(self, value):
    # create new node
    new_node = Node(value)

    # if list is empty
    if self.head is None:
      new_node.prev = None
      self.head = new_node

      self.n += 1

    # otherwise
    else:
      new_node.next = self.head
      self.head.prev = new_node
      self.head = new_node
      new_node.prev = None

      # or
      # temp = self.head
      # self.head.prev = new_node
      # new_node.next = self.head
      # self.head = new_node

      self.n += 1

  # Insert at end/tail (.append())
  def insert_at_end(self, value):
    new_node = Node(value)

    # if list is empty and new_node is the first node
    if self.head is None:
      new_node.prev = None
      self.head = new_node

    temp = self.head
    while temp.next:
      temp = temp.next

    temp.next = new_node
    new_node.prev = temp
    new_node.next = None

    self.n += 1

  # Insert at given position
  def insert_at_position(self, pos, value):
    # create new node
    count_node = self.node_count()

    if pos < 1 or pos > (count_node+1):
      print("Invalid Position.")
      return
    if pos == 1:
      self.insert_at_first(value)
      self.n += 1
    elif pos > 1 or pos < (count_node-1):
      new_node = Node(value)
      temp = self.head
      for i in range(1, pos-1):
        temp = temp.next

      new_node.prev = temp
      new_node.next = temp.next
      # temp.next.prev = new_node
      temp.next = new_node

      # not understood
      # if the position is last (inserting at end position)
      if temp.next:
        temp.next.prev = new_node

      self.n += 1

    # elif pos == count_node-1:
    #   self.insert_at_end(value)

  # Insert after certain element
  def insert_after(self, key, data):
    new_node = Node(data)
    current = self.head
    while current:
      # if there is one node in list
      if current.next is None and current.data == key:
        self.insert_at_end(data)
        return
      elif current.data == key:
        temp = current.next # store the address of the next node (to manipulate the remaining pointers)
        current.next = new_node
        new_node.next = temp
        new_node.prev = current
        temp.prev = new_node

      # update the current pointer
      current = current.next

  # Insert before certain element
  def insert_before(self, key, data):
    new_node = Node(data)
    current = self.head

    while current:
    # if there is one node in list
      if current.prev is None and current.data == key:
        self.insert_at_first(data)
        return
      elif current.data == key:
        temp = current.prev
        temp.next = new_node
        current_prev = new_node
        new_node.next = current
        new_node.prev =  temp

      current = current.next

  # Deletion Operations
  # Delete from head/first
  def delete_first(self):
    # edge case
    current = self.head
    if current == self.head:
      if not current.next: # not pointing to any node (single node in list)
        current = None
        self.head = None
        return
      else: # pointing to node
        temp = current.next
        current.next = None
        temp.prev = None
        current = None # pahila pointer cha address ch udun takla (sampla wishay)
        self.head = temp
        return

  # Delete from tail/last (.pop())
  def delete_last(self):
    current = self.head
    if self.head == None:
      return "Linked list is empty."
    # edge case: only one node
    elif not current.next:
      current = None
      self.head = None
      return
    else:
      temp = current.next
      before = self.head

      while temp.next:
        temp = temp.next
        before = before.next

      before.next = None
      temp.next = None

  # Delete from given position
  def delete_from_position(self, pos):
    count_node = self.node_count()

    if pos < 1 or pos > (count_node+1):
      return "Invalid Position."
    elif pos == 1:
      self.delete_first()
      return
    else:
      current = self.head.next
      before = self.head

      for i in range(1, pos-1):
        current = current.next
        before = before.next

      before.next = current.next
      current.next.prev = before
      current.prev = None
      current.next = None
      return

  def node_count(self):
    return self.n

  # display linked list
  def display(self):
    # if linked list is empty
    if self.head is None:
      print("Linked list is empty.")

    temp = self.head
    res = ""
    while temp:
      res = res + str(temp.data) + ' -> '
      temp = temp.next

    return res[:-3]

if __name__ == '__main__':
  l = DoublyLinkedList()
  l.insert_at_end(10)
  l.insert_at_end(20)
  l.insert_at_end(30)
  # l.insert_at_end(40)
  # l.insert_at_end(50)
  # l.insert_at_first(9)
  print(l.display())

  # l.insert_before(9, 90)
  # l.delete_first()
  # l.delete_last()
  l.delete_from_position(3)
  print(l.display())


class Solution:

    '''
    @param root: An object of TrieNode, denote the root of the trie.
    This method will be invoked first, you should design your own algorithm
    to serialize a trie which denote by a root node to a string which
    can be easily deserialized by your own "deserialize" method later.
    '''
    def serialize(self, root):
        # Write your code here
        if root is None:
            return ""

        data = ""
        for key, value in root.children.items():
            data += key + self.serialize(value)

        return "<%s>" % data

    '''
    @param data: A string serialized by your serialize method.
    This method will be invoked second, the argument data is what exactly
    you serialized at method "serialize", that means the data is not given by
    system, it's given by your own serialize method. So the format of data is
    designed by yourself, and deserialize it here as you serialize it in
    "serialize" method.
    '''
    def deserialize(self, data):
        # Write your code here
        if data is None or len(data) == 0:
            return None

        root = TrieNode()
        current = root
        path = []
        for c in data:
            if c == '<':
                path.append(current)
            elif c == '>':
                path.pop()
            else:
                current = TrieNode()
                path[-1].children[c] = current

        return root


"""TestCountingDecorator"""
import time
import random
import unittest
from counting_decorator import counting

@counting(2)
def square_sleep_1(num):
    """square_sleep_1"""
    rand_sec = round(0.1 + random.random() * 0.01, 3)
    time.sleep(rand_sec)
    print(f'square_sleep_1 slept {rand_sec} seconds')
    return num * num

@counting(3)
def square_sleep_3(num):
    """square_sleep_3"""
    rand_sec = round(0.3 + random.random() * 0.01, 3)
    time.sleep(rand_sec)
    print(f'square_sleep_3 slept {rand_sec} seconds')
    return num * num

class TestCountingDecorator(unittest.TestCase):
    """TestCountingDecorator"""
    def test_counting_decorator(self):
        """test_counting_decorator"""
        for _ in range(6):
            square_sleep_1(10)
            square_sleep_3(10)
        self.assertTrue(True)


class Solution:
    def getPermutation(self, nums: int, k: int) -> str:
        factorial_table = [1] # 从0到n的阶乘结果表
        for l in range(1, nums):
            factorial_table.append(factorial_table[-1]*l)
        k = k - 1 # 求第k个实际上在计算机中就是求第k-1个
        nums = [_ for _ in range(1, nums+1)]
        ret = ''
        while nums:
            fa = factorial_table[len(nums)-1] # 求出len(nums) - 1的阶乘fa
            ret += str(nums.pop(k // fa)) # 将下标为k//fa的nums中的元素添加到字符串上
            k = k % fa # k为减去x个fa后的余数
        return ret


"""
Author: Manish Saroya
Contact: saroyam@oregonstate.edu
"""
import pickle
import numpy as np
import matplotlib.pyplot as plt
map_type = "intel"
roadmap_types = ["gng", "gng_top", "gng_top_feedback", "prm", "prm_dense", "prm_dense_hilbert"]

# roadmap_types = ["gng_top", "gng"]
data_save_dic = {"gng": "gng_output/", "gng_top": "gng_top_output/", "gng_top_feedback": "gng_top_feedback_output/", "prm": "prm_output/",
                     "prm_dense": "prm_dense_output/", "prm_dense_hilbert": "prm_dense_hilbert_output/"}
for roadmap in roadmap_types:
	if roadmap == "gng":
		with open(data_save_dic[roadmap] + "{}_gng1208_200.pickle".format(map_type), 'rb') as tf:
			gng_data = pickle.load(tf)
	elif roadmap == "gng_top":
		with open(data_save_dic[roadmap] + "{}_gngtop_1208_200.pickle".format(map_type), 'rb') as tf:
			gngtop_data = pickle.load(tf)
	elif roadmap == "gng_top_feedback":
		with open(data_save_dic[roadmap] + '{}_gngtop_feedback_1208_200.pickle'.format(map_type), 'rb') as tf:
			gngtop_feedback_data = pickle.load(tf)
	elif roadmap == "prm":
		with open(data_save_dic[roadmap] + '{}_prm1208.pickle'.format(map_type), 'rb') as tf:
			prm_data = pickle.load(tf)
	elif roadmap == "prm_dense":
		with open(data_save_dic[roadmap] + '{}_prmdense_2500.pickle'.format(map_type), 'rb') as tf:
			prmdense_data = pickle.load(tf)
	elif roadmap == "prm_dense_hilbert":
		with open(data_save_dic[roadmap] + '{}_prmdense_hilbert4000.pickle'.format(map_type), 'rb') as tf:
			prmdense_hilbert_data = pickle.load(tf)

# with open("test_output/prm1208.pickle", 'rb') as tf:
# 	prm_data = pickle.load(tf)
#
# with open("test_output/prmdense_2500.pickle", 'rb') as tf:
# 	prmdense_data = pickle.load(tf)
	# with open("test_output/" + 'prm1208.pickle', 'wb') as handle:
	# 	pickle.dump([success_list, node_explored_list, distance_to_goal_list], handle)
print("hello")
count = 0
gng_path_cost = []
gngtop_path_cost = []
gngtop_feedback_path_cost = []
prm_path_cost = []
prmdense_path_cost =[]
prmdense_hilbert_path_cost =[]

gng_node_explored = []
gngtop_node_explored = []
gngtop_feedback_node_explored = []
prm_node_explored = []
prmdense_node_explored = []
prmdense_hilbert_node_explored = []

gng_mismatch_indices = []
gngtop_mismatch_indices = []
index_list = []
spl_gngtop = 0
spl_gngtop_feedback = 0
spl_gng = 0
spl_prm = 0
spl_prmdense = 0
spl_prmdense_hilbert = 0
spl_count = 0
for i in range(len(gng_data[0])):
	if prmdense_data[0][i]!=gng_data[0][i]:
		gng_mismatch_indices.append(i)
	if prmdense_data[0][i]!=gngtop_data[0][i]:
		gngtop_mismatch_indices.append(i)
	if gng_data[0][i]==False and gngtop_feedback_data[0][i]==True and prmdense_data[0][i]==True:
		index_list.append(i)
	#if prmdense_data[0][i]==False:
	#	index_list.append(i)
	if gng_data[0][i] and gngtop_data[0][i] and gngtop_feedback_data[0][i] and prmdense_data[0][i] and prmdense_hilbert_data[0][i]:# and prm_data[0][i]:
	#if prm_data[0][i]==True:
		gng_path_cost.append(gng_data[2][i])
		gngtop_path_cost.append(gngtop_data[2][i])
		gngtop_feedback_path_cost.append(gngtop_feedback_data[2][i])
		#prm_path_cost.append(prm_data[2][i])
		prmdense_path_cost.append(prmdense_data[2][i])
		prmdense_hilbert_path_cost.append(prmdense_hilbert_data[2][i])

		gng_node_explored.append(gng_data[1][i])
		gngtop_node_explored.append(gngtop_data[1][i])
		gngtop_feedback_node_explored.append(gngtop_feedback_data[1][i])
		#prm_node_explored.append(prm_data[1][i])
		prmdense_node_explored.append(prmdense_data[1][i])
		prmdense_hilbert_node_explored.append(prmdense_hilbert_data[1][i])

	# # sil score calculation
	# if prmdense_data[0][i]:
	# 	if gngtop_data[0][i]:
	# 		spl_gngtop += (prmdense_data[2][i] / max(prmdense_data[2][i], gngtop_data[2][i]))
	# 	if gngtop_feedback_data[0][i]:
	# 		spl_gngtop_feedback += (prmdense_data[2][i] / max(prmdense_data[2][i], gngtop_feedback_data[2][i]))
	# 	if gng_data[0][i]:
	# 		spl_gng += (prmdense_data[2][i] / max(prmdense_data[2][i], gng_data[2][i]))
	# 	if prm_data[0][i]:
	# 		spl_prm += (prmdense_data[2][i] / max(prmdense_data[2][i], prm_data[2][i]))
	# 	if prmdense_data[0][i]:
	# 		spl_prmdense += (prmdense_data[2][i] / max(prmdense_data[2][i], prmdense_data[2][i]))
	# 	if prmdense_hilbert_data[0][i]:
	# 		spl_prmdense_hilbert += (prmdense_data[2][i] / max(prmdense_data[2][i], prmdense_hilbert_data[2][i]))
	# 	spl_count += 1
	if prmdense_data[0][i]:
		if gngtop_data[0][i]:
			spl_gngtop += (prmdense_data[1][i] / gngtop_data[1][i])
		if gngtop_feedback_data[0][i]:
			spl_gngtop_feedback += (prmdense_data[1][i] / gngtop_feedback_data[1][i])
		if gng_data[0][i]:
			spl_gng += (prmdense_data[1][i] /  gng_data[1][i])
		if prm_data[0][i]:
			spl_prm += (prmdense_data[1][i] /  prm_data[1][i])
		if prmdense_data[0][i]:
			spl_prmdense += (prmdense_data[1][i] /  prmdense_data[1][i])
		if prmdense_hilbert_data[0][i]:
			spl_prmdense_hilbert += (prmdense_data[1][i] / prmdense_hilbert_data[1][i])
		spl_count += 1

print("Path cost")
print("prmdense_cost 4000 mean:", np.mean(prmdense_path_cost), np.std(prmdense_path_cost))
print("prmdense_hilbert_cost 2000 mean:", np.mean(prmdense_hilbert_path_cost), np.std(prmdense_hilbert_path_cost))
print("gngtop_cost mean:", np.mean(gngtop_path_cost), np.std(gngtop_path_cost))
print("gngtop_feedback_cost mean:", np.mean(gngtop_feedback_path_cost), np.std(gngtop_feedback_path_cost))
print("gng_cost mean:", np.mean(gng_path_cost), np.std(gng_path_cost))
#print("prm_cost mean:", np.mean(prm_path_cost), np.std(prm_path_cost))

print("gng_mismatch_indices",len(gng_mismatch_indices))
print("gngtop_mismatch_indices",len(gngtop_mismatch_indices))

print("node_explored")
print("prmdense_node_explored 4000mean:", np.mean(prmdense_node_explored), np.std(prmdense_node_explored))
print("prmdense_hilbert_node_explored 2000 mean:", np.mean(prmdense_hilbert_node_explored), np.std(prmdense_hilbert_node_explored))
print("gngtop_node_explored mean:", np.mean(gngtop_node_explored), np.std(gngtop_node_explored))
print("gngtop_feedback_node_explored mean:", np.mean(gngtop_feedback_node_explored), np.std(gngtop_feedback_node_explored))
print("gng_node_explored mean:", np.mean(gng_node_explored), np.std(gng_node_explored))
#print("prm_node_explored mean:", np.mean(prm_node_explored), np.std(prm_node_explored))

print("spl_prmdense PRM4000", spl_prmdense/spl_count, sum(prmdense_data[0])/sum(prmdense_data[0]))
print("spl_prmdense_hilbert PRM 2000", spl_prmdense_hilbert/spl_count, sum(prmdense_hilbert_data[0])/sum(prmdense_data[0]))
print("spl_gngtop ", spl_gngtop/spl_count, sum(gngtop_data[0])/sum(prmdense_data[0]))
print("spl_gngtop_feedback ", spl_gngtop_feedback/spl_count, sum(gngtop_feedback_data[0])/sum(prmdense_data[0]))
print("spl_gng ", spl_gng/spl_count, sum(gng_data[0])/sum(prmdense_data[0]))
print("spl_prm 1000", spl_prm/spl_count, sum(prm_data[0])/sum(prmdense_data[0]))