from app import app
from flask import render_template, request
import pickle
from sklearn.neighbors import NearestNeighbors

@app.route("/")
def index():
    with open(r'app/static/pickle/df1.pkl', "rb") as input_file:
        dataFrame_1=pickle.load(input_file)
    car_name=dataFrame_1['car_name'].values.tolist()
    return render_template('index.html',car_name=car_name)

@app.route("/content-based-search",methods = ['POST'])
def content_based_search():
    if request.method == 'POST':
      result = request.form
    #   print(result['keyword'])
      return recommend(result['keyword'])

@app.route("/item-based-search",methods = ['POST'])
def item_based_search():
    if request.method == 'POST':
      result = request.form
    #   print(result['keyword'])
      return recommend_knn(result['highway_mileage'],result['city_mileage'],result['price'],result['companyRatingvalue'],result['consumerRatingvalue'])

def recommend_knn(highway_mileage,city_mileage,price,companyRatingvalue,consumerRatingvalue):
    with open(r'app/static/pickle/csr_sample.pkl', "rb") as input_file:
        csr_sample=pickle.load(input_file)
    input_file.close()
    with open(r'app/static/pickle/df1.pkl', "rb") as input_file:
        cars_data=pickle.load(input_file)
    input_file.close()
    cars_data.rename(columns={'name':'cname'},inplace=True)
    with open(r'app/static/pickle/df2.pkl', "rb") as input_file:
        df=pickle.load(input_file)
    input_file.close()

    knn = NearestNeighbors(metric='cosine', algorithm='brute', n_neighbors=5, n_jobs=-1)
    knn.fit(csr_sample)
    dataset_sort_des = df.sort_values(['rating','city_milege','highway_milege','msrp','consumer_rating'], ascending=[True,True,True,True,True])
    # filter1 = dataset_sort_des.loc[((dataset_sort_des['rating'] == companyRatingvalue)  | (dataset_sort_des['consumer_rating'] == consumerRatingvalue) )  | ((dataset_sort_des['city_milege'] == city_mileage) | (dataset_sort_des['highway_milege'] == highway_mileage))  | (dataset_sort_des['msrp'] == price) ].row_num
    filter1 = dataset_sort_des.loc[ (dataset_sort_des['consumer_rating'] == float(consumerRatingvalue))  | (dataset_sort_des['rating'] == float(companyRatingvalue) ) | ( ( dataset_sort_des['msrp'] == float(price)) ) |( (dataset_sort_des['city_milege'] == float(city_mileage)) | (dataset_sort_des['highway_milege'] == float(highway_mileage))) ].row_num
    filter1 = filter1.tolist()

    #print(len(filter1) )

    distances1=[]
    indices1=[]

    for i in filter1:

        distances , indices = knn.kneighbors(csr_sample[i],n_neighbors=5)
        indices = indices.flatten()
        indices= indices[1:]
        indices1.extend(indices)

    df1=df[df['row_num'].isin(indices1)]
    recom_list=df1['ID'].values.tolist()[1:11]
    result={}
    if len(recom_list)>0:
        list_of_cars=[]
        for val in recom_list:
            df2=cars_data.loc[cars_data['ID']==val]
            # print(df2)
            temp={}
            temp['car name']=df2.cname.values[0]
            temp['brand name']=df2.brand_name.values[0]
            temp['engine']=df2.engine_cc.values[0]
            temp['submodel']=df2.submodel.values[0]
            temp['msrp']=df2.msrp.values[0]
            temp['photo']=df2.photo.values[0]
            temp['hm']=df2.highway_milege.values[0]
            temp['cm']=df2.city_milege.values[0]
            temp['conrat']=df2.consumer_rating.values[0]
            temp['comrat']=df2.rating.values[0]

            list_of_cars.append(temp)
        result['data']=list_of_cars
        result['Status']=200
        result['msg']="successfull"
    else:
        result['data']=[]
        result['Status']=404
        result['msg']="Cars not Found!!!"
    return result

def recommend(car):
    with open(r'app/static/pickle/df1.pkl', "rb") as input_file:
        cars_data=pickle.load(input_file)
    input_file.close()

    cars_data.rename(columns={'name':'cname'},inplace=True)
    # print(cars_data.columns)

    with open(r'app/static/pickle/similarity.pkl', "rb") as input_file:
        similarity=pickle.load(input_file)
    input_file.close()
    car_record=cars_data[cars_data['car_name'] == car]
    result={}
    if len(car_record)>0:
        car_index = car_record.index[0]
        distances = similarity[car_index]
        cars_list = sorted(list(enumerate(distances)),reverse=True,key = lambda x: x[1])[1:7]

        list_of_cars=[]
        for i in cars_list:
            # print(cars_data.iloc[i[0]])
            temp={}
            temp['car name']=cars_data.iloc[i[0]].cname
            temp['brand name']=cars_data.iloc[i[0]].brand_name
            temp['engine']=cars_data.iloc[i[0]].engine_cc
            temp['submodel']=cars_data.iloc[i[0]].submodel
            temp['msrp']=cars_data.iloc[i[0]].msrp
            temp['photo']=cars_data.iloc[i[0]].photo

            list_of_cars.append(temp)
        result['data']=list_of_cars
        result['Status']=200
        result['msg']="successfull"
    else:
        result['data']=[]
        result['Status']=404
        result['msg']="Cars not Found!!!"
    return result


from django.conf.urls import url
from . import views

urlpatterns = [
    url(
        '^(?P<chart_id>\d+)/'
        '(?:(?P<song_slug>[a-z0-9-_]+)/)?'
        '(?:(?P<key_tonic>[A-Z#♭]+)/)?$',
        views.chart,
        name='chart'
    ),
    url(r'^new/', views.new_chart, name='new_chart'),
    url(
        r'^edit/'
        '(?P<chart_id>\d+)/'
        '(?:(?P<song_slug>[a-z0-9-_]+)/)?$',
        views.chart,
        {'edit': True},
        name='edit_chart',
    ),
    url(
        r'^delete/'
        '(?P<song_slug>[a-z0-9-_]+)/'
        '(?P<chart_id>\d+)/$',
        views.delete_chart,
        name='delete_chart',
    ),
    url(r'^how-to-read/$', views.how_to_read, name='how_to_read'),
    url(r'^chord-symbols/$', views.chord_symbols, name='chord_symbols')
]


import os
import imutils
import numpy as np
from imutils import paths
from matplotlib import pyplot as plt

from source.face_recognition import FaceRecognition

def extract_embeddings(classes_dir: str = "", model_path: str = "", default_classname: str=None,
                       one_face_limit=True, save_dataset=True):
    image_paths = list(paths.list_images(classes_dir))

    recognition = FaceRecognition()

    X = []
    y = []
    for k, image_path in enumerate(image_paths):
        print(f"[INFO] processing image {image_path} --- {k + 1}/{len(image_paths)}")

        label = image_path.split(os.path.sep)[-2] if not default_classname else default_classname
        image_array = recognition.load_image(image_path)
        if image_array is not None:
            height, width = image_array.shape[:2]
            if width > 600:
                image_array = imutils.resize(image_array, width=600)
            faces = recognition.detect_faces(image_array)

            if faces:
                if one_face_limit and len(faces) > 1:
                    print(f'ERROR - {image_path} - faces - {len(faces)}')
                    continue
                    # plt.imshow(face_array)
                    # plt.title(image_path.split(os.path.sep)[-1])
                    # plt.show()

                face_array = faces[0]['array']
                face_keypoints = faces[0]['keypoints']
                face_array = recognition.align_face(image_array, face_keypoints)

                face_array = recognition.preprocess_face(face_array, target_size=(160, 160))
                embedding = recognition.get_embeddings(face_array)
                X.append(embedding)
                y.append(label)
            else:
                print(f'[WARNING] Face is not found: {image_path}')

    if save_dataset:
        np.savez_compressed(f"{model_path}/embeddings-dataset.npz", np.asarray(X), np.asarray(y))

    return np.asarray(X), np.asarray(y)

if __name__ == '__main__':
    base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    dataset_path = os.path.join(base_path, "dataset")
    model_path = os.path.join(base_path, "models")

    extract_embeddings(dataset_path, model_path)


from app_store_scraper import AppStore
import nltk
from nltk.corpus import stopwords
from pprint import pprint
import re

'''
Setup
  - Install "pip", the package installer for python. (https://pip.pypa.io/en/stable/installation/)
  - Install "NLTK", a platform for working with human language data. (https://www.nltk.org/install.html). We use this to filter out common English words.
  - Install "app_store_scaper". Instructions here: (https://pypi.org/project/app-store-scraper/)

  - When calling the "generate_word_count_dict" function in the code below below: modify the app_name, country, and the number_of_reviews you want to analyze.

  - To run, in your terminal, navigate to the directory where this file lives and type:

    python3 appStore_wordFrequency_scraper.py
 '''

class WordCount:
	def __init__(self, word, count):
		self.word = word
		self.count = count

	def __str__(self):
		return "%s: %d" % (self.word, self.count)

	def __repr__(self):
		return str(self)

# generic func to fetch app store reviews and generate word count.
# note: uses the NLTK data to filter out common "stopwords" (ie: "a", "the", etc.)
def generate_word_count_dict(app_name, country_code, number_of_reviews):
	# fetches app metadata
	app = AppStore(country=country_code, app_name=app_name)
	app.review(how_many=number_of_reviews) #

	# create an object to store and associate words with their respective frequency.
	word_count_dict = {}

	# Get list of English stop words to filter out (ie: "a", "the", etc.) and convert them all to lowercase
	take_out = stopwords.words('english')
	take_out = [word.lower() for word in take_out]

	# iterate through each review
	for review_metadata in app.reviews:
		raw_review = review_metadata["review"]

		# break a single review into individual words
		review_words = raw_review.split()

		for word in review_words:

			# remove non-alphanumeric characters from each word and lowercase everything
			word_filtered = re.sub(r'\W+', '', word).lower()

			# skip words that are common
			if word_filtered not in take_out:
				if word_filtered in word_count_dict:
					word_count_dict[word_filtered] += 1
				else:
					word_count_dict[word_filtered] = 1

	return word_count_dict

# --------PROGRAM EXECUTION BEGINS HERE------------
nltk.download('stopwords')
word_count_dict = generate_word_count_dict("myfitnesspal", "us", 100)

# Uncomment to visualize the generated word count dictionary
# pprint(word_count_dict)

word_count_list = []

# transform {word : count} pair into WordCount object and add to list for sorting.
for key in word_count_dict:
	wordObject = WordCount(key, word_count_dict[key])
	word_count_list.append(wordObject)

# sort our words by frequency they were used
word_count_list.sort(key=lambda x: x.count)

# output the results
print(*word_count_list,sep='\n')


# ！
# encoding: utf-8
'''
@author: String
@softwore: pycharm
@file:
@desc:
'''

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time

uer = []
# 定义全局变量url、headers、movie_links、movie_names = []
url = "https://movie.douban.com/top250"
headers = {'user-agent': 'my-app/0.0.1'}
movie_links = []
movie_names = []
all_movie = []

# 在获取每个电影信息的时候，查提取每个电影的连接的方法
def get_list(soup_list):
    list = []
    for ele in soup_list:
        list.append(ele.text)
    return list

# 访问主页面，并且完成页面跳转
def get_page(page_url):
    page = 0
    max_page = 225
    while page <= max_page:
        time.sleep(5)
        url = page_url+"?start="+page.__str__()+"&filter="
        response = requests.get(url=url, headers=headers).text
        soup = BeautifulSoup(response, 'html.parser')
        get_link(soup)
        page += 25

# 获取每页的所有电影链接
def get_link(soup):
    for ele in soup.findAll(class_="hd"):
        movie_links.append(ele.find('a', href=True).attrs['href'])
        movie_names.append(ele.find(class_="title").text)
        print(movie_links)
        # exit()

# 根据电影链接，获取个电影的信息
def get_movieinfo(movie_link):
    time.sleep(5)
    resbons = requests.get(url=movie_link, headers=headers).text
    soup = BeautifulSoup(resbons, 'html.parser')
    movie_info = {}
    movie_info['movie_title'] = soup.find(property="v:itemreviewed").string
    movie_info['movie_director'] = soup.find(rel="v:directedBy").text
    movie_info['movie_writer'] = soup.find_all(class_="attrs")[1].text if len(soup.find_all(class_="attrs"))>1 else ""
    # print(movie_info['movie_writer'])
    # exit()
    movie_info['movie_actor'] = get_list(soup.find_all(rel="v:starring"))
    movie_info['movie_genre'] = get_list(soup.findAll(property="v:genre"))
    movie_info['movie_country'] = soup.find(text="制片国家/地区:").next_element
    movie_info['movie_langage'] = soup.find(text="语言:").next_element
    movie_info['movie_ReleaseDate'] = soup.find(property="v:initialReleaseDate").text
    movie_info['movie_runtime'] = soup.find(property="v:runtime").text
    movie_info['movie_average'] = soup.find(property="v:average").text
    movie_info['movie_RatingPeople'] = soup.find(property="v:votes").text
    movie_info['movie_linke'] = movie_link
    for key in movie_info:
        print(key, ":", movie_info.get(key))

    # 把一个电影的所有信息装入一个容器里
    all_movie.append(movie_info)

# for循环找出每一条连接，并根据连接获取每个电影的详细信息
def get_onelink(movie_links):
    for n,l in zip(movie_names,movie_links):
        print( n+"："+l )
        get_movieinfo(l)
        print("-------------------------------------------------------")

# 运行作为一个入口文件
if __name__ =='__main__':
    # 测试代码
    # get_movieinfo('https://movie.douban.com/subject/26430107/')
    # exit()

    # 调用获取页面连接方法
    get_page(url)
    # 调用获取页面信息方法
    get_onelink(movie_links)

    # 将所有电影数据存入表格中
    data = pd.DataFrame(all_movie)
    data.to_excel("Top250豆瓣高分电影.xlsx")


import json
import logging
import sys
from multiprocessing.dummy import Pool as ThreadPool

import requests

# 日志配置
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
logger = logging.getLogger()
logger.setLevel(level=logging.INFO)

def main_handler(event, context):
    logger.info("start main handler")
    request_id = context.get('request_id')

    if "body" not in event.keys():
        return {"code": 410, "errorMsg": "event is not come from api gateway"}
    callback_url = ''
    try:
        req_body = event['body']
        req_param = json.loads(req_body)
        logger.info("输入参数: " + json.dumps(req_param))
        videos = req_param['Data']['Videos']
        audio = req_param['Data']['Audio']
        callback_url = req_param['Data']['CallbackURL']
        vod_region = req_param['Data']['Output']['Vod']['Region']
        sub_app_id = req_param['Data']['Output']['Vod']['SubAppId']
        class_id = req_param['Data']['Output']['Vod']['ClassId']

        param_list = []
        for video in videos:
            json_str = json.dumps(video)
            print(json_str)
            param_list.append(json_str)

        pool = ThreadPool(6)
        results = pool.map(composition, param_list)
        print(results)
        pool.close()
        pool.join()

        urls = []
        logger.info("开始拼接视频")
        for result in results:
            print(result)
            if 'Failure' in result:
                return result
            url = result['Data']['OutputUrl']
            urls.append(url)
        callback_body = splice(urls, audio, '', vod_region, sub_app_id, class_id)
        callback_body['RequestId'] = request_id
        callback(callback_url, callback_body)
    except Exception as err:
        callback_body = {
            "Result": "Failure",
            "ErrorCode": "InvalidParameter",
            "ErrorMessage": "Invalid parameter: " + str(err),
            "RequestId": request_id
        }
        callback(callback_url, callback_body)
        return json.dumps(callback_body)
    return callback_body

def splice(urls, audio, callback_url, vod_region, sub_app_id, class_id):
    splice_data = {
        "Action": "SpliceVideo",
        "Data": {
            "Input": {
                "URLs": urls,
                "Audio": audio,
                "Transitions": "None",
                "CallbackURL": callback_url
            },
            "Output": {
                "Vod": {
                    "Region": vod_region,
                    "SubAppId": sub_app_id,
                    "ClassId": class_id
                }
            }
        }
    }
    print(splice_data)

    response = requests.post(
        'https://service-bis1czil-1307427535.cd.apigw.tencentcs.com/release/shifang-ffmpeg-splice-sync',
        data=json.dumps(splice_data))
    print(response.content)
    return json.loads(response.text.encode('utf8'))

def composition(param_json):
    response = requests.post(
        'https://service-ngvp1ppd-1307427535.cd.apigw.tencentcs.com/release/shifang-ffmpeg-composition-sync',
        data=param_json)
    print(response.content)
    return json.loads(response.text.encode('utf8'))

# 回调逻辑。
def callback(url, data):
    if not url:
        logger.info("Callback url is empty, no need to callback.")
        return

    response = requests.post(url, json=data)
    logger.info("Callback response:", response.text.encode('utf8'))


from math import atan2
from collections import defaultdict

with open('input', 'r') as f:
    the_final_frontier = f.read().splitlines()

height = len(the_final_frontier)
width = len(the_final_frontier[0])

for i in range(len(the_final_frontier)):
    the_final_frontier[i] = [j for j in the_final_frontier[i]]

def get_angle(p1, p2):
    dx = p2[0] - p1[0]
    dy = p2[1] - p1[1]
    angle = atan2(dy, dx)
    return angle

asteroids = []

for y, r in enumerate(the_final_frontier):
    for x, value in enumerate(r):
        if value == '#':
            asteroids.append((x,y))

# logic behind the program
# from every single asteroid to all the other asteroids, calculate the angles
# the number of visible asteroids will simply be equal to the number of
# unique angles

angles = defaultdict(set)

for i in asteroids:
    for j in [k for k in asteroids if k!=i]:
        angles.setdefault(i,set()).add(get_angle(i,j))

asteroid = None
max_vis = 0

for ast, vis in angles.items():
    if len(vis)>max_vis:
        asteroid = ast
        max_vis = len(vis)

print(asteroid)
print(max_vis)


from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, \
    comon_parameters, main
from pymodaq.utils.parameter import Parameter
from pymodaq.utils.data import DataFromPlugins, DataToExport
import numpy as np
from pathlib import Path
import serial

class PhotoinoController:
    """Controller class for interacting with photoino."""

    available_ports = \
        [str(path) for path in list(Path('/dev/').glob('ttyACM0'))]

    def open(self, port, baudrate):
        if port == '':
            port = self.available_ports[0]
        if baudrate == 0:
            baudrate = 115200

        if hasattr(self, 'ser') and self.ser is not None:
            self.ser.close()

        try:
            self.ser = serial.Serial(port=port, baudrate=baudrate, timeout=1)
        except:
            self.ser = None
            raise ValueError("couldn't open port '%s'" % port)

    def close(self):
        if self.ser is not None:
            self.stop()
            self.ser.close()
            self.ser = None

    def start(self):
        self.ser.write('start\n'.encode())

    def stop(self):
        self.ser.write('stop\n'.encode())

    def receive_number(self):
        while True: # skip leading line breaks
            c = self.ser.read(1)
            if c != b'\n' and c != b'\r':
                break
        result = 0
        while c != b'\n' and c != b'\r':
            result = result * 10 + int(c)
            c = self.ser.read(1)
        n = self.ser.in_waiting # skip trailing stuff
        if n > 0:
            self.ser.read(n)
        return result

    @property
    def count_rate(self):
        self.ser.write(str.encode('rate?\n'))
        return self.receive_number()

    @property
    def trigger_level(self):
        self.ser.write(str.encode('level?\n'))
        return self.receive_number()

    @trigger_level.setter
    def trigger_level(self, value):
        self.ser.write(str.encode('level %f\n' % value))

    @property
    def time_base(self):
        self.ser.write(str.encode('timebase?\n'))
        return self.receive_number()

    @time_base.setter
    def time_base(self, value):
        self.ser.write(str.encode('timebase %f\n' % value))

class DAQ_0DViewer_photoino(DAQ_Viewer_base):
    """PyMoDAQ plugin for controlling photoino single-photon
       counting module"""

    controller_type = PhotoinoController
    serial_ports = PhotoinoController.available_ports

    params = comon_parameters+[
        {'title': 'Serial port:', 'name': 'serial_port', 'type': 'str',
         'limits': serial_ports },
        {'title': 'Baud rate:', 'name': 'baud_rate', 'type': 'int', 'min': 0},
        {'title': 'Time base:', 'name': 'time_base', 'type': 'float',
         'min': 0.1, 'max': 1e5},
        {'title': 'Trigger level:', 'name': 'trigger_level', 'type': 'float',
         'min': -5.0, 'max': 5.0},
    ]

    def ini_attributes(self):
        self.controller: PhotoinoDriver = None

    def ini_detector(self, controller=None):
        """Detector communication initialization

        Parameters
        ----------
        controller: (object)
            custom object of a PyMoDAQ plugin (Slave case). None if only one
            actuator/detector by controller (Master case)

        Returns
        -------
        info: str
        initialized: bool
            False if initialization failed otherwise True
        """

        import pdb
        pdb.set_trace()
        self.ini_detector_init(old_controller=controller,
                               new_controller=self.controller_type())
        self.controller.open(self.settings['serial_port'],
                             self.settings['baud_rate'])

        self.init_params()

        info = "photoino initialised"
        return info, True

    def init_params(self):
        self.controller.time_base = self.settings['time_base']
        self.controller.trigger_level = self.settings['trigger_level']

    def close(self):
        self.controller.close()

    def commit_settings(self, param: Parameter):
        """Apply the consequences of a change of value in the detector settings

        Parameters
        ----------
        param: Parameter
            A given parameter (within detector_settings) whose value has been
            changed by the user
        """
        if param.name() == "time_base":
            self.controller.time_base = self.settings.child('time_base').value()
        elif param.name() == "trigger_level":
            self.controller.trigger_level = \
                self.settings.child('trigger_level').value()

    def grab_data(self, Naverage=1, **kwargs):
        """Start a grab from the detector

        Parameters
        ----------
        Naverage: int
            Number of hardware averaging (if hardware averaging is possible,
            self.hardware_averaging should be set to
            True in class preamble and you should code this implementation)
        kwargs: dict
            others optionals arguments
        """

        data = [np.array([self.controller.count_rate])]
        data_to_emit = DataFromPlugins(name='Photon counter', data=data,
                                       dim='Data0D', labels=['Counts'],)
        self.data_grabed_signal.emit([data_to_emit])

    def stop(self):
        self.controller.stop()
        return ''

if __name__ == '__main__':
    main(__file__)


import logging
import platform
import sys
import warnings
from pathlib import Path
from typing import Any
from typing import Iterator

import click
from click_default_group import DefaultGroup

from xsdata import __version__
from xsdata.codegen.transformer import SchemaTransformer
from xsdata.logger import logger
from xsdata.models.config import GeneratorConfig
from xsdata.models.config import GeneratorOutput
from xsdata.utils.click import LogFormatter
from xsdata.utils.click import LogHandler
from xsdata.utils.click import model_options
from xsdata.utils.downloader import Downloader
from xsdata.utils.hooks import load_entry_points

# Load cli plugins
load_entry_points("xsdata.plugins.cli")

# Setup xsdata logger to print records to stdout/stderr
handler = LogHandler()
handler.formatter = LogFormatter()

logger.handlers = [handler]
logger.propagate = False

# Attach the cli handler to the python warnings logger
py_warnings = logging.getLogger("py.warnings")
py_warnings.handlers = [handler]
py_warnings.propagate = False

# Log warnings as well
logging.captureWarnings(True)

@click.group(cls=DefaultGroup, default="generate", default_if_no_args=False)
@click.pass_context
@click.version_option(__version__)
def cli(ctx: click.Context, **kwargs: Any):
    """Xsdata command line interface."""
    logger.setLevel(logging.INFO)
    formatwarning_orig = warnings.formatwarning
    logger.info(
        "========= xsdata v%s / Python %s / Platform %s =========\n",
        __version__,
        platform.python_version(),
        sys.platform,
    )

    def format_warning(message: Any, category: Any, *args: Any) -> str:
        return (
            f"{category.__name__}: {message}" if category else message
        )  # pragma: no cover

    def format_warning_restore():
        warnings.formatwarning = formatwarning_orig

    warnings.formatwarning = format_warning  # type: ignore

    ctx.call_on_close(format_warning_restore)

@cli.command("init-config")
@click.argument("output", type=click.Path(), default=".xsdata.xml")
@click.option("-pp", "--print", is_flag=True, default=False, help="Print output")
def init_config(**kwargs: Any):
    """Create or update a configuration file."""
    file_path = Path(kwargs["output"])
    if file_path.exists():
        config = GeneratorConfig.read(file_path)
        logger.info("Updating configuration file %s", kwargs["output"])
    else:
        logger.info("Initializing configuration file %s", kwargs["output"])
        config = GeneratorConfig.create()

    if kwargs["print"]:
        config.write(sys.stdout, config)
    else:
        with file_path.open("w") as fp:
            config.write(fp, config)

    handler.emit_warnings()

@cli.command("download")
@click.argument("source", required=True)
@click.option(
    "-o",
    "--output",
    type=click.Path(),
    default="./",
    help="Output directory, default cwd",
)
def download(source: str, output: str):
    """Download a schema or a definition locally with all its dependencies."""
    downloader = Downloader(output=Path(output).resolve())
    downloader.wget(source)

    handler.emit_warnings()

@cli.command("generate")
@click.argument("source", required=True)
@click.option(
    "-r",
    "--recursive",
    is_flag=True,
    default=False,
    help="Search files recursively in the source directory",
)
@click.option("-c", "--config", default=".xsdata.xml", help="Project configuration")
@click.option("-pp", "--print", is_flag=True, default=False, help="Print output")
@click.option("--cache", is_flag=True, default=False, help="Cache sources loading")
@click.option("--debug", is_flag=True, default=False, help="Show debug messages")
@model_options(GeneratorOutput)
def generate(**kwargs: Any):
    """
    Generate code from xml schemas, webservice definitions and any xml or json
    document.

    The input source can be either a filepath, uri or a directory
    containing xml, json, xsd and wsdl files.
    """

    debug = kwargs.pop("debug")
    if debug:
        logger.setLevel(logging.DEBUG)

    source = kwargs.pop("source")
    stdout = kwargs.pop("print")
    cache = kwargs.pop("cache")
    recursive = kwargs.pop("recursive")
    config_file = Path(kwargs.pop("config")).resolve()

    params = {k.replace("__", "."): v for k, v in kwargs.items() if v is not None}
    config = GeneratorConfig.read(config_file)
    config.output.update(**params)

    transformer = SchemaTransformer(config=config, print=stdout)
    uris = sorted(resolve_source(source, recursive=recursive))
    transformer.process(uris, cache=cache)

    handler.emit_warnings()

def resolve_source(source: str, recursive: bool) -> Iterator[str]:
    if source.find("://") > -1 and not source.startswith("file://"):
        yield source
    else:
        path = Path(source).resolve()
        match = "**/*" if recursive else "*"
        if path.is_dir():
            for ext in ["wsdl", "xsd", "dtd", "xml", "json"]:
                yield from (x.as_uri() for x in path.glob(f"{match}.{ext}"))
        else:  # is file
            yield path.as_uri()

if __name__ == "__main__":  # pragma: no cover
    cli()


# -*- coding: utf-8 -*-
from __future__ import print_function
import numpy
import numpy.ma
import scipy
import scipy.misc
import scipy.ndimage
import scipy.signal
import scipy.cluster
#import matplotlib
#import matplotlib.mlab
#import pylab
#import pretty_logger
def get_Z_offset_guess(room):
	# Assume we are ~2.5 m away in Z
	DEFAULT_OFFSET = 2.5

	if room.units == 'm':
		offset = DEFAULT_OFFSET
	elif room.units == 'cm':
		offset = DEFAULT_OFFSET * 100
	elif room.units == 'in':
		offset = (DEFAULT_OFFSET * 100) / 2.54
	else:
		raise NotImplementedError('Unknown unit: {}'.format(room.units))

	if room.user_is == 'below':
		pass
	elif room.user_is == 'above':
		offset = -offset
	else:
		raise NotImplementedError('Unkonwn user position: {}'.format(room.user_is))

	return offset
def aoa(room, lights, Zf=2950, k_init_method= 'YS_brute', actual_location=None):
    centers = numpy.array(list(zip(*lights))[0])
    transmitters = numpy.array(list(zip(*lights))[1])
    centers = numpy.append(centers, Zf * numpy.ones((len(lights), 1)), axis=1)
    image_squared_distance = numpy.sum(numpy.square(centers), axis=1)
    pair_shape = (len(lights)-1, len(lights))
    transmitter_pair_squared_distance = numpy.zeros(pair_shape)
    pairwise_image_inner_products     = numpy.zeros(pair_shape)
    for i in range(len(lights)-1):
        for j in range(i+1, len(lights)):
            transmitter_pair_squared_distance[i][j] =\
            numpy.sum(numpy.square(transmitters[i] - transmitters[j]))
            pairwise_image_inner_products[i][j]=\
            numpy.dot(centers[i], centers[j])
    def least_squares_scaling_factors(k_vals):
        errs = []
        for i in range(len(lights)-1):
            for j in range(i+1, len(lights)):
                errs.append(
                        k_vals[i]**2 * image_squared_distance[i] +\
						      k_vals[j]**2 * image_squared_distance[j] -\
						      2*k_vals[i]*k_vals[j] * pairwise_image_inner_products[i][j] -\
						      transmitter_pair_squared_distance[i][j]
						      )
        return errs
    def scalar_scaling(k_vals):
        errs = numpy.array(least_squares_scaling_factors(k_vals))
        return numpy.sum(errs)
    def sol_guess_subset(index, var_cnt, sol_guess):
        sol_guess_sub = numpy.array([sol_guess[0,0]])
        for i in range(1,len(lights)):
            if sol_guess[i, 1] < 0:
                sol_guess_sub = numpy.append(sol_guess_sub, sol_guess[i, int((index%(2**var_cnt))/2**(var_cnt-1))])
                var_cnt -= 1
            else:
                sol_guess_sub = numpy.append(sol_guess_sub, sol_guess[i, 0])
        return sol_guess_sub
    def brute_force_k():
        number_of_iteration = 500
        k0_vals = numpy.linspace(-0.1, -0.01, number_of_iteration)
        err_history = []
        idx_history = []
        k_vals = numpy.array([])
        for j in range(number_of_iteration+1):
            if (j==number_of_iteration):
                min_error_history_idx = err_history.index(min(err_history))
                min_idx = idx_history[min_error_history_idx]
                k0_val = k0_vals[min_idx]
            else:
                k0_val = k0_vals[j]
            sol_guess = numpy.array([[k0_val, 0]])
            sol_found = 1
            multiple_sol = 0
            for i in range(1, len(lights)):
                sol = numpy.roots([image_squared_distance[i], -2*sol_guess[0,0]*pairwise_image_inner_products[0,i], (sol_guess[0,0]**2*image_squared_distance[0]-transmitter_pair_squared_distance[0, i])]);
                if numpy.isreal(sol)[0]:
                    if (sol[0] < 0) and (sol[1] < 0):
                        sol_guess = numpy.append(sol_guess, [sol], axis=0)
                        multiple_sol += 1
                    elif sol[0] < 0:
                        sol_guess = numpy.append(sol_guess, numpy.array([[sol[0], 0]]), axis=0)
                    elif sol[1] < 0:
                        sol_guess = numpy.append(sol_guess, numpy.array([[sol[1], 0]]), axis=0)
                    else:
                        sol_found = 0
                        break
                else:
                    sol_found = 0
                    break
            if sol_found:
                scaling_factors_error_combination = []
                for m in range(1, 2**multiple_sol+1):
                    sol_guess_combination = sol_guess_subset(m, multiple_sol, sol_guess)
                    scaling_factors_error_arr = least_squares_scaling_factors(sol_guess_combination)
                    scaling_factors_error = 0
                    for n in scaling_factors_error_arr:
                        scaling_factors_error += n**2
                    scaling_factors_error_combination.append(scaling_factors_error)
                k_vals = sol_guess_subset(numpy.argmin(scaling_factors_error_combination)+1, multiple_sol, sol_guess)
                err_history.append(min(scaling_factors_error_combination))
                idx_history.append(j)
        return k_vals

    if k_init_method == 'static':
        k_val_from_z = get_Z_offset_guess(room) / Zf
        k_vals_init= [k_val_from_z] * len(lights)
    elif k_init_method == 'YS_brute':
        k_vals = brute_force_k()
    elif k_init_method == 'scipy_brute':
        k_ranges = [slice(.01, .1, (.1-.01)/10) for i in range(len(lights))]
        k_vals_init = scipy.optimize.brute(scalar_scaling, k_ranges, disp=True)
    elif k_init_method == 'scipy_basin':
        k_vals_init = [-.05] * len(lights)
        res = scipy.optimize.basinhopping(scalar_scaling, k_vals_init,
				T=1e12,
				stepsize=0.01,
				)
        k_vals_init = res.x
    elif k_init_method == 'actual':
        assert actual_location is not None
        k_vals_init = k_vals_actual
    else:
        k_vals, ier = scipy.optimize.leastsq(least_squares_scaling_factors, k_vals_init)
    def least_squares_rx_location(rx_location):
        dists = []
        for i in range(len(lights)):
            dists.append(
					numpy.sum(numpy.square(rx_location - transmitters[i])) -\
					k_vals[i]**2 * image_squared_distance[i]
					)
        return dists
    def initial_position_guess(room, transmitters):
        guess = numpy.mean(transmitters, axis=0)[0]
        offset = get_Z_offset_guess(room)
        guess[2] = guess[2] - offset
        return guess
    if k_init_method == 'actual':
        rx_location_init = actual_location
    else:
        rx_location_init = initial_position_guess(room, transmitters)
        rx_location, ier = scipy.optimize.leastsq(least_squares_rx_location, rx_location_init)
    def least_squares_rotation(rotation):
        rotation = rotation.reshape((3,3))
        r = transmitters.T - rotation.dot(absolute_centers) - rx_location.reshape(3,1)
        r = numpy.square(r)
        r = r.flatten()
        return r
    absolute_centers = centers.T * numpy.vstack([k_vals, k_vals, k_vals])
    rx_rotation_init = numpy.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]])
    rx_rotation, ier = scipy.optimize.leastsq(least_squares_rotation, rx_rotation_init)
    rx_rotation = numpy.array(rx_rotation).reshape((3,3))
    rx_location_error = numpy.sum(numpy.abs(
			numpy.sqrt(numpy.sum(numpy.square(rx_location - transmitters[i]))) -\
			numpy.sqrt(k_vals[i]**2 * image_squared_distance[i])
			))
    return (rx_location, rx_rotation, rx_location_error)


import json
from unittest import mock

from attr import define

from .utils import MockedRedis

@define
class MockAsyncResult:
    task_id: str
    state: str

def test_status(client):
    response = client.get("/api/v1/status")

    assert response.status_code == 200
    assert response.json() == {"status": "OK"}

def test_task_state(client):
    """test getting state of given celery task_id"""
    with mock.patch("ubi_manifest.app.api.app.AsyncResult") as task_mock:
        task_id = "some-task-id"
        task_mock.return_value = MockAsyncResult(task_id=task_id, state="PENDING")

        response = client.get(f"/api/v1/task/{task_id}")

        # 200 status code is expected
        assert response.status_code == 200
        json_data = response.json()
        # task_id and state are properly set in response
        assert json_data["task_id"] == task_id
        assert json_data["state"] == "PENDING"

def test_task_state_not_found(client):
    """test getting state of given celery task when task is not found"""
    with mock.patch("ubi_manifest.app.api.app.AsyncResult") as task_mock:
        task_id = "some-task-id"
        task_mock.return_value = None

        response = client.get(f"/api/v1/task/{task_id}")
        # 404 is expected status code
        assert response.status_code == 404
        json_data = response.json()
        # proper detail is set in the response
        assert json_data["detail"] == f"Task {task_id} not found"

def test_manifest_get(client):
    """test getting depsolved content for repository"""
    depsolver_result_item = [
        {
            "src_repo_id": "source-foo-bar-repo-1",
            "unit_type": "RpmUnit",
            "unit_attr": "filename",
            "value": "some-filename.rpm",
        },
        {
            "src_repo_id": "source-foo-bar-repo-2",
            "unit_type": "RpmUnit",
            "unit_attr": "filename",
            "value": "some-other-filename.rpm",
        },
    ]

    depsolver_result_item_json_str = json.dumps(depsolver_result_item)

    redis_data = {"ubi_repo_id": depsolver_result_item_json_str}

    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data=redis_data)
        response = client.get(f"/api/v1/manifest/ubi_repo_id")

        # expected status code in 200
        assert response.status_code == 200
        json_data = response.json()
        # repo_id is set to the one we requested
        assert json_data["repo_id"] == "ubi_repo_id"

        content = sorted(json_data["content"], key=lambda x: x["value"])
        # there are two units in the content
        assert len(content) == 2
        content_item = content[0]
        # details of unit are set properly
        assert content_item["src_repo_id"] == "source-foo-bar-repo-1"
        assert content_item["unit_type"] == "RpmUnit"
        assert content_item["unit_attr"] == "filename"
        assert content_item["value"] == "some-filename.rpm"

        content_item = content[1]
        # details of unit are set properly
        assert content_item["src_repo_id"] == "source-foo-bar-repo-2"
        assert content_item["unit_type"] == "RpmUnit"
        assert content_item["unit_attr"] == "filename"
        assert content_item["value"] == "some-other-filename.rpm"

def test_manifest_get_empty(client):
    """test getting empty manifest for repository"""
    depsolver_result_item = []
    depsolver_result_item_json_str = json.dumps(depsolver_result_item)

    redis_data = {"ubi_repo_id": depsolver_result_item_json_str}

    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data=redis_data)
        response = client.get(f"/api/v1/manifest/ubi_repo_id")

        # expected status code in 200
        assert response.status_code == 200
        json_data = response.json()
        # repo_id is set to the one we requested
        assert json_data["repo_id"] == "ubi_repo_id"

        content = sorted(json_data["content"], key=lambda x: x["value"])
        # the content is empty
        assert len(content) == 0

def test_manifest_get_not_found(client):
    """test getting depsolved content when the cotent is not available for given repo_id"""
    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data={})
        response = client.get("/api/v1/manifest/ubi_repo_id")
        # expected status code is 404
        assert response.status_code == 404
        json_data = response.json()
        # response detail is properly set
        assert json_data["detail"] == "Content for ubi_repo_id not found"

def test_manifest_post(client):
    """test request for depsolving for given repo ids"""
    with mock.patch("celery.app.task.Task.apply_async") as mocked_apply_async:
        mocked_apply_async.return_value = MockAsyncResult(
            task_id="foo-bar-id", state="PENDING"
        )

        # will request depsolving for 2 repos
        # 'repo_1' is set in the default config, and it will be depsolving
        # 'repo_not_allowed' will be skipped - not present in the config
        response = client.post(
            "/api/v1/manifest", json={"repo_ids": ["repo_1", "repo_not_allowed"]}
        )

        # depsolve task is run with 2 repos in args:
        # 'repo_1' was requested via API
        # 'repo_2' is taken from repo_group that is defined in the config
        # it's required to run depsolving for whole repo_group, otherwise we
        # won't be able to find some deps that are not in the 'repo_1' but are
        # present in 'repo_2'
        # 'repo_not_allowed' is skipped completely
        # the content config url is also determined from default conf and passed as arg
        mocked_apply_async.assert_called_once_with(
            args=[["repo_1", "repo_2"], "url_to_config_repository"]
        )

        # expected status code is 200
        assert response.status_code == 201
        json_data = response.json()
        # one task is expected to be spawned therefore there is only one item
        # in the response with proper task_id and state set
        assert len(json_data) == 1
        item = json_data[0]
        assert item["task_id"] == "foo-bar-id"
        assert item["state"] == "PENDING"

def test_manifest_post_not_allowed(client):
    """test request for depsolving for given repo ids, but none of the is allowed by config"""
    with mock.patch("celery.app.task.Task.apply_async") as mocked_apply_async:
        # none of repos in request are allowed for depsolving by config
        response = client.post(
            "/api/v1/manifest",
            json={"repo_ids": ["repo_not_allowed_1", "repo_not_allowed_2"]},
        )
        # we never call apply_async on depsolve_task
        mocked_apply_async.assert_not_called()
        # expected status code is 404
        assert response.status_code == 404
        # there is enough detail info in the response
        json_data = response.json()
        assert (
            json_data["detail"]
            == "None of ['repo_not_allowed_1', 'repo_not_allowed_2'] are allowed for depsolving."
        )


#gui
from tkinter import *

#Files
from importFile import *
from settingsPage import *
import settings
from settings import *
from testingFramework import *

#graphing
import matplotlib as graphTool
from matplotlib import pyplot as graphEditor
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

#Key Modules
import os

root = Tk()

root.title(TITLE)

data = []
timeData = []
fileSuccess = False
icons = []
currentFilter = None

class Init:
    def setup():
        img = PhotoImage(file = "bg.png")
        bg = Label(root, image = img)
        bg.image = img
        bg.place(x = 0, y = 0)
        Init.buttons()

    def buttons():
        global icons
        icons = Init.loadIcons()

        allDataPoints = Button(root, image = icons[1], command = lambda: Commands.filterData("all"))
        allDataPoints.image = icons[1]
        allDataPoints['state'] = DISABLED
        allDataPoints.place(x = 20, y = 255)

        ph = Button(root, image = icons[2], command = lambda: Commands.filterData("ph"))
        ph.image = icons[2]
        ph['state'] = DISABLED
        ph.place(x = 20, y = 355)

        temperature = Button(root, image = icons[3], command = lambda: Commands.filterData("temp"))
        temperature.image = icons[3]
        temperature['state'] = DISABLED
        temperature.place(x = 20, y = 450)

        ppm = Button(root, image=icons[4], command = lambda: Commands.filterData("ppm"))
        ppm.image = icons[4]
        ppm['state'] = DISABLED
        ppm.place(x = 20, y = 540)

        settingButton = Button(root, image=icons[6], command = lambda: settingsPage.startup(root))
        settingButton.image = icons[6]
        settingButton.place(x = 1004, y = 20)

        buttons = [allDataPoints, ph, temperature, ppm]

        loadFile = Button(root, image = icons[0], command = lambda: Commands.load(buttons))
        loadFile.image = icons[0]
        loadFile.place(x = 20, y = 100)

    def loadIcons():
        icons = []
        currentdir = os.path.dirname(os.path.abspath(__file__))
        currentdir += '\icons'
        dirLength = len(os.listdir(currentdir))

        for icon in range(0, dirLength):
            img = PhotoImage(file = f"{currentdir}/{icon}.png")
            icons.append(img)

        return icons

class Commands:
    ##Loads the file
    def load(buttonArray):
        global fileSuccess
        fileSuccess = False
        print("Loading file...")
        file = FileImport.importfile()
        if file != "failed":
            fileSuccess = True
        print(fileSuccess)
        if fileSuccess:
            file = open(file, "r")
            for button in buttonArray:
                button['state'] = ACTIVE
            Commands.decodeData(file)

    #STUB - filters the graph by data type
    def filterData(filter):
        global data, timeData, fileSuccess, currentFilter
        if fileSuccess:
            tempArray = []

            #data[0] is pH,
            #data[1] = temperature
            #data[2] = ppm
            #data[3] = time

            if filter == "all" or filter == None:
                graph = LineGraph.graph_draw(data, timeData)
                currentFilter = 'all'

            if filter == "ph":
                tempArray = []
                tempArray.append(data[0])
                graph = LineGraph.graph_draw(tempArray, timeData, LINE_COLOURS[0], "pH")
                currentFilter = 'ph'

            if filter == "temp":
                tempArray = []
                tempArray.append(data[1])
                graph = LineGraph.graph_draw(tempArray, timeData, LINE_COLOURS[1], "Temperature")
                currentFilter = 'temp'

            if filter == "ppm":
                tempArray = []
                tempArray.append(data[2])
                graph = LineGraph.graph_draw(tempArray, timeData, LINE_COLOURS[2], "Salinity")
                currentFilter = 'ppm'
            return graph
        else:
            messagebox.showwarning("No File Loaded", "No file was loaded. Please load one for data to display")

    #Decodes the text file and formats it properly
    def decodeData(file):
        global data, timeData
        oldData = file.readlines()
        repairedData = []
        #remove unnecessary data
        for dataItem in oldData:
            dataItem = dataItem.strip("\n")
            repairedData.append(dataItem)
        tempData = []

        #Check if data is complete
        if (len(repairedData) % DATA_AMOUNT) == 0:
            print("Data is adequate!")
        elif ((len(repairedData) - 1) % DATA_AMOUNT) == 0:
            print("Data is repaired! Removed 1 data piece")
            settings.removedDataLength += 1
        elif ((len(repairedData) - 2) % DATA_AMOUNT) == 0:
            print("Data is repaired! Removed 2 data pieces")
            settings.removedDataLength += 2
        elif ((len(repairedData) - 3) % DATA_AMOUNT) == 0:
            print("Data is repaired! Removed 3 data pieces")
            settings.removedDataLength += 3

        ##Remove the excess data that is unneeded
        for i in range(0,settings.removedDataLength):
            repairedData.remove(repairedData[(len(repairedData) - 1) - i])

        ##Split the data into groups of 4 to represent the different pieces of data
        pHArray = []
        temperatureArray = []
        ppmArray = []
        timeData = []

        for i in range(0,len(repairedData)):
            dataPiece = repairedData[i]
            if settings.dataCounter == 0: #ph
                pHArray.append(dataPiece)
            if settings.dataCounter == 1: #ph
                temperatureArray.append(dataPiece)
            if settings.dataCounter == 2: #ph
                ppmArray.append(dataPiece)
            if settings.dataCounter == 3:
                timeData.append(dataPiece)
                settings.dataCounter = 0
            else:
                settings.dataCounter += 1

        data.append(pHArray)
        data.append(temperatureArray)
        data.append(ppmArray)

        #Graph Data
        #Graph.graph_draw([[50,20,24,53,17]])
        LineGraph.graph_draw(data, timeData)

    def checkdatatype(mainArray, partOfArray, mainArrayLength):
        for i in range(0, mainArrayLength):
            if i == 0 and mainArray[i] == partOfArray:
                return "pH"
            elif i == 1 and mainArray[i] == partOfArray:
                return "Temperature"
            elif i == 2 and mainArray[i] == partOfArray:
                return "Salinity"

class LineGraph:
    def init():
        graphTool.use("TkAgg")

    def graph_draw(data, timerange, *args):
        global icons
        filteredData = False
        colours = COLOURS
        #Initialise the graph
        f = Figure(figsize = (GRAPH_WIDTH,GRAPH_HEIGHT), dpi=100)
        a = f.add_subplot(111)
        a.set_xlabel("Time (in minutes)")
        a.set_ylabel("Data")
        themedGraph = LineGraph.setTheme(f, a)
        f = themedGraph[0]
        a = themedGraph[1]
        #check for filter arguments
        if args:
            filteredData = True

        #Load and display the data
        insertedTimeRange = []
        for dataArray in data:
            insertedTimeRange = timerange
            dataLabel = Commands.checkdatatype(data, dataArray, len(data))
            dataArray = list(map(int, dataArray))
            insertedTimeRange = list(map(int, insertedTimeRange))

            if not filteredData:
                a.plot(insertedTimeRange, dataArray, label = dataLabel)
            else:
                a.plot(insertedTimeRange, dataArray, color = args[0], label = args[1])

        f.suptitle("Data Collected")

        canvas = FigureCanvasTkAgg(f, root)
        a.legend()
        canvas.get_tk_widget().place(x = 250, y = 100)

        saveImg = Button(root, image = icons[5], command = LineGraph.saveGraph)
        saveImg.image = icons[5]
        saveImg.place(x =940, y = 625)
        return f

    def saveGraph():
        global currentFilter
        #Get the current graph
        savableGraph = Commands.filterData(currentFilter)
        #save graph
        if currentFilter == "all":
            savableGraph.savefig("Graph.png")
        elif currentFilter == "ph":
            savableGraph.savefig("Acidity.png")
        elif currentFilter == "temp":
            savableGraph.savefig("Temperature.png")
        elif currentFilter == "ppm":
            savableGraph.savefig("Salinity.png")

    def setTheme(fig, graph):
        currentTheme = settings.CURRENT_THEME
        colours = COLOURS
        if currentTheme == 'Light':
            attri = LineGraph.changeTheme(graph, 0)
        elif currentTheme == 'Dark':
            attri = LineGraph.changeTheme(graph, 1)
        elif currentTheme == 'Desert':
            attri = LineGraph.changeTheme(graph, 2)
        elif currentTheme == 'Oceanic':
            attri = LineGraph.changeTheme(graph, 3)
        elif currentTheme == 'MOZ-Theme':
            attri = LineGraph.changeTheme(graph, 4)
        fig.set_facecolor(attri[0])
        graph.set_facecolor(attri[1])
        return fig, graph

    def changeTheme(self, theme):
        graphEditor.rcParams['text.color'] = themeAttributes[theme][0]
        self.spines['left'].set_color(themeAttributes[theme][1])
        self.spines['right'].set_color(themeAttributes[theme][2])
        self.spines['top'].set_color(themeAttributes[theme][3])
        self.spines['bottom'].set_color(themeAttributes[theme][4])
        self.xaxis.label.set_color(themeAttributes[theme][5])
        self.yaxis.label.set_color(themeAttributes[theme][6])
        self.tick_params(axis = 'x', colors = themeAttributes[theme][7])
        self.tick_params(axis = 'y', colors = themeAttributes[theme][8])
        outline = themeAttributes[theme][9]
        background = themeAttributes[theme][10]

        return outline, background

class TestingFramework:
    def testData():
        start = Button(root, text = "Generate Test Data", command = dataGen.allData)
        start.place(x = 50, y = 650)

##Run window and setup
Init.setup()
root.geometry(f"{WIDTH}x{HEIGHT}")
root.resizable(width = False, height = False)
root.mainloop()


from OpenGL.GL import *
from glfw.GLFW import *
import glm
import ctypes
import numpy as np
import os
import time

azimuth = 0.
elevation = 5
distance = 5
w_vec = glm.vec3(0, 0, 1)
v_vec = glm.vec3(0, 0, 1)
u_vec = glm.vec3(0, 0, 1)
Vup_vec = glm.vec3(0, 1, 0)
targetpos = glm.vec3(0, 0, 0)
camerapos = glm.vec3(3, 2, 4)
cameradirection = glm.vec3(0, 0, -1)
leftButtonPressed = False
rightButtonPressed = False
start_xpos = 0
start_ypos = 0
start_zpos = 0
cur_xpos = 0
cur_ypos = 0
cur_zpos = 0
prev_offsetX = 0
prev_offsetY = 0
offsetX = 0
offsetY = 0
mode = True

channel_list = []
joint_list = []
motion_list = []
offset_list = []
parent_list = []
parent_index_list = []
name_stack = []
index_stack = []
channel_num_list = []
offset_vertex_list = []
npoffset_vertex_list = []
glmoffset_vertex_list = []
numOfJoint = 0
fps = 0
frames = 0
node_list = []
len = 0
dropped = 0
moving = 0
idx = 0
first = 0
frame_cnt=0
motionitr=0
color_loc=0
resize = 1
lineOrBox = 1

g_vertex_shader_src = '''
#version 330 core

layout (location = 0) in vec3 vin_pos;
layout (location = 1) in vec3 vin_normal;

out vec3 vout_surface_pos;
out vec3 vout_normal;

uniform mat4 MVP;
uniform mat4 M;

void main()
{
    vec4 p3D_in_hcoord = vec4(vin_pos.xyz, 1.0);
    gl_Position = MVP * p3D_in_hcoord;

    vout_surface_pos = vec3(M * vec4(vin_pos, 1));
    vout_normal = normalize( mat3(inverse(transpose(M)) ) * vin_normal);
}
'''

g_fragment_shader_src = '''
#version 330 core

in vec3 vout_surface_pos;
in vec3 vout_normal;

out vec4 FragColor;

uniform vec3 view_pos;
uniform vec3 material_color;
void main()
{
    // light and material properties
    vec3 light_pos = vec3(3,2,4);
    vec3 light_pos1 = vec3(3,2,4);
    vec3 light_color = vec3(0,1,1);
    vec3 light_color1 = vec3(1,0,1);
    float material_shininess = 32.0;
    float material_shininess1 = 32.0;

    // light components
    vec3 light_ambient = 0.1*light_color;
    vec3 light_diffuse = light_color;
    vec3 light_specular = light_color;

    vec3 light_ambient1 = 0.1*light_color1;
    vec3 light_diffuse1 = light_color1;
    vec3 light_specular1 = light_color1;

    // material components
    vec3 material_ambient = material_color;
    vec3 material_diffuse = material_color;
    vec3 material_specular = light_color;  // for non-metal material

    vec3 material_ambient1 = material_color;
    vec3 material_diffuse1 = material_color;
    vec3 material_specular1 = light_color1;  // for non-metal material

    // ambient
    vec3 ambient = light_ambient * material_ambient;
    vec3 ambient1 = light_ambient1 * material_ambient1;

    // for diffiuse and specular
    vec3 normal = normalize(vout_normal);
    vec3 surface_pos = vout_surface_pos;
    vec3 light_dir = normalize(light_pos - surface_pos);

    vec3 normal1 = normalize(vout_normal);
    vec3 surface_pos1 = vout_surface_pos;
    vec3 light_dir1 = normalize(light_pos1 - surface_pos1);

    // diffuse
    float diff = max(dot(normal, light_dir), 0);
    vec3 diffuse = diff * light_diffuse * material_diffuse;

    float diff1 = max(dot(normal1, light_dir1), 0);
    vec3 diffuse1 = diff1 * light_diffuse1 * material_diffuse1;

    // specular
    vec3 view_dir = normalize(view_pos - surface_pos);
    vec3 reflect_dir = reflect(-light_dir, normal);
    float spec = pow( max(dot(view_dir, reflect_dir), 0.0), material_shininess);
    vec3 specular = spec * light_specular * material_specular;

    vec3 view_dir1 = normalize(view_pos - surface_pos1);
    vec3 reflect_dir1 = reflect(-light_dir1, normal1);
    float spec1 = pow( max(dot(view_dir1, reflect_dir1), 0.0), material_shininess1);
    vec3 specular1 = spec1 * light_specular1 * material_specular1;

    vec3 color = ambient + diffuse + specular;
    vec3 color1 = ambient1 + diffuse1 + specular1;

    FragColor = vec4((color+color1), 1.);
}
'''

def prepare_V_mat():
    global azimuth, elevation, cur_xpos, cur_ypos, cur_zpos, start_xpos, start_ypos, start_zpos
    global w_vec, u_vec, v_vec, Vup_vec
    global camerapos, targetpos, distance

    w_vec = glm.vec3(np.cos(elevation)*np.sin(azimuth),
                     np.sin(elevation), np.cos(elevation)*np.cos(azimuth))
    u_vec = np.cross(Vup_vec, w_vec)
    u_vec /= np.sqrt(np.dot(u_vec, u_vec))
    v_vec = glm.vec3(np.cross(u_vec, w_vec))
    v_vec /= np.sqrt(np.dot(v_vec, v_vec))
    camerapos = glm.vec3(distance*w_vec.x+targetpos.x, distance *
                         w_vec.y+targetpos.y, distance*w_vec.z+targetpos.z)

def load_shaders(vertex_shader_source, fragment_shader_source):
    # build and compile our shader program
    # ------------------------------------

    # vertex shader
    # create an empty shader object
    vertex_shader = glCreateShader(GL_VERTEX_SHADER)
    # provide shader source code
    glShaderSource(vertex_shader, vertex_shader_source)
    # compile the shader object
    glCompileShader(vertex_shader)

    # check for shader compile errors
    success = glGetShaderiv(vertex_shader, GL_COMPILE_STATUS)
    if (not success):
        infoLog = glGetShaderInfoLog(vertex_shader)
        print("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" + infoLog.decode())

    # fragment shader
    # create an empty shader object
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
    # provide shader source code
    glShaderSource(fragment_shader, fragment_shader_source)
    # compile the shader object
    glCompileShader(fragment_shader)

    # check for shader compile errors
    success = glGetShaderiv(fragment_shader, GL_COMPILE_STATUS)
    if (not success):
        infoLog = glGetShaderInfoLog(fragment_shader)
        print("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" + infoLog.decode())

    # link shaders
    # create an empty program object
    shader_program = glCreateProgram()
    # attach the shader objects to the program object
    glAttachShader(shader_program, vertex_shader)
    glAttachShader(shader_program, fragment_shader)
    glLinkProgram(shader_program)                    # link the program object

    # check for linking errors
    success = glGetProgramiv(shader_program, GL_LINK_STATUS)
    if (not success):
        infoLog = glGetProgramInfoLog(shader_program)
        print("ERROR::SHADER::PROGRAM::LINKING_FAILED\n" + infoLog.decode())

    glDeleteShader(vertex_shader)
    glDeleteShader(fragment_shader)

    return shader_program    # return the shader program

def key_callback(window, key, scancode, action, mods):
    global g_cam_ang, g_cam_height, mode, h_mode, wiremode, moving, lineOrBox
    if key == GLFW_KEY_ESCAPE and action == GLFW_PRESS:
        glfwSetWindowShouldClose(window, GLFW_TRUE)
    else:
        if action == GLFW_PRESS:
            if key == GLFW_KEY_ESCAPE:
                glfwSetWindowShouldClose(window, GLFW_TRUE)
            if key == GLFW_KEY_SPACE:
                moving = 1
            elif key == GLFW_KEY_1:
                lineOrBox = 1
            elif key == GLFW_KEY_2:
                lineOrBox = 2

def button_callback(window, button, action, mod):
    global leftButtonPressed, rightButtonPressed, start_xpos, start_ypos, cur_xpos, cur_ypos, azimuth, elevation
    if button == GLFW_MOUSE_BUTTON_LEFT:
        if action == GLFW_PRESS:
            start_xpos, start_ypos = glfwGetCursorPos(window)
            cur_xpos, cur_ypos = glfwGetCursorPos(window)
            leftButtonPressed = True
        elif action == GLFW_RELEASE:
            leftButtonPressed = False
    if button == GLFW_MOUSE_BUTTON_RIGHT:
        if action == GLFW_PRESS:
            start_xpos, start_ypos = glfwGetCursorPos(window)
            cur_xpos, cur_ypos = glfwGetCursorPos(window)
            rightButtonPressed = True
        elif action == GLFW_RELEASE:
            rightButtonPressed = False

def cursor_callback(window, xpos, ypos):
    global cur_xpos, cur_ypos, leftButtonPressed, rightButtonPressed, camerapos
    global azimuth, elevation, Vup_vec, u_vec, w_vec, v_vec, targetpos, start_xpos, start_ypos

    if leftButtonPressed == True:
        start_xpos = cur_xpos
        start_ypos = cur_ypos
        cur_xpos, cur_ypos = glfwGetCursorPos(window)
        elevation -= (cur_ypos-start_ypos)/150
        if np.sin(elevation) < 0:
            azimuth -= (cur_xpos-start_xpos)/100
        else:
            azimuth += (cur_xpos-start_xpos)/100

    if rightButtonPressed == True:
        start_xpos = cur_xpos
        start_ypos = cur_ypos
        cur_xpos, cur_ypos = glfwGetCursorPos(window)
        targetpos += ((start_xpos-cur_xpos)*u_vec +
                      (start_ypos-cur_ypos)*v_vec)/500
        camerapos += ((start_xpos-cur_xpos)*u_vec +
                      (start_ypos-cur_ypos)*v_vec)/500

def scroll_callback(window, xoffset, yoffset):
    global distance
    distance *= np.power(1.1, float(-yoffset))

def drop_callback(window, paths):
    global joint_list, motion_list, channel_list, parent_list, name_stack, channel_num_list, numOfJoint, fps, frames, parent_index_list, len, dropped
    global npoffset_vertex_list, glmoffset_vertex_list, index_stack, offset_list, idx, first, moving,resize
    idx = 0
    dropped = 1
    joint_list = []
    motion_list = []
    channel_list = []
    parent_list = []
    name_stack = []
    index_stack = []
    channel_num_list = []
    numOfJoint = 0
    fps = 0
    frames = 0
    parent_index_list = []
    len = 0
    realPosition_list = []
    npoffset_vertex_list = []
    glmoffset_vertex_list = []
    offset_list = []
    first = 1
    moving=0
    resize = 1
    # print obj file name
    for path in paths:
        file_name = os.path.basename(path)
    bvhFile = open(path, 'r')
    lines = bvhFile.readlines()  # 파일 내용을 한 줄씩 읽어 리스트로 저장
    for line in lines:
        parts = line.split()
        if parts[0] == "ROOT":
            joint_list.append(parts[1])
            parent_list.append("None")
            parent_index_list.append(-1)
            name_stack.append(parts[1])
            index_stack.append(idx)
            numOfJoint += 1
            idx += 1
        elif parts[0] == "JOINT":
            joint_list.append(parts[1])
            parent_list.append(name_stack[-1])
            parent_index_list.append(index_stack[-1])
            numOfJoint += 1
            name_stack.append(parts[1])
            index_stack.append(idx)
            idx += 1
        elif parts[0] == "End":
            joint_list.append(parts[1])
            parent_list.append(name_stack[-1])
            parent_index_list.append(index_stack[-1])
            name_stack.append(parts[1])
            index_stack.append(idx)
            idx += 1
        elif parts[0] == "}":
            name_stack.pop()
            index_stack.pop()
        elif parts[0] == "OFFSET":
            x=float(parts[1])
            y=float(parts[2])
            z=float(parts[3])
            if (glm.dot(glm.vec3(x,y,z), glm.vec3(x,y,z))>1) :
                resize = 100
            offset_list.append(x/resize)
            offset_list.append(y/resize)
            offset_list.append(z/resize)
        elif parts[0] == "CHANNELS":
            channel_num_list.append(parts[1])
            for i in range(2, int(parts[1])+2):
                channel_list.append(parts[i])
        elif parts[0] == "Frames:":
            frames = int(parts[1])
        elif parts[0] == "Frame":
            fps = float(parts[2])
        elif parts[0] == "{" or parts[0] == "HIERARCHY" or parts[0] == "MOTION":
            continue
        else:
            for part in parts:
                motion_list.append(float(part))
    print("Obj file name : %s" % (file_name))
    print("Number of Frame : %d" % (frames))
    print("fps : %f" % (fps))
    print("Number of joints : %d" % (numOfJoint))
    print("List of all joint names :")
    for joint in joint_list:
        if (joint == "Site"):
            continue
        print(joint)
    idx -= 1

def prepare_node_list():
    global joint_list, motion_list, channel_list, parent_list, name_stack, channel_num_list, numOfJoint, fps, frames, parent_index_list, len, dropped
    global npoffset_vertex_list, glmoffset_vertex_list, index_stack, offset_list, node_list, idx
        # create a hirarchical model - Node(parent, link_transform_from_parent, shape_transform, color)
    for i in range(0, idx+1):
        if parent_list[i] == "None":
            node_list.append(Node(None, glm.mat4(), glm.mat4(), glm.vec3(1, 1, 1)))
        else:
            node_list.append(Node(node_list[parent_index_list[i]], glm.translate((offset_list[i*3+0], offset_list[i*3+1], offset_list[i*3+2])), glm.mat4(), glm.vec3(1, 1, 1)))

def prepare_vao_grid(i):
    # prepare vertex data (in main memory)
    vertices = glm.array(glm.float32,
                         # position        # color
                         -10.0, 0.0, i*0.1,  1.0, 1.0, 1.0,  # x-axis start
                         10.0, 0.0, i*0.1,   1.0, 1.0, 1.0,  # x-axis end
                         -10.0, 0.0, -i*0.1,  1.0, 1.0, 1.0,  # z-axis start
                         10.0, 0.0, -i*0.1,   1.0, 1.0, 1.0,  # z-axis end
                         i*0.1, 0.0, -10.0,  1.0, 1.0, 1.0,  # x-axis start
                         i*0.1, 0.0, 10.0,   1.0, 1.0, 1.0,  # x-axis end
                         -i*0.1, 0.0, -10.0,  1.0, 1.0, 1.0,  # z-axis start
                         -i*0.1, 0.0, 10.0,   1.0, 1.0, 1.0,  # z-axis end
                         )

    # create and activate VAO (vertex array object)
    # create a vertex array object ID and store it to VAO variable
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)      # activate VAO

    # create and activate VBO (vertex buffer object)
    # create a buffer object ID and store it to VBO variable
    VBO = glGenBuffers(1)
    # activate VBO as a vertex buffer object
    glBindBuffer(GL_ARRAY_BUFFER, VBO)

    # copy vertex data to VBO
    # allocate GPU memory for and copy vertex data to the currently bound vertex buffer
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes,
                 vertices.ptr, GL_STATIC_DRAW)

    # configure vertex positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)

    # configure vertex colors
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), ctypes.c_void_p(3*glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)

    return VAO

def prepare_vao_frame():
    # prepare vertex data (in main memory)
    vertices = glm.array(glm.float32,
                         # position        # color
                         -3.0, 0.0, 0.0,  1.0, 0.0, 0.0,  # x-axis start
                         3.0, 0.0, 0.0,  1.0, 0.0, 0.0,  # x-axis end
                         0.0, 0.0, 3.0,  0.0, 0.0, 1.0,  # y-axis start
                         0.0, 0.0, -3.0,  0.0, 0.0, 1.0,  # y-axis end
                         )

    # create and activate VAO (vertex array object)
    # create a vertex array object ID and store it to VAO variable
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)      # activate VAO

    # create and activate VBO (vertex buffer object)
    # create a buffer object ID and store it to VBO variable
    VBO = glGenBuffers(1)
    # activate VBO as a vertex buffer object
    glBindBuffer(GL_ARRAY_BUFFER, VBO)

    # copy vertex data to VBO
    # allocate GPU memory for and copy vertex data to the currently bound vertex buffer
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes,
                 vertices.ptr, GL_STATIC_DRAW)

    # configure vertex positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)

    # configure vertex colors
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), ctypes.c_void_p(3*glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)

    return VAO

def prepare_vao_bvh_line_modified(list):
    nptemp_list = np.array(list, dtype=np.float32)
    glmtemp_list = glm.array(nptemp_list, dtype=glm.float32)
    # prepare vertex data (in main memory)
    vertices = glmtemp_list
    # create and activate VAO (vertex array object)
    # create a vertex array object ID and store it to VAO variable
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)      # activate VAO

    # create and activate VBO (vertex buffer object)
    # create a buffer object ID and store it to VBO variable
    VBO = glGenBuffers(1)
    # activate VBO as a vertex buffer object
    glBindBuffer(GL_ARRAY_BUFFER, VBO)

    # copy vertex data to VBO
    # allocate GPU memory for and copy vertex data to the currently bound vertex buffer
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes,
                 vertices.ptr, GL_STATIC_DRAW)

    # configure vertex positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)

    # configure vertex colors
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), ctypes.c_void_p(3*glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)
    return VAO

def prepare_vao_cube():
    # prepare vertex data (in main memory)
    # 36 vertices for 12 triangles
    vertices = glm.array(glm.float32,
        # position      normal
        -1 ,  1 ,  1 ,  0, 0, 1, # v0
         1 , -1 ,  1 ,  0, 0, 1, # v2
         1 ,  1 ,  1 ,  0, 0, 1, # v1

        -1 ,  1 ,  1 ,  0, 0, 1, # v0
        -1 , -1 ,  1 ,  0, 0, 1, # v3
         1 , -1 ,  1 ,  0, 0, 1, # v2

        -1 ,  1 , -1 ,  0, 0,-1, # v4
         1 ,  1 , -1 ,  0, 0,-1, # v5
         1 , -1 , -1 ,  0, 0,-1, # v6

        -1 ,  1 , -1 ,  0, 0,-1, # v4
         1 , -1 , -1 ,  0, 0,-1, # v6
        -1 , -1 , -1 ,  0, 0,-1, # v7

        -1 ,  1 ,  1 ,  0, 1, 0, # v0
         1 ,  1 ,  1 ,  0, 1, 0, # v1
         1 ,  1 , -1 ,  0, 1, 0, # v5

        -1 ,  1 ,  1 ,  0, 1, 0, # v0
         1 ,  1 , -1 ,  0, 1, 0, # v5
        -1 ,  1 , -1 ,  0, 1, 0, # v4

        -1 , -1 ,  1 ,  0,-1, 0, # v3
         1 , -1 , -1 ,  0,-1, 0, # v6
         1 , -1 ,  1 ,  0,-1, 0, # v2

        -1 , -1 ,  1 ,  0,-1, 0, # v3
        -1 , -1 , -1 ,  0,-1, 0, # v7
         1 , -1 , -1 ,  0,-1, 0, # v6

         1 ,  1 ,  1 ,  1, 0, 0, # v1
         1 , -1 ,  1 ,  1, 0, 0, # v2
         1 , -1 , -1 ,  1, 0, 0, # v6

         1 ,  1 ,  1 ,  1, 0, 0, # v1
         1 , -1 , -1 ,  1, 0, 0, # v6
         1 ,  1 , -1 ,  1, 0, 0, # v5

        -1 ,  1 ,  1 , -1, 0, 0, # v0
        -1 , -1 , -1 , -1, 0, 0, # v7
        -1 , -1 ,  1 , -1, 0, 0, # v3

        -1 ,  1 ,  1 , -1, 0, 0, # v0
        -1 ,  1 , -1 , -1, 0, 0, # v4
        -1 , -1 , -1 , -1, 0, 0, # v7
    )

    # create and activate VAO (vertex array object)
    VAO = glGenVertexArrays(1)  # create a vertex array object ID and store it to VAO variable
    glBindVertexArray(VAO)      # activate VAO

    # create and activate VBO (vertex buffer object)
    VBO = glGenBuffers(1)   # create a buffer object ID and store it to VBO variable
    glBindBuffer(GL_ARRAY_BUFFER, VBO)  # activate VBO as a vertex buffer object

    # copy vertex data to VBO
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr, GL_STATIC_DRAW) # allocate GPU memory for and copy vertex data to the currently bound vertex buffer

    # configure vertex positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)

    # configure vertex normals
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * glm.sizeof(glm.float32), ctypes.c_void_p(3*glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)

    return VAO

def prepare_vao_bvh_line():
    global offset_vertex_list, npoffset_vertex_list, glmoffset_vertex_list
    # prepare vertex data (in main memory)
    vertices = glmoffset_vertex_list
    # create and activate VAO (vertex array object)
    # create a vertex array object ID and store it to VAO variable
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)      # activate VAO

    # create and activate VBO (vertex buffer object)
    # create a buffer object ID and store it to VBO variable
    VBO = glGenBuffers(1)
    # activate VBO as a vertex buffer object
    glBindBuffer(GL_ARRAY_BUFFER, VBO)

    # copy vertex data to VBO
    # allocate GPU memory for and copy vertex data to the currently bound vertex buffer
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes,
                 vertices.ptr, GL_STATIC_DRAW)

    # configure vertex positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), None)
    glEnableVertexAttribArray(0)

    # configure vertex colors
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 *
                          glm.sizeof(glm.float32), ctypes.c_void_p(3*glm.sizeof(glm.float32)))
    glEnableVertexAttribArray(1)
    return VAO

class Node:
    def __init__(self, parent, link_transform_from_parent, shape_transform, color):
        # hierarchy
        self.parent = parent
        self.children = []
        if parent is not None:
            parent.children.append(self)

        # transform
        self.link_transform_from_parent = link_transform_from_parent
        self.joint_transform = glm.mat4()
        self.global_transform = glm.mat4()

        # shape
        self.shape_transform = shape_transform
        self.color = color

    def set_joint_transform(self, joint_transform):
        self.joint_transform *= joint_transform

    def update_tree_global_transform(self):
        if self.parent is not None:
            self.global_transform = self.parent.get_global_transform() * self.link_transform_from_parent * self.joint_transform
        else:
            self.global_transform = self.link_transform_from_parent * self.joint_transform

        for child in self.children:
            child.update_tree_global_transform()

    def get_global_transform(self):
        return self.global_transform

    def get_shape_transform(self):
        return self.shape_transform

    def get_color(self):
        return self.color

    def get_position(self):
        return self.get_global_transform() * glm.vec4(0,0,0,1).xyz

    def init_joint_transform(self):
        self.joint_transform = glm.mat4()

    def get_parent(self):
        return self.parent

def draw_node(vao, node, color_loc):
    # MVP = VP * node.get_global_transform() * node.get_shape_transform()
    color = node.get_color()

    glBindVertexArray(vao)
    # glUniformMatrix4fv(MVP_loc, 1, GL_FALSE, glm.value_ptr(MVP))
    glUniform3f(color_loc, color.r, color.g, color.b)
    glDrawArrays(GL_LINES, 0, 2)

def get_rotate_matrix(curPos, parentcurPos):
    offset = glm.vec3(curPos-parentcurPos)
    len = glm.length(offset)
    vec1 = glm.normalize(glm.vec3(0,len,0))
    vec2 = glm.normalize(offset)

    dot = glm.dot(vec1, vec2)
    cross = glm.cross(vec1, vec2)
    if cross==glm.vec3(0,0,0):
        return glm.mat4()
    axis = glm.normalize(cross)
    angle = glm.acos(dot)

    rotate = glm.rotate(angle,axis)
    return rotate

def draw_cube(vao, MVP, MVP_loc):
    glBindVertexArray(vao)
    glUniformMatrix4fv(MVP_loc, 1, GL_FALSE, glm.value_ptr(MVP))
    glDrawArrays(GL_TRIANGLES, 0, 36)

def draw_one_frame(vao_cube,P,V, MVP_loc):
    global joint_list, node_list, channel_num_list, channel_list, frame_cnt, motionitr,color_loc, resize
    if frame_cnt==frames or frame_cnt==0:
        frame_cnt=0
        motionitr=0
    for node in node_list :
        node.init_joint_transform()
    cnt = 0
    nodeitr = 0
    channel_numitr = 0
    channelitr = 0
    for _ in range(0,idx+1):# 노드 돌아가면서,,
        if (joint_list[nodeitr]=="Site"):
            nodeitr+=1
            continue
        node = node_list[nodeitr]
        channel_num = channel_num_list[channel_numitr]
        for _ in range(0, int(channel_num)):
            motion = motion_list[motionitr]
            channel = channel_list[channelitr]
            if channel == "XPOSITION" or channel == "Xposition":
                node.set_joint_transform(glm.translate((motion/resize, 0, 0)))
            elif channel == "YPOSITION" or channel == "Yposition":
                node.set_joint_transform(glm.translate((0, motion/resize, 0)))
            elif channel == "ZPOSITION" or channel == "Zposition":
                node.set_joint_transform(glm.translate((0, 0, motion/resize)))
            elif channel == "XROTATION" or channel == "Xrotation":
                node.set_joint_transform(glm.rotate(np.deg2rad(motion), (1, 0, 0)))
            elif channel == "YROTATION" or channel == "Yrotation":
                node.set_joint_transform(glm.rotate(np.deg2rad(motion), (0, 1, 0)))
            elif channel == "ZROTATION" or channel == "Zrotation":
                node.set_joint_transform(glm.rotate(np.deg2rad(motion), (0, 0, 1)))
            # print("frame_cnt is %d joint_list[nodeitr] is %s motion is %f channel is %s"%(frame_cnt, joint_list[nodeitr], motion, channel))
            motionitr += 1
            channelitr += 1
        cnt+=1
        nodeitr += 1
        channel_numitr += 1
    node_list[0].update_tree_global_transform()
    for node in node_list:
        if (node.get_parent()==None):
            continue
        templist = []
        curPos = node.get_position()
        parentcurPos = node.get_parent().get_position()
        templist.append(curPos.x)
        templist.append(curPos.y)
        templist.append(curPos.z)
        templist.append(0.0)
        templist.append(1.0)
        templist.append(0.0)
        templist.append(parentcurPos.x)
        templist.append(parentcurPos.y)
        templist.append(parentcurPos.z)
        templist.append(0.0)
        templist.append(1.0)
        templist.append(0.0)
        vao_bvh = prepare_vao_bvh_line_modified(templist)
        draw_node(vao_bvh,node,color_loc)
        if lineOrBox==2:
                len = glm.length(curPos-parentcurPos)
                rotateMat = get_rotate_matrix(curPos, parentcurPos)
                Matrix = glm.translate((curPos+parentcurPos)/2)*rotateMat*glm.scale((0.02,len/2, 0.02))
                draw_cube(vao_cube,P*V*Matrix, MVP_loc)

    frame_cnt+=1

def main():
    global azimuth, elevation, cur_xpos, cur_ypos, cur_zpos, start_xpos, start_ypos, start_zpos, leftButtonPressed, rightButtonPressed
    global cameradirection, camerapos, targetpos, offsetX, offsetY, mode, dropped, first, moving, node_list, channel_num_list, channel_list
    global motion_list, numOfJoint, fps, frames,color_loc, frame_cnt, lineOrBox

    # initialize glfw
    if not glfwInit():
        return
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)   # OpenGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
    # Do not allow legacy OpenGl API calls
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)  # for macOS

    # create a window and OpenGL context
    window = glfwCreateWindow(800, 800, 'assignment1-2019073181', None, None)
    if not window:
        glfwTerminate()
        return
    glfwMakeContextCurrent(window)

    # register event callbacks
    glfwSetCursorPosCallback(window, cursor_callback)
    glfwSetMouseButtonCallback(window, button_callback)
    glfwSetScrollCallback(window, scroll_callback)
    glfwSetKeyCallback(window, key_callback)
    glfwSetDropCallback(window, drop_callback)

    # load shaders
    shader_program = load_shaders(g_vertex_shader_src, g_fragment_shader_src)

    # get uniform locations
    MVP_loc = glGetUniformLocation(shader_program, 'MVP')
    color_loc = glGetUniformLocation(shader_program, 'material_color')
    M_loc = glGetUniformLocation(shader_program, 'M')
    view_pos_loc = glGetUniformLocation(shader_program, 'view_pos')

    vao_cube = prepare_vao_cube()

    # loop until the user closes the window
    while not glfwWindowShouldClose(window):
        # render
        # enable depth test (we'll see details later)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glEnable(GL_DEPTH_TEST)

        glUseProgram(shader_program)

        glfwPollEvents()

        if mode == True:
            P = glm.perspective(45, 1, 1, 100)
        else:
            P = glm.ortho(-1, 1, -1, 1, -100, 100)
        prepare_V_mat()
        V = glm.lookAt(glm.vec3(camerapos), glm.vec3(targetpos), glm.vec3(Vup_vec))
        M = glm.mat4()
        MVP = P*V*M
        glUniformMatrix4fv(MVP_loc, 1, GL_FALSE, glm.value_ptr(MVP))
        glUniformMatrix4fv(M_loc, 1, GL_FALSE, glm.value_ptr(M))
        glUniform3f(view_pos_loc, camerapos.x, camerapos.y, camerapos.z)

        glUniform3f(color_loc, 1, 1, 1)
        vao_frame = prepare_vao_frame()
        glBindVertexArray(vao_frame)
        glDrawArrays(GL_LINES, 0, 4)

        for i in range(100):
            vao_frame = prepare_vao_grid(i)
            glBindVertexArray(vao_frame)
            glDrawArrays(GL_LINES, 0, 8)
        if dropped == 1 and first == 1 and moving==0:  # 처음 드롭
            vao_bvh_list = []
            node_list = []
            prepare_node_list()
            node_list[0].update_tree_global_transform()
            for node in node_list:
                if node.get_parent()==None:
                    continue
                templist = []
                curPos = node.get_position()
                parentcurPos = node.get_parent().get_position()
                templist.append(curPos.x)
                templist.append(curPos.y)
                templist.append(curPos.z)
                templist.append(0.0)
                templist.append(1.0)
                templist.append(0.0)
                templist.append(parentcurPos.x)
                templist.append(parentcurPos.y)
                templist.append(parentcurPos.z)
                templist.append(0.0)
                templist.append(1.0)
                templist.append(0.0)
                vao_bvh = prepare_vao_bvh_line_modified(templist)
                vao_bvh_list.append(vao_bvh)
                draw_node(vao_bvh,node,color_loc)
            first = 0
            frame_cnt = 0
        if dropped == 1 and first == 0 and moving==0:  # 준비과정은 필요없음.
            i=0
            for node in node_list:
                if node.get_parent()==None:
                    continue
                curPos = node.get_position()
                parentcurPos = node.get_parent().get_position()
                if lineOrBox ==1:
                    draw_node(vao_bvh_list[i], node, color_loc)
                    i+=1
                if lineOrBox==2:
                    len = glm.length(curPos-parentcurPos)
                    rotateMat = get_rotate_matrix(curPos, parentcurPos)
                    Matrix = glm.translate((curPos+parentcurPos)/2)*rotateMat*glm.scale((0.02,len/2, 0.02))
                    draw_cube(vao_cube,P*V*Matrix, MVP_loc)

        if dropped ==1 and moving == 1:
            draw_one_frame(vao_cube,P,V,MVP_loc)
            time.sleep(fps)

        # swap front and back buffers
        glfwSwapBuffers(window)

    # terminate glfw
    glfwTerminate()

if __name__ == "__main__":
    main()


from prettytable import PrettyTable
import random
import math
import pandas as pd
import matplotlib.pyplot as plt
def pareto_optim(x,y):#алгоритм исключения заведомо неэффективных решений
    global paret
    paret = []
    for i in range(len(x)):
        paret.append(i)
    for i in paret:
        for j in paret:
            if ((x[i] <= x[j]) and (y[i] < y[j])) or ((x[i] < x[j]) and (y[i] <= y[j])):
                paret.remove(j)
    return paret

def __checker(x1,y1,x,y): ## проверка на уникальность точки
    for i in range(len(x)):
        if x1 == x[i] and y1 == y[i]:
            return False
    return True

def find_angle():#поиск угловых коэффицентов ограничений конуса доминирования
    nu1min = 0.2
    nu1max = 0.5
    nu2min = 0.3
    nu2max = 0.8
    points_x = []
    points_y = []
    x = 0
    while(len(points_x) < 2):
        y = - x + 1
        if (y == nu2min) and (x >= nu1min) and (x <= nu1max):
            points_x.append(x)
            points_y.append(y)
        elif (y == nu2max) and (x >= nu1min) and (x <= nu1max):
            points_x.append(x)
            points_y.append(y)
        elif (x == nu1min) and (y >= nu2min) and (y <= nu2max):
            points_x.append(x)
            points_y.append(y)
        elif (x == nu1max) and (y >= nu2min) and (y <= nu2max):
            points_x.append(x)
            points_y.append(y)
        x =round(x + 0.1, 1)
        if x > 1:
            break
    #cos_angle = (points_x[0]*points_x[1] + points_y[0]*points_y[1])/(math.sqrt(points_x[0]**2+points_y[0]**2))*(math.sqrt(points_x[1]**2+points_y[1]**2))
    #return cos_angle
        global tg_a
        global tg_b
    tg_a = -1/(points_y[0]/points_x[0])
    tg_b = -1/(points_y[1]/points_x[1])

def generate_points():
    global j1,j2
    j1 = []
    j2 = []
    while(len(j1)<100):
        u1 = random.randint(0,79)
        u2 = random.randint(0,79)
        buf = ((0.2 * (u1 - 70) * (u1 - 70)) + (0.8 * (u2 - 20) * (u2 - 20)))
        buf1 = ((0.2 * (u1 - 10) * (u1 - 10)) + (0.8 * (u2 - 70) * (u2 - 70)))

        if __checker(buf,buf1, j1,j2):
            print(buf)
            j1.append(buf)
            print(buf1)
            j2.append(buf1)
    print(j1[1],j2[1])

def __angle_point(x,y, x1, y1):
    if (x-x1 == 0):
        return 1000
    else:
        return (y-y1)/(x-x1)

def omega_opt(j1,j2):
    global omega
    omega=[]
    for i in range(len(j1)):
        omega.append(i)
    for i in omega:
        for j in omega:
            if (i != j):
                if ((__angle_point(j1[i],j2[i],j1[j],j2[j]) > tg_a) and (j1[i]-j1[j]<0))or ((__angle_point(j1[i],j2[i],j1[j],j2[j]) < tg_b) and (j1[i]-j1[j]>0)) or (j1[i]<j1[j] and j2[i]<j2[j]):
                    omega.remove(j)

    return omega
generate_points()
find_angle()
pareto_optim(j1,j2)
omega_opt(j1,j2)

print("Парето-оптимальные точки: ", *paret)
print("Омега оптимальные точки:", *omega)
omega_x = []
omega_y = []
omega_list = omega
for i in omega_list:
    omega_x.append(j1[i])
    omega_y.append(j2[i])
pareto_x = []
pareto_y = []
pareto_list = paret
for i in pareto_list:
    pareto_x.append(j1[i])
    pareto_y.append(j2[i])
df = pd.DataFrame({'j1': j1,'j2': j2})
plt.scatter(df['j1'], df['j2'])
df = pd.DataFrame({'f1': pareto_x,'f2': pareto_y})
plt.scatter(df['f1'], df['f2'],c='green')
df = pd.DataFrame({'c1': omega_x,'c2': omega_y})
plt.scatter(df['c1'], df['c2'],c='black')

plt.show()


from pyramid.view import view_config
from pyramid.response import Response, FileResponse
from pyramid.httpexceptions import HTTPUnauthorized, HTTPNotFound, HTTPFound

import time

class SessionView:

    def __init__(self, request):
        """This is called always when you access the session demo page
        """
        self.request = request
        self.session = self.request.session
        self.initSession("data_list", default = [])
        # now we have self.data_list that refers to self.request.session.data_list
        # if it wasn't in the cache, it is set to [] (i.e. empty list)

    def initSession(self, key, default = None):
        """Init something to self.request.session where redis cached data lives
        """
        if key not in self.session:
            self.session[key] = default
            self.session.changed() # re-serialize

    @view_config(route_name = "session", renderer = "../templates/session.jinja2")
    def session_view(self):
        """Return cached data to the template renderer
        """
        res = {
            "data_list" : self.session["data_list"] # self.data_list lives in the cache (refers to self.request.session)
        }
        return res

    @view_config(route_name = "session_push")
    def session_push(self):
        """Push more data to cache
        """
        # new_data = self.request.params.get("data", None) # if the key "data" had been passed with GET
        new_data = "timestamp: %i" % int(time.time()*1000)
        # self.request.session["data_list"].append(new_data)
        self.session["data_list"].append(new_data) # self.data_list lives in the cache (refers to self.request.session)
        self.session.changed()
        print("session_push: data_list: ", self.session["data_list"])
        return HTTPFound(location='/session') # redirect

    @view_config(route_name = "session_clear")
    def session_clear(self):
        """Clear cached data
        """
        self.session["data_list"] = [] # self.data_list lives in the cache (refers to self.request.session)
        self.session.changed()
        return HTTPFound(location='/session') # redirect