import gym
import numpy as np
import time

from utils.data_utils import read_file

class PolicyEvaluation(object):
    """
    Class with policy evaluation implementation.
    """
    def __init__(self, cfg):
        """
        Initializes class.
        :param cfg: config
        """
        self.cfg = cfg

        self.init_env()
        self.show_env_info()

        self.transition_matrix = self.env.transition_matrix
        self.states_num = len(self.transition_matrix)
        self.actions_num = len(self.transition_matrix[0])
        self.init_matrices()

        self.solutions_types = ['direct', 'iterative']

    def init_env(self):
        """
        Initializes environment with parameters from config.
        """
        self.env = gym.make('frozen_lake:default-v0', map_name=self.cfg.map_name, action_set_name=self.cfg.action_set)
        self.env.reset(start_state_index=0)

    def show_env_info(self):
        """
        Prints information about current environment.
        """
        if self.cfg.verbose:
            self.env.render(object_type="environment")
            self.env.render(object_type="actions")
            self.env.render(object_type="states")
            print(f'\nMap type: {self.cfg.map_name}\n'
                  f'Policy type: {self.cfg.policy_type}\n'
                  f'Action Set: {self.cfg.action_set}\n'
                  f'Discount Factor: {self.cfg.discount_factor}')

    def init_matrices(self):
        """
        init transition probability matrix, reward matrix.
        """
        self.transition_prob_matrix = np.zeros((self.states_num, self.states_num, self.actions_num))
        self.reward_matrix = np.zeros((self.states_num, self.actions_num, self.states_num))

        for s in range(self.states_num):
            for a in range(self.actions_num):
                for new_s_tuple in self.transition_matrix[s][a]:
                    transition_prob, new_s, reward, _ = new_s_tuple
                    self.transition_prob_matrix[s][new_s][a] += transition_prob
                    self.reward_matrix[s][a][new_s] += reward

        self.reward_matrix = np.max(self.reward_matrix, axis=-1)  # mean

    def get_policy(self):
        """
        Initializes policy within config params.
        """
        if self.cfg.policy_type == 'stochastic':
            self.policy = np.random.uniform(0, 1, (self.states_num, self.actions_num))
            self.policy = [self.policy[i, :] / np.sum(self.policy, 1)[i]
                           for i in range(self.states_num)]

        elif self.cfg.policy_type == 'optimal':
            data = read_file(self.cfg.optimal_policies_file_path)
            self.policy = np.asarray(data[self.cfg.map_name][self.cfg.action_set])

        else:
            raise Exception

    def get_model_with_policy(self):
        """
        Gets transition probability matrix, reward matrix within chosen policy.
        :return:
        """
        self.transition_prob_matrix_pi = np.zeros((self.states_num, self.states_num))
        self.reward_matrix_pi = np.zeros(self.states_num)

        for s in range(self.states_num):
            for new_s in range(self.states_num):
                self.transition_prob_matrix_pi[s][new_s] = self.policy[s] @ self.transition_prob_matrix[s][new_s]

            self.reward_matrix_pi[s] = self.policy[s] @ self.reward_matrix[s]

    def get_direct_solution(self):
        """
        Gets direct solution with given formula V = (I − γP)^−1 R.
        :return: v vector
        """
        start_time = time.time()

        eye_matrix = np.eye(self.states_num)
        v_pi = np.linalg.inv(
            eye_matrix - self.cfg.discount_factor * self.transition_prob_matrix_pi) @ self.reward_matrix_pi

        self.direct_solution_time = time.time() - start_time
        if self.cfg.verbose:
            print(f'\nDirect solution time: {self.direct_solution_time} s')
        return v_pi

    def get_iterative_solution(self):
        """
        Gets iterative solution.
        :return: v vector
        """
        start_time = time.time()

        v = np.zeros(self.states_num)
        step = 0

        while True:  # step <= self.cfg.max_iter:
            dif = 0
            for s in range(self.states_num):
                prev_v = v[s]
                v[s] = self.reward_matrix_pi[s] + self.cfg.discount_factor * (self.transition_prob_matrix_pi[s] @ v)
                dif = np.max([dif, abs(prev_v - v[s])])
            # print(step, dif, v')
            step += 1

            if dif < self.cfg.estimation_accuracy_thr:
                break

        self.iterative_solution_time = time.time() - start_time
        if self.cfg.verbose:
            print(f'Iterative solution time: {self.iterative_solution_time} s\n')
        return v

    def run(self):
        """
        Runs direct and iterative policy evaluation algorithms.
        """

        self.get_policy()
        self.get_model_with_policy()

        self.v_direct = self.get_direct_solution()
        self.v_iterative = self.get_iterative_solution()

        assert np.allclose(self.v_iterative, self.v_direct, atol=1e-1)

        if self.cfg.verbose:
            print(f'Direct solution: v={self.v_direct}\n')
            print(f'Iterative solution: v={self.v_iterative}\n')

            fast_solution_type = self.solutions_types[np.argmin([self.direct_solution_time,
                                                                 self.iterative_solution_time])]
            time_dif = abs(self.direct_solution_time - self.iterative_solution_time)
            print(f'Faster solution: {fast_solution_type}, is faster by: {time_dif} seconds')


import hydra
import os
from omegaconf import DictConfig, OmegaConf

@hydra.main(version_base=None, config_path="conf", config_name="config")
def func(cfg: DictConfig):
    working_dir = os.getcwd()
    orig_cwd = hydra.utils.get_original_cwd()

    print(f"The current working directory is {working_dir}")
    print(f"Getting original current working directory: {orig_cwd}")

    # Read file
    path = f"{orig_cwd}/test.txt"
    with open(path, "r") as f:
        print(f.read())

    # Write file
    path = f"output.txt"
    with open(path, "w") as f:
        f.write("This is a dog")

    # To access elements of the config
    print(f"The batch size is {cfg.batch_size}")
    print(f"The learning rate is {cfg['lr']}")

if __name__ == "__main__":
    func()


# -*- coding: utf-8 -*-

"""nlp100 in python3"""

__author__ = "Yu Sawai (tuxedocat@github.com)"
__copyright__ = "Copyright 2015, tuxedocat"
__credits__ = ["Naoaki Okazaki", "Inui-Okazaki Lab. at Tohoku University"]
__license__ = "MIT"

import sys
import subprocess
import math
from docopt import docopt

if __name__ == '__main__':
    __doc__ = ( """Simplified implementation of split command. \n\n"""
                """usage: \n"""
                """  p16.py [-n <N>] <file> \n\n"""
                """options: \n"""
                """  -n <N>     num of split [default: 5]""")

    args = docopt(__doc__)
    n = int(args["-n"]) if "-n" in args else 5

    with open(args["<file>"], 'r') as input:
        text = input.readlines()
        L = len(text)
        N = math.floor(L / n)
        c = 1
        splits = []
        _s = []
        for line in text:
            if c >= N:
                _s.append(line)
                splits.append(_s)
                _s = []
                c = 1
            else:
                _s.append(line)
                c += 1

    for i, split in enumerate(splits):
        with open("./p16-split-{}.txt".format(i+1), "w") as output:
            output.writelines(split)


def solution(nums):
    answer = ''
    # 0 1 0 10 0 1 0 10 0 -1 -2 -1
    # w+1 s-1 d+10 a-10
    # wsdawsdassw

    for i in range(1, len(nums)):
        m = nums[i] - nums[i-1]
        if m == 1:
            answer += 'w'
        elif m == -1:
            answer += 's'
        elif m == 10:
            answer += 'd'
        else:
            answer += 'a'

    return answer

프로그래머스/unrated/181925. 수 조작하기 2/수 조작하기 2.py


import numpy as np

from .base_graph import Graph
from riotwatcher import RiotWatcher
import matplotlib.pyplot as plt
from matplotlib import rcParams

class ChampionWinsGraph(Graph):
    def __init__(self, api_watcher, region, champion_json):
        super(ChampionWinsGraph, self).__init__(api_watcher, region)
        self.champion_json = champion_json

    def render(self, summoner_name="SamuelTheRandom", filepath="cw-summoner.png"):
        summoner = self.api_watcher.summoner.by_name(self.region, summoner_name)
        history = self.api_watcher.match.matchlist_by_account(self.region, summoner["accountId"], end_index=20) # Get the most recent 20 games played

        champ_match_dict = dict()
        for match in history["matches"]:
            champion_id_dict = self.champion_json["keys"]
            champion_name = champion_id_dict[str(match["champion"])] # Uses the champion id and retrieves the champions name

            if champion_name not in champ_match_dict:
                match_list = list()
            else:
                match_list = champ_match_dict[champion_name]

            match_list.append(match["gameId"])
            champ_match_dict[champion_name] = match_list

        dataset = dict()
        for champion in champ_match_dict:
            games_played = len(champ_match_dict[champion])
            games_won = 0

            for match_id in champ_match_dict[champion]:
                match = self.api_watcher.match.by_id(self.region, match_id)

                for participant in match["participants"]:
                    if self.champion_json["keys"][str(participant["championId"])] == champion:
                        team_id = participant["teamId"]

                for team in match["teams"]:
                    if team["teamId"] == team_id:
                        if team["win"] == "Win":
                            games_won+= 1

            dataset[champion] = (games_played, games_won)

        x = dataset.keys() # The x axis of champion names
        y1,y2 = zip(*dataset.values()) #Unpack the total games played, and games won

        ind = np.arange(len(x))
        width = 0.35

        fig, ax = plt.subplots(1)

        p1 = ax.bar(ind, y1, width, color='#d62728')
        p2 = ax.bar(ind, y2, width)

        plt.ylabel('Number of Games')
        plt.title('Champion wins over the past 20 games played for ' + summoner["name"])
        plt.xticks(ind, x)
        plt.yticks(np.arange(0, 21, 1))
        plt.legend((p1[0], p2[0]), ('Number of Games Played', 'Number of Games Won'))
        fig.autofmt_xdate()
        plt.savefig(filepath, bbox_inches='tight')


import os,sys,glob
from os import path

from win32com import client

# Notes on accessing Powerpoint from Python with COM:
# TODO: Find new links! [Links Found, just have to insert here!]
# http://stackoverflow.com/questions/6337595/python-win32-com-closing-excel-workbook
# http://www.numbergrinder.com/2008/11/closing-excel-using-python/
# http://stackoverflow.com/questions/24023518/using-python-to-autofit-all-columns-of-an-excel-sheet

# FileFormat numbers
format_number = {'.pptx':51,
                 '.ppt':52,
                 '.pdf':57}

#
# Uses Powerpoint to convert to .pptx and to .pdf
# https://stackoverflow.com/questions/16683376/print-chosen-worksheets-in-excel-files-to-pdf-in-python
# https://github.com/mwhit74/excel/blob/master/excel_to_pdf.py
def powerpoint_convert(infile,out_ext):
    if out_ext not in format_number:
        print("Unknown extension '{}': valid extensions: {}".format(out_ext,format_number.keys()))

    infile_fullpath = os.path.abspath(infile)
    (base,in_ext) = os.path.splitext(infile_fullpath)

    powerpoint = None
    if not os.path.isfile(infile_fullpath):
        print("{} does not exist".format(infile_fullpath));
        return False

    outfile    = base+out_ext
    if os.path.exists(outfile):
        print("   {} exists".format(outfile))
        return False

    if in_ext==out_ext:
        return False

    # if in_ext.lower()=='.xml' and not is_xls_xml(infile_fullpath):
    #     return False

    powerpoint = client.DispatchEx("Powerpoint.Application")
    powerpoint.Visible = 0
    powerpoint.DisplayAlerts = False

    print("Opening {}".format(infile_fullpath))
    presentation = powerpoint.Presentations.Open(infile_fullpath)

    if out_ext == '.pdf':
        for slide in presentation.Slides:
            # Don't change the orientation
            # ws.PageSetup.Orientation    = 1     # 1=Portrait, 2=Landscape

            # Set page margins (in points) to .5 inches
            # https://docs.microsoft.com/en-us/office/vba/api/excel.pagesetup.leftmargin

            slide.PageSetup.LeftMargin = 36
            slide.PageSetup.RightMargin = 36
            slide.PageSetup.TopMargin = 36
            slide.PageSetup.BottomMargin = 36

            # Make it fit on one page wide
            slide.PageSetup.FitToPagesWide = 1
            # ws.PageSetup.FitToPagesTall = 1

            # We could limit the print area...
            # ws.PageSetup.PrintArea = 'A1:G50'

    print("{} => {}".format(infile_fullpath,outfile))

    # wb.Worksheets.Sheet()
    try:
        presentation.SaveAs(outfile, FileFormat=format_number[out_ext])
    except Exception as e:
        print("Failed to convert")
        print(str(e))

    if presentation:
        presentation.Close(False)         # May work
        powerpoint.Quit()
    return True

if __name__=="__main__":
    import argparse
    parser = argparse.ArgumentParser(description='Convert files to .pptx and .pdf',
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("infile")
    parser.add_argument("out_ext")
    args = parser.parse_args()
    if "*" or "?" in args.infile:
        for fn in glob.glob(args.infile):
            powerpoint_convert(fn,args.out_ext)
    else:
        powerpoint_convert(args.infile,args.out_ext)


from .database import DataBase

keyname = 'PhosphoSitePlus'
alternative_keynames = []

class PhosphoSitePlus(DataBase):

    def __init__(self, id=None):

        self.database = keyname
        self.name = 'PhosphoSitePlus'
        self.id = id
        self.web = 'https://www.phosphosite.org/homeAction.action'
        self.webid = 'https://www.phosphosite.org/homeAction.action'
        self.info = 'PhosphoSitePlus'


# Build a dictionary that contains the movie collection.
# Since we'll be referencing movies primarily by year and dictionary keys must be unique,
# each year's collection of movies is a list containing all movies associated with that year.
# Each individual movie is represented as a list containing the title and director.

movie_collection = {
    2005: [['Munich', 'Steven Spielberg']],
    2006: [['The Prestige', 'Christopher Nolan'], ['The Departed', 'Martin Scorsese']],
    2007: [['Into the Wild', 'Sean Penn']],
    2008: [['The Dark Knight', 'Christopher Nolan']],
    2009: [['Mary and Max', 'Adam Elliot']],
    2010: [['The King\'s Speech', 'Tom Hooper']],
    2011: [['The Artist', 'Michel Hazanavicius'], ['The Help', 'Tate Taylor']],
    2012: [['Argo', 'Ben Affleck']],
    2013: [['12 Years a Slave', 'Steve McQueen']],
    2014: [['Birdman', 'Alejandro G. Inarritu']],
    2015: [['Spotlight', 'Tom McCarthy']],
    2016: [['The BFG', 'Steven Spielberg']]
}


from turtle import Screen, colormode
from paddle import Paddle
from ball import Ball
from scoreboard import Scoreboard
import time

colormode(255)
# Screen Setup
screen = Screen()
screen.bgcolor("black")
screen.setup(height=600, width=800)
screen.title("The Ping Pong Game")
screen.listen()
screen.tracer(0)

paddle_left = Paddle((-350, 0))
paddle_right = Paddle((350, 0))
ball = Ball()
scoreboard = Scoreboard()
screen.onkey(paddle_right.go_up, "Up")
screen.onkey(paddle_right.go_down, "Down")
screen.onkey(paddle_left.go_up, "w")
screen.onkey(paddle_left.go_down, "s")

game_is_on = True
while game_is_on:
    time.sleep(ball.move_speed)
    screen.update()
    ball.move()

    # Detect collision with the walls
    if ball.ycor() > 280 or ball.ycor() < -280:
        ball.bounce_y()

    # Detect collision with the paddles
    if ball.distance(paddle_right) < 50 and ball.xcor() > 320 or ball.distance(paddle_left) < 50 and ball.xcor() < -320:
        ball.bounce_x()

    # Detect Right paddle misses
    if ball.xcor() > 380:
        ball.reset_position()
        scoreboard.score_increase_left()

    # Detect Left paddle misses
    if ball.xcor() < -380:
        ball.reset_position()
        scoreboard.score_increase_right()

screen.exitonclick()


from itertools import product

def iterative_multiply(n, m):
    """
    Multiplies n by m and returns the product without using the * operator
    Time Complexity: O(N/2) => O(N)
    Space Complexity: O(1)
    """

    divideBy2Count = 0

    while n >= 2:
        divideBy2Count += 1
        n -= 2

    product = 0
    while divideBy2Count:
        product += (m << 1)
        divideBy2Count -= 1

    if n == 1:
        product += m

    return product

def recursive_multiply(n, m):
    """
    Multiplies n by m and returns the product without using the * operator
    Time Complexity: O(N)
    Space Complexity: O(N)
    """
    if n <= 0 or m <= 0:
        return 0

    if n == 1:
        return m

    if m == 1:
        return n

    return recursive_multiply(n - 1, m) + m

def iterative_new(n, m):

    while n > 1:
        m <<= 1
        n >>= 1
    return (n, m)

def main():
    cases = [
        (6, 9),
        (2, 4),
        (5, 7),
        (1, 6),
        (5, 9),
        ()
        (116, 135)
    ]

    for case in cases:
        print(iterative_new(case[0], case[1]))
        print(case[0] * case[1])
    # for case in cases:
    #     mine = recursive_multiply(case[0], case[1])
    #     correct = case[0] * case[1]
    #     if mine != correct:
    #         print(mine)
    #         print(correct)
    #         print('--------------------')

    # print(9 << 3)

if __name__ == '__main__':
    main()


from __future__ import unicode_literals

from django.apps import AppConfig
from django.db.models.functions import Now
from django.utils.translation import ugettext_lazy as _

class SchedulerConfig(AppConfig):
    name = 'scheduler'
    verbose_name = _('Django RQ Scheduler')

    def ready(self):
        try:
            self.reschedule_cron_jobs()
            self.reschedule_repeatable_jobs()
            self.reschedule_scheduled_jobs()
        except:
            # Django isn't ready yet, example a management command is being
            # executed
            pass

    def reschedule_cron_jobs(self):
        CronJob = self.get_model('CronJob')
        jobs = CronJob.objects.filter(enabled=True)
        self.reschedule_jobs(jobs)

    def reschedule_repeatable_jobs(self):
        RepeatableJob = self.get_model('RepeatableJob')
        jobs = RepeatableJob.objects.filter(enabled=True)
        self.reschedule_jobs(jobs)

    def reschedule_scheduled_jobs(self):
        ScheduledJob = self.get_model('ScheduledJob')
        jobs = ScheduledJob.objects.filter(
            enabled=True, scheduled_time__lte=Now())
        self.reschedule_jobs(jobs)

    def reschedule_jobs(self, jobs):
        for job in jobs:
            if job.is_scheduled() is False:
                job.save()


#Author Shaelynn Caltagirone
#Create very simple student tracking app

from tkinter import *
import tkinter as tk
from tkinter import messagebox

import student_gui
import student_func

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

        self.master = master
        self.master.minsize(500,300)
        self.master.maxsize(500,300)

        self.master.title("Student Tracking")

        student_gui.load_gui(self)

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


import networkx as nx
import matplotlib.pyplot as plt
from networkx.drawing.nx_agraph import graphviz_layout

g=nx.Graph()

g.add_node(1)
g.add_node(2)

for i in range(1,5):
	g.add_node(i)

for i in range(4,1,-1):
	g.add_edge(i-1,i)
	if(i!=2):
		g.add_edge(i-2,i)
	if(i!=3):
		g.add_edge(i-3,i)

#g.add_edge(1,5)
#g.add_edge(2,3)
#g.add_edges_from([(1,2),(3,4)])
#nx.draw(g)
#plt.show()

#nx.draw(g, pos=graphviz_layout(g), node_size=1600, cmap=plt.cm.Blues, node_color=range(len(g)), prog='dot',with_labels=True)

nx.draw(g, os=graphviz_layout(g), node_size = 1200, node_color='skyblue',edge_color='red', width='3.0', with_labels = True)

plt.show()


from flask import Flask, render_template, request
import pandas as pd
from sklearn.preprocessing import LabelEncoder
import pickle

app = Flask(__name__)

model = pickle.load(open('Voting_model.pkl', 'rb'))

#reg.pickle.load(open('Voting_model1.pkl', 'rb'))

# create a LabelEncoder object for categorical columns
categorical_encoder = LabelEncoder()

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/predict',methods=['POST'])
def predict():
    # get the input values from the HTML form
    name = request.form.get('name')
    category_name = request.form.get('category_name')
    brand_name = request.form.get('brand_name')
    item_description = request.form.get('item_description')
    item_condition_id = request.form.get('item_condition_id')
    shipping = request.form.get('shipping')

    # create a pandas dataframe with the input values
    data = pd.DataFrame({'name':[name],'item_condition_id':[item_condition_id], 'category_name':[category_name], 'brand_name':[brand_name],
                         'shipping':[shipping],'item_description':[item_description]})
    categorical_columns = ["name", "category_name", "brand_name", "item_description"]
    # convert the categorical variables to numerical using label encoding
    data[categorical_columns] = categorical_encoder.fit_transform(data[categorical_columns].astype(str).values.ravel())
    print("above predict--------------------")
    data['item_condition_id'] = pd.to_numeric(data['item_condition_id'])
    data['shipping'] = pd.to_numeric(data['shipping'])
    # make predictions using the trained model
    prediction = model.predict(data)
    print("below predict--------------------")

    # format the prediction as a string
    prediction_str = f'${round(prediction[0], 2)}'

    # render the HTML template with the prediction
    return render_template('index.html', prediction_text='  Predicted Price: {}  '.format(prediction_str))

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


import itertools
from datetime import datetime

from flask import render_template, request
from flask_login import login_required

from app import service_api_client
from app.main import main
from app.main.forms import DateFilterForm
from app.statistics_utils import get_formatted_percentage
from app.utils import user_is_platform_admin

@main.route("/platform-admin")
@login_required
@user_is_platform_admin
def platform_admin():
    form = DateFilterForm(request.args)
    api_args = {'detailed': True,
                'only_active': False,     # specifically DO get inactive services
                'include_from_test_key': form.include_from_test_key.data,
                }

    if form.start_date.data:
        api_args['start_date'] = form.start_date.data
        api_args['end_date'] = form.end_date.data or datetime.utcnow().date()

    platform_stats = service_api_client.get_aggregate_platform_stats(api_args)

    for stat in platform_stats.values():
        stat['failure_rate'] = get_formatted_percentage(stat['failed'], stat['requested'])

    return render_template(
        'views/platform-admin/index.html',
        include_from_test_key=form.include_from_test_key.data,
        form=form,
        global_stats=platform_stats,
    )

@main.route("/platform-admin/live-services", endpoint='live_services')
@main.route("/platform-admin/trial-services", endpoint='trial_services')
@login_required
@user_is_platform_admin
def platform_admin_services():
    form = DateFilterForm(request.args)
    api_args = {'detailed': True,
                'only_active': False,    # specifically DO get inactive services
                'include_from_test_key': form.include_from_test_key.data,
                }

    if form.start_date.data:
        api_args['start_date'] = form.start_date.data
        api_args['end_date'] = form.end_date.data or datetime.utcnow().date()

    services = filter_and_sort_services(
        service_api_client.get_services(api_args)['data'],
        trial_mode_services=request.endpoint == 'main.trial_services',
    )

    return render_template(
        'views/platform-admin/services.html',
        include_from_test_key=form.include_from_test_key.data,
        form=form,
        services=list(format_stats_by_service(services)),
        page_title='{} services'.format(
            'Trial mode' if request.endpoint == 'main.trial_services' else 'Live'
        ),
        global_stats=create_global_stats(services),
    )

def sum_service_usage(service):
    total = 0
    for notification_type in service['statistics'].keys():
        total += service['statistics'][notification_type]['requested']
    return total

def filter_and_sort_services(services, trial_mode_services=False):
    return [
        service for service in sorted(
            services,
            key=lambda service: (
                service['active'],
                sum_service_usage(service),
                service['created_at']
            ),
            reverse=True,
        )
        if service['restricted'] == trial_mode_services
    ]

def create_global_stats(services):
    stats = {
        'email': {
            'delivered': 0,
            'failed': 0,
            'requested': 0
        },
        'sms': {
            'delivered': 0,
            'failed': 0,
            'requested': 0
        },
        'letter': {
            'delivered': 0,
            'failed': 0,
            'requested': 0
        }
    }
    for service in services:
        for msg_type, status in itertools.product(('sms', 'email', 'letter'), ('delivered', 'failed', 'requested')):
            stats[msg_type][status] += service['statistics'][msg_type][status]

    for stat in stats.values():
        stat['failure_rate'] = get_formatted_percentage(stat['failed'], stat['requested'])
    return stats

def format_stats_by_service(services):
    for service in services:
        yield {
            'id': service['id'],
            'name': service['name'],
            'stats': {
                msg_type: {
                    'sending': stats['requested'] - stats['delivered'] - stats['failed'],
                    'delivered': stats['delivered'],
                    'failed': stats['failed'],
                }
                for msg_type, stats in service['statistics'].items()
            },
            'restricted': service['restricted'],
            'research_mode': service['research_mode'],
            'created_at': service['created_at'],
            'active': service['active']
        }


import websockets
import json
import asyncio
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from base64 import b64decode
from multiprocessing import *
from Logger import *
import traceback

clearConsole = lambda: os.system('cls' if os.name in ('nt', 'dos') else 'clear')

def get_key(motoo: bool):
    config = configparser.ConfigParser()
    config.read('config.ini', encoding='utf-8')

    if motoo == True: a = '모투'
    else: a = '실투'
    app_key = config[a]['app_key']
    secret_key = config[a]['secret_key']
    acc_num = config[a]['acc_num']
    id = config[a]['id']

    return app_key, secret_key, acc_num, id

def stockhoka(data):
    recvvalue = data.split('^')  # 수신데이터를 split '^'
    return dict(종목코드 = recvvalue[0], 예상체결가 = int(recvvalue[47]), 예상체결수량 = int(recvvalue[48]), 예상거래량 = int(recvvalue[49]), 매수호가01 = int(recvvalue[13]), 매수호가01잔량 = int(recvvalue[33]), 매도호가01 = int(recvvalue[3]), 매도호가01잔량 = int(recvvalue[23]), TRID = 'H0STASP0')

def stocks_purchase(data):
    menulist = "유가증권단축종목코드|주식체결시간|주식현재가|전일대비부호|전일대비|전일대비율|가중평균주식가격|주식시가|주식최고가|주식최저가|매도호가1|매수호가1|체결거래량|누적거래량|누적거래대금|매도체결건수|매수체결건수|순매수체결건수|체결강도|총매도수량|총매수수량|체결구분|매수비율|전일거래량대비등락율|시가시간|시가대비구분|시가대비|최고가시간|고가대비구분|고가대비|최저가시간|저가대비구분|저가대비|영업일자|신장운영구분코드|거래정지여부|매도호가잔량|매수호가잔량|총매도호가잔량|총매수호가잔량|거래량회전율|전일동시간누적거래량|전일동시간누적거래량비율|시간구분코드|임의종료구분코드|정적VI발동기준가"
    menustr = menulist.split('|')
    pValue = data.split('^')
    data_list = {}
    for i in range(len(menustr)):     # 넘겨받은 체결데이터 개수만큼 print 한다
        data_list.update({menustr[i] : pValue[i]})
    return data_list

def aes_cbc_base64_dec(key, iv, cipher_text):
    """
    :param key:  str type AES256 secret key value
    :param iv: str type AES256 Initialize Vector
    :param cipher_text: Base64 encoded AES256 str
    :return: Base64-AES256 decodec str
    """
    try:
        try:
            cipher = AES.new(key.encode('cp949'), AES.MODE_CBC, iv.encode('cp949'))
            return bytes.decode(unpad(cipher.decrypt(b64decode(cipher_text)), AES.block_size))
        except:
            cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
            result = bytes.decode(unpad(cipher.decrypt(b64decode(cipher_text)), AES.block_size), 'utf-8',
                                  errors='replace')
            result = result.replace('\ufffd', '')
            return result

    except Exception as e:
        print(e)
        print(traceback.format_exc())
        Logger().add_log('', 'error')
        Logger().telegram_bot('복호화 과정에서 에러발생')

def get_approval(key, secret):
    """웹소켓 접속키 발급"""
    url = 'https://openapi.koreainvestment.com:9443'
    headers = {"content-type": "application/json"}
    body = {"grant_type": "client_credentials",
            "appkey": key,
            "secretkey": secret}
    PATH = "oauth2/Approval"
    URL = f"{url}/{PATH}"
    res = requests.post(URL, headers=headers, data=json.dumps(body))
    approval_key = res.json()["approval_key"]
    return approval_key

def OrderExecData(data, key, iv):
    # AES256 처리 단계

    aes_dec_str = aes_cbc_base64_dec(key, iv, data)
    pValue = aes_dec_str.split('^')

    if pValue[13] == '2':  # 체결통보
        print("#### 국내주식 체결 통보 ####")
        menulist = "고객ID|계좌번호|주문번호|원주문번호|매도매수구분|정정구분|주문종류|주문조건|주식단축종목코드|체결수량|체결단가|주식체결시간|거부여부|체결여부|접수여부|지점번호|주문수량|계좌명|체결종목명|신용구분|신용대출일자|체결종목명40|주문가격"
        menustr1 = menulist.split('|')
    else:
        print("#### 국내주식 주문·정정·취소·거부 접수 통보 ####")
        menulist = "고객ID|계좌번호|주문번호|원주문번호|매도매수구분|정정구분|주문종류|주문조건|주식단축종목코드|주문수량|주문가격|주식체결시간|거부여부|체결여부|접수여부|지점번호|주문수량|계좌명|주문종목명|신용구분|신용대출일자|체결종목명40|체결단가"
        menustr1 = menulist.split('|')

    data_list = {}
    min_len = min(len(pValue), len(menustr1))  #### pValue 갯수가 일정하게 들어오지 않음, 어떤때는 22개, 어떤때는 25개가 날라옴
    for i in range(min_len):  ### 그래서 pvalue와 mennustr1 갯수 중에서 작은 값을 for문 돌림
        data_list.update({menustr1[i]: pValue[i]})
    return data_list

class Receiver:
    def __init__(self,TotalSubStocks, stg_option, Qlist, managerList, account_data):

        self.app_key = account_data[0]
        self.secret_key = account_data[1]
        self.acc_num = account_data[2]
        self.id = account_data[3]
        self.motoo = account_data[4]

        self.PriceQ = Qlist[0]
        self.OrderQ = Qlist[1]
        self.OrderCheckQ = Qlist[2]
        self.ExecQ = Qlist[3]
        self.WindowQ = Qlist[4]

        self.BuyList = managerList[0]
        self.PriceManger = managerList[1]
        self.OrderManager = managerList[2]
        self.ExecManager = managerList[3]
        self.PositionManager = managerList[4]
        self.BalanceManager = managerList[5]
        self.TradingManager = managerList[6]
        self.subsStocks = TotalSubStocks

        # self.stg_name = stg_option['전략명']
        self.logger = Logger()
        self.PriceExecChecker()

    async def PriceExecWebsocket(self):

        if self.motoo == True:
            url = 'ws://ops.koreainvestment.com:31000'  # 모의계좌
            tr_id = 'H0STCNI9'
        else:
            url = 'ws://ops.koreainvestment.com:21000'  # 실전계좌
            tr_id = 'H0STCNI0'

        approval_key = get_approval(self.app_key, self.secret_key)

        code_list = [['1', 'H0STCNT0', x] for x in self.subsStocks]
        code_list2 = [['1', 'H0STASP0', x] for x in self.subsStocks]

        send_data_list = []
        for i, j, k in code_list:
            temp = '{"header":{"approval_key": "%s","custtype":"%s","tr_type":"%s","content-type":"utf-8"},"body":{"input":{"tr_id":"%s","tr_key":"%s"}}}' % (approval_key, 'P', i, j, k)
            send_data_list.append(temp)

        for i, j, k in code_list2:
            temp = '{"header":{"approval_key": "%s","custtype":"%s","tr_type":"%s","content-type":"utf-8"},"body":{"input":{"tr_id":"%s","tr_key":"%s"}}}' % (approval_key, 'P', i, j, k)
            send_data_list.append(temp)

        code_list = ['1', tr_id, self.id]
        temp = '{"header":{"approval_key": "%s","custtype":"P","tr_type":"%s","content-type":"utf-8"},"body":{"input":{"tr_id":"%s","tr_key":"%s"}}}' % (
            approval_key, code_list[0], code_list[1], code_list[2])
        send_data_list.append(temp)

        async with websockets.connect(url, ping_interval = None) as websocket:
            for send_data in send_data_list:
                await websocket.send(send_data)

            print('\n======================== Receiver Start ========================\n')

            while True:
                if not websocket.open:
                    try:
                        websocket = await websocket.connect(url)
                        for send_data in send_data_list:
                            await websocket.send(send_data)
                    except:
                        print('웹소켓 재연결 시도중 ...')

                data = await websocket.recv()

                if data[0] == '0':
                    recvstr = data.split('|')
                    trid0 = recvstr[1]

                    if trid0 == 'H0STASP0':
                        result = stockhoka(recvstr[3])
                        self.PriceQ.put(result)

                    elif trid0 == 'H0STCNT0':
                        resp = stocks_purchase(recvstr[3])
                        stock_code = resp['유가증권단축종목코드']
                        dayopen = int(resp['주식시가'])
                        dayhigh = int(resp['주식최고가'])
                        daylow = int(resp['주식최저가'])
                        dayclose = int(resp['주식현재가'])
                        dayvolume = int(resp['누적거래량'])
                        dayamount = int(resp['누적거래대금'])
                        buy_hoka1 = int(resp['매수호가1'])
                        sell_hoka1 = int(resp['매도호가1'])

                        result = dict(종목코드 = stock_code, 당일시가 = dayopen, 당일고가 = dayhigh, 당일저가 = daylow, 현재가 = dayclose,
                                  당일누적거래량 = dayvolume, 당일누적거래대금 = dayamount, 매수호가1 = buy_hoka1, 매도호가1 = sell_hoka1, TRID = 'H0STCNT0')

                        self.PriceQ.put(result)

                elif data[0] == '1':
                    recvstr = data.split('|')  # 수신데이터가 실데이터 이전은 '|'로 나뉘어져있어 split
                    trid0 = recvstr[1]
                    if trid0 == "K0STCNI0" or trid0 == "K0STCNI9" or trid0 == "H0STCNI0" or trid0 == "H0STCNI9":
                        resp = OrderExecData(recvstr[3], aes_key, aes_iv)
                        self.ExecQ.put(resp)

                else:
                    jsonObject = json.loads(data)
                    trid = jsonObject["header"]["tr_id"]

                    if trid != "PINGPONG":
                        rt_cd = jsonObject["body"]["rt_cd"]
                        if rt_cd == '1':  # 에러일 경우 처리
                            print("### 현재가 ERROR RETURN CODE [ %s ] MSG [ %s ]" % (rt_cd, jsonObject["body"]["msg1"]))
                            pass
                        elif rt_cd == '0':  # 정상일 경우 처리
                            print("### 현재가 RETURN CODE [ %s ] MSG [ %s ]" % (rt_cd, jsonObject["body"]["msg1"]))
                            # 체결통보 처리를 위한 AES256 KEY, IV 처리 단계
                            if trid == "K0STCNI0" or trid == "K0STCNI9" or trid == "H0STCNI0" or trid == "H0STCNI9":
                                aes_key = jsonObject["body"]["output"]["key"]
                                aes_iv = jsonObject["body"]["output"]["iv"]
                                print("### TRID [%s] KEY[%s] IV[%s]" % (trid, aes_key, aes_iv))

                    elif trid == "PINGPONG":
                        print("### RECV [PINGPONG] [%s]" % (data))
                        await websocket.send(data)
                        print("### SEND [PINGPONG] [%s]" % (data))

    def PriceExecChecker(self):
        my_loop = asyncio.get_event_loop()
        my_loop.run_until_complete(self.PriceExecWebsocket())
        my_loop.close()

if __name__ == '__main__':
    PriceQ, OrderQ, OrderCheckQ, ExecCheckQ, WindowQ = \
        Queue(), Queue(), Queue(), Queue(), Queue()

    BuyList, PriceManger, OrderManager, ExecManager, PositionManager, BalanceManager, TradingManager = \
        Manager().list(), Manager().dict(), Manager().dict(), Manager().dict(), Manager().dict(), Manager().dict(), Manager().dict()

    qlist = [PriceQ, OrderQ, OrderCheckQ, ExecCheckQ, WindowQ]
    managerlist = [BuyList, PriceManger, OrderManager, ExecManager, PositionManager, BalanceManager, TradingManager]

    motoo = True
    app_key, secret_key, acc_num, id = get_key(motoo)
    print(app_key)
    print(secret_key)
    account_data = [app_key, secret_key, acc_num, id, motoo]
    strategy_name = '테스트'

    subStocks = ['122630', '233740']
    stg_option = None
    Receiver(subStocks, stg_option, qlist, managerlist, account_data)


# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
from urllib import request

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices

from app.ui.ui_main_window import Ui_MainWindow
from app.util.download_thread import GetVideoInfoThread
from app import mlog, mconfig

from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QDesktopWidget
from PyQt5.QtGui import QIcon
from app.ui.about_widget import AboutWdiget
from app.ui.files_list_dialog import FilesListDialog
from app.ui.icon_rc import *

from app.you_get.status import set_default

class MainWindow(Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.main_window = QMainWindow()
        self.setupUi(self.main_window)
        self.main_window.setFixedSize(self.main_window.width(), self.main_window.height())
        self.msg = QMessageBox()
        self.set_slot()
        self.qr = self.main_window.frameGeometry()  # move to center of screen
        self.cp = QDesktopWidget().availableGeometry().center()
        self.qr.moveCenter(self.cp)
        self.main_window.move(self.qr.topLeft())
        self.text_edit_urls.setAcceptRichText(False)

    def set_slot(self):
        self.button_download.clicked.connect(self.get_info)
        self.action_about.triggered.connect(self.show_about)
        self.action_file_path.triggered.connect(self.set_file_path)
        self.action_check_for_updates.triggered.connect(self.check_for_updates)
        self.action_report_bugs.triggered.connect(self.report_bugs)
        # self.action_supported_sites.triggered.connect(self.get_supported_sites)

    # def get_supported_sites(self):
    #     QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/wiki/Supported-Sites'))

    def get_info(self):
        mconfig.set_default()
        set_default()
        self.button_download.setEnabled(False)
        self.urls = (str(self.text_edit_urls.toPlainText())).split(';')
        mlog.debug(self.urls[0])

        self.m_thread = GetVideoInfoThread(self.urls, **mconfig.kwargs)
        self.m_thread.finish_signal.connect(self.finish_get_info)
        self.m_thread.start()

    def finish_get_info(self, ls, can_download):
        mlog.debug('finish_get_info: ' + str(can_download))
        self.button_download.setEnabled(True)
        if can_download:
            self.files_list_dialog = FilesListDialog()
            self.files_list_dialog.update_files_list(ls)
            mconfig.set_urls(self.urls)
        else:
            self.show_msg(QMessageBox.Critical, 'Failed ', 'Can not get the files list (╯°Д°)╯︵ ┻━┻')

    def show_about(self):
        mlog.debug('show about widget')
        self.about_widget = AboutWdiget()
        self.about_widget.about_widget.move(self.qr.topLeft())
        self.about_widget.about_widget.show()

    def set_file_path(self):
        fname = QFileDialog.getExistingDirectory(self.main_window, caption='Select Path', directory='',
                                                 options=QFileDialog.ShowDirsOnly)
        if fname:
            mconfig.set_file_path(fname)
            mlog.debug('changed file path to ' + mconfig.get_file_path())
            self.show_msg(QMessageBox.Information, 'Tip', 'Changed file path to:\n' + str(fname))
        else:
            mconfig.set_file_path(mconfig.base_dir)
            self.show_msg(QMessageBox.Information, 'Tip', 'Default file path:\n' + str(mconfig.base_dir))

    def show_msg(self, icon, title, text):
        self.msg.setWindowTitle(title)
        self.msg.setWindowIcon(QIcon(':/res/favicon.ico'))
        self.msg.setIcon(icon)
        self.msg.setText(text)
        self.msg.setStandardButtons(QMessageBox.Ok)
        self.msg.show()

    def check_for_updates(self):
        try:
            with request.urlopen('https://raw.githubusercontent.com/ingbyr/GUI-YouGet/master/version.json') as f:
                raw_inf = str(f.read())[2:-1]
                mlog.debug(str(f.read())[2:-1])
                remote_inf = json.loads(raw_inf)
                mlog.debug('remote version is ' + remote_inf['version'])
        except Exception as e:
            mlog.exception(e)
            self.show_msg(QMessageBox.Critical, 'Failed', 'Check for updates failed')
            return

        if mconfig.version >= remote_inf['version']:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'No available updates')
        else:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'There is a new version')
            self.do_updates()

    def do_updates(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/releases'))

    def report_bugs(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/issues'))


import json
import sys
import extractor.util.mongo as mongo

def main(argv):
    file_name="datasets.json"
    if len(argv) > 0:
        file_name=argv[0]

    with open(file_name) as data_file:
        data = json.load(data_file)["datasets"]
        for dat in data:
            id = mongo.getLastIdEndpointsLodex()
            ds={'_id':id,'name':dat['name'],'url':dat['url']}
            mongo.inserLodexDatasets(ds)

if __name__ == "__main__":
    main(sys.argv[1:])


from typing import Tuple

import torch
import torch.nn as nn

__all__ = ["ReparamLargeKernelConv"]

class ReparamLargeKernelConv(nn.Module):
    """Building Block of RepLKNet

    This class defines overparameterized large kernel conv block
    introduced in `RepLKNet <https://arxiv.org/abs/2203.06717>`_

    Reference: https://github.com/DingXiaoH/RepLKNet-pytorch
    """

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size: int,
        stride: int,
        groups: int,
        small_kernel: int,
        inference_mode: bool = False,
        activation: nn.Module = nn.GELU(),
    ) -> None:
        """Construct a ReparamLargeKernelConv module.

        Args:
            in_channels: Number of input channels.
            out_channels: Number of output channels.
            kernel_size: Kernel size of the large kernel conv branch.
            stride: Stride size. Default: 1
            groups: Group number. Default: 1
            small_kernel: Kernel size of small kernel conv branch.
            inference_mode: If True, instantiates model in inference mode. Default: ``False``
            activation: Activation module. Default: ``nn.GELU``
        """
        super(ReparamLargeKernelConv, self).__init__()

        self.stride = stride
        self.groups = groups
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.activation = activation

        self.kernel_size = kernel_size
        self.small_kernel = small_kernel
        self.padding = kernel_size // 2
        if inference_mode:
            self.lkb_reparam = nn.Conv2d(
                in_channels=in_channels,
                out_channels=out_channels,
                kernel_size=kernel_size,
                stride=stride,
                padding=self.padding,
                dilation=1,
                groups=groups,
                bias=True,
            )
        else:
            self.lkb_origin = self._conv_bn(
                kernel_size=kernel_size, padding=self.padding
            )
            if small_kernel is not None:
                assert (
                    small_kernel <= kernel_size
                ), "The kernel size for re-param cannot be larger than the large kernel!"
                self.small_conv = self._conv_bn(
                    kernel_size=small_kernel, padding=small_kernel // 2
                )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """Apply forward pass."""
        if hasattr(self, "lkb_reparam"):
            out = self.lkb_reparam(x)
        else:
            out = self.lkb_origin(x)
            if hasattr(self, "small_conv"):
                out += self.small_conv(x)

        self.activation(out)
        return out

    def get_kernel_bias(self) -> Tuple[torch.Tensor, torch.Tensor]:
        """Method to obtain re-parameterized kernel and bias.
        Reference: https://github.com/DingXiaoH/RepLKNet-pytorch

        Returns:
            Tuple of (kernel, bias) after fusing branches.
        """
        eq_k, eq_b = self._fuse_bn(self.lkb_origin.conv, self.lkb_origin.bn)
        if hasattr(self, "small_conv"):
            small_k, small_b = self._fuse_bn(self.small_conv.conv, self.small_conv.bn)
            eq_b += small_b
            eq_k += nn.functional.pad(
                small_k, [(self.kernel_size - self.small_kernel) // 2] * 4
            )
        return eq_k, eq_b

    def reparameterize(self) -> None:
        """
        Following works like `RepVGG: Making VGG-style ConvNets Great Again` -
        https://arxiv.org/pdf/2101.03697.pdf. We re-parameterize multi-branched
        architecture used at training time to obtain a plain CNN-like structure
        for inference.
        """
        eq_k, eq_b = self.get_kernel_bias()
        self.lkb_reparam = nn.Conv2d(
            in_channels=self.in_channels,
            out_channels=self.out_channels,
            kernel_size=self.kernel_size,
            stride=self.stride,
            padding=self.padding,
            dilation=self.lkb_origin.conv.dilation,
            groups=self.groups,
            bias=True,
        )

        self.lkb_reparam.weight.data = eq_k
        self.lkb_reparam.bias.data = eq_b
        self.__delattr__("lkb_origin")
        if hasattr(self, "small_conv"):
            self.__delattr__("small_conv")

    @staticmethod
    def _fuse_bn(
        conv: torch.Tensor, bn: nn.BatchNorm2d
    ) -> Tuple[torch.Tensor, torch.Tensor]:
        """Method to fuse batchnorm layer with conv layer.

        Args:
            conv: Convolutional kernel weights.
            bn: Batchnorm 2d layer.

        Returns:
            Tuple of (kernel, bias) after fusing batchnorm.
        """
        kernel = conv.weight
        running_mean = bn.running_mean
        running_var = bn.running_var
        gamma = bn.weight
        beta = bn.bias
        eps = bn.eps
        std = (running_var + eps).sqrt()
        t = (gamma / std).reshape(-1, 1, 1, 1)
        return kernel * t, beta - running_mean * gamma / std

    def _conv_bn(self, kernel_size: int, padding: int = 0) -> nn.Sequential:
        """Helper method to construct conv-batchnorm layers.

        Args:
            kernel_size: Size of the convolution kernel.
            padding: Zero-padding size.

        Returns:
            A nn.Sequential Conv-BN module.
        """
        mod_list = nn.Sequential()
        mod_list.add_module(
            "conv",
            nn.Conv2d(
                in_channels=self.in_channels,
                out_channels=self.out_channels,
                kernel_size=kernel_size,
                stride=self.stride,
                padding=padding,
                groups=self.groups,
                bias=False,
            ),
        )
        mod_list.add_module("bn", nn.BatchNorm2d(num_features=self.out_channels))
        return mod_list


from __future__ import annotations

from operator import ge

import numpy as np

class LogisticRegressionGD:
    """
    Gradient descent based logistic
    regression classifier.

    Parameters
    ----------

    eta : float
        Learning Rate
    n_iter : int
        Epochs
    random_state : int
        Random number generator seed for
        random weight generation.

    Attributes
    ----------

    w_ : np.ndarray(1-D)
        Weights after training.
    b_ : np.ndarray(Scalar)
        Bias unit after training.
    losses_ : list
        Mean squared error loss function values
        in each epoch

    """

    def __init__(self, eta: float = 0.01, n_iter: int = 50, random_state: int = 1) -> None:
        self.eta = eta
        self.n_iter = n_iter
        self.random_state = random_state

    def fit(self, X: np.ndarray, y: np.ndarray) -> LogisticRegressionGD:
        """
        Fit training data.

        Parameters
        ----------
        X : np.ndarray, shape = [n_examples, n_features]
            Training vectors, where n_examples is the
            number of available data samples and n_features
            is the number of given features of each samples.
        y : np.ndarray, shape = [n_examples]
            Target/Class values.

        Returns
        -------
        self : Instance of LogisticRegressionGD

        """
        rgen = np.random.RandomState(self.random_state)
        self.w_ = rgen.normal(loc=0.0, scale=0.01, size=X.shape[1])
        self.b_ = np.float_(0.0)
        self.losses_: list = []

        for _ in range(self.n_iter):
            net_input = self.net_input(X)
            output = self.activation(net_input)
            errors = (y - output)
            self.w_ += self.eta * 2.0 * \
                np.dot(np.transpose(X), errors) / X.shape[0]
            self.b_ += self.eta * 2.0 * errors.mean()
            loss = ((-np.dot(y, np.log(output)))
                    - ((np.dot(1 - y, np.log(1 - output))))
                    / X.shape[0])
            self.losses_.append(loss)

        return self

    def net_input(self, X: np.ndarray) -> np.ndarray:
        """Calculate net input"""
        return np.dot(X, self.w_) + self.b_

    def activation(self, z: float | np.ndarray) -> float | np.ndarray:
        return 1.0 / (1.0 + np.exp(-np.clip(z, -250, 250)))

    def predict(self, X: np.ndarray) -> np.ndarray:
        """Return class label after unit step"""
        return np.where(ge(self.activation(self.net_input(X)), 0.5), 1, 0)


# Wrapper script to make waveform plots

import waveform as wv
from numpy import zeros,linspace,pi
import matplotlib.pyplot as plot
from astropy import constants
from astropy.table import Table
plot.ion()

m1=[5,10,15,20,30,40,50]
m2=[5,10,15,20,30,40,50]

nCycLim=200.

n2m=len(m1)*len(m2)
m1arr=zeros(n2m)
m2arr=zeros(n2m)
mcharr=zeros(n2m)
n=0
for i in range(len(m1)):
    for j in range(len(m2)):
        m1arr[n]=m1[i]
        m2arr[n]=m2[j]
        mcharr[n]=wv.calc_Mch(m1[i],m2[j])
        n+=1

K0=(5**(3./8.)/(8.*pi))*(constants.c**3 / constants.G)**(5./8.)

t0arr=zeros(n2m)
t1arr=zeros(n2m)
f0arr=zeros(n2m)
f1arr=zeros(n2m)
ncarr=zeros(n2m)
for n in range(n2m):
    ncarr[n]=0
    t0arr[n]=0.
    print('Masses: (%g,%g) -> %g Msun'%(m1arr[n],m2arr[n],mcharr[n]))
    while ncarr[n]<nCycLim:
        t0arr[n]+=1.
        f0arr[n]=K0.value * (mcharr[n]*constants.M_sun.value)**(-5./8.) * t0arr[n]**(-3./8.)
        ncarr[n]=t0arr[n]*f0arr[n]
    print('  t=%g s: f0= %g Hz -> nc=%g'%(t0arr[n],f0arr[n],ncarr[n]))
    t1arr[n]=(nCycLim * (mcharr[n]*constants.M_sun.value)**(5./8.) / K0.value)**(8./5.)
    f1arr[n]=nCycLim**(-3./5.) * (mcharr[n]*constants.M_sun.value)**(-1) * (K0.value)**(8./5.)
    print('  t=%g s: f0= %g Hz'%(t1arr[n],f1arr[n]))

plot.figure(1)
plot.clf()
plot.plot(mcharr,f0arr,ls='None',marker='x',c='b')
plot.plot(mcharr,f1arr,ls='None',marker='o',c='g')
plot.xlabel('Chirp mass (Msun)')
plot.ylabel('Cutoff frequency (Hz)')

plot.figure(2)
plot.clf()
plot.plot(mcharr,t0arr,ls='None',marker='x',c='b')
plot.plot(mcharr,t1arr,ls='None',marker='o',c='g')
plot.xlabel('Chirp mass (Msun)')
plot.ylabel('Waveform length (t)')
plot.show()

tabOut=Table([m1arr,m2arr,mcharr,f1arr,t1arr],names=['m1','m2','M_ch','f_low','duration'])
tabOut.write('low-f_calcs.csv',format='ascii.csv')


import yaml
import sys
from typing import List
import re

from blueprint.schema import module
from blueprint.schema import param

from blueprint.lib import dag
from blueprint.lib import event
from blueprint.validate import blueprint_validator

from blueprint.lib.logger import logr
# import logging
# logr = logging.getLogger(__name__)

def eprint(*args, **kwargs):
    logr.error(*args)
    print(*args, file=sys.stderr, **kwargs)
#========================================================================

BlueprintType = "blueprint"

class Blueprint(dict):
    yaml_tag = u'!Blueprint'
    def __init__(self,
                    name: str                       = "__init__",
                    description: str                = None,
                    inputs: List[param.Input]       = None,
                    outputs: List[param.Output]     = None,
                    settings: List[param.Setting]   = None,
                    modules: List[module.Module]    = None ):
        """Blueprint schema.

        :param name: Name of the blueprint
        :param description: Blueprint description
        :param inputs: List of input parameters (type param.Input)
        :param outputs: List of output parameters (type param.Output)
        :param settings: List of envitonment settings (type param.Setting)
        :param modules: List of modules in the blueprint (type module.Module)
        """

        self.schema_version = "1.0.0"
        self.type = BlueprintType
        self.name = name
        self.modules = []
        if(description != None):
            self.description = description
        else:
            self.description = None
        if(inputs != None):
            self.set_inputs(inputs)
        else:
            self.inputs = None
        if(outputs != None):
            self.set_outputs(outputs)
        else:
            self.outputs = None
        if(settings != None):
            self.set_settings(settings)
        else:
            self.settings = None
        if(modules != None):
            self.set_modules(modules)
        else:
            self.modules = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.name = "__init__"

    def __str__(self):
        txt = "Blueprint("
        txt += "name:" + (self.name if hasattr(self, 'name') else 'None') + ", "
        txt += "inputs:" + str(self.inputs if hasattr(self, 'inputs') else 'None') + ", "
        txt += "outputs:" + str(self.outputs if hasattr(self, 'outputs') else 'None') + ", "
        txt += "settings:" + str(self.settings if hasattr(self, 'settings') else 'None') + ", "
        txt += "modules:" + str(self.modules if hasattr(self, 'modules') else 'None')
        txt += ")"
        return txt

    def __repr__(self):
        return self.__str__()

    def noop(self, *args, **kw):
        pass

    yaml.emitter.Emitter.process_tag = noop

    def __eq__(self, other):
        if other == None:
            return False

        self_name = "" if self.name == None else self.name
        self_schema_version = "" if self.schema_version == None else self.schema_version
        self_type = "" if not hasattr(self, 'type') or self.type == None else self.type
        self_description = "" if not hasattr(self, 'description') or self.description == None else self.description
        self_inputs = "" if not hasattr(self, 'inputs') or self.inputs == None else str(self.inputs)
        self_outputs = "" if not hasattr(self, 'outputs') or self.outputs == None else str(self.outputs)
        self_settings = "" if not hasattr(self, 'settings') or self.settings == None else str(self.settings)
        self_modules = "" if not hasattr(self, 'modules') or self.modules == None else str(self.modules)

        other_name = "" if other.name == None else other.name
        other_schema_version = "" if other.schema_version == None else other.schema_version
        other_type = "" if not hasattr(other, 'type') or other.type == None else other.type
        other_description = "" if not hasattr(other, 'description') or other.description == None else other.description
        other_inputs = "" if not hasattr(other, 'inputs') or other.inputs == None else str(other.inputs)
        other_outputs = "" if not hasattr(other, 'outputs') or other.outputs == None else str(other.outputs)
        other_settings = "" if not hasattr(other, 'settings') or other.settings == None else str(other.settings)
        other_modules = "" if not hasattr(other, 'modules') or other.modules == None else str(other.modules)

        return (self_name == other_name) and (self_type == other_type) and (self_schema_version == other_schema_version) \
            and (self_description == other_description) and (self_modules == other_modules) \
            and (self_inputs == other_inputs) and (self_outputs == other_outputs) and (self_settings == other_settings)

    def __hash__(self):
        self_name = "" if self.name == None else self.name
        self_schema_version = "" if self.schema_version == None else self.schema_version
        self_type = "" if not hasattr(self, 'type') or self.type == None else self.type
        self_description = "" if not hasattr(self, 'description') or self.description == None else self.description
        self_inputs = "" if not hasattr(self, 'inputs') or self.inputs == None else str(self.inputs)
        self_outputs = "" if not hasattr(self, 'outputs') or self.outputs == None else str(self.outputs)
        self_settings = "" if not hasattr(self, 'settings') or self.settings == None else str(self.settings)
        self_modules = "" if not hasattr(self, 'modules') or self.modules == None else str(self.modules)

        return hash((self_name, self_schema_version, self_type, self_description, self_inputs, self_outputs, self_settings, self_modules))

    def remove_null_entries(self):
        if self.name == None:
            del self.name
        if hasattr(self, 'type') and self.type == None:
            del self.type
        if hasattr(self, 'schema_version') and self.schema_version == None:
            del self.schema_version
        if hasattr(self, 'description') and self.description == None:
            del self.description

        if hasattr(self, 'inputs'):
            if self.inputs == None or (self.inputs != None and len(self.inputs) == 0):
                del self.inputs
            else:
                for p in self.inputs:
                    p.remove_null_entries()

        if hasattr(self, 'outputs'):
            if self.outputs == None or (self.outputs != None and len(self.outputs) == 0):
                del self.outputs
            else:
                for p in self.outputs:
                    p.remove_null_entries()

        if hasattr(self, 'settings'):
            if self.settings == None or (self.settings != None and len(self.settings) == 0):
                del self.settings
            else:
                for p in self.settings:
                    p.remove_null_entries()

        if hasattr(self, 'modules'):
            if self.modules == None or (self.modules != None and len(self.modules) == 0):
                del self.modules
            else:
                for m in self.modules:
                    m.remove_null_entries()

    def to_yaml(self, stream = None):
        self.remove_null_entries()
        errors = self.validate()
        # eprint(errors)

        return (yaml.safe_load(self.to_yaml_str()), errors)

    def _process_comment(self, s):
        out_str = ""
        pattern = 'comment:'
        if pattern not in s:
            return s
        re_loc = re.finditer(pattern=pattern, string=s)
        loc = [ind.start() for ind in re_loc]
        start = 0
        for i in loc:
            out_str += s[start:i]
            j = s.find("'", i)
            out_str += s[i:j+1]
            j += 1

            while True:
                k = s.find("'", j)
                n = s.find("\n", j)
                if k < n:
                    out_str += s[j:k+1]
                    start = k+1
                    break
                else:
                    out_str += s[j:n+1]
                    k = n+1
                    lenn = 0
                    while True:
                        if s[k] != ' ':
                            break
                        k += 1
                        lenn += 1
                    k = 0
                    while k < lenn-2:
                        out_str += ' '
                        k += 1
                    out_str += '#'
                    out_str += ' '
                    j=n+1+lenn
                    start = j
        return out_str

    def to_yaml_str(self, do_validate = True, stream = None) -> str:
        self.remove_null_entries()
        errors = []
        if do_validate:
            errors = self.validate()
            # if len(errors) > 0:
            #     eprint(errors)
        yaml_str = yaml.dump(self, sort_keys=False)
        yaml_str = yaml_str.replace("comment: ", "# comment: ")
        yaml_str = self._process_comment(yaml_str)
        return (yaml_str, errors)

    def generate_input_file(self, stream = None):
        inputs_data = {}
        for p in self.inputs:
            if p.type != None:
                if p.type.lower() == "string" :
                    inputs_data[p.name] = "sample string for " + p.name
                elif p.type.lower() == "boolean" :
                    inputs_data[p.name] = False
                elif p.type.lower() == "number" or p.type.tolower() == "integer" :
                    inputs_data[p.name] = 0
                elif p.type.lower() == "date" or p.type.tolower() == "date-time" :
                    inputs_data[p.name] = "2000-12-30 19:21:03.478039"
                else:
                    inputs_data[p.name] = ""
            else:
                inputs_data[p.name] = ""

        return yaml.dump(inputs_data, sort_keys=False)

    @classmethod
    def from_yaml_str(cls, yaml_str):
        yaml_data = yaml.safe_load(yaml_str)
        bp = Blueprint.from_yaml_data(yaml_data)
        return cls(bp.name, bp.description,
                    bp.inputs, bp.outputs, bp.settings,
                    bp.modules)

    @classmethod
    def from_yaml_data(cls, yaml_data):
        value_ref = dict()
        name = yaml_data['name']
        try:
            description = yaml_data['description']
        except KeyError:
            description = None

        try:
            inputs=[]
            for p in yaml_data['inputs']:
                in_param = param.Input.from_yaml(p)
                value_ref.update({"$blueprint." + in_param.name : "$blueprint.inputs." + in_param.name})
                inputs.append(in_param)
        except (KeyError, UnboundLocalError, TypeError):
            inputs = None

        try:
            outputs=[]
            for p in yaml_data['outputs']:
                out_param = param.Output.from_yaml(p)
                value_ref.update({"$blueprint." + out_param.name : "$blueprint.outputs." + out_param.name})
                outputs.append(out_param)

        except (KeyError, UnboundLocalError, TypeError):
            outputs = None

        try:
            settings=[]
            for p in yaml_data['settings']:
                env_param = param.Setting.from_yaml(p)
                value_ref.update({"$blueprint." + env_param.name : "$blueprint.settings." + env_param.name})
                settings.append(env_param)

        except (KeyError, UnboundLocalError, TypeError):
            settings = None

        try:
            modules=[]
            for d in yaml_data['modules']:
                mod = module.Module.from_yaml(d)
                mod.repair_module(value_ref)
                modules.append(mod)

        except (KeyError, UnboundLocalError, TypeError):
            modules = None

        return cls(name, description,
                    inputs, outputs, settings, modules)

    def validate(self):
        bp_validator = blueprint_validator.BlueprintModel(self)
        return bp_validator.validate()

    def input_ref(self, key): # -> (str, event.ValidationEvent):
        if hasattr(self, "inputs") and self.inputs != None:
            for p in self.inputs:
                if p.name == key:
                    return ("$blueprint.inputs." + key, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint input parameter not found', self))

    def output_ref(self, key): # -> (str, event.ValidationEvent):
        if hasattr(self, "outputs") and self.outputs != None:
            for p in self.outputs:
                if p.name == key:
                    return ("$blueprint.outputs." + key, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint output parameter not found', self))

    def setting_ref(self, key): # -> (str, event.ValidationEvent):
        if hasattr(self, "settings") and self.settings != None:
            for p in self.settings:
                if p.name == key:
                    return ("$blueprint.settings." + key, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint settings parameter not found', self))

    def input_param(self, key): # -> (param.Input, event.ValidationEvent):
        if hasattr(self, "inputs") and self.inputs != None:
            for p in self.inputs:
                if p.name == key:
                    return (p, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint input parameter not found', self))

    def output_param(self, key): # -> (param.Output, event.ValidationEvent):
        if hasattr(self, "outputs") and self.outputs != None:
            for p in self.outputs:
                if p.name == key:
                    return (p, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint output parameter not found', self))

    def setting_param(self, key): # -> (param.Setting, event.ValidationEvent):
        if hasattr(self, "settings") and self.settings != None:
            for p in self.settings:
                if p.name == key:
                    return (p, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Blueprint settings parameter not found', self))

    def module_ref(self, mod_name, key): # -> (str, event.ValidationEvent):
        if hasattr(self, "modules") and self.modules != None:
            (m, err) = self.get_module(mod_name)
            if err == None:
                (mod_ref, err) = m.module_ref(key)
                if err == None:
                    return (mod_ref, None)
                else:
                    return (None, err)
            else:
                return (None, err)
        return (None, event.ValidationEvent(event.BPWarning, 'Invalid modules in blueprint', self))

    def module_input_ref(self, mod_name, key): # -> (str, event.ValidationEvent):
        (m, err) = self.get_module(mod_name)
        if err == None:
            (mod_ref, err) = m.input_ref(key)
            if err == None:
                return (mod_ref, None)
            else:
                return (None, event.ValidationEvent(event.BPWarning, 'Invalid module input, in the blueprint', self, None, chain = err))
        else:
            return (None, event.ValidationEvent(event.BPWarning, 'Invalid module input, in the blueprint', self, None, chain = err))

    def module_output_ref(self, mod_name, key): # -> (str, event.ValidationEvent):
        (m, err) = self.get_module(mod_name)
        if err == None:
            (mod_ref, err) = m.output_ref(key)
            if err == None:
                return (mod_ref, None)
            else:
                return (None, event.ValidationEvent(event.BPWarning, 'Invalid module output in blueprint', self, None, chain=err))
        else:
            return (None, event.ValidationEvent(event.BPWarning, 'Invalid module output in blueprint', self, None, chain=err))

    def module_setting_ref(self, mod_name, key): # -> (str, event.ValidationEvent):
        (m, err) = self.get_module(mod_name)
        if err == None:
            (mod_ref, err) = m.setting_ref(key)
            if err == None:
                return (mod_ref, None)
            else:
                return (None, event.ValidationEvent(event.BPWarning, 'Invalid module setting in blueprint', self, None, chain=err))
        else:
            return (None, event.ValidationEvent(event.BPWarning, 'Invalid module setting in blueprint', self, None, chain=err))

    def list_input_param_names(self) -> List[str]:
        if hasattr(self, "inputs") and self.inputs != None:
            param_names = []
            for p in self.inputs:
                param_names.append(p.name)
            return param_names
        return None

    def set_inputs(self,
                    input_params: List[param.Input]) -> List[event.ValidationEvent]:
        errors = []
        if(input_params == None):
            self.inputs = None
            return errors
        for param in input_params:
            errors += param.validate()

        # Set the input params, even if there are errors in them
        self.inputs = []
        self.inputs.extend(list(input_params))
        return errors

    def add_input(self,
                    input_param: param.Input) -> List[event.ValidationEvent]:
        if self.inputs == None:
            self.inputs = []
        errors = input_param.validate()

        # Add input param, even if there are errors in them
        self.inputs.append(input_param)
        return errors

    def update_input(self,
                    input_param: param.Input) -> List[event.ValidationEvent]:
        if self.inputs == None:
            self.inputs = []
        errors = input_param.validate()

        # Find and update the input param, even if there are errors in the input_param
        for param in self.inputs:
            if param.name == input_param.name:
                param.type          = input_param.type      if hasattr(input_param, 'type') else None
                param.description   = input_param.description if hasattr(input_param, 'description') else None
                param.value         = input_param.value     if hasattr(input_param, 'value') else None
                param.default       = input_param.default   if hasattr(input_param, 'default') else None
                param.optional      = input_param.optional  if hasattr(input_param, 'optional') else None

        return errors

    def add_inputs(self,
                    input_params: List[param.Input]) -> List[event.ValidationEvent]:
        if self.inputs == None:
            self.inputs = []
        errors = []
        for param in input_params:
            errors += param.validate()

        self.inputs.extend(list(input_params))
        return errors

    def set_input_value(self,
                    param_name: str,
                    param_value: str,
                    param_type:str = "string") -> List[event.ValidationEvent]:
        errors = []
        param_copy = []
        for p in self.inputs:
            if p.name == param_name:
                p.value = param_value
                p.type = param_type
            e = p.validate()
            if len(e) == 0:
                param_copy.append(p)
            errors += e
        self.inputs = param_copy
        return errors

    def list_output_param_names(self) -> List[str]:
        if hasattr(self, "outputs") and self.outputs != None:
            param_names = []
            for p in self.outputs:
                param_names.append(p.name)
            return param_names
        return None

    def set_outputs(self, output_params) -> List[event.ValidationEvent]:
        errors = []
        if(output_params == None):
            self.outputs = None
            return errors
        for param in output_params:
            errors += param.validate()

        self.outputs = []
        self.outputs.extend(output_params)
        return errors

    def add_output(self, output_param) -> List[event.ValidationEvent]:
        if self.outputs == None:
            self.outputs = []
        errors = output_param.validate()

        self.outputs.append(output_param)
        return errors

    def add_outputs(self, output_params) -> List[event.ValidationEvent]:
        errors = []
        if self.outputs == None:
            self.outputs = []
        for param in output_params:
            errors += param.validate()

        self.outputs.extend(list(output_params))
        return errors

    def update_output(self,
                    output_param: param.Output) -> List[event.ValidationEvent]:
        if self.outputs == None:
            self.outputs = []
        errors = output_param.validate()

        # Find and update the output param, even if there are errors in the output_param
        for param in self.outputs:
            if param.name == output_param.name:
                param.type          = output_param.type     if hasattr(output_param, 'type') else None
                param.description   = output_param.description if hasattr(output_param, 'description') else None
                param.value         = output_param.value    if hasattr(output_param, 'value') else None

        return errors

    def set_output_value(self, param_name, param_value) -> List[event.ValidationEvent]:
        errors = []
        param_copy = []
        for p in self.outputs:
            if p.name == param_name:
                p.value = param_value
            e = p.validate()
            if len(e) == 0:
                param_copy.append(p)
            errors += e
        self.outputs = param_copy
        return errors

    def list_setting_param_names(self) -> List[str]:
        if hasattr(self, "inputs") and self.inputs != None:
            param_names = []
            for p in self.settings:
                param_names.append(p.name)
            return param_names
        return None

    def set_settings(self, setting_params) -> List[event.ValidationEvent]:
        errors = []
        if(setting_params == None):
            self.settings = None
            return
        for param in setting_params:
            errors += param.validate()

        self.settings = []
        self.settings.extend(setting_params)
        return errors

    def add_setting(self, setting_param) -> List[event.ValidationEvent]:
        if self.settings == None:
            self.settings = []
        errors = setting_param.validate()

        self.settings.append(setting_param)
        return errors

    def add_settings(self, setting_params) -> List[event.ValidationEvent]:
        errors = []
        if self.settings == None:
            self.settings = []
        for param in setting_params:
            errors += param.validate()

        self.settings.extend(list(setting_params))
        return errors

    def update_setting(self,
                    setting_param: param.Setting) -> List[event.ValidationEvent]:
        if self.settings == None:
            self.settings = []
        errors = setting_param.validate()

        # Find and update the output param, even if there are errors in the output_param
        for param in self.settings:
            if param.name == setting_param.name:
                param.type          = setting_param.type        if hasattr(setting_param, 'type') else None
                param.description   = setting_param.description if hasattr(setting_param, 'description') else None
                param.value         = setting_param.value       if hasattr(setting_param, 'value') else None
                param.default       = setting_param.default     if hasattr(setting_param, 'default') else None

        return errors

    def set_setting_value(self, param_name, param_value) -> List[event.ValidationEvent]:
        errors = []
        param_copy = []
        for p in self.settings:
            if p.name == param_name:
                p.value = param_value
            e = p.validate()
            if len(e) == 0:
                param_copy.append(p)
            errors += e
        self.settings = param_copy
        return errors

    def get_modules(self) -> List[module.Module]:
        return self.modules

    def get_module(self, mod_name): # -> (module.Module, event.ValidationEvent):
        if hasattr(self, 'modules') and self.modules != None:
            for m in self.modules:
                if mod_name == m.name:
                    return (m, None)
        return (None, event.ValidationEvent(event.BPWarning, 'Invalid module name: ' + str(mod_name), self))

    def set_modules(self, mods) -> List[event.ValidationEvent]:
        if(mods == None):
            self.modules = None
            return
        self.modules = []
        errors = []
        for mod in mods:
            e = mod.validate()
            if len(e) == 0:
                self.modules.append(mod)
            else:
                errors += e
        return errors

    def add_module(self, mod) -> List[event.ValidationEvent]:
        errors = []
        errors = mod.validate()

        if self.modules == None:
            self.modules = []
        self.modules.append(mod)

        return errors

    def add_modules(self, mods) -> List[event.ValidationEvent]:
        if(mods == None):
            self.modules = None
            return
        if self.modules == None:
            self.modules = []
        errors = []
        for mod in mods:
            e = mod.validate()
            if len(e) == 0:
                self.modules.append(mod)
            else:
                errors += e
        return errors

    def update_module(self, mod) -> List[event.ValidationEvent]:
        errors = []
        if mod != None:
            if self.modules == None:
                self.modules = []
            try:
                (m, err) = self.get_module(mod.name)
                if err == None:
                    m.merge(mod)
                else:
                    errors += err
                return errors
            except:
                self.modules.append(mod)
        return errors

    def set_module_inputs(self, mod_name, inputs) -> List[event.ValidationEvent]:
        (m, err) = self.get_module(mod_name)
        if err == None:
            err = m.set_inputs(inputs)
        return err

#========================================================================

    def find_replace_in_module(self, param_ref, value) -> List[event.ValidationEvent]:
        errors = []
        if self.modules != None:
            for mod in self.modules:
                param_ref_alias = param_ref.replace("$blueprint.inputs.", "$blueprint.")
                param_name = mod.find_input_ref(param_ref)
                if param_name == None:
                    param_name = mod.find_input_ref(param_ref_alias)
                if param_name != None:
                    mod.set_input_value(param_name, value)
                else:
                    param_name = mod.find_setting_ref(param_ref)
                    if param_name == None:
                        param_name = mod.find_setting_ref(param_ref_alias)
                    if param_name != None:
                        mod.set_setting_value(param_name, value)

                param_ref_alias = param_ref.replace("$blueprint.settings.", "$blueprint.")
                param_name = mod.find_setting_ref(param_ref)
                if param_name == None:
                    param_name = mod.find_setting_ref(param_ref_alias)
                if param_name != None:
                    mod.set_setting_value(param_name, value)
                else:
                    param_name = mod.find_input_ref(param_ref)
                    if param_name == None:
                        param_name = mod.find_input_ref(param_ref_alias)
                    if param_name != None:
                        mod.set_input_value(param_name, value)

        return errors

    def propagate_blueprint_input_data(self) -> List[event.ValidationEvent]:
        errors = []
        for p in self.inputs:
            if p.value != None:
                (p_ref, err) = self.input_ref(p.name)
                if err != None:
                    self.find_replace_in_module(p_ref, p.value)

        for p in self.settings:
            if p.value != None:
                (p_ref, err) = self.setting_ref(p.name)
                if err != None:
                    self.find_replace_in_module(p_ref, p.value)

        return errors

    def propagate_module_data(self, module_data) -> List[event.ValidationEvent]:
        # module_data -> dict
        errors = []
        if self.modules != None:
            for mod in self.modules:
                for p in mod.inputs:
                    if p.value != None and p.value in module_data.keys():
                        mod.set_input_value(p.name, module_data[p.value])

                for p in mod.settings:
                    if p.value != None and p.value in module_data.keys():
                        mod.set_setting_value(p.name, module_data[p.value])

        if self.outputs != None:
            for p in self.outputs:
                if p.value != None:
                    if p.value != None and p.value in module_data.keys():
                        self.set_output_value(p.name, module_data[p.value])

        return errors

#======================================================================

    def build_dag(self) -> dag.BlueprintGraph:
        g = dag.BlueprintGraph()
        if hasattr(self, "modules") and self.modules != None:
            for m in self.modules:
                iref = m.input_value_refs()
                for i in iref:
                    if i.startswith("$module.") :
                        n = i[8:i.find(".", 8)]
                        if n != m.name:
                            g.addEdge(m.name, n)
                    elif i.startswith("$blueprint.") :
                        g.addEdge(m.name, "blueprint")

                oref = m.output_refs()
                for o in oref:
                    if o.startswith("$module.") :
                        n = o[8:o.find(".", 8)]
                        if n != m.name:
                            g.addEdge(n, m.name)
                    elif o.startswith("$blueprint.") :
                        g.addEdge("blueprint", m.name)

                g.addEdge("root", m.name)

        return g

    def is_dag_empty(self, bp_graph: dag.BlueprintGraph) -> bool:
        return bp_graph.isEmpty()

    def dag_next_node(self, bp_graph: dag.BlueprintGraph):
        if bp_graph.isEmpty():
            return None

        while not bp_graph.isEmpty():
            node_name = bp_graph.getAnIndependentNode()
            if node_name == "root" or node_name == "blueprint":
                bp_graph.popNode(node_name)
            else:
                return node_name

        return None

#======================================================================


import numpy as np
import pandas as pd
from py2neo import Graph
from tqdm import tqdm
from connector import connect
import os
import sys
import re
import traceback
import configparser
from datetime import datetime

class DataTransfer:

    def __init__(self):
        self.driver = connect()
        self.config = configparser.ConfigParser()
        self.config.read("config.ini")

    def createNode(self, data, label):

        """
        -------------------------------------------------
        Description : Function to create Nodes to GraphDb

        Parameters :
        @param data -- a python list containing data as dict
        @param label -- a string value

        Return :
        None
        ---------------------------------------------------
        """

        create = [self.config["NODES"]["CREATE"]]
        create = [i == "TRUE" for i in create][0]

        if create:
            print("Creating Nodes in Neo4j 🛠")

            try:
                with tqdm(total=len(data)) as pbar:
                    for i, datum in enumerate(data):
                        keys = datum.keys()

                        _query = f"CREATE ({label[0]}{i}:{label}) SET "
                        for k in keys:
                            if type(datum[k]) == str:
                                _query += f'{label[0]}{i}.{k} = "{datum[k]}",'
                            else:
                                _query += f'{label[0]}{i}.{k} = {datum[k]},'

                        _query = _query.strip(",")
                        self.driver.run(_query)
                        pbar.update(1)

            except Exception:
                print("Error Occured ⛔ ⛔")
                print(traceback.print_exc())

        else:
            print("Forbidden ❌ for creating nodes")

    def createRelationship(self, data, label1, label2, relationship, towards=True):

        """
        -------------------------------------------------------
        Description : Function to create relationships in Neo4j

        Parameters :
        @param data -- a python list containing pair of relationships
        @param label1 -- a string representing label in Neo4j for entity1
        @param label2 -- a string representing label in Neo4j for entity2
        @param relationship -- a string that will used to create the name of the relationship
        @param towards -- a boolean value

        Return:
        None
        --------------------------------------------------------
        """

        create = [self.config["RELATIONSHIPS"]["CREATE"]]
        create = [i == "TRUE" for i in create][0]

        if create:

            print("Creating Relationships in Neo4j 🛠")

            try :
                with tqdm(total = len(data)) as pbar:

                    for d in data:

                        if towards:
                            _query = f'MATCH (N1:{label1}), (N2:{label2}) WHERE N1.name="{d[0]}" and N2.name="{d[1]}" CREATE (N1)-[:{relationship}]->(N2)'
                        else:
                            _query = f'MATCH (N1:{label1}), (N2:{label2}) WHERE N1.name="{d[0]}" and N2.name="{d[1]}" CREATE (N1)<-[:{relationship}]-(N2)'

                        self.driver.run(_query)

                        pbar.update(1)

            except Exception:
                print("Error Occured 🚫 🚫")
                print(traceback.print_exc())

        else:
            print("Forbidden ❌ for creating relationships")

def dealDuplicates(df):
    """
    -----------------------------------------------------------
    Description : Function to deal with duplicate movie titles

    Parameters :
    @param df -- the pandas Dataframe containing the whole data

    Return :
    None
    -----------------------------------------------------------
    """

    duplicates = df[df.duplicated(subset="showName")]

    showNames = duplicates["showName"].values

    for names in showNames:

        releaseYear = df.loc[df["showName"] == names, "releaseYear"].values
        recentYear = max(releaseYear)

        for year in releaseYear:
            if year != recentYear:
                df.loc[(df["showName"] == names) & (df["releaseYear"] == year), "showName"] = names + "-" + str(year)

def buildNodes(df, fieldName, showNames):
    """
    ------------------------------------------------------
    Description : Function to build the node data for Neo4j

    Parameters :
    @param df -- pandas Dataframe containing the complete data
    @param fieldName -- name of column for which the node data is to be made
    @param showNames -- list of show present in the dataset

    Return:
    @ret ret -- a python set
    -------------------------------------------------------
    """
    ret = set()
    for show in showNames:

        people = df.loc[df["showName"] == show, fieldName].values[0]
        people = people.split(",")

        for person in people:
            person = person.replace("\"", "")
            person = person.strip()
            ret.add(person)

    return ret

def buildRelationship(df, showList, fieldName):
    """
    ----------------------------------------------------------
    Description : Function to prepare relationship pair for Neo4j

    Parameters :
    @param df -- pandas dataframe containing the whole data
    @param showList -- list of show present in the dataset
    @param fieldName -- string representing the column name

    Return:
    @ret ret -- a python list containing pair of relationships for entities
    ------------------------------------------------------------

    """

    ret = list()

    for show in showList:

        finders_keepers = df.loc[df["showName"] == show, fieldName].values.tolist()

        for f in finders_keepers:
            f = f.split(",")
            for _f in f:
                _f = _f.replace("\"", "")
                _f = _f.strip()

                if (_f, show) not in ret:
                    ret.append((_f, show))

    return ret

if __name__ == "__main__":

    df = pd.read_csv("./DATA/imdbData_movies.csv")
    print(df.head(5))

    print(df.info())

    print("Counting the duplicate values in showName 👬 ....")
    print(df.duplicated(subset="showName").sum())

    dealDuplicates(df)

    print("Counting duplicates 👬 after processing 🛠 showName ... ")
    print(df.duplicated(subset="showName").sum())

    showList = df["showName"].unique()

    showDirectors = buildNodes(df, "director", showList)
    showCast = buildNodes(df, "cast", showList)
    showGenre = buildNodes(df, "genre", showList)

    # Prepare Node data for Directors
    nodeDirectors = []

    for i, directors in enumerate(showDirectors):
        nodeDirectors.append({"name": directors, "id":f"D{i}"})

    # Prepare Node data for cast
    nodeCast = []

    for i, cast in enumerate(showCast):
        nodeCast.append({"name":cast, "id":f"A{i}"})

    # Prepare Node data for Genre
    nodeGenre = []
    for i, genre in enumerate(showGenre):
        nodeGenre.append({"name":genre, "id":f"G{i}"})

    # Prepare Node data for Movie
    nodeMovies = []

    for i, movies in enumerate(showList):

        rating = df.loc[df["showName"] == movies, "imdbRating"].values[0]
        metascore = df.loc[df["showName"] == movies, "metascore"].values[0]
        releaseYear = df.loc[df["showName"] == movies, "releaseYear"].values[0]

        nodeMovies.append({"name":movies, "imdbRating":rating, "metascore":metascore, "releaseYear":releaseYear, "id":f"M{i}"})

    DataTransfer().createNode(nodeDirectors, "Director")
    DataTransfer().createNode(nodeCast, "Actor")
    DataTransfer().createNode(nodeMovies, "Movie")
    DataTransfer().createNode(nodeGenre, "Genre")

    movieCast = buildRelationship(df, showList, "cast")
    movieDirector = buildRelationship(df, showList, "director")
    movieGenre = buildRelationship(df, showList, "genre")

    # checkCast = list(filter(lambda x: "," in x[0], movieCast))
    # checkDirector = list(filter(lambda x: "," in x[0], movieDirector))
    checkGenre = list(filter(lambda x: "," in x[0], movieGenre))

    # assert(checkCast == [])
    # assert(checkDirector == [])

    # assert(checkGenre == [])

    DataTransfer().createRelationship(movieCast, "Actor", "Movie", "Acted_In")
    DataTransfer().createRelationship(movieDirector, "Director", "Movie", "Directed_by")
    DataTransfer().createRelationship(movieGenre, "Genre", "Movie", "type_of", towards=False)


from setuptools import setup,find_packages

from pip._internal.req import parse_requirements

def load_requirements(fname):
    reqs = parse_requirements(fname, session="test")
    return [str(ir.req) for ir in reqs]

#Actual setup
setup(
    name="grpyc",
    version='0.1.3',
    description='Framework for grpcio (gRPC for python)',
    long_description="To ease compilation, project structure and tests",
    long_description_content_type='text/plain',
    license='MIT',
    author="gloxounet",
    packages=find_packages('src'),
    package_dir={'': 'src'},
    url='https://github.com/Gloxounet/gRPyC',
    keywords='gRPC framework',
    py_modules=['cli','compilation'],
    install_requires=['grpcio-tools>=1.49.1','Click'],
    python_requires='>=3',
    entry_points='''
        [console_scripts]
        grpyc=cli:cli
    ''',
)


# An isogram is a word that has no repeating letters, consecutive or non-consecutive. Implement a function that determines whether a string that contains only letters is an isogram. Assume the empty string is an isogram. Ignore letter case.
#to check whether an alphabet is repeated or not

def is_isogram(s):
    s1 = s.lower()
    for i in s1:
        a = s1.count(i)
        if(a > 1):
            res = False
            break
        else:
            res = True
    print(res)

is_isogram("mOose")


from flask import render_template, flash, redirect,request
from app import app
from app.models import User
from .forms import LoginForm
from app import db
import os
from werkzeug import secure_filename
import tinys3
from sqlalchemy.exc import IntegrityError

@app.route('/')
@app.route('/index',methods=['GET', 'POST'])
def index():
    form = LoginForm()
    error = None
    return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)
    error = None
    success = None
    if form.validate_on_submit():
        user = User(first_name=form.first_name.data,last_name=form.last_name.data,email=form.email.data)
        fileName = form.email.data + ".pdf"
        file = request.files['resume']
        if file and allowed_file(file.filename):
            file.save(fileName)
            conn = tinys3.Connection(app.config['FILESTOREK'],app.config['FILESTOREKS'],tls=True,endpoint="s3-us-west-2.amazonaws.com")
            f = open(fileName,'rb')
            conn.upload("resumes/"+fileName,f,'tigerbuilds')
            os.remove(fileName)
            try:
              db.session.add(user)
              db.session.commit()
              success = "Application Complete, Thank You"
            except IntegrityError:
              error = "The email you entered already exists"
            return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error,
                           success=success)
        error = "Resume must be a pdf"
    else:
        error = "Information not correct. You must fill everything out"
    return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error)