import random
import matplotlib.pyplot as plt
import numpy as np
import math
class City(object):
    def __init__(self,x,y):
        self.x=x
        self.y=y
class Country(object):
    def __init__(self,cities):
        self.cities=cities
class Genetic:
    def __init__(self,individual):
        self.individual=individual
        self.population=[]
        for i in range(len(self.individual)):
            self.population.append(np.random.permutation(list(range(0,len(self.individual)))))
        self.population_fitness={}
        self.generation=[]
        self.evaluate_generations=[]
        self.generation_fitness={}
    def fitness_function(self):
        fitness=[]
        distance=[]
        for i in range(len(self.population)):
            for j in range(len(self.population[i])-1):
                xDis = abs((self.individual[self.population[i][j]-1].x)-(self.individual[self.population[i][j+1]-1].x))
                yDis = abs((self.individual[self.population[i][j]-1].y)-(self.individual[self.population[i][j+1]-1].y))
                distance.append(round(np.sqrt((xDis ** 2) + (yDis ** 2)),2))
            sum_distance=sum(distance)
            fitness.append(sum_distance)
        for num in range(len(self.population)):
            self.population_fitness.update({num:fitness[num]})
        return self.population_fitness
    def tournament_selection(self):
        parents = random.choices(self.population_fitness, k=10)
        parents = sorted(parents)
        for key,value in self.population_fitness.items():
            if value==parents[0]:
                first_parent=key
            if value==parents[1]:
                second_parent=key
        return first_parent,second_parent
    def crossover(self,first_parent,second_parent):
        offspring=[]
        crossover_point1=random.randint(0,(int(len(self.individual)/2)))
        crossover_point2=random.randint(int(len(self.individual)/2),(len(self.individual)-1))
        for individual in range(len(self.population[first_parent])):
            if individual<crossover_point1:
                offspring.append(self.population[first_parent][individual])
            elif crossover_point1<=individual and individual<crossover_point2:
                offspring.append(self.population[second_parent][individual])
            elif crossover_point2<individual:
                offspring.append(self.population[first_parent][individual])
        return offspring
    def mutation(self,offspring):
        i=np.random.randint(2,(len(offspring)-1))
        j=np.random.randint(2,(len(offspring)-1))
        t=offspring[i]
        offspring[i]=offspring[j]
        offspring[j]=t
        return offspring
    def evaluating_generation(self,offspring):
        distance=[]
        for  i in range(len(offspring)-1):
            xDis = abs((self.individual[offspring[i]].x)-(self.individual[offspring[i+1]].x))
            yDis = abs((self.individual[offspring[i]].y)-(self.individual[offspring[i+1]].y))
            distance.append(round(np.sqrt((xDis ** 2) + (yDis ** 2)),2))
        self.generation.append(offspring)
        self.evaluate_generations.append(sum(distance))
    def best_genration(self):
        for i in range(len(self.generation)):
            self.generation_fitness.update({i:self.evaluate_generations[i]})
        best=min(self.generation_fitness.values())
        for i,j in self.generation_fitness.items():
            if j==best:
                return self.generation[i]
    def show_route(self,mutation_offspring):
        x=[]
        y=[]
        colors = []
        for entity in mutation_offspring:
            x.append(self.individual[entity].x)
            y.append(self.individual[entity].y)
            colors.append('#%06X' % random.randint(0, 0xFFFFFF))
        for i in range(len(x) - 1):
            plt.plot([x[i], x[i+1]], [y[i], y[i+1]], '-o', color=colors[i])
        plt.show()
##########################Cycle####################################################Cycle##########################
number_of_city=int(input('Enter number of city:'))
x1,x2=input('Specify the beginning and end of the x range:').split()
y1,y2=input('Specify the beginning and end of the y range:').split()
cities=[]
for i in range(number_of_city):
    x=random.randint(int(x1),int(x2))
    y=random.randint(int(y1),int(y2))
    city=City(x,y)
    cities.append(city)
usa=Country(cities)
a=Genetic(usa.cities)
a.fitness_function()
crossover_Condition=True
while crossover_Condition:
    first_parent,second_parent=a.tournament_selection()
    offspring=a.crossover(first_parent,second_parent)
    setoffspring=set(offspring)
    if len(setoffspring)==len(offspring):
        crossover_Condition=False
        offspring.append(offspring[0])
    else:
        crossover_Condition=True
for i in range(0,5):
    mutation_offspring=a.mutation(offspring)
    a.evaluating_generation(mutation_offspring)
    offspring=mutation_offspring
a.show_route(a.best_genration())


from flask import jsonify

class CustomException(Exception):

    def __init__(self, status_code, name = "Custom Error", description = 'Error'):
        super().__init__()
        self.status_code = status_code
        self.name = name
        self.description = description

    def get_response(self):
        response = jsonify({
            'error': {
                'code': self.status_code,
                'name': self.name,
                'description': self.description,
            }
        })
        response.status_code = self.status_code
        return response

class BadRequestError(CustomException):
    def __init__(self, username, paswwordd):
        super().__init__(status_code=400, name="Bad Request", description=f"User with username {username} not found")
        super().__init__(status_code=400, name="Bad Request", description=f"User with paswwordd {paswwordd} not found")

class NotFoundError(CustomException):
    def __init__(self, username):
        super().__init__(status_code=404, name="Not Found", description=f"User with username {username} not found")

class ForbiddenError(CustomException):
    def __init__(self, id_usuario):
        super().__init__(status_code=403, name="Forbidden", description=f"The user {id_usuario} does not have permission to perform this action")

class ServerError(CustomException):
    def __init__(self, id_servidor):
        super().__init__(status_code=500, name="Server Error", description=f"Internal Server Error{id_servidor}")


from turtle import Turtle, Screen

tim = Turtle()
screen = Screen()

def move_forwards():
    tim.forward(10)

def move_backwards():
    tim.backward(10)

def turn_left():
    new_heading = tim.heading() + 10
    tim.setheading(new_heading)

def turn_right():
    new_heading = tim.heading() - 10
    tim.setheading(new_heading)

def clear():
    tim.clear()
    tim.penup()
    tim.home()
    tim.pendown()

screen.listen()
screen.onkey(move_forwards, "w")
screen.onkey(move_backwards, "s")
screen.onkey(turn_left, "a")
screen.onkey(turn_right, "d")
screen.onkey(clear, "c")  # don't need to put ()
screen.exitonclick()

Day 19 - Turtle Race and Etch A Sketch/Etch A Sketch/main.py


import io
import numpy as np
from torch import nn
import torch.utils.model_zoo as model_zoo
import torch.onnx

import torch.nn as nn
import torch.nn.init as init
from gen_data import gen_np_args, args_adaptor

import onnx

def box_xyxy_to_cxcywh(x):
    x0, y0, x1, y1 = x.unbind(-1)
    b = [(x0 + x1) / 2, (y0 + y1) / 2, (x1 - x0), (y1 - y0)]
    return torch.stack(b, dim=-1)

class Bbox(nn.Module):
    def __init__(self):
        super(Bbox, self).__init__()
        self.box_xyxy_to_cxcywh = box_xyxy_to_cxcywh

    def forward(self, x):
        return self.box_xyxy_to_cxcywh(x)

torch_model = Bbox()

torch_model.eval()

x = args_adaptor(gen_np_args(50, 4))
torch_out = torch_model(x)

torch.onnx.export(torch_model,
        (x),
        "box_xyxy_to_cxcywh.onnx",
        verbose=True,
        export_params=True,
        opset_version=12,
        input_names=['x'],
        output_names = ['output'])


import logging

from flask import request, abort, jsonify, g
from flask_restplus import Resource
from api.problems.serializers import problem as api_problem
from api.problems.serializers import problem_table, problem_description, problem_edition, main_problem
from api.restplus import api
from models import db, Problem, Topic, ProblemTopic, \
    Case, Language, User, Taken, Statistic, Team, Teamenroll, Submission
from sqlalchemy import join, and_
from sqlalchemy.orm import Load
from authorization import auth_required
from api.evaluators.services import update_test_cases_in_filesystem

log = logging.getLogger(__name__)

ns = api.namespace('problems', description='Operations related to problems')

@ns.route('/')
@api.header('Authorization', 'Auth token', required=True)
class ProblemCollection(Resource):

    @api.marshal_list_with(api_problem)
    @auth_required('professor')
    def get(self):
        """
        Returns list of problems.
        """
        problems = db.session.query(Problem).filter(Problem.is_subproblem == False).order_by(Problem.id).all()

        # Get user
        token = request.headers.get('Authorization', None)
        user = User.verify_auth_token(token)

        # Retrieve problem's language name
        for problem in problems:
            problem.language = Language.query.filter(Language.value == problem.language).one().name
            if (user.role == 'admin'):
                problem.can_edit = True
            elif (user.role == 'professor' and problem.author_id == user.id):
                problem.can_edit = True
            else:
                problem.can_edit = False

        return problems

@ns.route('/changestatus/<int:problem_id>/<int:status>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemStatus(Resource):

    @api.response(204, 'Problem successfully updated.')
    @auth_required('professor')
    def put(self, problem_id, status):
        """
        Updates a problem's status.
        """
        if (status == 0):
            active = False
        else:
            active = True

        Problem.query.filter(Problem.id == problem_id).update({'active' : active})

        db.session.commit()

        return None, 204

@ns.route('/problembyname/<string:problem_name>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemStatus(Resource):

    @api.marshal_with(api_problem)
    @api.response(204, 'Problem successfully updated.')
    @auth_required('professor')
    def get(self, problem_name):
        """
        Return problem by name
        """
        # Check if problem exists
        problem = db.session.query(Problem).filter(Problem.name == problem_name).first()

        if (problem is not None):
            problem.language = Language.query.filter(Language.value == problem.language).one().name
        else:
            return None, 404

        return problem

@ns.route('/<int:id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemItem(Resource):

    @api.marshal_with(api_problem)
    @auth_required('professor')
    def get(self, id):
        """
        Returns a problem.
        """

        # Check if id is valid
        try:
            id = int(id)
        except ValueError:
            return None, 404

        # Check if problem exists
        problem = db.session.query(Problem).filter(Problem.id == id).first()

        if (problem is not None):
            problem.language = Language.query.filter(Language.value == problem.language).one().name
        else:
            return None, 404

        return problem

    @api.response(204, 'Problem successfully deleted.')
    @auth_required('admin')
    def delete(self, id):
        """
        Deletes a problem.
        """
        problem = Problem.query.filter(Problem.id == id).one()
        case = Case.query.filter(Case.problem_id == id).one()
        problemtopic = ProblemTopic.query.filter(ProblemTopic.problem_id == id).one()
        statistic = Statistic.query.filter(Statistic.problem_id == id).one()
        db.session.delete(case)
        db.session.delete(problemtopic)
        db.session.delete(statistic)
        db.session.delete(problem)
        db.session.commit()

        return None, 204

    @api.expect(api_problem)
    @api.response(204, 'Problem successfully updated.')
    @auth_required('professor')
    def put(self, id):
        """
        Updates a problem.
        """
        data = request.json

        topics = data['topics']
        test_cases  = data.get('cases')
        data.pop('topics', None)
        data.pop('cases', None)

        # Update problem's common fields
        Problem.query.filter(Problem.id == id).update(data)

        # Update test cases
        if (test_cases is not None):
            Case.query.filter(Case.problem_id == id).delete()

            # Create test cases
            for i in range(len(test_cases)):
                new_case = Case(is_sample=test_cases[i]['is_sample'],
                                input=test_cases[i]['input'],
                                feedback=test_cases[i]['feedback'],
                                output=test_cases[i]['output'],
                                problem_id=id)
                db.session.add(new_case)

            update_test_cases_in_filesystem({'problem_id' : id, 'test_cases' : test_cases})

        # Delete problem's topics
        ProblemTopic.query.filter(ProblemTopic.problem_id == id).delete()

        # Create new problem's topic
        new_problemtopic = ProblemTopic(problem_id=id,
                                    topic_id=topics)
        db.session.add(new_problemtopic)

        db.session.commit()

        return None, 204

@ns.route('/description/<int:id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemDescription(Resource):

    @api.marshal_with(problem_description)
    @auth_required('student')
    def get(self, id):
        """
        Returns the descriptions of a problem.
        """
        # Check if id is valid
        try:
            id = int(id)
        except ValueError:
            return None, 404

        problem = db.session.query(Problem).filter(Problem.id == id).first()

        if (problem is None):
            return None, 404

        # If user is student, check that problem is activated
        # Get user
        token = request.headers.get('Authorization', None)
        user = User.verify_auth_token(token)
        if (user.role == 'student' and problem.active == False):
            return None, 404

        # Complete missing fields
        cases = db.engine.execute("""
            SELECT c.input, c.output
            FROM problem p, \"case\" c
            WHERE c.problem_id = p.id AND p.id = %d AND c.is_sample = TRUE""" % (id)).fetchall()

        descriptions = {}
        descriptions["english"]       = problem.description_english
        descriptions["spanish"]       = problem.description_spanish
        descriptions["title"]         = problem.name
        descriptions["test_cases"]    = cases
        descriptions["signature"]     = problem.signature
        descriptions["language_name"] = Language.query.filter(Language.value == problem.language).one().name
        descriptions["language_code"] = problem.language

        print(descriptions)

        return descriptions

@ns.route('/listbytopic/<int:user_id>/<int:topic_id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemsByTopic(Resource):

    @auth_required('student')
    def get(self, user_id, topic_id):
        """
        Returns list of problems by topic, indicating if the problem has been solved by user
        """

        # Retrieve raw list of problems by topic

        # If topic id == 0, return all problems
        if (topic_id == 0):
            result = db.engine.execute("SELECT p.id, p.name, p.difficulty FROM Problem p WHERE p.active=true AND p.is_subproblem =false")
        else:
            result = db.engine.execute("SELECT p.id, p.name, p.difficulty FROM Problem p, ProblemTopic pt WHERE p.active=true AND p.is_subproblem = false AND p.id = pt.problem_id AND pt.topic_id = %d" % (topic_id))

        problems_list = []

        # Mark problem status (not attempted, attempted but wrong answer, or solved)
        for problem in result:
            # Problem not attempted
            if (len(db.engine.execute("SELECT p.id FROM Problem p WHERE p.id = %d AND NOT EXISTS (SELECT s.id FROM Submission s WHERE p.id = s.problem_id AND s.user_id = %d)" % (problem[0], user_id)).fetchall()) > 0):
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'not_attempted'})
            # Problem attempted but not solved
            elif (len(db.engine.execute("SELECT p.id FROM Problem p WHERE p.id = %d AND NOT EXISTS (SELECT s.id FROM Submission s WHERE p.id = s.problem_id AND s.grade = 100 AND s.user_id = %d)" % (problem[0], user_id)).fetchall()) > 0):
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'wrong_answer'})
            # Problem solved
            else:
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'accepted'})

        return problems_list

@ns.route('/list/')
@api.header('Authorization', 'Auth token', required=True)
class ProblemsList(Resource):

    @api.marshal_list_with(problem_table)
    @auth_required('professor')
    def get(self):
        """
        Returns list of problems for table display
        """

        # Retrieve raw list of problems by topic
        result = db.engine.execute("SELECT p.id, p.name, t.name as topic, p.difficulty, p.active, p.author_id FROM Problem p, Topic t, ProblemTopic pt WHERE p.id = pt.problem_id AND t.id = pt.topic_id").fetchall()

        # Get user
        token = request.headers.get('Authorization', None)
        user = User.verify_auth_token(token)

        problems = []

        # Retrieve problem's language name
        for row in result:
            problem = dict(row.items())
            if (user.role == 'admin'):
                problem["can_edit"] = True
            elif (user.role == 'professor' and row.author_id == user.id):
                problem["can_edit"] = True
            else:
                problem["can_edit"] = False
            problems.append(problem.copy())

        return problems

@ns.route('/mainproblems/')
@api.header('Authorization', 'Auth token', required=True)
class ProblemsList(Resource):

    @api.marshal_list_with(main_problem)
    @auth_required('professor')
    def get(self):
        """
        Returns list of main problems
        """
        # problems = db.engine.execute("""
        # SELECT *
        # FROM Problem p
        # WHERE p.is_subproblem = 'False'
        # """).fetchall()

        problems = Problem.query.filter(Problem.is_subproblem == False).all()

        return problems

#
@ns.route('/check-parent-team/<int:team_id>/<int:problem_id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemsByTopic(Resource):

    @auth_required('student')
    def get(self, team_id, problem_id):
        """
        Returns a list containing whether the team has done all the subchilds
        problems or not = can they submit the parent problem?
        """

        # Retrieve raw list of the sub-problems of the main problem(problem_id)
        result = db.engine.execute("SELECT p.id, p.name, p.difficulty, p.is_subproblem FROM Problem p WHERE p.belongs_to = %d" % (problem_id)).fetchall()
        # get students of the team
        users = Teamenroll.query.filter(Teamenroll.team_id == team_id).all()
        # initialize the states of the subproblems. False means they are not done by anyone on the team
        problems_list = [False for p in result]
        index = 0
        for user in users:
            index = 0
            for problem in result:
                res = Submission.query.filter(
                    Submission.user_id == user.student_id,
                    Submission.problem_id == problem.id,
                    Submission.grade == 100
                    ).all()
                # if the result is not an empty list
                if res:
                    problems_list[index] = True
                index = index + 1

        canSolveParent = True
        for p in problems_list:
            if p == False:
                canSolveParent = False

        if canSolveParent:
            problems_list.append({'all_accepted':'ok'})
        else:
            problems_list.append({'all_accepted':'no'})

        return problems_list

@ns.route('/listbysub-problem/<int:user_id>/<int:problem_id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found.')
class ProblemsByTopic(Resource):

    @auth_required('student')
    def get(self, user_id, problem_id):
        """
        Returns list of sub-problem by problem, indicating if the problem has been solved by user
        """

        # Retrieve raw list of problems by sub-problems

        result = db.engine.execute("SELECT p.id, p.name, p.difficulty, p.is_subproblem FROM Problem p WHERE p.belongs_to = %d" % (problem_id))
        problems_list = []
        counter = True

        print(result)
        # Mark problem status (not attempted, attempted but wrong answer, or solved)
        for problem in result:
            # Problem not attempted
            print(problem[0])
            if (len(db.engine.execute("SELECT p.id FROM Problem p WHERE p.id = %d AND NOT EXISTS (SELECT s.id FROM Submission s WHERE p.id = s.problem_id AND s.user_id = %d)" % (problem[0], user_id)).fetchall()) > 0):
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'not_attempted', 'is_subproblem': problem[3]})
                counter = False
            # Problem attempted but not solved
            elif (len(db.engine.execute("SELECT p.id FROM Problem p WHERE p.id = %d AND NOT EXISTS (SELECT s.id FROM Submission s WHERE p.id = s.problem_id AND s.grade = 100 AND s.user_id = %d)" % (problem[0], user_id)).fetchall()) > 0):
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'wrong_answer', 'is_subproblem':problem[3]})
                counter = False
            # Problem solved
            else:
                problems_list.append({'problem_id' : problem[0], 'name' : problem[1], 'difficulty' : problem[2], 'status' : 'accepted', 'is_subproblem':problem[3]})

        if counter:
            problems_list.append({'all_accepted':'ok'})
        else:
            problems_list.append({'all_accepted':'no'})

        return problems_list

@ns.route('/take-problem/<int:user_id>/<int:problem_id>/<int:team_id>')
@api.header('Authorization', 'Auth token', required=True)
@api.response(404, 'Problem not found')
class TakeProblem(Resource):
    @auth_required('student')
    def put(self, user_id, problem_id, team_id):
        """
        Marks a problem as Taken
        """
        validates = db.engine.execute("SELECT p.belongs_to FROM Problem p WHERE p.id = %d" % (problem_id))
        main_problem = validates
        for row in main_problem:
            print(row[0])
            if row[0] is not None:
                validates = db.engine.execute("SELECT p.id FROM Problem p WHERE p.belongs_to = %d" % (row[0]))
                sub_problems = validates
                for problem in sub_problems:
                    print(problem[0])
                    validates = db.engine.execute("SELECT t.id FROM Taken t WHERE t.user_id = %d AND t.problem_id = %d" % (user_id, problem[0]))
                    # User already has one problem from the sub_problems taken
                    if validates.rowcount > 0:
                        return None, 404
            else:
                return None, 404

        new_taken = Taken(user_id = user_id, problem_id = problem_id, team_id = team_id)
        db.session.add(new_taken)
        db.session.commit()

@ns.route('/leave_problem/<int:user_id>/<int:problem_id>')
@api.header('Authorization', 'Auth toke', required=True)
@api.response(404, 'Problem not found')
class LeaveProblem(Resource):
    @auth_required('student')
    def delete(self, user_id, problem_id):
        """
        Unmarks a problem
        """
        taken = Taken.query.filter(and_(Taken.user_id == user_id, Taken.problem_id == problem_id)).first()
        print(type(taken))
        if taken is not None:
            db.session.delete(taken)
            db.session.commit()
            return None, 204
        else:
            return None, 404


import json
import os
import re
import urllib.request

from bs4 import BeautifulSoup

def save_to_dir(parsed_entry):
    folder = re.sub(r'\W+', '', parsed_entry['title'])
    directory = './out/' + folder
    os.makedirs(directory)

    with open(directory + '/body.html', 'w', encoding='utf8') as f:
        f.write(parsed_entry['html'])

    with open(directory + '/meta.json', 'w', encoding='utf8') as outfile:
        json.dump(parsed_entry, outfile, ensure_ascii=False)

def print_tags(url):
    response = urllib.request.urlopen(url).read()
    html = BeautifulSoup(response, 'html.parser')
    tag_list_ul = html.find("ul", class_="ljtaglist")
    for li in tag_list_ul.contents:
        print(li.contents[0].contents[0])

def parse_entry(url):
    print('reading from: ' + url)
    response = urllib.request.urlopen(url).read()
    html = BeautifulSoup(response, 'html.parser')

    tags_div = html.find("div", class_="ljtags")
    tags = []
    if tags_div is not None:
        tags = [k.text for k in tags_div.find_all("a")]
        tags_div.extract()

    parsed_entry = {
        'url': url,
        'title': html.find("div", class_="subject").text.strip(),
        'html': html.find("div", class_="entry_text").prettify(),
        'tags': tags
    }

    return parsed_entry

def read_entries(url):
    entries = {}
    skip = 0
    while True:
        page_entries = parse_page(urllib.request.urlopen(url + '?skip=' + str(skip)).read())
        for page_entry in page_entries:
            entries[page_entry['url']] = page_entry
        skip += 10
        print('skip = ' + str(skip))
        if len(page_entries) == 0:
            break
    return entries

def parse_page(response):
    html = BeautifulSoup(response, 'html.parser')
    entries = html.find_all("div", class_="subject")
    parsed_entries = []
    for div in entries:
        parsed_entries.append(parse_entry(div.contents[0]['href']))
    return parsed_entries

journal_url = "http://mixam-lv.livejournal.com"
tags_path = "/tags"
# print_tags(journal_url+tags)

for entry in read_entries(journal_url).values():
    save_to_dir(entry)


import datetime
import os
from string import capwords
import nonebot
import aiohttp

from bs4 import BeautifulSoup
from nonebot.adapters.cqhttp.bot import Bot
from nonebot.adapters.cqhttp.event import MessageEvent
from nonebot.plugin import on_command
from utils import HEADERS
from utils.image import FONT, Draw, ImgDraw
from utils.message_builder import image
from utils.text import *
from utils.zhongguose import *

root_path = os.path.join('.', 'res', 'chinese_almanac')
card_path = os.path.join(root_path, 'card')
if not os.path.exists(root_path):
    os.makedirs(root_path)
if not os.path.exists(card_path):
    os.makedirs(card_path)

__usage__ = f'发送 黄历 今日黄历 可获取当天黄历信息'
__help__version__ = '0.1.1'
__help__plugin_name__ = "黄历 | 今日黄历"

async def chinese_almanac(date: 'datetime | None' = None) -> dict:
    """
    老黄历，来自 www.laohuangli.net
    :param date: 日期，不传入则默认今天

    result:
    :attr ndate: 农历日期
    :attr gdate: 公历日期
    :attr ywarn: 今日所宜，警告
    :attr jwarn: 今日所忌，警告
    :attr jrsy:  今日所宜
    :attr jrsj:  今日所忌
    :attr jsyq:  吉神宜趋
    :attr xsyj:  凶煞宜忌
    :attr mqjq:  目前节气
    :attr xgjq:  下个节气
    :attr csw:   财神位 [x, f, c] 喜神，福神，财神
    :attr yygs:  阴阳贵神 [yang, yin] 阳贵神 阴贵神
    """
    result = {
        'ndate': '',
        'gdate': '',
        'ywarn': '',
        'jwarn': '',
        'jrsy':  '',
        'jrsj':  '',
        'jsyq':  '',
        'xsyj':  '',
        'mqjq':  '',
        'xgjq':  '',
        'csw': {'x': '', 'f': '', 'c': ''},
        'yygs': {'yang': '', 'yin': ''}
    }
    payload = date.__format__('%Y/%Y-%m-%d.html') if date is not None else ''
    async with aiohttp.ClientSession() as c:
        r = await c.get(
            'https://www.laohuangli.net/' + payload,
            headers=HEADERS
        )
        soup = BeautifulSoup((await r.text()), features='lxml')
    table = soup.select_one(
        '.cate-box.mt-10 .title-table-index.table-border-box table')
    bg_table = table.select_one('.middle-rowspan')
    result['ndate'] = space_multiple_to_one(
        bg_table.select_one('.p-relative').text)
    date2 = space_multiple_to_one(
        bg_table.select_one('.page-btn-box span').text)
    result['gdate'] = space_multiple_to_one(bg_table.select_one(
        '.middle-rowspan p:first-child').text)
    # 【日值岁破 大事勿用】
    tf3 = table.select('.table-three-div', limit=2)
    appropriates = []
    for i in tf3[0].select('.t-center span'):
        appropriates.append(delete_space(i.text))
    result['jrsy'] = appropriates
    w = tf3[0].select_one('.t-center')
    [i.decompose() for i in w('span')]
    result['ywarn'] = space_multiple_to_one(w.text)

    taboos = []
    for i in tf3[1].select('.t-center span'):
        taboos.append(delete_space(i.text))
    result['jrsj'] = taboos
    w = tf3[1].select_one('.t-center')
    [i.decompose() for i in w('span')]
    result['jwarn'] = space_multiple_to_one(w.text)

    tf5 = table.select('.table-five-div', limit=2)
    jsyq = ''
    for i in tf5[0].select('.t-center span'):
        jsyq += delete_space(i.text)
    result['jsyq'] = jsyq
    xsyj = ''
    for i in tf5[1].select('.t-center span'):
        xsyj += delete_space(i.text)
    result['xsyj'] = xsyj

    jq = table.select_one('.text-p').select('td')
    result['mqjq'] = jq[0].text
    result['xgjq'] = jq[1].text

    e = soup.select('.table-box2 .img-box .flex-1.t-center')
    for i in e:
        for j in i('strong'):
            j.decompose()
    csw = e[0].select('li')
    result['csw']['x'] = delete_space(csw[0].text)
    result['csw']['f'] = delete_space(csw[1].text)
    result['csw']['c'] = delete_space(csw[2].text)
    yygs = e[1].select('li')
    result['yygs']['yang'] = delete_space(yygs[0].text)
    result['yygs']['yin'] = delete_space(yygs[1].text)
    return result

async def make_almanac(date: 'datetime | None' = None) -> str:
    """
    构建黄历图片并返回路径
    """
    date = date or datetime.datetime.now()
    out_path = os.path.join(
        card_path,
        date.__format__('%Y-%m-%d')+'.jpg'
    )
    data = (await chinese_almanac(date))
    bg = Draw.make_bg(1200, 1500)
    draw = ImgDraw(bg)
    await draw.init()
    await draw.openfont(FONT)
    draw.pos = (0, 30)

    await draw.putTextCenter('今日黄历', 1200, 0, 30, fontsize=100, fill=MANJIANGHONG)
    await draw.putTextCenter(data['gdate'], 1200, 0, 10, fontsize=32)
    await draw.putTextCenter(data['ndate'], 1200, 0, 30, fontsize=32)
    tmp = draw.y
    await draw.putTextCenter('宜', 600, 0, 20, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(data['ywarn'], 600, 0, fontsize=32, fill=SHANCHAHONG)
    await draw.putTextCenter(linefeed(data['jrsy'], 15), 600, 0, 30, fontsize=32)
    maxy = draw.y
    draw.pos = (600, tmp)
    await draw.putTextCenter('忌', 600, 0, 20, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(data['jwarn'], 600, 0, fontsize=32, fill=SHANCHAHONG)
    await draw.putTextCenter(linefeed(data['jrsj'], 15), 600, 0, 30, fontsize=32)
    draw.pos = (0, max(maxy, draw.y))

    tmp = draw.y
    await draw.putTextCenter('吉神宜趋', 600, 0, 20, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(linefeed(data['jsyq'], 15), 600, 0, 30, fontsize=32)
    maxy = draw.y
    draw.pos = (600, tmp)
    await draw.putTextCenter('凶煞宜忌', 600, 0, 20, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(linefeed(data['xsyj'], 15), 600, 0, 50, fontsize=32)

    draw.pos = (0, max(maxy, draw.y))
    await draw.putTextCenter('节    气', 1200, 0, 40, fontsize=72, fill=YANHONG)
    draw.x = 50
    await draw.putTextCenter(data['mqjq'], 500, -1, fontsize=32)
    draw.x = 550
    await draw.putTextCenter('==>', 100, -1, fontsize=32)
    draw.x = 650
    await draw.putTextCenter(data['xgjq'], 500, 0, 50, fontsize=32)

    draw.x = 0
    await draw.putTextCenter('财神位', 1200, 0, 30, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(
        (
            '喜神', data['csw']['x'], '',
            '福神', data['csw']['f'], '',
            '财神', data['csw']['c']
        ), 1200, 0, 50, fontsize=50
    )
    draw.x = 0
    await draw.putTextCenter('阴阳贵神', 1200, 0, 30, fontsize=72, fill=YANHONG)
    await draw.putTextCenter(
        (
            '阳贵神', data['yygs']['yang'], '',
            '阴贵神', data['yygs']['yin']
        ), 1200, 0, 50, fontsize=50
    )

    draw.x = 800
    await draw.putText('临时版面 Sakuyark@2021', fill=(196, 196, 196))
    await draw.save(out_path)
    return os.path.abspath(out_path)

ca = on_command(
    '今日黄历', aliases={'黄历'},
    priority=2
)

@ca.handle()
async def _(bot: Bot, event: MessageEvent):
    path = (await make_almanac())
    await bot.send(event, image(path), at_sender=True)


from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('tanner', views.tanner, name='tanner'),
    path('eric', views.eric, name='eric'),
    path('amanda', views.amanda, name='amanda'),
    path('sawyer', views.sawyer, name='sawyer'),
    path('<slug:cls>', views.class_lookup, name='class_lookup'),
    path('api/class_list', views.list_classes, name='list_classes'),
]


import getopt
import json
import sys

def get_default_options(options_file):
    """get default program options from json file"""
    try:
        with open(options_file, "r") as f:
            config = json.load(f)
    except ValueError as err:
        print(f"Can`t read config file: {options_file}, with error: {err}")
        sys.exit(2)
    return config

def get_command_line_options(args, cmd_line_opts):
    """get program options from command line"""
    try:
        opts, _ = getopt.getopt(args[1:], cmd_line_opts)
    except getopt.GetoptError as err:
        print(f"Invalid argument value with error: {err}")
        sys.exit(2)
    return opts

def get_options(args, options_file):
    options = get_default_options(options_file)
    cl_options = get_command_line_options(args, "a:p:")
    for opt in cl_options:
        print("get port from options")
        if opt[0] == "-a":
            options['DEFAULT']['HOST'] = opt[1]
        elif opt[0] == "-p":
            options['DEFAULT']['PORT'] = opt[1]
    return options


#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      alex
#
# Created:     29/08/2019
# Copyright:   (c) alex 2019
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import csv
import json
#import unidecode
import unicodedata

with open('dictionary.csv') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=';')
    header = csv_reader.next()
    dic = {}
    for name in header:
        uname = unicode(name, "utf-8")
        uname=unicodedata.normalize('NFKD', uname).encode('ascii','ignore')
        dic[uname.upper()] = {}
    for row in csv_reader:
        for idx,name in enumerate(header):
            uname = unicode(name, "utf-8")
            uname=unicodedata.normalize('NFKD', uname).encode('ascii','ignore')
            value = row[idx].strip()
            if value != '':
                uvalue = unicode(value, "utf-8")
                nuvalue=unicodedata.normalize('NFKD', uvalue).encode('ascii','ignore')
                letter = nuvalue[0].upper()# unidecode.unidecode(value)[0]

                uvalues = uvalue.split("/")
                if len(uvalues) == 0:
                    uvalues = uvalue.split("\\")
                if len(uvalues) == 0:
                    uvalues = uvalue.split(",")
                if len(uvalues) == 0:
                    uvalues = [uvalue]

                for item in uvalues:
                    try:
                        dic[uname.upper()][letter].append(item.strip())
                    except:
                        dic[uname.upper()][letter] = [item.strip()]

with open(r'../plugin/list_of_words.js', 'w') as f:
    f.write("var stopCheats = ")
    json.dump (dic, f, indent=4, sort_keys=True)# , encoding='Win-1252')
    f.write(";\n\n")

    #var stopCheats = [


# 백준 2138번 전구와 스위치

"""
아이디어

1. 첫번째 전구를 키는 케이스와 키지 않는 케이스로 나누는 것

-> 첫번째 전구는 비교할 이전 전구가 없기 때문에 두가지 경우를 모두 확인한다.

2. 한번 지나간 전구는 다시 건드리지 않는 것

-> 한번 지나간 전구를 다시 건드린다고 불가능한게 가능해지지도 않고 횟수만 늘어나기 때문이다.
-> 그리디 분류 이유

3. 전구의 상태가 바뀌면 양옆 전구가 바뀌기 때문에

    두번째 전구부터 시작해서 이전 전구의 상태가 희망하는 상태인지 확인하고

    다르다면 스위치를 눌러 상태를 변경하는 것

-> 이전 전구의 상태만 비교하는 것은 for문을 돌면서 어차피 다음 전구는 비교 하기 때문이다.
"""

N = int(input())
state = list(input())
hope = list(input())

# 첫번째 전구가 켜져있는 상태의 메소드
def change_zero(light):
    cnt = 1
    light[0] = str(1 - int(light[0])) # 첫번째와 그 다음 전구 상태 변경
    light[1] = str(1 - int(light[1]))

    # 이전과 비교해야하기 때문에 range는 1부터 시작
    for i in range(1, len(light)):
        # 만들어주려는 전구모양과 일치하면 그대로 통과
        if light[i-1] == hope[i -1]:
            continue
        # 아니라면 cnt 증가하고 전구모양을 변경
        else:
            cnt += 1

            light[i-1] = str(1 - int(light[i -1]))
            light[i] = str(1 - int(light[i]))
            if i < len(light) - 1: # 해당 길이를 벗어나지 않는 경우에만 다음 전구 변경
                light[i+1] = str(1 - int(light[i+1]))

    if hope == light:
        return cnt

    return 200002

# 처음에 전구가 켜져 있지 않는 경우
def non_change_zero(light):
    cnt = 0
    # 따로 변경해주지 않고 바로 비교

    for i in range(1, len(light)):
        if light[i -1] == hope[i-1]:
            continue
        else:
            cnt += 1

            light[i-1] = str(1 - int(light[i -1]))
            light[i] = str(1 - int(light[i]))
            if i < len(light) -1:
                light[i + 1] = str(1 - int(light[i + 1]))

    if hope == light:
        return cnt

    return 100002

cnt1 = change_zero(state[:])
cnt2 = non_change_zero(state[:])

ans = min(cnt1, cnt2)
if ans == 100002: # 첫번째 전구가 켜져있는 상태의 return 값인 200002과 min으로 비교했을 때 ans 값에 저장된 것이기 때문에 불가능한 경우에 해당하고 -1 출력
    ans = -1
print(ans)


from django.conf import settings

from maria.client import HTTPAPIClient

class PayMongoClient(HTTPAPIClient):

    BASE_URL = settings.PAYMONGO_API_URL

    def __init__(self):
        super(PayMongoClient, self).__init__(base_url=self.BASE_URL)
        self.SECRET_KEY = settings.PAYMONGO_SECRET_KEY
        self.PUBLIC_KEY = settings.PAYMONGO_PUBLIC_KEY

    def get_auth(self):
        return (self.SECRET_KEY, None)

    def get_default_headers(self):
        return {"Content-Type": "application/json"}

    def create_payment_intent(self, amount, description=None, statement_descriptor=None, metadata=None):
        data = {
            "data": {
                "attributes": {
                    "amount": int(amount * 100),  # amount is in cents
                    "payment_method_allowed": ["card"],
                    "payment_method_options": {"card": {"request_three_d_secure": "any"}},
                    "currency": "PHP",
                    **{
                        k: v for k, v in [
                            ("description", description),
                            ("statement_descriptor", statement_descriptor),
                            ("metadata", metadata,)
                        ] if v
                    }
                }
            }
        }

        r = self.post(
            '/payment_intents',
            json=data
        )
        return r.json()

    def get_payment_intent(self, id):
        r = self.get('/payment_intents/{}'.format(id))
        return r.json()

    def attach_payment_method(self, client_key, method_id):
        intent_id = client_key.split('_client')[0]
        data = {
            "data": {
                "attributes": {
                    "payment_method": method_id,
                }
            }
        }
        r = self.post(
            '/payment_intents/{}/attach'.format(intent_id),
            json=data
        )
        return r.json()

    def pay_amount(
        self,
        amount,
        payment_method_id,
        description=None,
        statement_descriptor=None,
        metadata=None
    ):
        pi_res = self.create_payment_intent(
            amount,
            description=description,
            statement_descriptor=statement_descriptor,
            metadata=metadata
        )
        if 'errors' in pi_res:
            return pi_res
        else:
            client_key = pi_res['data']['attributes']['client_key']
            apm_res = self.attach_payment_method(
                client_key,
                payment_method_id
            )
            return apm_res


# 두개 뽑아서 더하기

def solution(numbers):
    answer = set()

    for i in range(len(numbers)):
        for j in range(i+1, len(numbers)):
            answer.add(numbers[i] + numbers[j])

    return sorted(list(answer)) # 오름차순 정렬 반환

print(solution([2,1,3,4,1]))
print(solution([5,0,2,7]))


"""
Topic:
Source:
Time Comlexity:O()
Space Comlexity:O()
"""

import heapq

def solver():
    m = []
    N = int(input())
    di = {}
    for i in range(N):
        b = input().split()
        if b[0] == '1':
            b = int(b[1])
            if b not in di or di[b] ==2:
                heapq.heappush(m, b)
                di[b] = 1
        elif b[0] == '2':
            b = int(b[1])
            di[b]=2
        else:
            while di[m[0]] == 2:
                heapq.heappop(m)
                # del di[m[0]]
            print(m[0])

if __name__ == '__main__':
    solver()


 #두 번 이상 나온 이름 찾기
#입력:이름이 n개 들어 있는 리스트
#출력:이름 n개 중 반복되는 이름의 집합

def find_same_name(a):
    n=len(a)                        #리스트의 자료 개수를 n에 저장// list를 넘김, list의 길이를 반환
    result=set()                    #결과를 저장할 빈 집합// set:집합형 자료형, list와 set는 모두 자료형, set는 중복을 허락하지 않는다!!
    for i in range(0,n-1):          #0부터 n-2까지 반복
        for j in range(i+1,n):      #i+1부터 n-1까지 반복
            if a[i]==a[j]:          #이름이 같으면
                result.add(a[i])    #찾은 이름을 result에 추가
    return result

name=["Tom", "Jerry", "Mike", "Tom"]
print(find_same_name(name))

name=["Tom", "Jerry", "Mike", "Tom", "Mike"]
print(find_same_name(name))

컴퓨팅 사고력 향상을 위한 SW코딩/두 번 이상 나온 이름 찾기.py

두 번 이상 나온 이름 찾기.py


from django.db import models

class Results(models.Model):
    sport = models.CharField('Вид спорта',max_length=100)
    tournament = models.CharField('Турнир',max_length=100)
    team_1 = models.CharField('Команда 1',max_length=100)
    team_2 = models.CharField('Команда 2',max_length=100)
    score_1 = models.IntegerField('Очки команды 1')
    score_2 = models.IntegerField('Очки команды 2')
    date_1 = models.DateField('Дата матча')

    def __str__(self):
        return f"{self.sport} | {self.team_1} | {self.team_2} | {self.date_1}"

    class Meta:
        verbose_name = 'Результат'
        verbose_name_plural = 'Результаты'


#join number of list into single list
from itertools import chain
lst = [list(range(0,10)) for _ in range(10)]
print(lst)

# list(chain(*lst))
r = []
for i in lst:
    r.extend(lst)
print(r)


from products.models import Products,Category
from .models import Customers
from django.views.generic import CreateView, DeleteView,UpdateView,ListView,FormView,View,DetailView
from .forms import *
from django.contrib.auth import get_user_model
from django.db.models import Q
from cart.cart import Cart
from cart.models import Item
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from django.urls import reverse,reverse_lazy
from django.shortcuts import render_to_response,redirect
from django.db.models import F
from django.contrib import messages
from django.db.models import Sum,Count
from django.views.generic import View
import datetime
from django.core.files.storage import FileSystemStorage
from django.template.loader import render_to_string

def add_to_cart(request):
    quantity = int(request.POST.getlist('quantity')[0])
    if(quantity !=0):
        product_id = request.POST['product_id']
        product = Products.objects.get(id=product_id)
        cart = Cart(request)
        cart.add(product, product.price, quantity)
        return HttpResponseRedirect(reverse('order_list_products'))
    else:
        messages.error(request,"Order fail Qty can't null")
        return HttpResponseRedirect(reverse('order_list_products'))

def remove_from_cart(request, product_id):
    product = Products.objects.get(id=product_id)
    cart = Cart(request)
    cart.remove(product)
    return HttpResponseRedirect(reverse('order_list_products'))

def generateInvoice():
    order = Orders.objects.only('created_at').order_by('-created_at')
    if order.count() > 0:
        order   = order.first()
        explode = order.invoice.split('-')
        count   = str(int(explode[1]) + 1)
        return 'INV-'+count
    return 'INV-1'
def get_cart(request):
    return render(request, 'orders/products/cart.html', {'cart': Cart(request)})

class ProductsViews(FormView):
    form_class = OrdersForm
    success_url = 'order_list_products'
    def get(self, request, *args, **kwargs):
        """Handle GET requests: instantiate a blank version of the form."""
        if request.method == 'GET' and 'search' in request.GET:
            if request.GET['search'] != '':
                kwargs['products']          = Products.objects.filter(Q(name=request.GET['search']) | Q(code=request.GET['search']))
            else:
                kwargs['products']          = Products.objects.all()
        elif request.method == 'GET' and 'categories' in request.GET:
            if request.GET['categories'] != '':
                kwargs['products']          = Products.objects.filter(Q(categories=request.GET['categories']))
            else:
                kwargs['products']          = Products.objects.all()
        else:
                kwargs['products']          = Products.objects.all()
        kwargs['cart']                      = Cart(request)
        return self.render_to_response(self.get_context_data(**kwargs))
    def get_context_data(self, **kwargs):
        kwargs['heading_title']     = "Order Transaction"
        kwargs['list_categories']   = Category.objects.all()
        kwargs['breadcrumb']        = {'content':'Order Product','class':'active'}
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        return context

    def get_success_url(self):
        """Return the URL to redirect to after processing a valid form."""
        if not self.success_url:
            raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
        return reverse_lazy(self.success_url)  # success_url may be lazy

class Checkout(CreateView):
    model = Orders
    form_class = OrdersForm
    success_url = 'ordes_list'
    def get(self, request, *args, **kwargs):
        """Handle GET requests: instantiate a blank version of the form."""
        self.object = None
        User = get_user_model()
        kwargs['cart']                   = Cart(request)
        kwargs['customers']              = Customers.objects.all()
        kwargs['barista']                = User.objects.all().filter(groups__name='Barista')
        return self.render_to_response(self.get_context_data(**kwargs))
    def get_context_data(self, **kwargs):
        kwargs['heading_title']     = "Order Transaction"
        kwargs['card_title']        = "Customers data"
        kwargs['breadcrumb']        = {'content':'Order Product','url':'order_list_products'}
        kwargs['breadcrumb2']       = {'content':'Checkout','class':'active'}
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        return context
    def post(self, request, *args, **kwargs):
        """
        Handle POST requests: instantiate a form instance with the passed
        POST variables and then check if it's valid.
        """
        self.object = None # assign the object to the view
        User = get_user_model()
        method = self.request.POST['customer']
        cart   = Cart(request)
        if(method):
            try:
                qty = []
                product = []
                orders = True
                for x in Item.objects.all():
                    product.append(x.object_id)
                    qty.append(x.quantity)
                queryset = Products.objects.filter(id__in=product).values('stock')
                for i in range(len(queryset)):
                    if queryset[i]['stock'] < qty[i]:
                        orders = False
                if not Item.objects.all():
                    orders = False
                if int(request.POST['payment']) < int(cart.summary()):
                    orders = False
                if request.POST['payment'] == "":
                    orders = False

                name = None
                if(request.POST['name'] == "others"):
                    name = request.POST['name_input']
                else:
                    name = request.POST['name']

                if name == "":
                    orders = False
                if request.POST['barista'] == "":
                    orders = False

                if orders:
                    barista  = User.objects.get(id=request.POST['barista']).id
                    customer = Customers.objects.create(
                        name=name,
                        email=request.POST['email'],
                        address=request.POST['address'],
                        phone=request.POST['phone'],
                        payment=request.POST['payment'],
                        barista_id=barista,
                    )

                    order = Orders(
                        invoice=generateInvoice(),
                        total=cart.summary(),
                        user_id=request.user.id,
                        customer_id=customer.id)
                    order.save()
                    if(order):
                        for x in Item.objects.all():
                            orderdetail = OrderDetails(
                                order_id = order.id,
                                product_id = x.object_id,
                                qty = x.quantity,
                                price = x.unit_price
                            )
                            orderdetail.save()
                            if(orderdetail):
                                product = Products.objects.get(id=x.object_id)
                                product.stock = F('stock') - x.quantity
                                product.save()
                                cart.clear()
                    return HttpResponseRedirect(self.get_success_url())
                else:
                    messages.error(request,'Order fail out of stock or form important null or payment minus')
                    return redirect(reverse('check_out_product'))
            except Exception as e:
                messages.error(request,'Order fail out of stock or form important null or cart null or payment minus')
                return redirect(reverse('check_out_product'))
    def get_success_url(self):
        """Return the URL to redirect to after processing a valid form."""
        if not self.success_url:
            raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
        return reverse_lazy(self.success_url)  # success_url may be lazy

class OrdersView(FormView):
    form_class = OrdersForm
    success_url = 'order_list'
    def get(self, request, *args, **kwargs):
        """Handle GET requests: instantiate a blank version of the form."""
        total_order_details  = OrderDetails.objects.aggregate(total_item=Sum('qty'))
        total_order          = Orders.objects.aggregate(total_omset=Sum('total'))
        total_customers      = Customers.objects.all().count()
        kwargs['total_item']      = total_order_details['total_item']
        kwargs['total_omset']     = total_order['total_omset']
        kwargs['total_customers'] = total_customers
        kwargs['orders']          = Orders.objects.all().order_by('-created_at')
        return self.render_to_response(self.get_context_data(**kwargs))

    def get_context_data(self, **kwargs):
        kwargs['heading_title']     = "Order List"
        kwargs['breadcrumb']        = {'content':'Order List','class':'active'}
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        return context

class GenerateInvoicePrint(DetailView):
    def get(self, request, *args, **kwargs):
        """Handle GET requests: instantiate a blank version of the form."""
        self.object = None
        kwargs['totalPrice']           = OrderDetails.objects.filter(order_id=self.kwargs['pk']).aggregate(totalPrice=Sum('price'))
        kwargs['totalQty']             = OrderDetails.objects.filter(order_id=self.kwargs['pk']).aggregate(totalQty=Sum('qty'))
        kwargs['total']                = OrderDetails.objects.filter(order_id=self.kwargs['pk']).aggregate(total=Sum(F('qty') * F('price')))
        kwargs['order']                = OrderDetails.objects.all().filter(order_id=self.kwargs['pk'])
        kwargs['orders']               = Orders.objects.all().get(pk=self.kwargs['pk'])
        kwargs['date_order']           = Orders.objects.get(pk=self.kwargs['pk']).created_at
        return self.render_to_response(self.get_context_data(**kwargs))

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        return context

#def GenerateInvoicePDF(request,pk):

#     orders = Orders.objects.filter(id=pk)
#     html_string = render_to_string('invoice/invoice_pdf.html', {'orders': orders})

    # html = HTML(string=html_string)
    # html.write_pdf(target='/tmp/mypdf.pdf');

    # fs = FileSystemStorage('/tmp')
    # with fs.open('mypdf.pdf') as pdf:
    #     response = HttpResponse(pdf, content_type='application/pdf')
    #     response['Content-Disposition'] = 'attachment; filename="mypdf.pdf"'
    #     return response

    # return response


from flask import request
from flasgger.utils import swag_from
from flask import Blueprint

from usersServiceApp.core.report_logic import validate_and_create_report, get_reports_info, \
    validate_and_update_report_status, get_report_status_dataset
from usersServiceApp.errors.usersException import usersException
from flask import jsonify

bp_report = Blueprint('report', __name__, url_prefix='/report/')

@bp_report.route("/", methods=['POST'])
@swag_from(methods=['POST'])
def new_report():
    """
    Register a new report
    The form has to be complete.
    ---
    tags:
      - report
    consumes:
      - application/json
    parameters:
      - name: body
        in: body
        required: true
        schema:
            required:
              - id_report_type
              - id_user_reported
              - id_user_reported_by
            properties:
              id_report_type:
                type: integer
                description: id_report_type
              id_user_reported:
                type: integer
                description: id_user_reported
              id_user_reported_by:
                type: integer
                description: id_user_reported_by
              other_text:
                type: String
                description: text for other report
    responses:
      200:
        description: A successful profile creation
        schema:
          properties:
              id:
                type: integer
                description: Unique identifier of the created report
    """
    try:
        post_data = request.get_json()
        validate_and_create_report(post_data)
    except usersException as e:
        return jsonify({'Error': e.message}), e.error_code
    return jsonify(
        {'Status': "Report Created"}), 200

@bp_report.route("/<int:user_id>", methods=['GET'])
@swag_from(methods=['GET'])
def get_user_if_registered(user_id):
    """
    Get user if registered
    ---
    tags:
      - report
    parameters:
      - in: path
        name: user_id
        type: integer
        required: true
    responses:
      200:
        description: A single user info if registered
        schema:
          properties:
              id:
                type: integer
                description: Unique identifier of the created user
              first_name:
                type: string
                description: first name of the created user
    """
    try:
        _reports = get_reports_info(user_id)
    except usersException as e:
        return jsonify({'Error': e.message}), e.error_code
    return jsonify(_reports), 200

@bp_report.route("/<int:report_id>", methods=['PUT'])
@swag_from(methods=['PUT'])
def update_report(report_id):
    """
    update status report
    The form has to be complete.
    ---
    tags:
      - report
    consumes:
      - application/json
    parameters:
      - in: path
        name: report_id
        type: integer
        required: true
      - name: body
        in: body
        required: true
        schema:
            required:
              - is_pending
            properties:
              is_pending:
                type: boolean
                description: is_pending
    responses:
      200:
        description: A successful profile creation
        schema:
          properties:
              id:
                type: integer
                description: Unique identifier of the updated report
    """
    try:
        post_data = request.get_json()
        validate_and_update_report_status(report_id, post_data['is_pending'])
    except usersException as e:
        return jsonify({'Error': e.message}), e.error_code
    return jsonify(
        {'Status': "Report Updated"}), 200

@bp_report.route("/dataset", methods=['GET'])
@swag_from(methods=['GET'])
def get_report_dataset():
    """
    Get dataset
    ---
    tags:
      - report
    responses:
      200:
        description: A single user info if registered
        schema:
          properties:
              id:
                type: integer
                description: Unique identifier of the created user
    """
    try:
        _reports = get_report_status_dataset()
    except usersException as e:
        return jsonify({'Error': e.message}), e.error_code
    return jsonify(_reports), 200


import socket
import sys
import time
x = socket.socket()
#host = input(str("Enter the hostname of the server: "))
host = '127.0.0.1'
port = 8080
x.bind((host,port))
#x.connect((host,port))
print("Connected to chat server...")
while True:
    incoming_msg = x.recv(1024)
    incoming_msg = imcoming_msg.decode()
    print("Server: ",incoming_msg)
    msg = input(str(">>"))
    Msg = msg.encode()
    x.send(Msg)
    print("Message has beem sent...")


import json
import os

import pytest
from click.testing import CliRunner

import brain.parsers
import brain.parsers.mq_agent.rabbitmq_agent
from brain.parsers import run_parser, invoke_parser
from brain.parsers.__main__ import cli
from brain.parsers.framework import Context
from brain.parsers.mq_agent import load_mq_agent
from brain.utils.consts import *
from .data_generators import gen_snapshot_for_parsers, PARSERS
from .utils import protobuf2dict

@pytest.fixture
def random_snapshot(tmp_path):
    snapshot = gen_snapshot_for_parsers(tmp_path, should_gen_user=True)
    data = snapshot.SerializeToString()
    file_path = str(tmp_path / 'snapshot.raw')
    with open(file_path, 'wb') as file:
        file.write(data)
    return snapshot, data, file_path

def verify_result_header(result, snapshot):
    assert result['uuid'] == str(snapshot.uuid)
    assert result['datetime'] == str(snapshot.datetime)
    assert result['user'] == protobuf2dict(snapshot.user)

def verify_pose(result, snapshot):
    assert result == protobuf2dict(snapshot.pose)

def verify_color_image(result, snapshot):
    assert result['width'] == snapshot.color_image.width
    assert result['height'] == snapshot.color_image.height
    assert os.path.isfile(result['path'])

def verify_depth_image(result, snapshot):
    assert os.path.isfile(result['path'])

def verify_feelings(result, snapshot):
    assert result == protobuf2dict(snapshot.feelings)

def test_pose(random_snapshot):
    snapshot, data, _ = random_snapshot
    result = run_parser('pose', data)
    verify_result_header(result, snapshot)
    verify_pose(result['result'], snapshot)

def test_color_image(random_snapshot):
    snapshot, data, _ = random_snapshot
    result = run_parser('color_image', data)
    verify_result_header(result, snapshot)
    verify_color_image(result['result'], snapshot)

def test_depth_image(random_snapshot):
    snapshot, data, _ = random_snapshot
    result = run_parser('depth_image', data)
    verify_result_header(result, snapshot)
    verify_depth_image(result['result'], snapshot)

def test_feelings(random_snapshot):
    snapshot, data, _ = random_snapshot
    result = run_parser('feelings', data)
    verify_result_header(result, snapshot)
    verify_feelings(result['result'], snapshot)

class MockMQAgent:
    snapshot = None
    result = None

    def __init__(self, url):
        pass

    def consume_snapshots(self, callback, topic):
        callback(self.__class__.snapshot)

    def publish_result(self, result, topic):
        self.__class__.result = result

    @classmethod
    def clear(cls):
        cls.snapshot = cls.result = None

@pytest.fixture
def mock_mq_agent(monkeypatch):
    yield monkeypatch.setattr(brain.parsers.mq_agent.rabbitmq_agent, 'MQAgent', MockMQAgent)
    MockMQAgent.clear()

@pytest.mark.parametrize('parser', ['pose', 'color_image', 'depth_image', 'feelings'])
def test_invoke_parser(parser, mock_mq_agent, random_snapshot):
    snapshot, data, _ = random_snapshot
    MockMQAgent.snapshot = data
    invoke_parser(parser, MQ_URL)
    result = MockMQAgent.result
    verify_result_header(result, snapshot)
    result = result['result']
    if parser == 'pose':
        verify_pose(result, snapshot)
    elif parser == 'color_image':
        verify_color_image(result, snapshot)
    elif parser == 'depth_image':
        verify_depth_image(result, snapshot)
    elif parser == 'feelings':
        verify_feelings(result, snapshot)

@pytest.fixture
def mock_rabbitmq(monkeypatch):
    def expected_callback(data):
        pass

    expected_data = {'abc': 'def'}

    class MockRabbitMQ:
        def __init__(self, url):
            assert url == MQ_URL

        def consume(self, callback, exchange, queues, exchange_type='fanout'):
            assert callback == expected_callback
            assert exchange == 'snapshot'
            assert queues == ['pose']

        def publish(self, data, exchange='', queue=''):
            assert json.loads(data) == expected_data
            assert exchange == 'saver'
            assert queue == 'saver_pose'

    monkeypatch.setattr(brain.parsers.mq_agent.rabbitmq_agent, 'RabbitMQ', MockRabbitMQ)
    yield expected_callback, expected_data

def test_context(tmp_path):
    ctx = Context(str(tmp_path))
    ctx.save('file.txt', 'Some data')
    with open(str(tmp_path / 'file.txt'), 'r') as file:
        assert file.read() == 'Some data'
    ctx = Context()
    calls = {ctx.save: ['file.txt', 'Some data'], ctx.path: ['file.txt'], ctx.delete: ['file.txt']}
    for func, args in calls.items():
        with pytest.raises(Exception) as error:
            func(*args)

        assert 'Cannot access context' in str(error.value)

def test_mq_agent(mock_rabbitmq):
    expected_callback, expected_data = mock_rabbitmq
    mq_agent_module = load_mq_agent('rabbitmq')
    mq_agent = mq_agent_module.MQAgent(MQ_URL)
    mq_agent.consume_snapshots(expected_callback, 'pose')
    mq_agent.publish_result(expected_data, 'pose')

@pytest.fixture
def mock_invoke_parser(monkeypatch):
    def fake_invoke_parser(parser, mq_url):
        assert parser == 'pose'
        assert mq_url == MQ_URL

    monkeypatch.setattr(brain.parsers.__main__, 'invoke_parser', fake_invoke_parser)

def test_cli(random_snapshot, mock_invoke_parser):
    snapshot, data, file_path = random_snapshot
    runner = CliRunner()
    for parser in PARSERS:
        result = runner.invoke(cli, ['parse', parser, file_path])
        assert result.exit_code == 0, result.exception
        parsed = json.loads(result.stdout)
        result_dict = parsed['result']
        if parser == 'pose':
            verify_pose(result_dict, snapshot)
        elif parser == 'color_image':
            verify_color_image(result_dict, snapshot)
        elif parser == 'depth_image':
            verify_depth_image(result_dict, snapshot)
        elif parser == 'feelings':
            verify_feelings(result_dict, snapshot)

    res = runner.invoke(cli, ['run-parser', 'pose', MQ_URL])
    assert res.exit_code == 0, res.exception


from PIL import Image , ImageDraw
from tqdm import tqdm
import numpy as np
import glob
import sys
import cv2
import psutil
from keras.models import model_from_json

print("Getting model")
json_file = open('model\car_detection.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json)
# load weights into new model
model.load_weights("model\model.h5")
print("Loaded model from disk")

responce = int(input("Single Image: 1\nList of Images: 2\nVideo: 3\nResponce: "))
print()
input_dim = 228

if responce == 1: #Single image

    path = r"testing\test.jpg"

    image = Image.open(path)
    image = image.resize((input_dim, input_dim))
    image = np.asarray(image) / 255.0

    image = np.expand_dims(image,axis=0)

    boxes = model.predict(image)
    image = image.squeeze(axis=0)
    #Grab the box locations and size them up to be the correct size.
    b = boxes[ 0 , 0 : 4 ] * input_dim
    img = image * input_dim
    #Rebuild the image.
    source_img = Image.fromarray( img.astype( np.uint8 ) , 'RGB' )
    #Draw the bounding box
    draw = ImageDraw.Draw( source_img )
    draw.rectangle( b , outline="blue" )
    #Save the image and add 1 to the image file name.
    print("Saving image")
    source_img.save( 'result\test_image_result.png' , 'png' )
    print("Image saved")

elif responce == 2:
    images = []
    boxes = []

    image_paths = glob.glob(r"testing\*.jpg")

    loader = tqdm(total=len(image_paths), position=0, leave=True, desc="Loading images...")
    for path in image_paths:
        image = Image.open(path)
        image = image.resize((input_dim, input_dim))
        image = np.asarray(image) / 255.0
        images.append(image)
        loader.update(1)

    loader.close()

    #Progress bar for predicting images and saving them to system
    images = np.asarray(images)

    loop = tqdm(total = len(image_paths), position=0, leave=True, desc="Predicting test images...")

    boxes = model.predict(images)

    #For each bounding box
    for i in range(len(image_paths)):
        #Grab the box locations and size them up to be the correct size.
        b = boxes[ i  , : ] * input_dim
        img = images[i] * input_dim

        #Rebuild the image.
        source_img = Image.fromarray( img.astype( np.uint8 ) , 'RGB' )
        #Draw the bounding box
        draw = ImageDraw.Draw( source_img )
        draw.rectangle( b , outline="blue" )
        #Save the image and add 1 to the image file name.
        source_img.save( 'result\image_{}.png'.format( i + 1 ) , 'png' )
        loop.update(1)

    loop.close()
    print("\nFinished")
    print("Complete")

elif responce == 3:
    #Create containers
    boxes = []
    images = []

    #Get video for capture
    cap = cv2.VideoCapture(r'testing\test.mp4')

    #If the video file cannot find data
    if cap.isOpened() == False:
        print("no video")

    #While there is data.
    while cap.isOpened():

        #Check if this frame exists and grab the frame regardless
        end, frame = cap.read()
        #If this is the end of the video exit the loop.
        if end == False:
            break

        #If memory usage goes above 95 stop the program to avoid a system crash.
        if psutil.virtual_memory()[2] > 95:
            print("Virtual memory at dangerously high levels. Closing application")
            sys.exit()

        #Perform preprocessing on the frame
        frame = cv2.resize(frame, (input_dim, input_dim))
        frame = np.asarray(frame) / 255
        #Store it in an array.
        images.append(frame)
    #Releases resources used by capture to reduce strain on memory.
    cap.release()

    #Make images into a numpy array
    images = np.asarray(images)

    #Initialise progress bar
    loop = tqdm(total = len(images), position=0, leave=True, desc="Predicting video...")

    #Predict the images
    boxes = model.predict(images)

    #Create video codec for MP4 videos that works on windows 10.
    fourcc = cv2.VideoWriter_fourcc(*'H264')
    #Create the video maker.
    out = cv2.VideoWriter('result\result.mp4', fourcc, 30, (input_dim, input_dim), 1)
    #For each bounding box
    for i in range(len(images)):
        #Grab the box locations and size them up to be the correct size.
        b = boxes[ i  , : ] * input_dim
        img = images[i] * input_dim

        #Rebuild the image.
        source_img = Image.fromarray( img.astype( np.uint8 ) , 'RGB' )
        #Draw the bounding box
        draw = ImageDraw.Draw( source_img )
        draw.rectangle( b , outline="blue" )
        img = np.asarray(source_img)
        #add the frame to the video.
        out.write(img)
        loop.update(1)
    out.release()
    loop.close()

else:
    sys.exit()


import os
from src.embedder import Embedder
from src.assistant import Assistant
from src.constants import DEMO_COLLECTION_NAME

def index_documents():
    # read all text files in the documents folder

    for file_name in os.listdir("./documents"):
        with open(f"./documents/{file_name}", "r") as f:
            text = f.read()

        print(f"Indexing document: {file_name}")
        Embedder().embed_information(
            collection=DEMO_COLLECTION_NAME,
            text=text,
            name=file_name,
        )

def query_documents():
    while True:
        question = input("\n\nAsk a question, (Type 'exit' to exit).\n\nQuestion: ")
        if question.lower().strip() == "exit":
            break

        answer = Assistant().get_answer(question=question)
        print(f"Answer: {answer}")
        print("\n\n\n")

def main():
    print("\n\nWhat would you like to do?\n1. Index documents\n2. Query documents")
    choice = input("Enter your choice: ")
    if choice == "1":
        index_documents()
    elif choice == "2":
        query_documents()

if __name__ == "__main__":
    main()


'''dataSimulator.py: Simulates process variation data across 5 parameters'''

# Author: Luke Henderson
__version__ = '2.0'

import numpy as np
import pickle

import config as cfg
import debugTools as dt
import colors as cl

def genCornerRon(sigma):
    return \
    {'epox': -0.5*sigma,
     'tox': 0.5*sigma,
     'w': -5*sigma,
     'l': 5*sigma,
     'na': -10*sigma}

def genCornerVth(sigma):
    return \
    {'epox': 0.5*sigma,
     'tox': -0.5*sigma,
     'w': 0*sigma,
     'l': 0*sigma,
     'na': -10*sigma}

def genCornerCgate(sigma):
    return \
    {'epox': 0.5*sigma,
     'tox': -0.5*sigma,
     'w': 5*sigma,
     'l': 5*sigma,
     'na': 0*sigma}

def genGaussian(sigma, count=1):
    return np.random.normal(loc=0, scale=sigma, size=count)

def genGaussianSingle(sigma):
    return np.random.normal(loc=0, scale=sigma, size=1)[0]

def genWafer(trCount=1):
    epoxWaferOffset = genGaussianSingle(0.5)
    toxWaferOffset  = genGaussianSingle(0.5)
    geomWaferOffset = genGaussianSingle(5)
    wWaferOffset = geomWaferOffset + genGaussianSingle(0.2)
    lWaferOffset = geomWaferOffset + genGaussianSingle(0.2)
    naWaferOffset  = genGaussianSingle(10)
    ret = []
    for i in range(trCount):
        ret.append({'epox': epoxWaferOffset + genGaussianSingle(0.05),
                    'tox': toxWaferOffset + genGaussianSingle(0.05),
                    'w': wWaferOffset + genGaussianSingle(2),
                    'l': lWaferOffset + genGaussianSingle(2),
                    'na': naWaferOffset + genGaussianSingle(3)})
    return ret

#usage: ds.noVar.copy()
noVar = \
    {'epox': 0,
     'tox': 0,
     'w': 0,
     'l': 0,
     'na': 0}
procVar1s = \
    {'epox': 0.5,
     'tox': 0.5,
     'w': 5,
     'l': 5,
     'na': 10}

class WaferConsumer:
    '''Wafer Consumer class'''

    def __init__(self, path=None):
        '''Wafer Consumer\n
        Args:
            path [str]: path of wafer pickle file
        Notes:
            self.waferIter [list of int]: the iterator for used transistor for each wafer\n
            self.waferNum [int]: wafer currently being used for testing/consuming'''
        with open(path, 'rb') as f:
            self.waferArr = pickle.load(f)
        self.waferIter = [0]*len(self.waferArr)
        self.waferNum = 0

    def consume(self, num):
        '''Consume x number of wafers. \n
        Args:
            num [int]: how many wafers to consume
        Return:
            [list of dict (procVar type)]: subarray of X wafers deterministically given in order'''
        # cl.blue(f'consuming from wafer #{waferNum}, returning {num} trs')
        # cl.yellow(f'this wafers iter is currenly {self.waferIter[waferNum]}')
        ret = []
        for trNum in range(num):
            # try:
            ret.append(self.waferArr[self.waferNum][self.waferIter[self.waferNum]+trNum])
            # except:
            #     dt.info(self.waferNum, 'self.waferNum')
            #     dt.info(trNum, 'trNum')
            #     dt.info(self.waferIter[self.waferNum]+trNum, 'self.waferIter[self.waferNum]+trNum')
            #     exit()

        self.waferIter[self.waferNum] += num
        # cl.purple(f'this wafers iter increased   {self.waferIter[waferNum]}')
        return ret

class DummyWaferConsumer:
    '''Dummy Wafer Consumer class'''

    def __init__(self):
        '''Dummy Wafer Consumer'''

    def consume(self, num):
        '''Consume x number of wafers. \n
        Args:
            num [int]: how many wafers to consume
        Return:
            None'''
        return None


import argparse
import hashlib
import json
import multiprocessing
import os
from datetime import datetime
from time import time

import numpy as np
from sklearn import utils
from sklearn.model_selection import ParameterGrid, RepeatedStratifiedKFold

import mlp
from mlp.activation_functions import Identity, Sigmoid, Softmax
from mlp.layers import DenseLayer, GaussianNoise
from mlp.losses import BinaryCrossEntropy, CategoricalCrossEntropy, RMSE
from mlp.network import MLPRegressor, EarlyStopping

class ParamSet:
    def __init__(self, params):
        assert len(params) == 6, "Expected six parameters, got %d." % len(params)

        self.n_inputs = int(params[0])
        self.hidden_layer_size = int(params[1])
        self.output_layer_size = int(params[2])
        self.learning_rate = params[3]
        self.momentum = params[4]
        self.error_criterion = params[5]

class ResultSet:
    def __init__(self, run_id, clf, params, train_loss, train_scores, val_loss, val_scores):
        if isinstance(params['clf_type'], type):
            params['clf_type'] = params['clf_type'].__name__

        if isinstance(params['activation_func'], type):
            params['activation_func'] = params['activation_func'].__name__

        self.run_id = run_id
        self.clf = clf
        self.params = params
        self.train_loss = train_loss
        self.train_scores = train_scores
        self.val_loss = val_loss
        self.val_scores = val_scores

    def __copy__(self):
        return ResultSet(self.run_id, self.clf, self.params,
                         self.train_loss, self.train_scores, self.val_loss, self.val_scores)

    def to_json(self):
        masked_train_loss = np.ma.masked_invalid(self.train_loss)
        masked_train_scores = np.ma.masked_invalid(self.train_scores)
        masked_val_loss = np.ma.masked_invalid(self.val_loss)
        masked_val_scores = np.ma.masked_invalid(self.val_scores)

        train_loss_min = masked_train_loss.min().tolist()
        train_scores_max = masked_train_scores.max().tolist()
        val_loss_min = masked_val_loss.min().tolist()
        val_scores_max = masked_val_scores.max().tolist()

        return {
            'run_id': self.run_id,
            'params': self.params,
            'train_loss_min': train_loss_min,
            'train_scores_max': train_scores_max,
            'val_loss_min': val_loss_min,
            'val_scores_max': val_scores_max
        }

    def save(self, path, subdir=None):
        if not path.endswith('/'):
            path += '/'

        run_path = path + (self.run_id if not subdir else subdir) + '/'
        os.makedirs(run_path, exist_ok=True)

        with open(run_path + 'statistics.json', 'w') as file:
            json.dump(self.to_json(), file)

        np.save(run_path + 'train_loss', self.train_loss)
        np.save(run_path + 'train_scores', self.train_scores)
        np.save(run_path + 'val_loss', self.val_loss)
        np.save(run_path + 'val_scores', self.val_scores)
        self.clf.save(run_path + 'model.json')
        self.clf.save_weights(run_path + 'weights')

def load_cfg(cfg_file):
    with open(cfg_file, 'r') as f:
        grid_search_cfg = json.load(f)

        if 'clf_type' in grid_search_cfg:
            for i, clf_type in enumerate(grid_search_cfg['clf_type']):
                class_ = getattr(mlp.network, clf_type)

                grid_search_cfg['clf_type'][i] = class_

        if 'activation_func' in grid_search_cfg:
            for i, activation_type in enumerate(grid_search_cfg['activation_func']):
                class_ = getattr(mlp.activation_functions, activation_type)

                grid_search_cfg['activation_func'][i] = class_

        print('Loaded configuration file: %s.\n' % cfg_file)

    return grid_search_cfg

def validate_datasets(data_dir, config):
    print('Scanning \'%s\' directory for data sets...' % data_dir)

    try:
        _, datasets, _ = next(os.walk(data_dir))
        datasets = sorted(datasets)
        print('Found the following data sets: ' + ', '.join(datasets))

        for dataset in config['dataset']:
            assert dataset in datasets, "The dataset '%s' was found in the configuration files, but it was " \
                                        "not found in the data directory '%s'." % (dataset, data_dir)
    except StopIteration:
        print('The data directory \'%s\' was not found.' % data_dir)
        return False

    return True

def get_model(shape, output_layer_activation_func, loss_func, param_set):
    input_shape, hidden_layer_size, output_layer_size = shape

    return param_set['clf_type']([
        GaussianNoise(input_shape, n_inputs=input_shape, std=param_set['gaussian_noise']),
        DenseLayer(hidden_layer_size, activation_func=param_set['activation_func']()),
        DenseLayer(output_layer_size, activation_func=output_layer_activation_func)
    ], learning_rate=param_set['learning_rate'], momentum=param_set['momentum'], loss_func=loss_func)

def pad(a, length, fill_value=float('-inf')):
    if len(a) == length:
        return a

    temp = np.zeros(length)
    temp.fill(fill_value)
    temp[:len(a)] = a

    return temp

def evaluation_step(clf, batch_size, shuffle_batches, X_train, y_train, val_set=0, n_epochs=10000):
    es = EarlyStopping(patience=1000, criterion=0.99)

    train_loss, train_score, val_loss, val_score = clf.fit(X_train, y_train, val_set=val_set,
                                                           n_epochs=n_epochs, batch_size=batch_size,
                                                           shuffle_batches=shuffle_batches, early_stopping=es,
                                                           log_verbosity=0)

    train_loss = pad(train_loss, n_epochs)
    train_score = pad(train_score, n_epochs)
    val_loss = pad(val_loss, n_epochs)
    val_score = pad(val_score, n_epochs)
    score = clf.score(*val_set) if val_set != 0 else clf.score(X_train, y_train)

    return score, train_loss, train_score, val_loss, val_score

def run_grid_search(args):
    np.random.seed(args.random_seed)

    data_dir = args.data_dir
    results_dir = args.results_dir
    n_trials = args.n_trials
    n_splits = args.n_splits
    n_jobs = args.n_jobs if args.n_jobs > 0 else len(os.sched_getaffinity(0))

    grid_search_cfg = load_cfg(args.config)

    if not validate_datasets(data_dir, grid_search_cfg):
        exit(1)

    param_grid = ParameterGrid(grid_search_cfg)
    n_param_sets = len(param_grid)
    total_steps = n_param_sets * n_trials

    start = datetime.now()
    print('Grid Search started at: %s' % start)
    print('Grid Search running with %d job(s).' % n_jobs)

    for i, param_set in enumerate(param_grid):
        md5 = hashlib.md5(str(time()).encode('utf-8'))
        run_id = md5.hexdigest()

        dataset = param_set['dataset']
        X = np.genfromtxt(data_dir + dataset + '/in.txt')
        y = np.genfromtxt(data_dir + dataset + '/teach.txt')
        raw_params = np.genfromtxt(data_dir + dataset + '/params.txt')

        if len(y.shape) == 1:
            y = y.reshape(-1, 1)
            y_multiclass = y
        else:
            y_multiclass = y.argmax(axis=1)
            y_multiclass = y_multiclass.reshape(-1, 1)

        utils.shuffle(X, y, y_multiclass)

        hidden_layer_size = ParamSet(raw_params).hidden_layer_size
        output_layer_size = y.shape[1]
        shape = (X.shape[1], hidden_layer_size, output_layer_size)

        if param_set['clf_type'] == MLPRegressor:
            output_layer_activation_func = Identity()
            loss_func = RMSE()
        else:
            if output_layer_size == 1:
                output_layer_activation_func = Sigmoid()
                loss_func = BinaryCrossEntropy()
            else:
                output_layer_activation_func = Softmax()
                loss_func = CategoricalCrossEntropy()

        batches = []
        clf = None

        if param_set['dataset'] == 'iris':
            cv = RepeatedStratifiedKFold(n_splits=n_splits, n_repeats=n_trials // n_splits)

            for train_index, val_index in cv.split(X, y_multiclass):
                X_train, X_val, y_train, y_val = X[train_index], X[val_index], y[train_index], y[val_index]

                clf = get_model(shape, output_layer_activation_func, loss_func, param_set)
                batches.append((clf, param_set['batch_size'], param_set['shuffle_batches'],
                                X_train, y_train, (X_val, y_val)))
        else:
            for n in range(n_trials):
                clf = get_model(shape, output_layer_activation_func, loss_func, param_set)
                X_train, y_train = utils.shuffle(X, y)
                batches.append((clf, param_set['batch_size'], param_set['shuffle_batches'],
                                X_train, y_train))

        with multiprocessing.Pool(n_jobs) as p:
            p_results = p.starmap(evaluation_step, batches)

        best_param_set_score = -2 ** 32 - 1
        best_param_set_clf = None
        train_loss_history = []
        train_scores = []
        val_loss_history = []
        val_scores = []

        for batch_i, (score, train_loss, train_score, val_loss, val_score) in enumerate(p_results):
            if score > best_param_set_score and score != float('nan') and abs(score) != float('inf'):
                best_param_set_score = score
                best_param_set_clf = batches[batch_i][0]

            train_loss_history.append(train_loss)
            train_scores.append(train_score)
            val_loss_history.append(val_loss)
            val_scores.append(val_score)

        results = ResultSet(run_id, best_param_set_clf if best_param_set_clf else clf, param_set,
                            train_loss_history, train_scores, val_loss_history, val_scores)

        subdir = '/'.join(['%s=%s' % (key, str(value)) for key, value in zip(param_set.keys(), param_set.values())])
        results.save(results_dir, subdir)

        curr_step = (i + 1) * n_trials
        print('\rProgress: %d/%d (%05.2f%%) - Elapsed time: %s'
              % (curr_step, total_steps, 100 * curr_step / total_steps, datetime.now() - start),
              end='')

    print('\nDone.')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Run grid search on various MLP configurations and datasets.')
    parser.add_argument('config', type=str, help='The configuration file to use for this experiment. '
                                                 'See `generate_grid_search_cfgs.py`,')
    parser.add_argument('--data-dir', type=str, default='data/', help='Where the data sets are located.')
    parser.add_argument('--results-dir', type=str, default='results/', help='Where to save the results to.')
    parser.add_argument('--n-trials', type=int, default=20, help='How many times to repeat each configuration.')
    parser.add_argument('--n-splits', type=int, default=5, help='How many folds to use for cross validation.')
    parser.add_argument('--n-jobs', type=int, default=1, help='How many processors to use.')
    parser.add_argument('--random-seed', type=int, default=42, help='The seed for the random number generator.')

    args = parser.parse_args()

    run_grid_search(args)


import pandas as pd
import networkx as nx
from pyvis import network as net
from torch_geometric.utils import to_networkx, degree
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
import plotly.express as px
from rdkit import Chem
from rdkit.Chem import Descriptors
import mols2grid
import py3Dmol

def generate_nx_graph(data):
    # Create a directed graph from the data object, then convert it to undirected.
    G = to_networkx(data)  # Do not use the parameter to_undriected. It does not work properly.
    G_undirected = G.to_undirected()
    return G, G_undirected

def generate_khop_subgraph(msi, G, gid, k):
    # Get the neighbors of the drug amphetamine (id=DB00182, name="Amphetamine", gid=17713)
    node_label_dict = {}
    node_type_dict = {}
    node_size_dict = {}
    subgraph_nodes = nx.single_source_shortest_path_length(G, gid, cutoff=k)
    print(f"Total subgraph nodes: {len(subgraph_nodes)}")

    # Get the maximum gids of each type of node.
    max_prot_gid = max(msi.mappings["prot_id_gid_map"].values())
    max_drug_gid = max(msi.mappings["drug_id_gid_map"].values())
    max_dz_gid = max(msi.mappings["dz_id_gid_map"].values())
    max_func_gid = max(msi.mappings["func_id_gid_map"].values())

    # Get the id_map, name_map, type, and size for each node in the subgraph.
    for node in subgraph_nodes:
        if node <= max_prot_gid:
            id_mapping = msi.mappings["prot_id_gid_map"].copy()
            name_mapping = msi.mappings["prot_id_name_map"].copy()
            node_type = "protein"
            node_size = "10"
        elif node > max_prot_gid and node <= max_drug_gid:
            id_mapping =  msi.mappings["drug_id_gid_map"].copy()
            name_mapping = msi.mappings["drug_id_name_map"].copy()
            node_type = "drug"
            node_size = "25"
        elif node > max_drug_gid and node <= max_dz_gid:
            id_mapping = msi.mappings["dz_id_gid_map"].copy()
            name_mapping = msi.mappings["dz_id_name_map"].copy()
            node_type = "disease"
            node_size = "35"
        else:
            id_mapping = msi.mappings["func_id_gid_map"].copy()
            name_mapping = msi.mappings["func_id_name_map"].copy()
            node_type = "function"
            node_size = "20"

        # Assign the node a label, type, and size.
        for id, gid in id_mapping.items():
            if node == gid:
                node_label_dict[gid] = name_mapping[id]
                node_type_dict[gid] = node_type
                node_size_dict[gid] = node_size

    # Generate the networkx subraph and assign node attributes.
    subG = G.subgraph(list(subgraph_nodes.keys()))
    for i, node in enumerate(subG.nodes):
        subG.nodes[node]["label"] = node_label_dict[node]
        subG.nodes[node]["group"] = node_type_dict[node]
        subG.nodes[node]["size"] = node_size_dict[node]

    return subG

def generate_pyvis_graph(G):
    pyvis_graph = net.Network(notebook=True)
    pyvis_graph.from_nx(G)
    return pyvis_graph

def draw_molecule(mol_smiles):

    mol = Chem.MolFromSmiles(mol_smiles)
    mol = Chem.MolToMolBlock(mol, confId=-1)
    view = py3Dmol.view(width=400,height=400)
    view.removeAllModels()

    view.addModel(mol,'sdf')
    view.setStyle({'stick':{}})
    view.setBackgroundColor('0xeeeeee')
    view.zoomTo()

    return view.show()

def interactive_mol_grid(
        mol_dict,
        n_cols=3,
        size=(210,130),
        gap=0,
        selection=True,
        border="2px ridge black",
        fontfamily="Times New Roman"):

    """ Create interactive molecule grid using mol2grid library.

    Parameters
    ----------
    mol_dict : dict
        Dictionary requiring 'name' key and list of molecule names as value and
        'smiles' key with list of smiles string as value.
    n_cols : int
        Set the number of columns for the viewer (default = 3).
    size : tuple
        Set the size of each molecule (default = (210,13))
    gap : int
        Set the spacing between the molecules in the grid (default=0).
    selection : bool
        Turn the selection box on or off (default = True).
    border : str
        Set the css border style (default = 2px ridge black).
    fontfamily : str
        Set the css-style font (default = Times New Roman).

    Returns
    -------
    viewer : IPython.core.display.HTML
        Interactive HTML object displaying molecules and accompanying information in
        a grid.
    df : DataFrame
        Dataframe with chemical information for each molecule.
    """

    # Load the dictionary into a dataframe.
    df = pd.DataFrame.from_dict(mol_dict)

    # Create mol objects from smiles strings.
    df["mol"] = df["SMILES"].apply(Chem.MolFromSmiles)

    # Compute extra molecular properties.
    df["MolWt"] = df["mol"].apply(Descriptors.ExactMolWt)
    df["QED"] = df["mol"].apply(Descriptors.qed)
    df["LogP"] = df["mol"].apply(Descriptors.MolLogP)
    df["NumHDonors"] = df["mol"].apply(Descriptors.NumHDonors)
    df["NumHAcceptors"] = df["mol"].apply(Descriptors.NumHAcceptors)

    # Reformat the dataframe.
    df.drop(columns=["mol"], inplace=True)

    # Create molecule viewer.
    viewer = mols2grid.display(
            df,
            n_cols=3,
            subset=["name", "img"],  # set the fields  displayed on the grid.
            tooltip=["name", "MolWt", "QED"], # set the fields displayed on mouse hover.
            template="pages",
            size=size, # size of each image.
            gap=gap, # spacing between molecules.
            selection=selection, # toggle selection box.
            border=border, # css border style.
            fontfamily=fontfamily) # css font style.

    return df, viewer

def visualize_tsne_embeddings(model, data, title, perplexity=30.0,
                              labeled=False, labels=[]):
    """Visualizes node embeddings in 2D space with t-SNE.

    Parameters
    ----------
    model : trained or untrained model
        A trained or untrained model.
    data : Data object
        A data object
    title : str
        Title of the plot
    perplexity : float
        t-SNE hyperparameter for perplexity
        """
    model.eval()
    x = data.x
    z = model.encode(x, data.edge_index)
    ax1, ax2 = zip(*TSNE(n_components=2, learning_rate='auto', perplexity=perplexity,
                       init='random').fit_transform(z.detach().cpu().numpy()))

    fig = px.scatter(x=ax1, y=ax2, color=['r']*17660 + ['g']*1661 + ['b']*840 + ['p']*9798,
                   title=title)

    if labeled:
        for i in labels:
            fig.add_annotation(x=ax1[i], y=ax2[i],
                         text=str(i), showarrow=False)
    fig.show()

def visualize_pca_embeddings(model, data, title, labeled=False, labels=[]):
    """Visualizes node embeddings in 2D space with PCA (components=2).

    Parameters
    ----------
    model : trained or untrained model.
    data : Data object
        A data object.
    title : str
        Title of the plot.
        """

    model.eval()
    x = data.x
    z = model.encode(x, data.edge_index)
    pca = PCA(n_components=2)
    components = pca.fit_transform(z.detach().cpu().numpy())
    fig = px.scatter(components, x=0, y=1, color=['r']*17660 + ['g']*1661 + ['b']*840 + ['p']*9798,
                   title=title)
    if labeled:
        for i in labels:
            fig.add_annotation(x=components[:,0][i], y=components[:,1][i],
                         text=str(i), showarrow=False)
    fig.show()