#!/usr/bin/env python3

"""
This Python script is used to translate a specific word from it source language,
such as Spanish into American English using the MyMemory translation service.
"""
__author__ = 'John Bumgarner'
__date__ = 'September 24, 2021'
__status__ = 'Production'
__license__ = 'MIT'
__copyright__ = "Copyright (C) 2021 John Bumgarner"

##################################################################################
# “AS-IS” Clause
#
# Except as represented in this agreement, all work produced by Developer is
# provided “AS IS”. Other than as provided in this agreement, Developer makes no
# other warranties, express or implied, and hereby disclaims all implied warranties,
# including any warranty of merchantability and warranty of fitness for a particular
# purpose.
##################################################################################

##################################################################################
#
# Date Completed: September 24, 2021
# Author: John Bumgarner
#
# Date Last Revised:
# Revised by:
#
##################################################################################

##################################################################################
# Python imports required for basic operations
##################################################################################
import sys
import logging
import requests
import traceback
from string import punctuation
from backoff import on_exception, expo
from requests.adapters import HTTPAdapter
from ratelimit import limits, RateLimitException
from requests.packages.urllib3.util.retry import Retry
from wordhoard.utilities.exceptions import RequestError
from wordhoard.utilities.exceptions import NotValidLength
from wordhoard.utilities.exceptions import TooManyRequests
from wordhoard.utilities.user_agents import get_random_user_agent
from wordhoard.utilities.exceptions import LanguageNotSupportedException

logger = logging.getLogger(__name__)

rand_user_agent = get_random_user_agent()
http_headers = {'user-agent': rand_user_agent}

class Translator(object):

    def __init__(self,
                 source_language='',
                 str_to_translate='',
                 email_address=None
                 ):

        self._source_language = source_language
        self._str_to_translate = str_to_translate
        self._url_to_query = 'http://api.mymemory.translated.net/get'
        self._email_address = email_address
        self._headers = http_headers

        ratelimit_status = False
        self._rate_limit_status = ratelimit_status

        # Retries the requests after a certain time period has elapsed
        handler = on_exception(expo, RateLimitException, max_time=60, on_backoff=self._backoff_handler)
        # Establishes a rate limit for making requests to the MyMemory translation service
        limiter = limits(calls=30, period=60)
        self.translate_word = handler(limiter(self.translate_word))
        self.reverse_translate = handler(limiter(self.reverse_translate))

    def _colorized_text(self, r, g, b, text):
        return f"\033[38;2;{r};{g};{b}m{text} \033[38;2;255;255;255m"

    def _backoff_handler(self, details):
        if self._rate_limit_status is False:
            print(self._colorized_text(255, 0, 0,
                                       'The MyMemory translation service query rate Limit was reached. The querying '
                                       'process is entering a temporary hibernation mode.'))
            logger.info('The MyMemory translation service query rate limit was reached.')
            self._rate_limit_status = True

    def _mymemory_supported_languages(self):
        """
        This function determines if the requested source language is
        one supported languages for the MyMemory Translator.

        :return: language
        :rtype: string
        """
        # MyMemory Translator supported languages as of 09-03-2021
        supported_languages = {'af': 'afrikaans',
                               'sq': 'albanian',
                               'am': 'amharic',
                               'ar': 'arabic',
                               'hy': 'armenian',
                               'az': 'azerbaijani',
                               'eu': 'basque',
                               'be': 'belarusian',
                               'bn': 'bengali',
                               'bs': 'bosnian',
                               'bg': 'bulgarian',
                               'ca': 'catalan',
                               'ceb': 'cebuano',
                               'ny': 'chichewa',
                               'zh-CN': 'chinese (simplified)',
                               'zh-TW': 'chinese (traditional)',
                               'co': 'corsican',
                               'hr': 'croatian',
                               'cs': 'czech',
                               'da': 'danish',
                               'nl': 'dutch',
                               'en': 'english',
                               'eo': 'esperanto',
                               'et': 'estonian',
                               'tl': 'filipino',
                               'fi': 'finnish',
                               'fr': 'french',
                               'fy': 'frisian',
                               'gl': 'galician',
                               'ka': 'georgian',
                               'de': 'german',
                               'el': 'greek',
                               'gu': 'gujarati',
                               'ht': 'haitian creole',
                               'ha': 'hausa',
                               'haw': 'hawaiian',
                               'iw': 'hebrew',
                               'hi': 'hindi',
                               'hmn': 'hmong',
                               'hu': 'hungarian',
                               'is': 'icelandic',
                               'ig': 'igbo',
                               'id': 'indonesian',
                               'ga': 'irish',
                               'it': 'italian',
                               'ja': 'japanese',
                               'jw': 'javanese',
                               'kn': 'kannada',
                               'kk': 'kazakh',
                               'km': 'khmer',
                               'rw': 'kinyarwanda',
                               'ko': 'korean',
                               'ku': 'kurdish',
                               'ky': 'kyrgyz',
                               'lo': 'lao',
                               'la': 'latin',
                               'lv': 'latvian',
                               'lt': 'lithuanian',
                               'lb': 'luxembourgish',
                               'mk': 'macedonian',
                               'mg': 'malagasy',
                               'ms': 'malay',
                               'ml': 'malayalam',
                               'mt': 'maltese',
                               'mi': 'maori',
                               'mr': 'marathi',
                               'mn': 'mongolian',
                               'my': 'myanmar',
                               'ne': 'nepali',
                               'no': 'norwegian',
                               'or': 'odia',
                               'ps': 'pashto',
                               'fa': 'persian',
                               'pl': 'polish',
                               'pt': 'portuguese',
                               'pa': 'punjabi',
                               'ro': 'romanian',
                               'ru': 'russian',
                               'sm': 'samoan',
                               'gd': 'scots gaelic',
                               'sr': 'serbian',
                               'st': 'sesotho',
                               'sn': 'shona',
                               'sd': 'sindhi',
                               'si': 'sinhala',
                               'sk': 'slovak',
                               'sl': 'slovenian',
                               'so': 'somali',
                               'es': 'spanish',
                               'su': 'sundanese',
                               'sw': 'swahili',
                               'sv': 'swedish',
                               'tg': 'tajik',
                               'ta': 'tamil',
                               'tt': 'tatar',
                               'te': 'telugu',
                               'th': 'thai',
                               'tr': 'turkish',
                               'tk': 'turkmen',
                               'uk': 'ukrainian',
                               'ur': 'urdu',
                               'ug': 'uyghur',
                               'uz': 'uzbek',
                               'vi': 'vietnamese',
                               'cy': 'welsh',
                               'xh': 'xhosa',
                               'yi': 'yiddish',
                               'yo': 'yoruba',
                               'zu': 'zulu'}
        try:
            if self._source_language in supported_languages.keys():
                return self._source_language
            elif self._source_language in supported_languages.values():
                return self._source_language
            else:
                return None
        except LanguageNotSupportedException as error:
            """
            An exception is thrown if the user uses a language that is not supported by the translator
            """
            logger.info(f'The language provided is not one of the supported languages of the MyMemory '
                        f'translation service.')
            logger.info(f'Requested language: {self._source_language}')
            logger.error(''.join(traceback.format_tb(error.__traceback__)))

    # reference: https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry
    @staticmethod
    def _requests_retry_session(retries=5,
                                backoff_factor=0.5,
                                status_forcelist=(500, 502, 504),
                                session=None,
                                ):
        session = session or requests.Session()
        retry = Retry(
            total=retries,
            read=retries,
            connect=retries,
            backoff_factor=backoff_factor,
            status_forcelist=status_forcelist,
        )
        adapter = HTTPAdapter(max_retries=retry)
        session.mount('http://', adapter)
        session.mount('https://', adapter)
        return session

    def _mymemory_translate(self, original_language):
        """
        This function is used to translated a word from it source language, such as Spanish
        into American English.

        :param original_language: language to translated from
        :return: translated word
        :rtype: string
        """
        try:
            if self._email_address is None:
                print(self._colorized_text(255, 0, 0,
                                           'A valid email address is required to use the MyMemory translation '
                                           'service.'))
                sys.exit(1)
            else:
                response = self._requests_retry_session().get(self._url_to_query,
                                                              params={'langpair': f'{original_language}|en-us',
                                                                      'q': self._str_to_translate,
                                                                      'de': self._email_address},
                                                              headers=self._headers)

                if response.status_code == 429:
                    raise TooManyRequests()
                elif response.status_code != 200:
                    raise RequestError()
                else:
                    data = response.json()
                    if not data:
                        return f'MyMemory could not translate the word {self._str_to_translate}.'

                    translation = data.get('responseData').get('translatedText')
                    if translation:
                        return str(translation).lower().rstrip(punctuation)

        except NotValidLength as error:
            """
            The exception is thrown if the provided text exceed the length limit of the translator
            """
            logger.error(f'The text length for the word: {self._str_to_translate} exceed the length limit of '
                         f'the MyMemory translation service.')
            logger.error(''.join(traceback.format_tb(error.__traceback__)))
        except TooManyRequests as error:
            """
            The exception is thrown if an error occurred during the request call, e.g a connection problem.
            """
            logger.error('Server Error: There has been too many requests to the server.')
            logger.error(''.join(traceback.format_tb(error.__traceback__)))

    def _mymemory_translate_reverse(self, return_all=False):
        """
        This function is used to translated a word from it source language, such as Spanish
        into American English.

        :return: translated word
        :rtype: string
        """
        try:
            if self._email_address is None:
                print(self._colorized_text(255, 0, 0,
                                           'A valid email address is required to use the MyMemory translation '
                                           'service.'))
                sys.exit(1)
            else:
                response = self._requests_retry_session().get(self._url_to_query,
                                                              params={'langpair': f'en-us|{self._source_language}',
                                                                      'q': self._str_to_translate,
                                                                      'de': self._email_address},
                                                              headers=self._headers)

                if response.status_code == 429:
                    raise TooManyRequests()
                elif response.status_code != 200:
                    raise RequestError()
                else:
                    data = response.json()
                    if not data:
                        return f'MyMemory could not translate the word {self._str_to_translate}.'

                    translation = data.get('responseData').get('translatedText')

                    if translation:
                        return str(translation).lower().strip(punctuation)

        except NotValidLength as error:
            """
            The exception is thrown if the provided text exceed the length limit of the translator
            """
            logger.error(f'The text length for the word: {self._str_to_translate} exceed the length limit of '
                         f'the MyMemory translation service.')
            logger.error(''.join(traceback.format_tb(error.__traceback__)))
        except TooManyRequests as error:
            """
            The exception is thrown if an error occurred during the request call, e.g a connection problem.
            """
            logger.error('Server Error: There has been too many requests to the server.')
            logger.error(''.join(traceback.format_tb(error.__traceback__)))

    def translate_word(self):
        """
        This function is used to translated a word from it source language, such as Spanish
        into American English.

        :return: translated word
        :rtype: string
        """
        supported_language = self._mymemory_supported_languages()
        if supported_language:
            return self._mymemory_translate(supported_language)
        elif not supported_language:
            logger.info(f'The language provided is not one of the supported languages for the MyMemory '
                        f'translation service.')
            logger.info(f'Requested language: {self._source_language}')
            return None

    def reverse_translate(self):
        """
        This function is used to translated a word from American English into
        another language, such as Spanish.

        :return: translated word
        :rtype: string
        """
        return self._mymemory_translate_reverse()


import json
import datetime as dt
from datetime import timedelta, timezone
from dateutil.relativedelta import relativedelta, FR

import numpy as np
import pandas as pd
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.models import AjaxDataSource, ColumnDataSource, HoverTool, CrosshairTool, formatters, CustomJS, DateRangeSlider, Plot,  Grid, LinearAxis, MultiLine
from bokeh.layouts import column

from market_dicts import title_dict, price_types

class BPBuilder():
	def __init__(self, tables, ohlc_tables, db, minutes=30):
		self.tables = tables
		self.minutes = minutes
		self.ohlc_tables = ohlc_tables
		self.db = db

		self.TOOLS = "pan,box_zoom,reset"

	def build_returns_components(self):
		# xs, ys, color, label = [], [], [], []
		colors = [
			'#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce',\
			'#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a'
		]

		plot = figure(
			plot_height=500,
			plot_width=1250,
			x_axis_type='datetime',
			toolbar_location="above",
			tools=self.TOOLS,
			title='Daily Returns Going Back 3 Years'
		)
		for i, table in enumerate(self.ohlc_tables):
			cp = table.__tablename__
			price_type = price_types[cp[:6]]
			'''
			direct markets:
				return = t1 quote / t0 quote

			indirect markets:
				return  = t0 quote / t1 quote

			to make this more accurate (account for spread)

			direct markets:
				return = t1 ask / t0 buy

			indirect markets:
				return = t0 buy / t1 ask
			'''
			if price_type == 'BID':
				period = -1
			elif price_type == 'ASK':
				period = 1
			cols = ['timestamp', 'close']
			df = pd.read_sql_table(cp, self.db.engine, columns=cols)\
				.set_index('timestamp', drop=True)
			three_years_ago = dt.datetime.now() - timedelta(days=365*3)
			df = df[df.index >= three_years_ago] # include range selector
			df.drop_duplicates(inplace=True)
			df = df.pct_change(period)
			df['close'] = df['close']*100
			df.dropna(inplace=True)
			x = (
				np.array(
					df.index.values.tolist()
				) / 1000000
			).astype(int).tolist()
			y = df.close.values.tolist()
			plot.line(
				x,
				y,
				line_color=colors[i],
				legend_label=cp[:6].upper()
			)
		plot.legend.location = "top_left"
		plot.legend.click_policy="hide"
		plot.title.text_color = "#f8f9fa"
		plot.background_fill_color = '#f8f9fa'
		plot.border_fill_color = "#343a40"
		plot.xaxis.axis_label_text_color = "#868e96"
		plot.yaxis.axis_label_text_color = "#868e96"
		plot.xaxis.major_label_text_color = "#868e96"
		plot.yaxis.major_label_text_color = "#868e96"
		plot.xgrid.visible=False
		return components(plot)

	def build_ohlc_components(self):
		plot_dict = {}
		for table in self.ohlc_tables:
			tname = table.__tablename__
			cp = tname[:6]

			df = pd.read_sql_table(
				tname,
				self.db.engine,
				columns=['timestamp','open', 'high','low','close']
			)
			df.drop_duplicates(inplace=True)
			r = pd.date_range(
				start=df.timestamp.min(), end=df.timestamp.max()
			)
			df = df.set_index('timestamp').reindex(r).fillna(np.NaN)
			df.index = df.index.rename('timestamp')

			df['open_inc'],df['high_inc'],df['low_inc'],df['close_inc']=\
			df['open'],    df['high'],    df['low'],    df['close']
			df['open_dec'],df['high_dec'],df['low_dec'],df['close_dec']=\
			df['open'],    df['high'],    df['low'],    df['close']

			inc = df.close > df.open
			dec = df.open > df.close

			df['open_dec'][inc]=None
			df['high_dec'][inc]=None
			df['low_dec'][inc]=None
			df['close_dec'][inc]=None

			df['open_inc'][dec]=None
			df['high_inc'][dec]=None
			df['low_inc'][dec]=None
			df['close_inc'][dec]=None

			source = ColumnDataSource(data=df)
			reference = ColumnDataSource(data=df)

			plot = figure(
				x_axis_type="datetime",
				plot_height=250,
				plot_width=1400,
				toolbar_location="above",
				tools=self.TOOLS,
				# these didn't do much
				# sizing_mode='stretch_width',
				# sizing_mode='stretch_height',
				# sizing_mode='stretch_both',
				# sizing_mode='scale_width',
				# sizing_mode='scale_height',
				# sizing_mode='scale_both',
				# sizing_mode='fixed',
				title=title_dict[cp]
			)
			seg = plot.segment(
				x0='timestamp',
				y0='high',
				x1='timestamp',
				y1='low',
				color='black',
				source=source
			)
			inc_bar = plot.vbar(
				x='timestamp',
				width=20*60*60*1000,
				top='close_inc',
				bottom='open_inc',
				fill_color="#D5E1DD",
				line_color="black",
				source=source
			)
			dec_bar = plot.vbar(
				x='timestamp',
				width=20*60*60*1000,
				top='open_dec',
				bottom='close_dec',
				fill_color="#F2583E",
				line_color="black",
				source=source
			)

			date_range_slider = DateRangeSlider(
				# width=400,
				align='center',
				margin=(25,50,5,50),
				# format="%x",
				format="%B %e, %Y",
				value=(
					df.index.min(),
					df.index.max()
				),
				start=df.index.min(),
				end=df.index.max(),
				background='#343a40',
				bar_color='#f8f9fa',
				step=86400000
			)

			args = dict(
				source=source,
				reference=reference
			)
			code =\
			"""
			const data = source.data;
			const data_ref = reference.data;

			const from_date = this.value[0];
			const to_date = this.value[1];

			var from_pos = data_ref['timestamp'].indexOf(to_date);
			var to_pos = data_ref['timestamp'].indexOf(from_date);

			data['timestamp'] = data_ref['timestamp'].slice(to_pos,from_pos);

			data['high'] = data_ref['high'].slice(to_pos,from_pos);
			data['low'] = data_ref['low'].slice(to_pos,from_pos);

			data['open_inc'] = data_ref['open_inc'].slice(to_pos,from_pos);
			data['high_inc'] = data_ref['high_inc'].slice(to_pos,from_pos);
			data['low_inc'] = data_ref['low_inc'].slice(to_pos,from_pos);
			data['close_inc'] = data_ref['close_inc'].slice(to_pos,from_pos);

			data['open_dec'] = data_ref['open_dec'].slice(to_pos,from_pos);
			data['high_dec'] = data_ref['high_dec'].slice(to_pos,from_pos);
			data['low_dec'] = data_ref['low_dec'].slice(to_pos,from_pos);
			data['close_dec'] = data_ref['close_dec'].slice(to_pos,from_pos);

			source.change.emit();
			"""
			callback = CustomJS(args=args, code=code)
			date_range_slider.js_on_change("value", callback)

			# NaN's sometimes show up in hover tool
			hover_tool = HoverTool(
				tooltips=[
				# https://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.formatters.DatetimeTickFormatter
					('timestamp', '@{timestamp}{%x}'),
					('open', '@{open}{%0.4f}'),
					('high', '@{high}{%0.4f}'),
					('low', '@{low}{%0.4f}'),
					('close', '@{close}{%0.4f}')
				],
				formatters={
					'@{timestamp}': 'datetime',
					'@{open}': 'printf',
					'@{high}': 'printf',
					'@{low}': 'printf',
					'@{close}': 'printf'

				},
				renderers=[inc_bar,dec_bar]
			)
			plot.add_tools(hover_tool)
			plot.background_fill_color = '#f8f9fa'
			plot.border_fill_color = "#343a40"
			plot.title.text_color = "#f8f9fa"
			plot.xaxis.axis_label_text_color = "#f8f9fa"
			plot.yaxis.axis_label_text_color = "#f8f9fa"
			plot.xaxis.major_label_text_color = "#f8f9fa"
			plot.yaxis.major_label_text_color = "#f8f9fa"
			plot.xgrid.visible = False
			plot.xaxis.formatter = formatters.DatetimeTickFormatter(
				days="%m/%d/%Y",
				months = "%m/%d/%Y"
			)
			# plot.background_fill_color = '#868e96'
			plot_dict[cp] = column(plot, date_range_slider)

		return components(plot_dict)

	def build_components(self, is_closed):
		plot_dict = {}
		for table in self.tables:
			cp = table.__tablename__
			url =f"http://localhost:5000/data/{cp}/{self.minutes}"
			if is_closed:
				# don't really need to use ajax
				source = AjaxDataSource(
					data_url=url,
					polling_interval=1000*60*60*48, # 2 days
					mode='replace'
				)
			else:
				source = AjaxDataSource(
					data_url=url,
					polling_interval=1000,
					mode='replace'
				)
			plot = figure(
				plot_height=150,
				plot_width=1200,
				x_axis_type='datetime',
				toolbar_location="above",
				tools=self.TOOLS,
			)

			plot.xaxis.formatter = formatters.DatetimeTickFormatter(
				days="%m/%d",
				hours = "%l:%M %P",
				hourmin = "%l:%M %P",
				minutes="%l:%M %P",
				minsec="%l:%M:%S %P",
				seconds="%l:%M:%S %P",
				microseconds="%l:%M:%S:%f %P",
				milliseconds="%l:%M:%S:%f %P"

			)
			# plot.xaxis.axis_label = "UTC"

			line = plot.line(
				'timestamp',
				'rate',
				source=source
			)
			plot.background_fill_color = '#f8f9fa'
			plot.border_fill_color = "#343a40"
			plot.xaxis.axis_label_text_color = "#868e96"
			plot.yaxis.axis_label_text_color = "#868e96"
			plot.xaxis.major_label_text_color = "#868e96"
			plot.yaxis.major_label_text_color = "#868e96"
			plot.xgrid.visible=False

			hover_tool = HoverTool(
				tooltips=[
				# https://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.formatters.DatetimeTickFormatter
					('timestamp', '@{timestamp}{%d %b %Y %l:%M:%S:%N %P}'),
					('rate', '@{rate}{%0.4f}'),
				],
				formatters={
					'@{timestamp}': 'datetime',
					'@{rate}': 'printf'
				}
			)
			plot.add_tools(hover_tool)
			callback = CustomJS(
				args={'line':line, 'source':source, 'cp':cp}, code="""
				var rates = source.data.rate;
				var first_val = rates[0];
				var last_val = rates[rates.length-1];
				var delta = Number.parseFloat(Math.abs(last_val-first_val)).toFixed(5);
				var increasing = first_val < last_val;
				if (increasing) {
					line.glyph.line_color = 'green';
				} else {
					line.glyph.line_color = 'red';
				}
						var card_class_dict = {
						true: {
						  "card_class":"card-text text-center font-weight-lighter text-success",
						  "new_color": "green",
						  "arrow": "▲"
						},
						false: {
						  "card_class":"card-text text-center font-weight-lighter text-danger",
						  "new_color": "red",
						  "arrow": "▼"
						  }
						}
						var formats = card_class_dict[increasing];

						$('#delta_'+cp)
						.removeClass()
						.addClass(
							  formats['card_class']
						)
						.html(
							formats["arrow"].concat(delta)
						);
						$('#current_'+cp).html(last_val);

				"""
			)
			source.js_on_change('change:data', callback)
			plot_dict[cp] = plot
		return components(plot_dict)


## Portions of Code from, copyright 2018 Jochen Gast

from __future__ import absolute_import, division, print_function

import argparse
import colorama
import inspect
import os
import sys
import torch
import logging

import datasets
import losses
import models
import augmentations

from core import tools, logger, optim

def _get_type_from_arg(arg):
    if isinstance(arg, bool):
        return tools.str2bool
    else:
        return type(arg)

def _add_arguments_for_module(parser,
                              module,
                              name,
                              default_class,
                              add_class_argument=True,   # whether to add class choice as argument
                              include_classes="*",
                              exclude_classes=[],
                              exclude_params=["self","args"],
                              param_defaults={},          # allows to overwrite any default param
                              forced_default_types={},    # allows to set types for known arguments
                              unknown_default_types={}):  # allows to set types for unknown arguments

    # -------------------------------------------------------------------------
    # Determine possible choices from class names in module, possibly apply include/exclude filters
    # -------------------------------------------------------------------------
    module_dict = tools.module_classes_to_dict(
        module, include_classes=include_classes, exclude_classes=exclude_classes)

    # -------------------------------------------------------------------------
    # Parse known arguments to determine choice for argument name
    # -------------------------------------------------------------------------
    if add_class_argument:
        parser.add_argument(
            "--%s" % name, type=str, default=default_class, choices=module_dict.keys())
        known_args = parser.parse_known_args(sys.argv[1:])[0]
    else:
        # build a temporary parser, and do not add the class as argument
        tmp_parser = argparse.ArgumentParser()
        tmp_parser.add_argument(
            "--%s" % name, type=str, default=default_class, choices=module_dict.keys())
        known_args = tmp_parser.parse_known_args(sys.argv[1:])[0]

    class_name = vars(known_args)[name]

    # -------------------------------------------------------------------------
    # If class is None, there is no point in trying to parse further arguments
    # -------------------------------------------------------------------------
    if class_name is None:
        return

    # -------------------------------------------------------------------------
    # Get constructor of that argument choice
    # -------------------------------------------------------------------------
    class_constructor = module_dict[class_name]

    # -------------------------------------------------------------------------
    # Determine constructor argument names and defaults
    # -------------------------------------------------------------------------
    try:
        argspec = inspect.getargspec(class_constructor.__init__)
        argspec_defaults = argspec.defaults if argspec.defaults is not None else []
        full_args = argspec.args
        default_args_dict = dict(zip(argspec.args[-len(argspec_defaults):], argspec_defaults))
    except TypeError:
        print(argspec)
        print(argspec.defaults)
        raise ValueError("unknown_default_types should be adjusted for module: '%s.py'" % name)

    # -------------------------------------------------------------------------
    # Add sub_arguments
    # -------------------------------------------------------------------------
    for argname in full_args:

        # ---------------------------------------------------------------------
        # Skip
        # ---------------------------------------------------------------------
        if argname in exclude_params:
            continue

        # ---------------------------------------------------------------------
        # Sub argument name
        # ---------------------------------------------------------------------
        sub_arg_name = "%s_%s" % (name, argname)

        # ---------------------------------------------------------------------
        # If a default argument is given, take that one
        # ---------------------------------------------------------------------
        if argname in param_defaults.keys():
            parser.add_argument(
                "--%s" % sub_arg_name,
                type=_get_type_from_arg(param_defaults[argname]),
                default=param_defaults[argname])

        # ---------------------------------------------------------------------
        # If a default parameter can be inferred from the module, pick that one
        # ---------------------------------------------------------------------
        elif argname in default_args_dict.keys():

            # -----------------------------------------------------------------
            # Check for forced default types
            # -----------------------------------------------------------------
            if argname in forced_default_types.keys():
                argtype = forced_default_types[argname]
            else:
                argtype = _get_type_from_arg(default_args_dict[argname])
            parser.add_argument(
                "--%s" % sub_arg_name, type=argtype, default=default_args_dict[argname])

        # ---------------------------------------------------------------------
        # Take from the unkowns list
        # ---------------------------------------------------------------------
        elif argname in unknown_default_types.keys():
            parser.add_argument("--%s" % sub_arg_name, type=unknown_default_types[argname])

        else:
            raise ValueError(
                "Do not know how to handle argument '%s' for class '%s'" % (argname, name))

def _add_special_arguments(parser):
    # -------------------------------------------------------------------------
    # Known arguments so far
    # -------------------------------------------------------------------------
    known_args = vars(parser.parse_known_args(sys.argv[1:])[0])

    # -------------------------------------------------------------------------
    # Add special arguments for training
    # -------------------------------------------------------------------------
    training_loss = known_args["training_loss"]
    if training_loss is not None:
        parser.add_argument("--training_key", type=str, default="total_loss")

    # -------------------------------------------------------------------------
    # Add special arguments for validation
    # -------------------------------------------------------------------------
    validation_loss = known_args["validation_loss"]
    if validation_loss is not None:
        parser.add_argument("--validation_key", type=str, default="total_loss")
        parser.add_argument("--validation_key_minimize", type=tools.str2bool, default=True)

    # -------------------------------------------------------------------------
    # Add special arguments for checkpoints
    # -------------------------------------------------------------------------
    checkpoint = known_args["checkpoint"]
    if checkpoint is not None:
        parser.add_argument(
            "--checkpoint_mode", type=str, default="resume_from_latest",
            choices=["resume_from_latest", "resume_from_best"])

        parser.add_argument(
            "--checkpoint_include_params", type=tools.str2list, default="[*]")
        parser.add_argument(
            "--checkpoint_exclude_params", type=tools.str2list, default="[]")

    # -------------------------------------------------------------------------
    # Add special arguments for optimizer groups
    # -------------------------------------------------------------------------
    parser.add_argument("--optimizer_group", action="append", type=tools.str2dict, default=None)

def _parse_arguments():

    # -------------------------------------------------------------------------
    # Argument parser and shortcut function to add arguments
    # -------------------------------------------------------------------------
    parser = argparse.ArgumentParser()
    add = parser.add_argument

    # -------------------------------------------------------------------------
    # Standard arguments
    # -------------------------------------------------------------------------
    add("--batch_size", type=int, default=1)
    add("--batch_size_val", type=int, default=1)
    add("--checkpoint", type=tools.str2str_or_none, default=None)
    add("--cuda", type=tools.str2bool, default=True)
    add("--evaluation", type=tools.str2bool, default=False)
    add("--num_workers", type=int, default=4)
    add("--save", "-s", default="temp_exp/", type=str)
    add("--seed", type=int, default=1)
    add("--start_epoch", type=int, default=1)
    add("--total_epochs", type=int, default=1)
    add("--save_flow", type=tools.str2bool, default=False)
    add("--save_disp", type=tools.str2bool, default=False)
    add("--save_disp2", type=tools.str2bool, default=False)
    add("--finetuning", type=tools.str2bool, default=False)
    ### for c3d
    add("--c3d_config_file", type=str, default="scripts/c3d_config.txt")
    add("--inbalance_to_closer", type=float, default=1, help="used in L1 depth loss, which favors closer GT depth when GT depth pcl has overlapping area caused by viewing angle difference. ")
    add("--disable_c3d", action="store_true", help="if specified, not applying any c3d loss")
    add("--save_per_epoch", type=int, default=0)
    add("--dep_warp_loss", action="store_true", help="if specified, any depth l1 loss on warped depth")
    add("--dep_weight", type=float, default=1e-3, help="weight for depth l1 loss ")
    add("--c3d_weight", type=float, default=1e-4, help="weight for c3d loss ")
    add("--c3d_knn_mode", action="store_true", help="if specified, use c3d loss calculated based on knn")
    add("--rigid", action="store_true", help="if set, predict camera motion and use it to compose the rigid flow")
    add("--rigid_pred", type=str, default="full", choices=["full", "res"], help="decide the meaning of the flow prediction. ")
    add("--rigid_warp", type=str, default="full", choices=["full", "res", "rigid"], help="how to warp next level feature maps before constructing cost volume. ")
    add("--rigid_pass", type=str, default="warp", choices=["warp", "pred"], help="what to feed to next level flow decoder. ")
    add("--save_pic_tboard", action="store_true", help="if specified, show visualization in tensorboard. ")
    add("--disable_residual_pred", action="store_true", help="if specified, predict full flow instead of add-on to last level predictions. ")
    add("--reg_depth", action="store_true", help="if specified, predict depth in meters, instead of normalized disparity ")
    add("--hourglass_decoder", action="store_true", help="if specified, predict using an hourglass structure (U-Net based on ResNet18) with resuable weight and consistent resolution. ")
    add("--highres_loss", action="store_true", help="if specified, using high resolution predictions to calculate loss. Only valid if hourglass_decoder is chosen.  ")
    add("--rigid_flow_loss", action="store_true", help="if specified, calculate loss for rigid flow separately. Otherwise just penalize difference between rigid flow and full flow at masked region.  ")
    add("--strict_flow_acc", action="store_true", help="if specified, accumulate the residual flow considering the shift of flow origin.  ")
    add("--strict_flow_acc_ramp", type=int, default=0, help="if greater than zero, gradually shift from original residual flow to warped residual flow in specified epochs. ")
    add("--c3d_pose_weight", type=float, default=0, help="if greater than zero, calculate pose loss using c3d loss between gt lidar scans with transformation. ")
    add("--shared_posehead", action="store_true", help="if specified, use shared pose predictor. Only valid if not using hourglass_decoder. ")
    add("--pose_not_separable", action="store_true", help="if specified, use FCN instead of two separate layers in spatial and feature dimensions.  ")
    add("--use_posenet", action="store_true", help="if specified, use a dedicated pose net for pose regression.  ")
    add("--strict_flow_acc_uvd", action="store_true", help="if specified, use uvd prediction as sceneflow representation and concat using strict recursive inference.  ")
    add("--pred_xyz_add_uvd", action="store_true", help="if specified, use uvd to aggregate while use xyz in prediction.  ")

    # -------------------------------------------------------------------------
    # Arguments inferred from losses
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        losses,
        name="training_loss",
        default_class=None,
        exclude_classes=["_*", "Variable"],
        exclude_params=["self","args"])

    _add_arguments_for_module(
        parser,
        losses,
        name="validation_loss",
        default_class=None,
        exclude_classes=["_*", "Variable"],
        exclude_params=["self","args"])

    # -------------------------------------------------------------------------
    # Arguments inferred from models
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        models,
        name="model",
        default_class="FlowNet1S",
        exclude_classes=["_*", "Variable"],
        exclude_params=["self","args"])

    # -------------------------------------------------------------------------
    # Arguments inferred from augmentations for training
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        augmentations,
        name="training_augmentation",
        default_class=None,
        exclude_classes=["_*"],
        exclude_params=["self","args"],
        forced_default_types={"crop": tools.str2intlist})

    # -------------------------------------------------------------------------
    # Arguments inferred from augmentations for validation
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        augmentations,
        name="validation_augmentation",
        default_class=None,
        exclude_classes=["_*"],
        exclude_params=["self","args"])

    # -------------------------------------------------------------------------
    # Arguments inferred from datasets for training
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        datasets,
        name="training_dataset",
        default_class=None,
        exclude_params=["self", "args", "is_cropped"],
        exclude_classes=["_*"],
        unknown_default_types={"root": str})

    # -------------------------------------------------------------------------
    # Arguments inferred from datasets for validation
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        datasets,
        name="validation_dataset",
        default_class=None,
        exclude_params=["self", "args", "is_cropped"],
        exclude_classes=["_*"],
        unknown_default_types={"root": str})

    # -------------------------------------------------------------------------
    # Arguments inferred from PyTorch optimizers
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        optim,
        name="optimizer",
        default_class="Adam",
        exclude_classes=["_*","Optimizer", "constructor"],
        exclude_params=["self", "args", "params"],
        forced_default_types={"lr": float,
                              "momentum": float,
                              "dampening": float,
                              "weight_decay": float,
                              "nesterov": tools.str2bool})

    # -------------------------------------------------------------------------
    # Arguments inferred from PyTorch lr schedulers
    # -------------------------------------------------------------------------
    _add_arguments_for_module(
        parser,
        torch.optim.lr_scheduler,
        name="lr_scheduler",
        default_class=None,
        exclude_classes=["_*","Optimizer"],
        exclude_params=["self", "args", "optimizer"],
        unknown_default_types={"T_max": int,
                               "lr_lambda": str,
                               "step_size": int,
                               "milestones": tools.str2intlist,
                               "gamma": float})

    # -------------------------------------------------------------------------
    # Special arguments
    # -------------------------------------------------------------------------
    _add_special_arguments(parser)

    # -------------------------------------------------------------------------
    # Parse arguments
    # -------------------------------------------------------------------------
    args = parser.parse_args()

    # -------------------------------------------------------------------------
    # Parse default arguments from a dummy commandline not specifying any args
    # -------------------------------------------------------------------------
    defaults = vars(parser.parse_known_args(['--dummy'])[0])

    # -------------------------------------------------------------------------
    # Consistency checks
    # -------------------------------------------------------------------------
    args.cuda = args.cuda and torch.cuda.is_available()

    return args, defaults

def postprocess_args(args):

    # ----------------------------------------------------------------------------
    # Get appropriate class constructors from modules
    # ----------------------------------------------------------------------------
    args.model_class = tools.module_classes_to_dict(models)[args.model]

    if args.optimizer is not None:
        optimizer_classes = tools.module_classes_to_dict(optim)
        args.optimizer_class = optimizer_classes[args.optimizer]

    if args.training_loss is not None:
        loss_classes = tools.module_classes_to_dict(losses)
        args.training_loss_class = loss_classes[args.training_loss]

    if args.validation_loss is not None:
        loss_classes = tools.module_classes_to_dict(losses)
        args.validation_loss_class = loss_classes[args.validation_loss]

    if args.lr_scheduler is not None:
        scheduler_classes = tools.module_classes_to_dict(torch.optim.lr_scheduler)
        args.lr_scheduler_class = scheduler_classes[args.lr_scheduler]

    if args.training_dataset is not None:
        dataset_classes = tools.module_classes_to_dict(datasets)
        args.training_dataset_class = dataset_classes[args.training_dataset]

    if args.validation_dataset is not None:
        dataset_classes = tools.module_classes_to_dict(datasets)
        args.validation_dataset_class = dataset_classes[args.validation_dataset]

    if args.training_augmentation is not None:
        augmentation_classes = tools.module_classes_to_dict(augmentations)
        args.training_augmentation_class = augmentation_classes[args.training_augmentation]

    if args.validation_augmentation is not None:
        augmentation_classes = tools.module_classes_to_dict(augmentations)
        args.validation_augmentation_class = augmentation_classes[args.validation_augmentation]

    return args

def setup_logging_and_parse_arguments(blocktitle):
    # ----------------------------------------------------------------------------
    # Get parse commandline and default arguments
    # ----------------------------------------------------------------------------
    args, defaults = _parse_arguments()

    # ----------------------------------------------------------------------------
    # Setup logbook before everything else
    # ----------------------------------------------------------------------------
    logger.configure_logging(os.path.join(args.save, 'logbook.txt'))

    # ----------------------------------------------------------------------------
    # Write arguments to file, as txt
    # ----------------------------------------------------------------------------
    tools.write_dictionary_to_file(
        sorted(vars(args).items()),
        filename=os.path.join(args.save, 'args.txt'))

    # ----------------------------------------------------------------------------
    # Log arguments
    # ----------------------------------------------------------------------------
    with logger.LoggingBlock(blocktitle, emph=True):
        for argument, value in sorted(vars(args).items()):
            reset = colorama.Style.RESET_ALL
            color = reset if value == defaults[argument] else colorama.Fore.CYAN
            logging.info('{}{}: {}{}'.format(color, argument, value, reset))

    # ----------------------------------------------------------------------------
    # Postprocess
    # ----------------------------------------------------------------------------
    args = postprocess_args(args)

    return args


# -*- coding: utf-8 -*-
"""
Created on Mon Oct 19 09:50:32 2015

@author: mamauer
"""
import os
import glob
from morphablegraphs.animation_data.bvh import BVHReader
import numpy as np
from morphablegraphs.construction.preprocessing import bitvector as bv
from morphablegraphs.construction.fpca.fpca_semantic_data import FPCASemanticData
from morphablegraphs.construction.motion_primitive.statistical_model_trainer import StatisticalModelTrainer
from morphablegraphs.motion_model.motion_primitive import MotionPrimitive
import matplotlib.pyplot as plt
import copy
import json
import scipy.interpolate as si

def test_bitvector_calulation():
    test_file = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\sidestepLeft\walk_001_4_sidestepLeft_139_263.bvh'
    bvhfile = BVHReader(test_file)
    features = ['Bip01_L_Toe0', 'Bip01_R_Toe0']
    bitvector = bv.calc_bitvector_walking(bvhfile.frames,
                                          features,
                                          verbose=True)
    print(bitvector)

def test_keyframe_annotation():
    skeleton_file = r'..\..\..\skeleton.bvh'
    test_file = r'C:\repo\data\1 - MoCap\2 - Rocketbox retargeting\Take_walk\walk_001_1.bvh'
    bvhfile = BVHReader(test_file)
    features = ['Bip01_L_Toe0', 'Bip01_R_Toe0']
    keyframes = bv.detect_keyframes(bvhfile.frames, features, verbose=False)
    print(keyframes)

def majority_vote(index, vector, w):
    selected_elements = vector[index-w: index+w+1]
    one_counter = sum(selected_elements == 1)
    zero_counter = sum(selected_elements == 0)
    if one_counter > zero_counter:
        vector[index] = 1
    else:
        vector[index] = 0

def smooth_bitvector(tmp, w=2):
    bitvectors = copy.deepcopy(tmp)
    features = bitvectors.keys()
    for feature in features:
        extented_bitvector = np.zeros(len(bitvectors[feature]) + 2*w)
        extented_bitvector[:w] = bitvectors[feature][0]
        extented_bitvector[-w:] = bitvectors[feature][-1]
        extented_bitvector[w: -w] = bitvectors[feature]
        # print(len(extented_bitvector))
        # print(extented_bitvector)
        for i in range(len(bitvectors[feature])):
            majority_vote(i+w, extented_bitvector, w)
        bitvectors[feature] = extented_bitvector[w : -w]
    return bitvectors

def test_smooth_bitvector():
    bitvector = {"left": np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1])}
    # print(len(bitvector['left']))
    blocks1 = bv.count_blocks(bitvector['left'])
    n_blocks1 = len(blocks1)

    smoothed_bitvector = smooth_bitvector(bitvector)
    print(smoothed_bitvector)
    blocks2 = bv.count_blocks(smoothed_bitvector['left'])
    n_blocks2 = len(blocks2)

    fig = plt.figure()
    plt.plot(bitvector['left'], 'b')
    plt.plot(smoothed_bitvector['left'], 'g')
    plt.ylim([-1, 2])
    plt.show()

def test_gen_annotation():
    # bvhfile = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\leftStance\
    bvhfile = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\rightStance\walk_001_1_rightStance_472_514.bvh'
    feature_points = ['Bip01_L_Toe0', 'Bip01_R_Toe0']
    motion_primitive_model = 'walk_rightStance'
    anno_vec = bv.gen_foot_contact_annotation(bvhfile, feature_points, motion_primitive_model)
    print(anno_vec)

def gen_walk_annotation():
    test_folder = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\rightStance'
    motion_primitive_model = 'walk_rightStance'
    feature_points = ['Bip01_L_Toe0', 'Bip01_R_Toe0']
    annotation_data = {}
    test_bvbfiles = glob.glob(test_folder + os.sep + '*.bvh')
    for item in test_bvbfiles:
        filename = os.path.split(item)[-1]
        anno_vec = bv.gen_foot_contact_annotation(item, feature_points, motion_primitive_model)
        # anno_vec['left_contact'] = anno_vec['left_contact'].tolist()
        # anno_vec['right_contact'] = anno_vec['right_contact'].tolist()
        annotation_data[filename] = anno_vec
    output_filename = test_folder + os.sep + 'walk_rightStance_semantic_annotation.json'
    with open(output_filename, 'w') as outfile:
        json.dump(annotation_data, outfile)

def load_spatial_temporal_params():
    test_file = r'C:\repo\data\2 - PCA\combine_spatial_temporal\walk_leftStance_low_dimensional_motion_data.json'
    with open(test_file, 'r') as infile:
        low_dimensional_data = json.load(infile)
    print(low_dimensional_data.keys())
    print(len(low_dimensional_data['motion_data']))
    print(low_dimensional_data['n_basis_temporal'])

def load_morphable_model():
    test_morphable_model = r'C:\repo\data\3 - Motion primitives\motion_primitives_quaternion_PCA95\elementary_action_models\elementary_action_walk\walk_leftStance_quaternion_mm.json'
    with open(test_morphable_model, 'r') as infile:
        data = json.load(infile)
    print(data.keys())
    # print(data['b_spline_knots_time'])
    # knots = data['b_spline_knots_time']
    # annotation_data_file = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\leftStance\walk_leftStance_semantic_annotation.json'
    # with open(annotation_data_file, 'r') as infile:
    #     annotation_data = json.load(infile)
    # keys = annotation_data.keys()
    # print(annotation_data[keys[0]])
    # left_annotation = annotation_data[keys[1]]['left_contact']
    # right_annotation = annotation_data[keys[0]]['right_contact']
    # x = range(len(left_annotation))
    # s_knots, s_coeffs, s_degree = si.splrep(x, left_annotation, t=knots[4:-4])
    # print(s_knots)
    # print(s_coeffs)
    # print(s_degree)
    # # evaluate fitted spline
    # evaluate_points = np.linspace(s_knots[0], s_knots[-1], 200)
    # points = si.splev(evaluate_points, (s_knots, s_coeffs[:-4], s_degree))
    # fig = plt.figure()
    # plt.plot(evaluate_points, points)
    # plt.plot(range(len(left_annotation)), left_annotation)
    # plt.show()

def test_fpca_semantic_data():
    data_file = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\leftStance\walk_leftStance_semantic_annotation.json'
    motion_primitive_model_file = r'C:\repo\data\3 - Motion primitives\motion_primitives_quaternion_PCA95\elementary_action_models\elementary_action_walk\walk_leftStance_quaternion_mm.json'
    with open(motion_primitive_model_file, 'r') as infile:
        model_data = json.load(infile)
    knots = model_data['b_spline_knots_time']
    fpca_semantic = FPCASemanticData()
    fpca_semantic.load_data_from_file(data_file)

    fpca_semantic.set_knots(knots)
    fpca_semantic.spline_representation()
    print(np.array(fpca_semantic.semantic_spline.values()).shape)
    fpca_semantic.dimension_reduction()
    fpca_semantic.save_data('walk_leftStance_semantic_low_dimensional_data.json')

def test_model_semantic_statistical_model():
    spatial_temporal_file = r'C:\repo\data\2 - PCA\combine_spatial_temporal\walk_rightStance_low_dimensional_motion_data.json'
    semantic_file = r'walk_rightStance_semantic_low_dimensional_data.json'
    model_trainer = StatisticalModelTrainer()
    model_trainer.load_data_from_file(spatial_temporal_file, semantic_file)
    model_trainer._train_gmm()
    model_trainer._create_gmm()
    # print(model_trainer.get_b_spline_knots(8, 46))
    model_trainer._save_model()

def check_semantic_labels():
    semantic_file = r'C:\repo\data\1 - MoCap\4 - Alignment\elementary_action_walk\rightStance\walk_rightStance_semantic_annotation.json'
    with open(semantic_file, 'r') as infile:
        semantic_data = json.load(infile)
    # count = 0
    # for filename in semantic_data.keys():
    #     count += 1
    #     if semantic_data[filename]['left_contact'][-1] != 1.0:
    #         print(filename, 'left_contact')
    #     if semantic_data[filename]['right_contact'][-1] != 1.0:
    #         print(filename, 'right_contact')
    # print(count)

    # spatial_temporal_file = r'C:\repo\data\2 - PCA\combine_spatial_temporal\walk_rightStance_low_dimensional_motion_data.json'
    # with open(spatial_temporal_file, 'r') as infile:
    #     spatial_temporal_data = json.load(infile)
    # print(spatial_temporal_data.keys())
    model_file = r'C:\git-repo\mgrd\data\walk_leftStance_quaternion_mm_with_semantic.json'
    with open(model_file, 'r') as infile:
        model_data = json.load(infile)
    print(model_data.keys())
    print(model_data['n_dim_semantic'])
    print(model_data['n_dim_spatial'])
    print(model_data['n_dim_time'])
    # knots = model_data['b_spline_knots_time']
    # print(knots)

    # semantci_file = r'walk_leftStance_semantic_low_dimensional_data.json'
    # with open(semantci_file, 'r') as infile:
    #     semantic_data = json.load(infile)
    # print(semantic_data.keys())
    # low_dimensional_data = np.array(semantic_data['semantic_low_dimensional_data'])
    # print(low_dimensional_data.shape)
    # s = np.sum(low_dimensional_data, axis=0)
    # print(s)

    # mean_vec = semantic_data['semantic_mean_vec']
    # left_contact_mean = mean_vec[:8]
    # right_contact_mean = mean_vec[8:]
    # left_contact_spline = (knots, left_contact_mean, 3)
    # right_contact_spline = (knots, right_contact_mean, 3)
    # x = np.linspace(knots[0], knots[-1], 100)
    # left_contact_points = si.splev(x, left_contact_spline)
    # right_contact_points = si.splev(x, right_contact_spline)
    # fig = plt.figure()
    # plt.plot(x, left_contact_points, label='left contact')
    # plt.plot(x, right_contact_points, label='right contact')
    # plt.legend()
    # plt.show()
    # # print(mean_vec)

def add_mean_info_spatial_temporal_params():
    spatial_temporal_file = r'C:\repo\data\2 - PCA\combine_spatial_temporal\walk_rightStance_low_dimensional_motion_data.json'
    morphable_model_file = r'C:\repo\data\3 - Motion primitives\motion_primitives_quaternion_PCA95\elementary_action_models\elementary_action_walk\walk_rightStance_quaternion_mm.json'
    with open(morphable_model_file, 'r') as infile:
        morphable_model_data = json.load(infile)
    with open(spatial_temporal_file, 'r') as infile:
        spatial_temporal_data = json.load(infile)
    # write mean_spatial, mean_temporal and n_dim_spatial into spatial_temporal_data
    spatial_temporal_data['mean_spatial_vector'] = morphable_model_data['mean_spatial_vector']
    spatial_temporal_data['mean_time_vector'] = morphable_model_data['mean_time_vector']
    spatial_temporal_data['n_dim_spatial'] = morphable_model_data['n_dim_spatial']
    with open(spatial_temporal_file, 'w') as outfile:
        json.dump(spatial_temporal_data, outfile)

def evaluate_semantic_spline(spline, granularity=100):
    knots, coeffs, degree = spline
    time_vector = np.linspace(knots[0], knots[-1], granularity)
    return si.splev(time_vector, spline)

def test_sample_semantic_morphable_model():
    model_file = r'C:\repo\data\3 - Motion primitives\motion_primitives_quaternion_PCA95\elementary_action_semantic_models\elementary_action_walk\walk_rightStance_quaternion_mm_with_low_level_semantic.json'
    # with open(model_file, 'r') as infile:
    #     semantic_model_data = json.load(infile)
    # print(semantic_model_data.keys())
    # print(semantic_model_data['semantic_annotation'])
    walk_leftStance = MotionPrimitive(model_file)
    sample = walk_leftStance.sample_low_dimensional_vector()
    print(sample)
    sample = walk_leftStance.sample()
    print(sample.semantic_spline)
    # points = evaluate_semantic_spline(sample.semantic_spline, granularity=100)
    # for vec in points:
    #     print(vec[-1])
    # print(points[-1])
    # semantic_annotation = sample.gen_semantic_annotation()
    # print(semantic_annotation)
    # N = 100
    # # bad_samples = 0
    # for i in range(N):
    #     sample = walk_leftStance.sample()
    #     points = evaluate_semantic_spline(sample.semantic_spline, granularity=100)
    #     for vec in points:
    #         print(vec[-1])
    #     sample = walk_leftStance.sample()
    #     annotations = sample.gen_semantic_annotation()
    #     count = 0
    #     for annot in annotations:
    #         if annot[-1] != 1:
    #             count += 1
    #     if count > 0:
    #         bad_samples += 1
    # print(bad_samples)
    # print(sample)
    # print(walk_leftStance.semantic_pca['n_components'])
    # print(walk_leftStance.s_pca['n_components'])
    # print(walk_leftStance.t_pca['n_components'])

def check_functional_data():
    pass

""" Main part, for testing purpose """
if __name__ == '__main__':
    # test_keyframe_annotation()
    # test_bitvector_calulation()
    # test_smooth_bitvector()
    # test_gen_annotation()
    # gen_walk_annotation()
    # load_spatial_temporal_params()
    # load_morphable_model()
    # test_fpca_semantic_data()
    # check_semantic_labels()
    # check_functional_data()
    test_sample_semantic_morphable_model()
    # add_mean_info_spatial_temporal_params()
#     data_folder = os.sep.join(('C:', 'MarkusMauer', 'motiongraph', 'data',
#                                '1 - MoCap', '2 - Rocketbox retargeting'))
#
#     skeleton_file = r'..\..\..\skeleton.bvh'
#
#     features = ['Bip01_L_Toe0', 'Bip01_R_Toe0']
# #    features = ['LeftFoot', 'RightFoot']
#
#     sourcefolder = os.sep.join((data_folder, 'Take_walk')) + os.sep
#     files = glob.glob(sourcefolder + r'*.bvh')
#     for f in files:
#         print f
#         reader = BVHReader(f)
#         frames = reader.frames
#
#         try:
#             keyframes = bv.detect_keyframes(frames, features, verbose=False)
#             bv.splitt_motion(frames, keyframes, f.split(os.sep)[-1])
#
#         except:
#             bitvector = bv.calc_bitvector_walking(frames, features,
#                                                   verbose=True, threshold=0.2)


import nltk
import tts_amazonpolly
from datetime import datetime
import time

conversation = False

def process_speech(inputspeech):
    processedspeech = inputspeech + " - Speech Processed"
    tokens = nltk.word_tokenize(inputspeech)
    print (tokens)
    tagged = nltk.pos_tag(tokens)
    print (tagged[0:6])
    entities = nltk.chunk.ne_chunk(tagged)
    print (entities)
    return processedspeech

"""def interpret_input(inputspeech):
    wordtokens = nltk.word_tokenize(inputspeech)
    print (wordtokens)
    if "shopping" in wordtokens:
        print ("Enable shopping speech sequence")"""

def check_for_wake_signal():
    listentext = raw_input("Enter Wake Signal (Hi Margo, Margo): ")
    listentexttokens = nltk.word_tokenize(listentext)
    print (listentexttokens)
    if "Margo" in listentexttokens:
        return True
    else:
        return False

def check_for_speech():
    listentext = raw_input("Enter speech: ")
    listentexttokens = nltk.word_tokenize(listentext)
    print (listentexttokens)
    return listentexttokens

def margo_greeting():
    hour = time.strftime("%H")
    print (hour)
    if hour == "18" or "19" or "20" or "21" or "22" or "23":
        speak_response("Good evening!  How can I help?")
    elif hour == "6" or "7" or "8" or "9" or "10":
        speak_response("Good morning!  How can I help?")
    elif hour == "12" or "13" or "14" or "15" or "16" or "17":
        speak_response("Good afternoon!  How can I help?")
    else:
        speak_response("Hi!  How can I help?")
    return

def speak_response(inputspeech):
    tts_amazonpolly.convert_text_to_speach(inputspeech)
    return


# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.linux-x86_64/egg/electrum_chi/electrum/base_crash_reporter.py
# Compiled at: 2019-08-24 06:06:43
# Size of source mod 2**32: 5458 bytes
import asyncio, json, locale, traceback, subprocess, sys, os
from .version import ELECTRUM_VERSION
from . import constants
from .i18n import _
from .util import make_aiohttp_session
from .logging import describe_os_version, Logger

class BaseCrashReporter(Logger):
    report_server = 'https://crashhub.electrum.org'
    config_key = 'show_crash_reporter'
    issue_template = '
Traceback
\n
\n{traceback}\n
\n\n
Additional information
\n
\n
Electrum version: {app_version}
\n
Python version: {python_version}
\n
Operating system: {os}
\n
Wallet type: {wallet_type}
\n
Locale: {locale}
\n
\n    '
    CRASH_MESSAGE = _('Something went wrong while executing Electrum-CHI.')
    CRASH_TITLE = _('Sorry!')
    REQUEST_HELP_MESSAGE = _('To help us diagnose and fix the problem, you can send us a bug report that contains useful debug information:')
    DESCRIBE_ERROR_MESSAGE = _('Please briefly describe what led to the error (optional):')
    ASK_CONFIRM_SEND = _('Do you want to send this report?')

    def __init__(self, exctype, value, tb):
        Logger.__init__(self)
        self.exc_args = (exctype, value, tb)

    def send_report(self, asyncio_loop, proxy, endpoint='/crash', *, timeout=None):
        if constants.net.GENESIS[-4:] not in ('4943', 'e26f'):
            if '.electrum.org' in BaseCrashReporter.report_server:
                raise Exception(_('Missing report URL.'))
        report = self.get_traceback_info()
        report.update(self.get_additional_info())
        report = json.dumps(report)
        coro = self.do_post(proxy, (BaseCrashReporter.report_server + endpoint), data=report)
        response = asyncio.run_coroutine_threadsafe(coro, asyncio_loop).result(timeout)
        return response

    async def do_post(self, proxy, url, data):
        async with make_aiohttp_session(proxy) as session:
            async with session.post(url, data=data) as resp:
                return await resp.text()

    def get_traceback_info(self):
        exc_string = str(self.exc_args[1])
        stack = traceback.extract_tb(self.exc_args[2])
        readable_trace = ''.join(traceback.format_list(stack))
        id = {'file':stack[(-1)].filename,
         'name':stack[(-1)].name,
         'type':self.exc_args[0].__name__}
        return {'exc_string':exc_string,
         'stack':readable_trace,
         'id':id}

    def get_additional_info(self):
        args = {'app_version':ELECTRUM_VERSION,
         'python_version':sys.version,
         'os':describe_os_version(),
         'wallet_type':'unknown',
         'locale':locale.getdefaultlocale()[0] or '?',
         'description':self.get_user_description()}
        try:
            args['wallet_type'] = self.get_wallet_type()
        except:
            pass

        try:
            args['app_version'] = self.get_git_version()
        except:
            pass

        return args

    @staticmethod
    def get_git_version():
        dir = os.path.dirname(os.path.realpath(sys.argv[0]))
        version = subprocess.check_output([
         'git', 'describe', '--always', '--dirty'],
          cwd=dir)
        return str(version, 'utf8').strip()

    def get_report_string(self):
        info = self.get_additional_info()
        info['traceback'] = ''.join((traceback.format_exception)(*self.exc_args))
        return (self.issue_template.format)(**info)

    def get_user_description(self):
        raise NotImplementedError

    def get_wallet_type(self):
        raise NotImplementedError

def trigger_crash():

    class TestingException(Exception):
        pass

    def crash_test():
        raise TestingException('triggered crash for testing purposes')

    import threading
    t = threading.Thread(target=crash_test)
    t.start()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.conf import settings
import audit_log.models.fields

class Migration(migrations.Migration):

    dependencies = [
        ('airplane', '0001_initial'),
        ('financial', '__first__'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('configuration', '0002_auto_20171114_1703'),
    ]

    operations = [
        migrations.AddField(
            model_name='airplaneauditlogentry',
            name='action_user',
            field=audit_log.models.fields.LastUserField(related_name='_airplane_audit_log_entry', editable=False, to=settings.AUTH_USER_MODEL, null=True),
        ),
        migrations.AddField(
            model_name='airplane',
            name='account',
            field=models.OneToOneField(related_name='airplane_account', null=True, blank=True, to='financial.Account'),
        ),
        migrations.AddField(
            model_name='airplane',
            name='reservation_types',
            field=models.ManyToManyField(to='configuration.ReservationType'),
        ),
    ]


import numpy as np
import json
import pickle
import math
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, Activation, Convolution2D, Flatten, Lambda, Dropout, Lambda, ELU
from keras.optimizers import Adam

# Load the data
data = {}
with open('data/driving_data.p', 'rb') as f:
    data = pickle.load(f)

# Split data into training and validation
X_train, X_val, y_train, y_val = train_test_split(data['features'], data['labels'], random_state=0, test_size=0.33)

# normalize: mean zero and range -0.5 to 0.5
print('Normalizing data')
def normalize_data(x):
    x = x.astype('float32')
    x = x / 255 - 0.5
    return x
# will use Lambda instead
X_train = normalize_data(X_train)
X_val = normalize_data(X_val)

# model
img_shape = (160, 320, 3)

model = Sequential()
model.add(Lambda(lambda x: x/127.5 - 1., input_shape=img_shape, output_shape=img_shape))
model.add(Convolution2D(16, 8, 8, subsample=(4, 4), border_mode="same"))
model.add(ELU())
model.add(Convolution2D(32, 5, 5, subsample=(2, 2), border_mode="same"))
model.add(ELU())
model.add(Convolution2D(64, 5, 5, subsample=(2, 2), border_mode="same"))
model.add(Flatten())
model.add(Dropout(.2))
model.add(ELU())
model.add(Dense(512))
model.add(Dropout(.5))
model.add(ELU())
model.add(Dense(1))
model.compile(optimizer="adam", loss="mse")
model.fit(X_train, y_train, batch_size=100, nb_epoch=100,validation_data=(X_val, y_val), shuffle=True)

# save model
print('Saving Model Weights!!')
model.save_weights('model.h5')
with open('model.json','w') as f:
    json.dump(model.to_json(),f,ensure_ascii=False)


# apply a tranformation matrix no new coordinates from
# a previous ProCare alignment
# matrices are stored in ProCare output procare.tsv

import numpy as np
from time import strftime, localtime
import os

def xtract_matrix(procare_file_, line_number_):
    with open(procare_file_, 'r') as f:
        data = f.read().split('\n')
    matrix_line = data[line_number_]
    matrix_cpnts = matrix_line.split('\t')[33:49]
    matrix_cpnts = [float(n) for n in matrix_cpnts]
    matrix = np.array([[n for n in matrix_cpnts[0:4]],
                      [n for n in matrix_cpnts[4:8]],
                      [n for n in matrix_cpnts[8:12]],
                      [n for n in matrix_cpnts[12:16]]])

    return matrix

def transform(mol2_, matrix_, ofile_):
    with open(mol2_, 'r') as f:
        mol2 = f.read()
        molecule_area = mol2.split('@<TRIPOS>MOLECULE\n')[1].split('@<TRIPOS>')[0]
        molecule_area = "@<TRIPOS>MOLECULE\n" + molecule_area
        atom_area = mol2.split('@<TRIPOS>ATOM\n')[1].split('@<TRIPOS>')[0]
        atoms = atom_area.split('\n')
        #print(atoms)
        del atoms[-1]
        new_atom_area = "@<TRIPOS>ATOM"
        for l in atoms:
            cols = l.split()
            coords = np.array([float(cols[2]), float(cols[3]), float(cols[4]), 1])
                # Umeyama Rt matrix [x, y, z, 1]
            matrix = np.array(matrix_)
            trans_coords = np.matmul(matrix, coords)
            #print(trans_coords, coords)
            new_atom_area += ("\n{:>7} {:<8} {:>9.4f} {:>9.4f} {:>9.4f} "
                              "{:<5} {:>5} {:<8} {:>9}".format(cols[0],
                                                     cols[1],
                                                     trans_coords[0],
                                                     trans_coords[1],
                                                     trans_coords[2],
                                                     cols[5],
                                                     cols[6],
                                                     cols[7],
                                                     cols[8]
                                                    ))
        new_atom_area += "\n"
        final_area = mol2.split('@<TRIPOS>BOND\n')[1]
        final_area = "@<TRIPOS>BOND\n" + final_area

    if ofile_[-5:] != '.mol2':
            ofile_ += '.mol2'
    basename = os.path.basename(ofile_)
    name = os.path.splitext(basename)[0]

    header = ""
    header += "# Modified by ProCare\n"
    header += "# Modification time: {}\n".format(
                            strftime("%a %d %b %Y %H:%M:%S", localtime()))
    header += "# Name: {}.mol2\n\n".format(name)

    with open(ofile_, 'w') as of:
        of.write('{}{}{}{}'.format(header, molecule_area, new_atom_area, final_area))

    print('output to {}'.format(ofile_))

if __name__ == '__main__':

    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--fileprocare', type=str, required=True,
                help='procare matrix file')
    parser.add_argument('-l', '--line', type=int, required=True,
                help='line number where to extract matrix components. Starts with 0 = header')
    parser.add_argument('-a', '--appliedtomol2', type=str, required=True, nargs='+',
                help='mol2 file to applied transformation')
    parser.add_argument('--prefix', type=str, required=False,
                help='prefix to output files')
    args = parser.parse_args()

    matrix = xtract_matrix(args.fileprocare, args.line)
    for mol2 in args.appliedtomol2:
        filename = os.path.basename(mol2)
        prefix = 'rot_'
        if args.prefix is not None:
            prefix = args.prefix
        ofile = '{}_{}'.format(prefix, filename)
        transform(mol2, matrix, ofile)


from udp_helper import udp
import numpy as np
import matplotlib.pyplot as plt
import sys
import time
from functools import wraps
from threading import Thread
import math
np.set_printoptions(precision=3)
#Supress scientific notation
np.set_printoptions(suppress=True)
# Prevent 0 from bein stripped from end of floats
np.set_printoptions(formatter={'float': '{: 0.3f}'.format})

def notify(func):
    '''
    Decorator that notify event start and ends
    '''
    @wraps(func)
    def wrapper(*args,**kwargs):
        print("Event:",func.__name__, " started")
        func(*args,**kwargs)
        print("Event:",func.__name__, " ended")
    return wrapper

def mapangle(angle,ll,ul):
    if angle < ll:
        controlangle =-1
    elif angle <0 and angle >= ll:
        controlangle = -angle/ll

    elif angle>=0 and angle <=ul:
        controlangle = angle/ul

    else:
        controlangle=1

    if angle ==-999:
        controlangle=-999

    return controlangle

class aircraft:
    def __init__(self,connection):
        self.con=connection
        self.t={}
        self.indexarray=[]
        self.valuearray=[]
        self.logdata=[]
        self.con.start()
    def elv(self,val):
        self.con.writedata([8],[[mapangle(val,-10,20),-999,-999,-999,-999,-999,
                           -999,-999]])

    def ail(self,val):
        self.con.writedata([8],[[-999,mapangle(val,-10,20),-999,-999,-999,-999,
                           -999,-999]])

    def rud(self,val):
        self.con.writedata([8],[[-999,-999,mapangle(val,-25,25),-999,-999,-999,
                           -999,-999]])

    def Vind(self):
        return self.con.readdata()[3][1]

    def pitch(self):
        return self.con.readdata()[17][0]

    def state(self):
        data=self.con.readdata()
        t = data[1][1]
        pitch = data[17][0]
        roll = data[17][1]
        yaw = data[17][2]
        aoa=data[18][0]
        sideslip=data[18][1]
        flightpath=data[18][3]
        lat = data[20][0]
        lon = data[20][1]
        alt = data[20][2]
        return (t,pitch,roll,yaw,aoa,sideslip,flightpath,lat,lon,alt)

    def controlsurface(self):
        data=self.con.readdata()
        t = data[1][1]
        elv = data[11][0]
        ail = data[11][1]
        rud = data[11][2]
        return (t,elv,ail,rud)

    def speed(self):
        data=self.con.readdata()
        t = data[1][1]
        Vias = data[3][0]
        Veas = data[3][1]
        Vktas = data[3][2]
        Vktgs = data[3][3]
        Q = data[16][0]
        P = data[16][1]
        R = data[16][2]
        return (t,Vias,Veas,Vktas,Vktgs,Q,P,R)

    def throttle(self,val):
        self.con.writedata([25],[[val,val,val,val,-999,-999,-999,-999]])

    def control(self,elv=-999,ail=-999,rud=-999):
        self.con.writedata([8],[[mapangle(elv,-10,20),mapangle(ail,-10,20),
            mapangle(rud,-25,25),-999,-999,-999,-999,-999]])

    def resetcontrol(self):
        self.control(elv=0,ail=0,rud=0)

    def brake(self,val):
        self.con.writedata([14],[[-999,val,-999,-999,-999,-999,-999,-999]])

    def gear(self,val):
        self.con.writedata([14],[[val,-999,-999,-999,-999,-999,-999,-999]])

    def elv_trim(self,val):
        self.con.writedata([13],[[val,-999,-999,-999,-999,-999,-999,-999]])

    @notify
    def takeoff(self,Vto=155,timeout=0):
        self.resetcontrol()
        self.throttle(1)
        self.brake(0)
        speed = self.speed()[1]
        while abs(speed - Vto) >= 10:
            state =self.state()
            speed = self.speed()[1]
        self.pitchpid(timeout=10,desired=20,Kp=1)
        self.run(b747.rollpid,timeout=10,Kp=0.8,Kd=0.3)
        self.run(b747.yawpid,timeout=10,desired=118,Kp=0.3)
        self.gear(0)

    @notify
    def pitchpid(self,timeout=60,Kp=0.0,Ki=0.0,Kd=0.0,desired = 0):
        state_old=self.state()
        error_old=0
        integral=0
        tstart = state_old[0]
        told=tstart
        t =0
        dt=0.001
        while t - tstart < timeout:
            #Get aircraft current state
            state=self.state()
            t= state[0]
            if t - told > dt:
                #PID control
                error = (desired - state[1])
                dt = t-told
                integral = integral + error * dt
                derivative = (error-error_old)/dt
                self.control(elv=Kp*(error)+Ki*(integral)+Kd*(derivative))
                #self.control(elv=Kp*(error))
                #Reset for new loop
                error_old=error
                told=t

    @notify
    def flightpathpid(self,timeout=60,Kp=0.0,Ki=0.0,Kd=0.0,desired = 0):
        state_old=self.state()
        error_old=0
        integral=0
        tstart = state_old[0]
        told=tstart
        t=0
        dt=0.001
        while t - tstart < timeout:
            #Get aircraft current state
            state=self.state()
            t= state[0]
            if t - told > dt:
                #PID control
                error = (desired - state[6])
                dt = t-told
                integral = integral + error * dt
                derivative = (error-error_old)/dt
                self.control(elv=Kp*(error)+Ki*(integral)+Kd*(derivative))
                #Reset for new loop
                error_old=error
                told=t

    @notify
    def altitudepid(self,timeout=60,Kp=0.0,Ki=0.0,Kd=0.0,desired = 0):
        state_old=self.state()
        error_old=0
        integral=0
        tstart = state_old[0]
        told=tstart
        t=0
        dt=0.001
        while t - tstart < timeout:
            #Get aircraft current state
            state=self.state()
            t= state[0]
            if t - told > dt:
                #PID control
                error = (desired - state[9])
                dt = t-told
                integral = integral + error * dt
                derivative = (error-error_old)/dt
                self.control(elv=Kp*(error)+Ki*(integral)+Kd*(derivative))
                #Reset for new loop
                error_old=error
                told=t
    @notify
    def rollpid(self,timeout=60,Kp=0.0,Ki=0.0,Kd=0.0,desired = 0):
        state_old=self.state()
        error_old=0
        integral=0
        tstart = state_old[0]
        told=tstart
        t=0
        dt=0.001
        while t - tstart < timeout:
            #Get aircraft current state
            state=self.state()
            t= state[0]
            if t - told > dt:
                #PID control
                error = (desired - state[2])
                dt = t-told
                integral = integral + error * dt
                derivative = (error-error_old)/dt
                self.control(ail=Kp*(error)+Ki*(integral)+Kd*(derivative))
                #self.control(ail=Kp*(error))
                #Reset for new loop
                error_old=error
                told=t

    @notify
    def yawpid(self,timeout=60,Kp=0.0,Ki=0.0,Kd=0.0,desired = 0.0):
        state_old=self.state()
        error_old=0
        integral=0
        tstart = state_old[0]
        told=tstart
        t=0
        dt=0.001
        while t - tstart < timeout:
            #Get aircraft current state
            state=self.state()
            t= state[0]
            if t - told > dt:
                #PID control
                error = (desired - state[3])
                integral = integral + error * dt
                derivative = (error-error_old)/dt
                control=Kp*(error)+Ki*(integral)+Kd*(derivative)
                #control=Kp*(error)
                self.control(rud=control)
                #Reset for new loop
                error_old=error
                told=t
                #print("Error,Control:",error,control)

    def run(self,event,*args,**kwargs):
        self.t[event.__name__] = Thread(target = event,args=args,kwargs=kwargs)
        self.t[event.__name__].start()

    def wait_speed(self,wait_speed,epsilon=5):
        speed =self.speed()[1]
        while abs(speed-wait_speed)<epsilon:
            pass

    def stop(self):
        for eventname,event in self.t.items():
            event.join()
        print("Events ended succesfully")

def b747_test():
    conn =udp('127.0.0.1',49003,'127.0.0.1',49000)
    b747 = aircraft(conn)

    t =[]
    pitch=[]
    #conn.start()
    b747.brake(0)
    b747.throttle(1)

    b747.run(b747.rollpid,timeout=180,Kp=0.8,Kd=0.3)
    b747.run(b747.yawpid,timeout=180,desired=191,Kp=0.3)
    b747.wait_speed(160)
    b747.run(b747.pitchpid,timeout=180,desired=20,Kp=0.5,Ki=0.0,Kd=0.0)

    b747.stop()
    conn.stop()

def pitch_control():
    conn =udp('127.0.0.1',49003,'127.0.0.1',49000)
    b747 = aircraft(conn)

    b747.run(b747.rollpid,timeout=18000,Kp=0.8,Kd=0.3)
    b747.run(b747.yawpid,timeout=18000,desired=191,Kp=0.3)
    b747.run(b747.pitchpid,timeout=18000,desired=20,Kp=0.5,Ki=0.0,Kd=0.0)

    b747.stop()
    conn.stop()

def vistest():
    conn =udp('127.0.0.1',49003,'127.0.0.1',49000)
    i=2285.0
    while True:
        i+=1/10
        try:
            conn.veh1([34.93,-117.8,i],[0.,0.,191.],[0.,0.,0.])
            time.sleep(1)
        except:
            conn.stop()
def setup():
    conn =udp('127.0.0.1',49003,'127.0.0.1',49000)
    #conn.veh1([34.93,-117.8,697.],[0.,0.,0.],[0.,0.,0.])
    conn.papt(type_start=12,rwy_ram=1)
    conn.stop()

if __name__=="__main__":
    b747_test()
    #pitch_control()
    #vistest()
    setup()


import urllib
from bs4 import BeautifulSoup
# open the top 250 films page from IMDB
url = "http://www.imdb.com/chart/top?ref_=nv_ch_250_4"
page = urllib.request.urlopen(url)
soup = BeautifulSoup(page.read())
movies = soup.find_all(class_ = "titleColumn")

# File to save informations
f0 = open("url.txt","wb") # Save url of 250 films
f1 = open("movie.txt","wb") # Save movie name
f2 = open("rate.txt","wb") # Save movie rating
f3 = open("year.txt","wb") # Save time information
for movie in movies:
    for link in movie.find_all("a",href = True):
        name = link.contents
        f0.write(str(link["href"]).encode("utf-8"))
        f0.write("\n".encode("utf-8"))
        f1.write(str(name[0]).encode("utf-8"))
        f1.write("\n".encode("utf-8"))

for movie in movies:
    for block in movie.find_all("span",{"name" : "ir"}):
        f2.write(str(block["data-value"]).encode('utf-8') )
        f2.write("\n".encode("utf-8"))

for movie in movies:
    for block in movie.find_all("span",{"class" : "secondaryInfo"}):
        f3.write(str(block["data-value"]).encode('utf-8') )
        f3.write("\n".encode("utf-8"))

f0.close()
f1.close()
f2.close()
f3.close()


import argparse
import torch
from torchvision import utils
import torchvision.transforms.functional as TF
import torch.nn.functional as F

from model import Generator

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--index", type=int, default=0)
    parser.add_argument("-d", "--degree", type=float, default=5, help='max degree')
    parser.add_argument('--m', type=int, default=3, help='imgs per latent')
    parser.add_argument("--ckpt", type=str, required=True)
    parser.add_argument("--size", type=int, default=256)
    parser.add_argument("-n", "--n_sample", type=int, default=7)
    parser.add_argument("--truncation", type=float, default=0.7)
    parser.add_argument("--device", type=str, default="cuda")
    parser.add_argument("--out_prefix", type=str, default="factor")
    parser.add_argument("--factor", type=str)
    args = parser.parse_args()
    assert args.m >= 0

    return args

def compare_axes():
    torch.set_grad_enabled(False)
    device = 'cuda'
    path_factor = 'factor.pt'
    m = 3
    degree = 10
    truncation = 0.7
    out_prefix = 'copmare_axes'
    imsize = 256

    # eigvec = torch.load(args.factor)["eigvec"].to(args.device)
    f_dict = torch.load(path_factor)
    eigvec = f_dict['V'].to(device)
    path_ckpt = f_dict['ckpt']
    print('loading eigenvector of %s' % path_ckpt)

    g = torch.load(path_ckpt).to(device)
    '''state_dict = g.state_dict()
    g = Generator(512, 512, 8).to(device)
    g.load_state_dict(state_dict)'''

    trunc = g.mean_latent(4096)
    torch.save(trunc, 'trunc.pt')

    latent = torch.randn(1, 512, device=device)
    latent = g.get_latent(latent)
    torch.save(latent, 'latent.pt')
    print(latent[0, :10])

    indices = torch.arange(10)
    imgs = torch.zeros((3, len(indices) * imsize, (2 * m + 1) * imsize))
    for i in range(len(indices)):
        index = indices[i]
        direction = degree * eigvec[:, index].unsqueeze(0)

        scales = torch.linspace(-1, 1, 2 * m + 1)
        for j in range(len(scales)):
            scale = scales[j]
            # TODO 이거 이렇게 안 넣고 batch로 g에 넣어주면 되지 않나?
            img, _ = g([latent + scale * direction], truncation=truncation, truncation_latent=trunc,
                       input_is_='latent', randomize_noise=False)
            img = F.interpolate(img, (imsize, imsize))
            imgs[:, i * imsize:(i + 1) * imsize, j * imsize:(j + 1) * imsize] = img[0]

    path_save = './control/%s_degree-%f.png' % (out_prefix, degree)
    imgs = torch.clamp(imgs * 256, 0, 255).type(torch.uint8)
    imgs = TF.to_pil_image(imgs.permute((1, 2, 0)).numpy())
    imgs.save(path_save)
    print(path_save)

def main():
    torch.set_grad_enabled(False)
    args = parse_args()

    # eigvec = torch.load(args.factor)["eigvec"].to(args.device)
    f_dict = torch.load(args.factor)
    eigvec = f_dict['V'].to(args.device)
    print('loading eigenvector of %s' % (f_dict['ckpt']))

    # ckpt = torch.load(args.ckpt)
    # g = Generator(args.size, 512, 8).to(args.device)
    # g.load_state_dict(ckpt["g_ema"], strict=False)
    g = torch.load(args.ckpt).to(args.device)

    trunc = g.mean_latent(4096)

    latent = torch.randn(args.n_sample, 512, device=args.device)
    latent = g.get_latent(latent)

    direction = args.degree * eigvec[:, args.index].unsqueeze(0)

    imgs = []
    scales = torch.linspace(-1, 1, 2 * args.m + 1)
    for scale in scales:
        img, _ = g([latent + scale * direction], truncation=args.truncation, truncation_latent=trunc,
                   input_is='latent', )
        imgs.append(img)
    imgs = torch.cat(imgs, 0)

    path_save = './control/%s_index-%d_degree-%f.png' % (args.out_prefix, args.index, args.degree)
    grid = utils.save_image(imgs, path_save, normalize=True, range=(-1, 1), nrow=args.n_sample, )
    print(path_save)

if __name__ == "__main__":
    # main()
    compare_axes()


from django.db import models

class Owner(models.Model):
    name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    age = models.IntegerField()
    # 주인은 누군가를 팔로잉 할 수 있고, 또 다른 사람을 팔로잉 할 수 있다
    following = models.ManyToManyField('self')
    followers = models.ManyToManyField('self')

nicolas = Owner.objects.get(pk=1)
pedro = Owner.objects.get(pk=2)
jisu = Owner.objects.get(pk=3)

# 여기서 PK는 primary key를 의마함 OR 장고의 ID를 뜻함

nicolas.followers.add(jisu. pedro)
# followers 칼럼 -> 2,3


import matplotlib.pyplot as plt
import numpy as np

def F(x):
    return x ** 3 - x ** 2 + 0.1

def Fp(x):
    return 3.0 * (x ** 2) - 2.0 * x

def Fa(x, x_0, y_0, m):
    return m * (x - x_0) + y_0

pause_time = 2

# Plot the function
xmin, xmax = -0.5, 1.5
x = np.linspace(xmin, xmax, 10001)
fig, ax = plt.subplots(figsize=(10, 6))
ax.axhline(0.0, color = "#888888")
ax.plot(x, F(x), color = "k", linestyle = "-")
ax.set(xlabel=r"$x$", ylabel=r"$F(x)$", xlim=(xmin, xmax), ylim=(-0.1, 0.2))
plt.ion()
plt.show()

# Initial guess
x_sa = 0.7

for k in range(10):
    lab_k = ax.text((xmax + xmin)/2, 0.18, f'Iteration k = {k}',
                    horizontalalignment='center')

    # Current guess
    marker_line = ax.axvline(x_sa, color = "r", linestyle = ":")
    current_guess = ax.plot([x_sa], [F(x_sa)],
                            marker = "x", markersize = 10,
                            color = "r", markeredgewidth = 2)
    plt.pause(pause_time)

    # New tangent
    x_0, y_0, m = x_sa, F(x_sa), Fp(x_sa)

    xa = np.array([xmin, xmax])
    tangent = ax.plot(xa, Fa(xa, x_0, y_0, m), color = "r", linestyle = "-")
    plt.pause(pause_time)

    # Next guess
    x_sa = (-y_0 / m) + x_0

    next_guess = ax.plot([x_sa], [0.0],
                         marker = "x", markersize = 10,
                         color = "r", markeredgewidth = 2)
    plt.pause(pause_time)

    tangent[0].remove()
    current_guess[0].remove()
    marker_line.remove()
    next_guess[0].remove()
    lab_k.remove()


"""Code for inference on the contents of a directory."""
import tensorflow as tf
from pathlib import Path

from ramjet.analysis.lightcurve_visualizer import plot_lightcurve
from ramjet.analysis.model_loader import get_latest_log_directory
from ramjet.models import ConvolutionalLstm
from ramjet.photometric_database.tess_data_interface import TessDataInterface
from ramjet.photometric_database.toi_lightcurve_database import ToiLightcurveDatabase

saved_log_directory = get_latest_log_directory('logs')  # Uses the latest log directory's model.
# saved_log_directory = Path('logs/baseline YYYY-MM-DD-hh-mm-ss')  # Specifies a specific log directory's model to use.

print('Setting up dataset...')
database = ToiLightcurveDatabase()
database.obtain_meta_data_frame_for_available_lightcurves()
example_paths = [str(database.lightcurve_directory.joinpath('tess2018319095959-s0005-0000000117979897-0125-s_lc.fits'))]
# Uncomment below to run the inference for all validation files.
# example_paths = pd.read_csv(saved_log_directory.joinpath('validation.csv'), header=None)[0].values

print('Loading model...')
model = ConvolutionalLstm()
model.load_weights(str(saved_log_directory.joinpath('model.ckpt')))

print('Inferring and plotting...')
for example_path in example_paths:
    example, label = database.evaluation_preprocessing(tf.convert_to_tensor(example_path))
    prediction = model.predict(tf.expand_dims(example, axis=0))[0]
    tess_data_interface = TessDataInterface()
    fluxes, times = tess_data_interface.load_fluxes_and_times_from_fits_file(example_path)
    label, prediction = database.inference_postprocessing(label, prediction, times.shape[0])
    tic_id = tess_data_interface.get_tic_id_from_single_sector_obs_id(Path(example_path).stem)
    sector = tess_data_interface.get_sector_from_single_sector_obs_id(Path(example_path).stem)
    plot_title = f'TIC {tic_id} sector {sector}'
    plot_lightcurve(times, fluxes, label, prediction, title=plot_title, save_path=f'{plot_title}.png')

print('Inference done.')


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='File',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(unique=True, max_length=255, db_index=True)),
                ('size', models.PositiveIntegerField(db_index=True)),
                ('_content', models.TextField(db_column='content')),
                ('created_datetime', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Created datetime', db_index=True)),
                ('_content_hash', models.CharField(db_index=True, max_length=128, null=True, db_column='content_hash', blank=True)),
            ],
            options={
                'db_table': 'database_files_file',
            },
        ),
    ]


#!/usr/bin/env python3
#
# Copyright 2021 Graviti. Licensed under MIT License.
#

"""Implementation of gas commit."""

from typing import Dict

import click

from .tbrn import TBRN, TBRNType
from .utility import edit_input, error, get_dataset_client, get_gas

_COMMIT_HINT = """{}
# Please enter the commit message for your changes.
# The Default commit message is set as the draft title.
# Lines starting with '#' will be ignored.
# And an empty commit message aborts the commit.
"""

def _implement_commit(obj: Dict[str, str], tbrn: str, message: str) -> None:
    gas = get_gas(**obj)
    info = TBRN(tbrn=tbrn)
    dataset_client = get_dataset_client(gas, info)

    if info.type != TBRNType.DATASET:
        error(f'To operate a commit, "{info}" must be a dataset')

    if not info.is_draft:
        error(f'To commit, "{info}" must be in draft status, like "{info}#1"')

    dataset_client.checkout(draft_number=info.draft_number)
    if not message:
        message, description = edit_input(_COMMIT_HINT.format(dataset_client.get_draft().title))

    if not message:
        error("Aborting commit due to empty commit message")

    if description:
        error('Commit with "description" is not supported yet')

    dataset_client.commit(message)
    commit_tbrn = TBRN(info.dataset_name, revision=dataset_client.status.commit_id).get_tbrn()
    click.echo(f"Committed successfully: {tbrn} -> {commit_tbrn}")