import re
from datetime import datetime, timedelta
from typing import Dict, List

from back_testing import BackTester, DayTracker, OptionLegDayTracker, Trade
from util import get_pickle_data

# this is called from flask router with back_test obj which was pickled earlier
def analyze_data(back_tester: BackTester, trade_date: str, option_type: str):
    # analyze_data(back_tester, "2021-09-03", "PE")
    minute_str_list = get_minute_list()
    day_trackers: List[DayTracker] = [day_tracker for day_tracker in back_tester.day_trackers if
                                      day_tracker.trading_date == trade_date]
    if len(day_trackers) == 0:
        return {}
    day_tracker: DayTracker = day_trackers[0]
    short_minute_str_list = [re.sub(r':00$', '', min_str) for min_str in minute_str_list]
    # getting profit,profit perc,option prem data for individual legs
    option_data_list = get_option_data(day_tracker.option_leg_trackers, minute_str_list)
    plot_data = {'minutes': short_minute_str_list, 'expiry': day_tracker.nearest_expiry,
                 'optionPremData': option_data_list, 'totalProfit': round(day_tracker.get_current_profit(), 2)}
    nifty_plot_data = get_nifty_plot_data(day_tracker.nifty_min_data_dic, minute_str_list, day_tracker.trading_date)
    plot_data["niftyData"] = nifty_plot_data
    # total_profit_list = get_total_profit_list(minute_str_list, option_data_list)
    # plot_data['totalProfit'] = total_profit_list
    # plot_data['total_profit_sum'] = day_tracker.get_current_profit()
    return plot_data

def get_option_data(option_leg_trackers: List[OptionLegDayTracker], minute_str_list):
    option_data_list = []
    for option_leg_tracker in option_leg_trackers:
        ticker_candles_dic: Dict[
            str, {}] = option_leg_tracker.strike_ticker_candles_for_trade_date_dic
        value_with_index = get_list_value_with_index(ticker_candles_dic, minute_str_list, option_leg_tracker)
        strike_data = get_strike_plot_data(option_leg_tracker.strike_price, minute_str_list)
        option_prem_data = {"data": value_with_index, 'strikeData': strike_data,
                            'file': option_leg_tracker.option_file_name,
                            "optionType": option_leg_tracker.option_leg.option_type}
        # profit_data, profit_perc_data = get_profit_date(option_leg_tracker, minute_str_list)
        # option_prem_data['profit'] = profit_data
        # option_prem_data['profit_perc'] = profit_perc_data
        option_data_list.append(option_prem_data)
    return option_data_list

def get_profit_date(option_leg_tracker: OptionLegDayTracker, minute_str_list):
    ticker_candles_dic: Dict[
        str, {}] = option_leg_tracker.strike_ticker_candles_for_trade_date_dic
    trades: List[Trade] = option_leg_tracker.trades
    in_our_out = -1
    # having flag to make sure even for boundary condition i am considering those days as trade days
    is_boundary = False
    for key in ticker_candles_dic:
        is_boundary = False
        candle = ticker_candles_dic[key]
        candle['axis_ref_index'] = minute_str_list.index(key)
        matching_trade = len([trade for trade in trades if trade.trade_time == key]) > 0
        if matching_trade:
            is_boundary = True
            in_our_out = in_our_out * -1
        # if its open or close, treat i has 1
        if is_boundary:
            candle['in_our_out'] = 1
        else:
            candle['in_our_out'] = in_our_out
    traded_candles = [ticker_candles_dic[key] for key in ticker_candles_dic if
                      ticker_candles_dic[key]['in_our_out'] == 1]
    profit_reversal = (-1 if option_leg_tracker.option_leg.buy_or_sell == "sell" else 1)
    for candle in traded_candles:
        candle['profit'] = (float(candle['close']) - float(traded_candles[0]['close'])) * profit_reversal
        candle['profit_perc'] = float(candle['profit']) / float(traded_candles[0]['close'])
    profit_data = [[candle['axis_ref_index'], candle['profit']] for candle in traded_candles]
    profit_perc_data = [[candle['axis_ref_index'], candle['profit_perc']] for candle in traded_candles]
    return profit_data, profit_perc_data

# getting total profit by summing up indv profits
def get_total_profit_list(minutes_str_list, option_data_list):
    total_profit_list = []
    for index in range(len(minutes_str_list)):
        profit = None
        for option_data in option_data_list:
            min_profit = get_profit_by_min(option_data['profit'], index)
            if min_profit is not None:
                profit = profit if profit is not None else 0
                profit = profit + min_profit
        if profit is not None:
            total_profit_list.append([index, profit])
    return total_profit_list

def get_profit_by_min(profit_list, min_index):
    min_profit = [profit for profit in profit_list if profit[0] == min_index]
    if len(min_profit) == 0:
        return None
    else:
        return min_profit[0][1]

def get_minute_list():
    # print((entry_date_time_str, exit_date_time_str))
    entry_date_time = datetime.strptime('2021-01-01 09:15:00', '%Y-%m-%d %H:%M:%S')
    exit_date_time = datetime.strptime('2021-01-01 15:30:00', '%Y-%m-%d %H:%M:%S')
    time_diff = exit_date_time - entry_date_time
    minute_diff = (time_diff.total_seconds() / 60)
    minute_list = [entry_date_time + timedelta(minutes=it) for it in range(0, int(minute_diff + 1))]
    minute_str_list = [minute.strftime('%H:%M:%S') for minute in minute_list]
    return minute_str_list

# this is needed for highchart so that the trade could be marked in the graph
def get_list_value_with_index(candle_list_dic: Dict[str, tuple], minute_str_list: List[str],
                              option_leg_tracker: OptionLegDayTracker):
    trades: List[Trade] = option_leg_tracker.trades
    option_premiums_with_trade_marked = []
    start_premium = None
    for key in candle_list_dic:
        matching_trades = [trade for trade in trades if trade.trade_time == key]
        premium_index = minute_str_list.index(key)
        option_value = float(candle_list_dic[key]['close'])
        matching_trade = None
        if len(matching_trades) > 0:
            matching_trade = matching_trades[0]
        if matching_trade is not None:
            # when trade is started/ended at this time, modify the data so that its shown diff. in the graph
            option_trade_entry = {"marker": {
                "fillColor": '#FF0000',
                "lineWidth": 3,
                "lineColor": "#FF0000",
                "radius": 4
            }, "y": option_value, "x": premium_index}
            if start_premium is None:
                start_premium = option_value
            else:
                profit = (option_value - start_premium) * -1
                profit_perc = (profit / start_premium) * 100
                start_premium = None
                option_trade_entry['marker']['profit'] = profit
                option_trade_entry['marker']['profitPerc'] = round(profit_perc, 2)

            option_premiums_with_trade_marked.append(option_trade_entry)
        else:
            option_premiums_with_trade_marked.append([premium_index, option_value])
    return option_premiums_with_trade_marked

def get_nifty_plot_data(nifty_data_dic: Dict[str, tuple], minute_str_list: List[str], date_str: str):
    nifty_min_data_with_index = []
    for index in range(len(minute_str_list)):
        time = minute_str_list[index]
        search_date_time_string = f'{date_str}T{time}+0530'
        if search_date_time_string in nifty_data_dic:
            nifty_min_data_with_index.append([index, nifty_data_dic[search_date_time_string]['close']])
    return nifty_min_data_with_index

def get_strike_plot_data(strike_price: float, minute_str_list: List[str]):
    strike_data_with_index = []
    for index in range(len(minute_str_list)):
        strike_data_with_index.append([index, strike_price])
    return strike_data_with_index


from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
from flask import Flask, jsonify, request
from flask_cors import CORS, cross_origin
import os
import numpy as np

# Setup flask app
app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

# Setup graphql client
client = Client(
    transport=RequestsHTTPTransport(
        url='https://graphql.fauna.com/graphql',
        headers={'Authorization': 'Bearer '+os.environ['FAUNA_SECRET']}),
    fetch_schema_from_transport=True)
    #schema=schema)

# Setup numpy float formatter for printing to graphql strings in proper format
floatFormatter = '{:.2f}'.format
np.set_printoptions(formatter={'float_kind': floatFormatter})

@app.route('/api/validate', methods=['OPTIONS', 'POST'])
@cross_origin()
def handleValidate():
    data = request.get_json()

    validateQuery = gql('''
        query {{
            findTestByID(id: {id}) {{
                _id
                a {{
                    name
                    data
                }}
                b {{
                    name
                    data
                }}
            }}
        }}
    '''.format(id=data['id']))

    res = client.execute(validateQuery)
    res = res['findTestByID']

    a = res['a']['data']
    b = res['b']['data']

    sortedA, sortedB, aEcdf, bEcdf, d = kolgomorovSmirnov(
        a,
        b)

    same = d <= data['thresh']

    validateMutation = gql('''
        mutation {{
            updateTest(
                id: {id}
                data: {{
                    aEcdf: {{
                        create: {{
                            name: "{aEcdfName}_ECDF"
                            data: {aEcdfData}
                        }}
                    }}
                    bEcdf: {{
                        create: {{
                            name: "{bEcdfName}_ECDF"
                            data: {bEcdfData}
                        }}
                    }}
                    thresh: {thresh}
                    d: {d}
                    same: {same}
            }})
        }}
    '''.format(id=data['id'],
               aEcdfName=res['a']['name'],
               aEcdfData=aEcdf,
               bEcdfName=res['b']['name'],
               bEcdfData=bEcdf,
               thresh=data['thresh'],
               d=d,
               same=same))

    return jsonify({
        'id': data['id'],
        'aName': res['a']['name'],
        'a': a,
        'sortedA': sortedA.tolist(),
        'bName': res['b']['name'],
        'b': b,
        'sortedB': sortedB.tolist(),
        'aEcdf': aEcdf.tolist(),
        'bEcdf': bEcdf.tolist(),
        'thresh': data['thresh'],
        'd': d,
        'same': bool(same),
        'msg': 'Successfully performed dataset validation'
    })

def kolgomorovSmirnov(a, b):
    sortedA = np.sort(a)
    sortedB = np.sort(b)

    sortedA_CDF = ecdf(sortedA)
    sortedA_ECDF = np.array([sortedA_CDF(x) for x in sortedA])

    sortedB_CDF = ecdf(sortedB)
    sortedB_ECDF = np.array([sortedB_CDF(x) for x in sortedB])

    d = dStatistic(sortedA, sortedB, sortedA_ECDF, sortedB_ECDF)

    return sortedA, sortedB, sortedA_ECDF, sortedB_ECDF, d

def ecdf(x):
    x = np.sort(x)
    def result(v):
        return np.searchsorted(x, v, side='right') / x.size
    return result

# NOTE: in order to use this function in the general case,
# we should normalize the concatenated a::b dataset
def dStatistic(a, b, a_ecdf, b_ecdf):
    def new_idx(arr1, arr2, arr1_idx, arr2_idx):
        if arr1_idx >= len(arr1)-1 and arr2_idx >= len(arr2-1):
            return arr1_idx, arr2_idx
        elif arr1_idx >= len(arr1)-1:
            return arr1_idx, arr2_idx+1
        elif arr2_idx >= len(arr2)-1:
            return arr1_idx+1, arr2_idx

        eps = 0.0005
        diff = arr1[arr1_idx] - arr2[arr2_idx]

        if np.abs(diff) < eps:
            return arr1_idx+1, arr2_idx+1
        elif diff < 0:
            return arr1_idx+1, arr2_idx
        else:
            return arr1_idx, arr2_idx+1

    a_idx = 0
    b_idx = 0
    d = -np.Inf
    while True:
        # set d to new max distance between ecdf functions
        d = np.maximum(d, np.abs(a_ecdf[a_idx]-b_ecdf[b_idx]))

        # break if reached the end of the arrays
        if a_idx >= len(a)-1 and b_idx >= len(b)-1:
            break

        # walk through arrays
        (a_idx, b_idx) = new_idx(a, b, a_idx, b_idx)

    return d

'''
control1 = np.array([0.22, -0.87, -2.39, -1.79, 0.37,
                     -1.54, 1.28, -0.31, -0.74, 1.72,
                     0.38, -0.17, -0.62, -1.10, 0.30,
                     0.15, 2.30, 0.19, -0.50, -0.09])
data1 = np.array([-5.13, -2.19, -2.43, -3.83, 0.50,
                  -3.25, 4.32, 1.63, 5.18, -0.43,
                  7.11, 4.87, -3.10, -5.81, 3.76,
                  6.31, 2.58, 0.07, 5.76, 3.50])
control2 = np.array([1.26, 0.34, 0.70, 1.75, 50.57,
                     1.55, 0.08, 0.42, 0.50, 3.20,
                     0.15, 0.49, 0.95, 0.24, 1.37,
                     0.17, 6.98, 0.10, 0.94, 0.38])
data2 = np.array([2.37, 2.16, 14.82, 1.73, 41.04,
                  0.23, 1.32, 2.91, 39.41, 0.11,
                  27.44, 4.51, 0.51, 4.50, 0.18,
                  14.68, 4.66, 1.30, 2.06, 1.19])
'''


from django.shortcuts import render, HttpResponse, redirect, HttpResponseRedirect

from .models import Teams
from car_app.models import Cars

from contact_app.models import Contact_me
from django.contrib import messages
from django.contrib.auth.models import User
from django.core.mail import send_mail, BadHeaderError

# Create your views here.

def Home_page(request):
    total_team = Teams.objects.all()
    features_car = Cars.objects.order_by('-create_data').filter(is_features=True)
    total_car = Cars.objects.order_by('-create_data')[:9]
    # search_fields = Cars.objects.values('model', 'city', 'year', 'body_style') # is this way problem  dublicatvalu
    model_search = Cars.objects.values_list('model', flat=True).distinct()
    city_search = Cars.objects.values_list('city', flat=True).distinct()
    year_search = Cars.objects.values_list('year', flat=True).distinct()
    body_style_search = Cars.objects.values_list('body_style', flat=True).distinct()
    data = {
        "total_team": total_team,
        "features_car": features_car,
        "total_car": total_car,
        # "search_fields": search_fields,
        "model_search": model_search,
        "city_search": city_search,
        "year_search": year_search,
        "body_style_search": body_style_search,
    }
    return render(request, 'pages/index.html', data)

def About_page(request):
    total_team = Teams.objects.all()
    data = {
        "total_team": total_team,
    }
    return render(request, 'pages/about.html', data)

def Services_page(request):
    return render(request, 'pages/services.html')

def Contact_page(request):
    if request.method == 'POST':
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        email = request.POST['email']
        subject = request.POST['subject']
        message = request.POST['message']
        data = Contact_me(first_name=first_name, last_name=last_name, email=email, subject=subject, message=message)
        admin_info = User.objects.get(is_superuser=True)
        admin_email = admin_info.email
        form_email = email
        messages.success(request, 'Thanks for contact Us !')
        return redirect('contact')

        # if subject and message and form_email:
        #     try:
        #         send_mail(subject, message, form_email, [admin_email])
        #     except BadHeaderError:
        #         return HttpResponse('Invalid header found.')
        #     data.save()
        #     messages.success(request, 'Thanks for contact Us !')
        #     return redirect('contact')
        # else:
        #     return HttpResponse('Make sure all fields are entered and valid.')

    return render(request, 'pages/contact.html')


import requests
import time
import sys
import subprocess

import redis
from redis import Redis

redis_db = redis.Redis(host='localhost', charset="utf-8", decode_responses=True)

id = input('ID: ').upper()
input = input('Text: ').lower()

letter = 'a'

while True:
    temp = subprocess.Popen(['/opt/vc/bin/vcgencmd', 'measure_temp'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout, stderr = temp.communicate()
    temp1 = str(stdout.decode('utf-8')).split('=')
    print(temp1)
    if len(input) > 0:
        tx_string = '6{}T{}:{}[{}]'.format(letter, temp1[1][:4], input, id)
    else:
        tx_string = '6{}T{}[{}]'.format(letter, temp1[1][:4], id)

    print(tx_string)
    redis_db.set((int(time.time()) - 1000), tx_string)
    print('Loaded into the broadcast queue')
    letter = chr(ord(letter) + 1)
    if letter == '{':
        letter = 'b'

    time.sleep(300)


import sys
import os
import json

from PyQt5.QtWidgets import (QWidget, QLabel, QGridLayout, QPushButton,
                            QLineEdit, QApplication, QComboBox)
from PyQt5.QtGui import QFont, QIcon
from PyQt5.QtCore import Qt

from gui_resources.style import StyleSheet as SS
from gui_resources.style import Font

#TODO
# Combobox selection for delimiter character and decimal character
# Default import configuration options

class SettingsWindow(QWidget):
    '''
    Custom window for application settings
    '''
    def __init__(self, settings: dict) -> None:
        super().__init__()

        # Global app settings
        self.settings = settings

        # Fonts for settings
        self.TitleFont = QFont()
        self.TitleFont.setBold(True)
        self.TitleFont.setPointSize(9)

        # Window settings
        self.setWindowTitle('Settings')
        self.setWindowIcon(QIcon("gui_resources/Quantum_icon.png"))
        self.setMinimumWidth(350)

        # Main layout for settings window
        self.MainLayout = QGridLayout()
        self.MainLayout.setAlignment(Qt.AlignTop)
        self.setLayout(self.MainLayout)

        # Add options for CSV imports
        self.CSVimportLabel = QLabel('CSV Import Settings')
        self.CSVimportLabel.setFont(Font.settings_title)
        self.CSVimportLabel.setAlignment(Qt.AlignCenter)
        self.MainLayout.addWidget(self.CSVimportLabel)

        # Add selection for default settings
        # self.defaultSettingsLabel = QLabel('Default Settings')
        # self.MainLayout.addWidget(self.defaultSettingsLabel, 1, 0)
        self.defaultSettingsCombo = QComboBox()
        self.defaultSettingsCombo.addItems(['Default Settings', 'Siemens', 'StrideLinx'])
        self.defaultSettingsCombo.textActivated.connect(self.defaultSettings)
        self.MainLayout.addWidget(self.defaultSettingsCombo, 1, 0)

        # Add csv import settings
        csv_settings = self.constructCSVsettings()
        self.MainLayout.addLayout(csv_settings, 2, 0)

        # Button to apply the settings
        self.ApplyButton = QPushButton('Apply')
        self.ApplyButton.clicked.connect(self.settingsApply)
        self.MainLayout.addWidget(self.ApplyButton)

    def show(self) -> None:
        '''
        Opens the settings window and populates it with the current settings
        '''
        # Populate current settings to window
        self.DelimiterSelection.setText(self.settings['delimiter'])
        self.DecimalSelection.setText(self.settings['decimal'])
        self.TimeHeaderString.setText(self.settings['time_header_title'])
        self.DateTimeFormatComboBox.clear()
        self.DateTimeFormatComboBox.addItems(self.settings['recent_date_time_format'])
        self.DateTimeFormatLineEdit.setText(self.settings['date_time_format'])

        # Show the settings window
        super().show()
        super().activateWindow()

    def settingsApply(self) -> None:
        '''
        Saves the current settings and stores them in a json file
        '''
        # Save csv import settings
        self.settings['delimiter'] = self.DelimiterSelection.text()
        self.settings['decimal'] = self.DecimalSelection.text()
        self.settings['time_header_title'] = self.TimeHeaderString.text()
        self.settings['date_time_format'] = self.DateTimeFormatLineEdit.text()

        date_time_formats = [
            self.DateTimeFormatComboBox.itemText(i) for i in range(self.DateTimeFormatComboBox.count())
            ][:6]
        if self.settings['date_time_format'] not in date_time_formats:
            date_time_formats.insert(0, self.settings['date_time_format'])
            self.DateTimeFormatComboBox.addItem(self.DateTimeFormatLineEdit.text())
        self.settings['recent_date_time_format'] = date_time_formats

        # Write settings to the settings file
        with open(os.path.join(os.path.dirname(__file__), 'settings.json'), 'w+') as json_file:
            json.dump(self.settings, json_file)

    def constructCSVsettings(self) -> QGridLayout:
        '''
        Convenience function for constructing widgets pertaining to csv import settings
        '''
        # Create layout of csv settings
        self.CSVLayout = QGridLayout()

        # Input for setting the CSV delimiter
        self.DelimiterSelectionLabel = QLabel('Delimiter')
        self.DelimiterSelectionLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.CSVLayout.addWidget(self.DelimiterSelectionLabel, 0, 0)
        self.DelimiterSelection = QLineEdit()
        self.CSVLayout.addWidget(self.DelimiterSelection, 0, 1)

        # Input for setting the CSV comma character
        self.DecimalSelectionLabel = QLabel('Decimal')
        self.CSVLayout.addWidget(self.DecimalSelectionLabel, 0, 2)
        self.DecimalSelection = QLineEdit()
        self.CSVLayout.addWidget(self.DecimalSelection, 0, 3)

        # Input for the time column header
        self.TimeHeaderStringLabel = QLabel('Time Header Title')
        self.CSVLayout.addWidget(self.TimeHeaderStringLabel, 1, 0)
        self.TimeHeaderString = QLineEdit()
        self.CSVLayout.addWidget(self.TimeHeaderString, 1, 1, 1, 3)

        # Input for date/time format of the data
        self.DateTimeFormatLabel = QLabel('Date/Time Format')
        self.CSVLayout.addWidget(self.DateTimeFormatLabel, 2, 0)
        self.DateTimeFormatComboBox = QComboBox()
        self.DateTimeFormatLineEdit = QLineEdit()
        self.DateTimeFormatComboBox.setLineEdit(self.DateTimeFormatLineEdit)
        self.CSVLayout.addWidget(self.DateTimeFormatComboBox, 2, 1, 1, 3)

        return self.CSVLayout

    def defaultSettings(self) -> None:
        selected = self.defaultSettingsCombo.currentText()

        if selected == 'Siemens':
            self.DelimiterSelection.setText(';')
            self.DecimalSelection.setText(',')
            self.TimeHeaderString.setText('TimeString')
            self.DateTimeFormatLineEdit.setText('%d.%m.%Y %H:%M:%S')

        elif selected == 'StrideLinx':
            self.DelimiterSelection.setText(',')
            self.DecimalSelection.setText('.')
            self.TimeHeaderString.setText('time')
            self.DateTimeFormatLineEdit.setText('%Y-%m-%d %H:%M:%S.%f')

if __name__ == '__main__':
    # Helps with scaling when using two screens with diffirent DPI
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
    QApplication.setAttribute(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)

    # Initialize application
    app = QApplication(sys.argv)
    # Create window
    MainWindow = SettingsWindow({})
    MainWindow.show()
    # Terminated when the application is closed
    sys.exit(app.exec())


#!/usr/bin/env python
# encoding: utf-8
#@contact: 罗湘飞
#@time: 2019/4/19 17:55
import random
# from pip._internal import main as install_requirements
# install_requirements(['install', '-r', 'requirements.txt'])
from requestProt.K8S_call.K8S_call_log_save import K8sCallLogSave
from common.timeDecorator import my_time
import threading   #多线程模块

a=(i for i in range(1,100000000))
def port_fun():
    phone = random.randint(10000000, 99999999)
    data = '{"caller":"136%s","callTime":"2019-04-16 00:00:00","region":"020","time":1,"type":"1"}' % phone
    try:
        result=K8sCallLogSave().call_log_dave_port(data)
        print(result+"次数为%s"%next(a))
    except Exception as e:
        print("连接失败")

def run(bingfa):
    '''并发测试--多线程'''
    a=[]
    for i in range(int(bingfa)):                    #设置并发数量
        b=threading.Thread(target=port_fun)
        a.append(b)
        b.start()
    for c in a:
        c.join()
@my_time
def run_num(bingfa,xunhuan):
    '''测试循环次数'''
    for i in range(int(xunhuan)):                      #设置循环次数
        run(bingfa)
if __name__ == '__main__':
    bingfa=1000
    xunhuan=1000
    run_num(bingfa,xunhuan)
    CGL = (next(a) - 1) / (bingfa * xunhuan)
    print("成功为【{}】次，执行请求【{}】次，成功率为【{}】".format((next(a) - 2), (bingfa * xunhuan), str(CGL * 100) + '%'))


from gi.repository import Gtk, GdkPixbuf
from typing import Callable, List
import time

from frames import LightsFrame, WindowFrame, ProjectorFrame, GeneralFrame
from screens import OffScreen

button_filenames = ["light.png", "window.png", "projector.png", "on.png"]
other_frames = [LightsFrame, WindowFrame, ProjectorFrame, GeneralFrame]

class HomeButtonRow(Gtk.Frame):
    def __init__(self, change_other_screen: Callable, change_screen: Callable, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.on = False
        self.current_state_index = len(button_filenames)
        self.change_other_screen = change_other_screen
        self.change_screen = change_screen
        self.__add_elements()
        self.__change_button_border()

    def __change_button_border(self):
        for i in range(len(button_filenames) - 1):
            if i == self.current_state_index:
                self.box.get_children()[i].get_style_context().add_class("active")
            else:
                self.box.get_children()[i].get_style_context().remove_class("active")

    def __on_click(self, index: int):
        if index == len(button_filenames) - 1:
            self.change_screen(OffScreen)
            return

        if index == self.current_state_index:
            self.current_state_index = len(button_filenames) - 1
        else:
            self.current_state_index = index

        self.change_other_screen(other_frames[self.current_state_index])
        self.__change_button_border()

    def __add_elements(self):

        self.box = Gtk.Box()
        self.box.set_homogeneous(True)
        buttons: List[Gtk.Button] = [Gtk.Button() for _ in button_filenames]

        for i, name in enumerate(button_filenames):
            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(f"images/{name}", 160, 160, True)
            image = Gtk.Image.new_from_pixbuf(pixbuf)

            buttons[i].set_image(image)

        for i in range(len(buttons)):
            buttons[i].connect("clicked", lambda _, x=i: self.__on_click(x))
            self.box.pack_start(buttons[i], True, False, 20)
            buttons[i].show()

        buttons[-1].get_style_context().add_class("red")

        self.add(self.box)
        self.props.name = "home-button-row"
        self.box.show()


from fractions import Fraction
from random import randint, choice

# val is the secret (the value when x = 0).
# n is the number of points to distribute.
# k is the number of points needed to reconstruct the polynomial.
# Return a list of n random points such that x != 0 for every point.
def split(val, n, k):
	r = 1000
	neg = [1, -1]
	coefs = [choice(neg) * Fraction(randint(1, r), randint(1, r)) for i in range(0, k)]
	coefs.insert(0, val)

	xs = []
	ys = []
	for i in range(n):
		p = 0
		while p == 0 or p in xs:
			p = randint(-r, r)

		xs.append(p)
		ys.append(polyVal(coefs, p))

	keys = [(xs[i], ys[i]) for i in range(len(xs))]
	return keys

#given list of coefficents for p, find p(x)
def polyVal(coefs, x):
	val = 0
	i = 0
	for c in coefs:
		val += c * (x**i)
		i += 1
	return val

# points is a list of shares.
# x is the x-coordinate in which to compute the secret at.
# Return the computed secret value.
def interpolate(points, x): #using lagrange interpolation from wiki
	val = 0
	for j in range(len(points)):
		y = points[j][1]
		l = basis(points, x, j)
		val += y*l
	return val

def basis(points, x, j):
	val = 1
	for m in range(len(points)):
		if not m == j:
			a = (x - points[m][0])
			b = (points[j][0] - points[m][0])
			v=Fraction(a)/Fraction(b)
			val *= v
	return val

if __name__ == "__main__":
	pass


import os
from datetime import datetime as dt
counter = 0
flag = 0
pull_counter=0
date_Time = dt.now()
#print(date_Time)
#print("Previous working Directory : {0}".format(os.getcwd()))
#os.chdir('d:')
f = open("gitlogs.txt","w+")
log_File_Path = "gitlogs.txt"
print("GitLogs file is created in: {0}".format(os.getcwd()))
#os.chdir('UIProject_OH')
print("Present working directory : {0}".format(os.getcwd()))
###check for status###
status = os.popen("git status")

f.write("----------------------------------------------------------\n")
f.write("GIT STATUS:\n")
f.write(date_Time.strftime("%m/%d/%Y, %H:%M:%S:%f")+"\n\n")
status = os.popen('git status')
f.write(status.read())
f.write("\n----------------------------------------------------------\n")
f.close()
Text = "Changes not staged for commit:"
fileR = open(log_File_Path,"r")
status_data = fileR.read()
if Text in status_data:
    print("\nThere are pending changes, Now going to stash the changes\n")
    flag = 1
else:
    print("There are no pending changes, Ready to Pull...")
    flag = 0
fileR.close()
if flag == 1:
    ###Stash the changes###
    stash = os.popen("git stash")
    stash_data = stash.read()
    stashed_Text = "Saved working directory"
    if stashed_Text in stash_data:
        print("Stashed\n")
        file_Stash = open(log_File_Path,"a+")
        file_Stash.write("\nGIT STASH:\n")
        #print("\nSTASH: \n {0}".format(file_Stash.read()))
        file_Stash.write(stash.read())
        file_Stash.write("\n----------------------------------------------------------\n")
        file_Stash.close()
        ###check for status again###
        status1 = os.popen('git status')
        status1_data = status1.read()
        #print (status1.read())
        status1_Text = "working tree clean"
        if status1_Text in status1_data:
            print("Working tree is clean, \nReady to Pull...\n")
            GitPull()
        else :
            print("Error, Please proceed manually\n")
    else :
        print("Not Stashed, Please proceed masnually\n")
else :
    print("Ready to Pull...\n")
    GitPull()

def GitPull():
    file_pull = open(log_File_Path,"a+")
    pull = os.popen('git pull')
    file_pull.write("\n----------------------------------------------------------\n")
    file_pull.write("GIT PULL:\n")
    file_pull.write(pull.read())
    print("Pull Successfull\n")
    print("Restoring Stashed Data\n")
    os.popen('git stash pop')
    print("Stashed data restored, You can now proceed...!\n")
    exit()

exit()

#os.system('cmd /k "git status"')


from flask import Flask, render_template, url_for, request, redirect, jsonify
from flask_sqlalchemy import SQLAlchemy
import requests
import json
import psycopg2
import pytz
from datetime import datetime, timedelta
from dateutil.parser import parse

app = Flask(__name__)

@app.route('/')
def main():
    return render_template("main.html")

@app.route('/statistics/all')
def statistics_all():
    articles = requests.get('http://127.0.0.1:5001/date_of_take')
    data = []
    data_keys = list(articles.json().keys())
    data_values = list(articles.json().values())
    for i in range(len(articles.json())):
        data.append([data_keys[i], data_values[i]])
    return render_template("statistics.html", data=data)

@app.route('/statistics/week')
def statistics_weak():
    articles = requests.get('http://127.0.0.1:5001/date_of_take')
    data = []
    data_keys = list(articles.json().keys())
    data_values = list(articles.json().values())
    for i in range(len(articles.json())):
        data.append([data_keys[i], data_values[i]])
    data = data[:-8:-1]
    data = data[::-1]
    return render_template("statistics.html", data=data)

@app.route('/statistics/last_month')
def statistics_last_month():
    articles = requests.get('http://127.0.0.1:5001/date_of_take')
    data = []
    data_keys = list(articles.json().keys())
    data_values = list(articles.json().values())
    for i in range(len(articles.json())):
        data.append([data_keys[i], data_values[i]])
    data = data[:-31:-1]
    data = data[::-1]
    return render_template("statistics.html", data=data)

@app.route('/statistics/month')
def statistics_month():
    articles = requests.get('http://127.0.0.1:5001/date_of_take/month')
    data = []
    data_keys = list(articles.json().keys())
    data_values = list(articles.json().values())
    for i in range(len(articles.json())):
        data.append([data_keys[i], data_values[i]])
    return render_template("statistics.html", data=data)

@app.route('/statistics/year')
def statistics_year():
    articles = requests.get('http://127.0.0.1:5001/date_of_take/year')
    data = []
    data_keys = list(articles.json().keys())
    data_values = list(articles.json().values())
    for i in range(len(articles.json())):
        data.append([data_keys[i], data_values[i]])
    return render_template("statistics.html", data=data)

@app.route('/all_users')
def all_users():
    info_person = requests.get('http://127.0.0.1:5001/person')
    return render_template("all_users.html", articles_person=info_person.json())

@app.route('/all_books', methods=['POST', 'GET'])
def all_books():
    info_book = requests.get('http://127.0.0.1:5001/book').json()
    if request.method == "POST":
        arrears = int(request.form['arrears'])
        return redirect(f"/all_books/arrears/{arrears}")
    return render_template("all_books.html", articles_books=info_book)

@app.route('/all_books/arrears/<int:arrears>', methods=['POST', 'GET'])
def all_books_arrears(arrears):
    info_book = requests.get('http://127.0.0.1:5001/book').json()
    data_arrears = []
    for i in info_book:
        if type(i["date_of_issue"]) == str:
            new_time = parse(i["date_of_issue"])
            time_now = datetime.now(pytz.timezone('Europe/Moscow')).strftime("%Y-%m-%d")
            if new_time.date() + timedelta(days=arrears) < parse(time_now).date():
                data_arrears.append(i)
    return render_template("all_books_arrears.html", articles_books=data_arrears, arrears=arrears)

@app.route('/add_person', methods=['POST', 'GET'])
def create_user():
    if request.method == "POST":
        surname = request.form['surname']
        name = request.form['name']
        patronymic = request.form['patronymic']
        cafedra = request.form['cafedra']
        passport_data = request.form['passport_data']
        date_of_birthday = request.form['date_of_birthday']
        registration = request.form['registration']
        place_of_residence = request.form['place_of_residence']
        telephone = request.form['telephone']

        requests.post('http://127.0.0.1:5001/add_user', json={"surname": surname, "name": name,
                                                              "patronymic": patronymic,
                                                              "cafedra": cafedra,
                                                              "passport_data": passport_data,
                                                              "date_of_birthday": date_of_birthday,
                                                              "registration": registration,
                                                              "place_of_residence": place_of_residence,
                                                              "telephone": telephone})
        return redirect('/all_users')
    else:
        return render_template("add_user.html")

@app.route('/add_book', methods=['POST', 'GET'])
def add_book():
    if request.method == "POST":
        author = request.form['author']
        name = request.form['name']

        requests.post('http://127.0.0.1:5001/add_book', json={"author": author, "name": name})
        return redirect('/all_books')
    else:
        return render_template("add_book.html")

@app.route('/book/<int:id>/put', methods=['POST', 'GET'])
def put_book(id):
    info_Book = requests.get(f'http://127.0.0.1:5001/book/{id}')
    if request.method == "POST":

        author = request.form['author']
        name = request.form['name']
        person_id = request.form['person_id']
        requests.put(f'http://127.0.0.1:5001/book/{id}/put',
                     json={"author": author, "name": name,
                           "person_id": person_id, "id": id})
        return redirect('/all_books')
    else:
        return render_template("book_update.html", info_Book=info_Book.json())

@app.route('/all_users/<int:id>/put', methods=['POST', 'GET'])
def put_user(id):
    info_Person = requests.get(f'http://127.0.0.1:5001/all_users/{id}')
    if request.method == "POST":
        surname = request.form['surname']
        name = request.form['name']
        patronymic = request.form['patronymic']
        cafedra = request.form['cafedra']
        passport_data = request.form['passport_data']
        date_of_birthday = request.form['date_of_birthday']
        registration = request.form['registration']
        place_of_residence = request.form['place_of_residence']
        telephone = request.form['telephone']

        requests.put(f'http://127.0.0.1:5001/all_users/{id}/put', json={"surname": surname, "name": name,
                                                              "patronymic": patronymic,
                                                              "cafedra": cafedra,
                                                              "passport_data": passport_data,
                                                              "date_of_birthday": date_of_birthday,
                                                              "registration": registration,
                                                              "place_of_residence": place_of_residence,
                                                              "telephone": telephone})
        return redirect('/all_users')
    else:
        return render_template("user_update.html", info_Person=info_Person.json())

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


import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import streamlit as st
import numpy as np

@ticker.FuncFormatter
def major_formatter(x, pos):
    return "d%d" % (x / 24 / 3600)

def plot(days, sources, color="#E28BFD"):
    fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=1)
    for s in sources:
        data = s[0].xt()
        ax.plot(data[1], data[0], color, label=s[1])
    ax.legend(loc="lower center", fontsize=18.0)
    ax.xaxis.set_ticks(np.arange(0, 24 * 3600 * (days + 1), 24 * 3600))
    ax.xaxis.set_tick_params(labelrotation=45)
    ax.xaxis.set_major_formatter(major_formatter)

    st.write(fig)


import numpy as np
from matplotlib import pyplot as plt
import C_Re
import airprops
import RK

class Particles:
    def __init__(self, dp, rop):
        self.dp = dp
        self.name = int(dp*1000000)
        self.rop = rop

    def __repr__(self):
        return "[dp = " + str(self.name) + ", rop = " + str(self.rop) + "]"

class Gas:
    def __init__(self, R, P, T):
        self.R = R
        self.P = P
        self.T = T
        self.muf = airprops.mu_air(self.T)
        self.rof = airprops.density_air(self.R, self.P, self.T)

    def __repr__(self):
        return "[R = " + str(self.R) + ", P = " + str(self.P) + " , T = " + str(self.T) + "]"

class Flow:
    def __init__(self, l, u, gas, particle):
        self.u = u
        self.gas = gas
        self.particles = particle
        self.l = l
        self.w_set_c = C_Re.w_settling_corrected(self.particles.rop,
                                                 self.particles.dp,
                                                 self.gas.muf,
                                                 self.gas.rof,
                                                 self.u,
                                                 9.81)

    def __repr__(self):
        return "u = " + str(self.u) + ", particles: " + repr(self.particles)

    def caaasmp(self):
        k = 80001
        i = 1
        dt = 0.00005
        self.v = np.zeros(k)
        self.Re_p = np.zeros(k - 1)
        self.cd = np.zeros(k - 1)
        self.time = np.zeros(k)
        self.x = np.zeros(k)
        while i < k:
            self.Re_p[i - 1] = C_Re.reynolds_particle(self.u,
                                                      self.v[i - 1],
                                                      self.particles.dp,
                                                      self.gas.muf,
                                                      self.gas.rof)
            self.cd[i - 1] = C_Re.c_drag(self.Re_p[i - 1])
            self.v[i] = RK.f_plus(dt,
                                  9.81,
                                  self.cd[i - 1],
                                  self.u,
                                  self.v[i - 1],
                                  self.gas.rof,
                                  self.particles.rop,
                                  self.particles.dp)
            self.x[i] = self.x[i - 1] + (self.v[i] + self.v[i - 1]) / 2.0 * dt
            self.time[i] = self.time[i - 1] + dt
            i += 1
    """def caaasmp_height(self):
        k = 10001
        i = 1
        dt = 0.00005
        #self.vh = - self.v[-1] * np.ones(k)
        self.vh = - 1 * self.v[self.l_element] * np.ones(k)
        #self.vh = np.zeros(k)
        #self.v = -np.ones(k)*31
        self.Re_ph = np.zeros(k - 1)
        self.cdh = np.zeros(k - 1)
        self.timeh = np.zeros(k)
        self.xh = np.zeros(k)
        while self.vh[i-1] < 0:
            self.Re_ph[i - 1] = C_Re.reynolds_particle(self.u,
                                                      self.vh[i - 1],
                                                      self.particles.dp,
                                                      self.gas.muf,
                                                      self.gas.rof)
            self.cdh[i - 1] = C_Re.c_drag(self.Re_ph[i - 1])
            self.vh[i] = RK.f_plus(dt,
                                  9.81,
                                  self.cdh[i - 1],
                                  self.u,
                                  self.vh[i - 1],
                                  self.gas.rof,
                                  self.particles.rop,
                                  self.particles.dp)
            self.xh[i] = self.xh[i - 1] + (self.vh[i] + self.vh[i - 1]) / 2.0 * dt
            self.timeh[i] = self.timeh[i - 1] + dt
            self.height = self.xh[i]
            i += 1

    def velocity_lenght(self):
        self.l_element = np.argmin(np.abs(self.x - self.l))"""

if __name__ == '__main__':
    air = Gas(287.0, 101325.0, 293.15)

    u = np.linspace(-20,0.0001,5)
    partlist = [Particles(160*1e-6, 2550.0), Particles(8000*1e-6, 1000.0)]

    flows = []

    for velocity in u:
        for p in partlist:
            #flows[velocity, p] = Flow(3.0, velocity, air, p)
            flows.append(Flow(3.0, velocity, air, p))

    for flow in flows:
        flow.caaasmp()

    for flow in flows:
        if flow.particles.name == 160:
            plt.plot(flow.x, flow.v, linestyle="--")
        else:
            plt.plot(flow.x, flow.v)
    plt.grid()
    plt.show()
    #for flow in flows:
    #    print(flow, ":")
    #    flow.caaasmp()
    #    print("-------------------------")
    """for i in partlist:
        f = {}
        for j in u:
            f[j] = Flow(3.0, j, air, i)
        flows[i.dp] = f
    for i in flows:
        for j in flows[i]:
            print('u = ', flows[i][j].u)
            flows[i][j].caaasmp()
            flows[i][j].velocity_lenght()
            flows[i][j].caaasmp_height()
    for i in flows:
        v = []
        u = []
        h = []
        for j in flows[i]:
            indx = flows[i][j].l_element
            #v.append(flows[i][j].v[indx]-flows[i][j].u)
            v.append(flows[i][j].v[indx]-flows[i][j].u)
            u.append(flows[i][j].u)
            h.append(-flows[i][j].height)
        plt.plot(u,v)
    #plt.axhline(1.069)
    plt.grid(True)
    plt.show()
    plt.plot(u, h)
    plt.show()"""


from django.db import models

class Recipient(models.Model):
    name = models.CharField(max_length=250)
    description = models.TextField(null=True, blank=True)
    recipient_type = models.ForeignKey(to='RecipientType', on_delete=models.SET_NULL, null=True)
    iban = models.CharField(max_length=50, null=True, blank=True)
    street = models.CharField(max_length=100, null=True, blank=True)
    housenumber = models.CharField(max_length=50, null=True, blank=True)
    postcode = models.CharField(max_length=5, null=True, blank=True)
    city = models.CharField(max_length=50, null=True, blank=True)
    phonenumber = models.CharField(max_length=20, null=True, blank=True)

    active = models.BooleanField(default=True)
    user = models.ForeignKey(to='users.CustomUser', on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return f"{self.name}"

class RecipientFavorit(models.Model):
    user = models.ForeignKey(to='users.CustomUser', on_delete=models.CASCADE, null=True)
    recipient = models.ForeignKey(to='Recipient', on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.id}"

class RecipientType(models.Model):
    name = models.CharField(max_length=250, unique=True)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return f"{self.name}"

class OpeningHours(models.Model):
    class Weekdays(models.IntegerChoices):
        Montag = 1
        Dienstag = 2
        Mittwoch = 3
        Donnerstag = 4
        Freitag = 5
        Samstag = 6
        Sonntag = 7

    recipient = models.ForeignKey(to='Recipient', on_delete=models.CASCADE)
    day = models.IntegerField(choices=Weekdays.choices)
    beginn_time = models.TimeField()
    end_time = models.TimeField()

    def __str__(self):
        return f"{self.recipient}"


from decimal import Decimal
from twython import TwythonStreamer
import json
import os
import requests
import re

settings = {
    #'twitter_userid': "12137672", # gorillamania (for testing)
    'twitter_userid': "961445378", # officialmcafee
    'exchange_key': os.getenv("EXCHANGE_KEY"), # your Bittrex API key
    'exchange_secret': os.getenv("EXCHANGE_SECRET"), # your Bittrex API secret
    'buy_amount_btc': Decimal(2), # Amount to buy
    'limit_multiplier': Decimal(1.075), # How much over the current ticker to set the limit order
    'twitter_app_key': os.getenv("TWITTER_APP_KEY"),
    'twitter_app_secret': os.getenv("TWITTER_APP_SECRET"),
    'twitter_oauth_token': os.getenv("TWITTER_OAUTH_TOKEN"),
    'twitter_oauth_secret': os.getenv("TWITTER_OAUTH_SECRET"),
}

"""
Flow
1. Set up the streamer to listen to all tweets from twitter_username
2. When a tweet is found, parse for symbol
3. Is it a valid symbol for Bittrex?
4. BUY!
"""

def get_markets():
    # Fetch the current markets so we know if it is a valid symbol
    response = requests.get("https://bittrex.com/api/v1.1/public/getmarkets")
    assert response.status_code == 200
    markets = []
    for m in response.json()["result"]:
        markets.append(m["MarketCurrency"])
    return markets
MARKETS = get_markets()

def handle_tweet(tweet):
    match = re.search("[A-Z]{3,5}", tweet)
    if not match:
        print("No symbol found in tweet: '%s'" % tweet)
        return

    symbol = match.group(0)
    if symbol not in MARKETS:
        print("%s is not tradeable on Bittrex" % symbol)
        return

    buy_crypto(symbol)

def buy_crypto(symbol):
    from bitex import Bittrex
    e = Bittrex(settings["exchange_key"], settings["exchange_secret"])

    pair = "BTC-" + symbol
    print("Fetching current quote for %s" % pair)
    quote = e.ticker(pair).formatted
    current_price = Decimal(quote[6])

    price = current_price * settings["limit_multiplier"]
    amount = settings["buy_amount_btc"] / price
    print("Buying %s of %s at %s" % (amount, symbol, price))
    response = e.bid(pair, price, amount, False)
    print(response.json())

## Set up the streamer
# https://twython.readthedocs.io/en/latest/usage/streaming_api.html
class OurStreamer(TwythonStreamer):

    def on_success(self, data):
        if "user" in data and data["user"]["id_str"] == settings["twitter_userid"]:
            print(json.dumps(data, indent=2))
            if 'text' in data:
                handle_tweet(data["text"])

    def on_error(self, status_code, data):
        print("Error:", status_code, data)
        self.disconnect()

print("Setting up Twitter feed listener")
stream = OurStreamer(
        settings["twitter_app_key"],
        settings["twitter_app_secret"],
        settings["twitter_oauth_token"],
        settings["twitter_oauth_secret"])
stream.statuses.filter(follow=settings["twitter_userid"])
print("Listening...")


import unittest

import pyAgrum as gum
from .pyAgrumTestSuite import pyAgrumTestCase, addTests
import pyAgrum.causal as csl

class TestSimpson(pyAgrumTestCase):
  def setUp(self):
    m1 = gum.fastBN("Gender->Drug->Patient;Gender->Patient")

    m1.cpt("Gender")[:] = [0.5, 0.5]
    m1.cpt("Drug")[:] = [[0.25, 0.75],  # Gender=0
                         [0.75, 0.25]]  # Gender=1

    m1.cpt("Patient")[{'Drug': 0, 'Gender': 0}] = [
      0.2, 0.8]  # No Drug, Male -> healed in 0.8 of cases
    # No Drug, Female -> healed in 0.4 of cases
    m1.cpt("Patient")[{'Drug': 0, 'Gender': 1}] = [0.6, 0.4]
    m1.cpt("Patient")[{'Drug': 1, 'Gender': 0}] = [
      0.3, 0.7]  # Drug, Male -> healed 0.7 of cases
    m1.cpt("Patient")[{'Drug': 1, 'Gender': 1}] = [
      0.8, 0.2]  # Drug, Female -> healed in 0.2 of cases
    self.model = csl.CausalModel(m1)

  def test_CausalImpactWithoutObservation(self):
    evs = {}
    latex, impact, explain = csl.causalImpact(
      self.model, "Patient", doing="Drug", knowing=evs)

  def test_CausalImpactWithObservation(self):
    evs = {'Gender'}
    latex, impact, explain = csl.causalImpact(
      self.model, "Patient", doing="Drug", knowing=evs)

class TestFromUsers(pyAgrumTestCase):
  def test_AccentsInVariables(self):
    bn = gum.fastBN("héhé->hoho")
    cm = csl.CausalModel(bn)
    formula, impact, explanation = csl.causalImpact(cm, "héhé", "hoho")

  def test_from_Musfiqshohan(self):
    cm = csl.CausalModel(gum.fastBN('A->B->C->F;'
                                    'A->D;'
                                    'A->E;'
                                    'C->D->E->F;'
                                    'C->E;'
                                    ), [
                           ('U0', ('C', 'F')),
                           ('U1', ('C', 'E')),
                           ('U2', ('E', 'F'))
                         ], keepArcs=True)
    csl.causalImpact(cm, on={'E'}, doing={'A', 'D', 'B'})

class TestFromR(pyAgrumTestCase):
  def setUp(self):
    m = gum.fastBN("z2->x->z1->y;z2->z1;z2->z3->y")

    m.cpt("z2")[:] = [0.5, 0.5]
    m.cpt("x")[:] = [[0.4, 0.6],  # z2=0
                     [0.4, 0.6]]  # z2=1
    m.cpt("z3")[:] = [[0.3, 0.7],  # z2=0
                      [0.3, 0.7]]  # z2=1
    m.cpt("z1")[{"z2": 0, "x": 0}] = [0.2, 0.8]
    m.cpt("z1")[{"z2": 0, "x": 1}] = [0.25, 0.75]
    m.cpt("z1")[{"z2": 1, "x": 0}] = [0.1, 0.9]
    m.cpt("z1")[{"z2": 1, "x": 1}] = [0.15, 0.85]

    m.cpt("y")[{"z1": 0, "z3": 0}] = [0.5, 0.5]
    m.cpt("y")[{"z1": 0, "z3": 1}] = [0.45, 0.55]
    m.cpt("y")[{"z1": 1, "z3": 0}] = [0.4, 0.6]
    m.cpt("y")[{"z1": 1, "z3": 1}] = [0.35, 0.65]

    self.d = csl.CausalModel(m, [("X-Z2", ["x", "z2"]),
                                 ("X-Z3", ["x", "z3"]),
                                 ("X-Y", ["x", "y"]),
                                 ("Y-Z2", ["y", "z2"])],
                             True)
    try:
      formula, result, msg = csl.causalImpact(
        self.d, on={"y", "z2", "z1", "z3"}, doing={"x"})
    except csl.HedgeException as h:
      self.fail("Should not raise")

class TestsFromGumWhy(pyAgrumTestCase):
  def test_Carouselp115(self):
    ab = gum.fastBN('Elapsed time[11]->Bag on Carousel<-Bag on Plane')
    ab.cpt("Bag on Plane").fillWith(1).normalize()
    ab.cpt("Elapsed time").fillWith(1).normalize()
    ab.cpt("Bag on Carousel").fillWith(
      [1.0, 0.0] * 11 + [1 - i / 20 if i % 2 == 0 else (i - 1) / 20 for i in range(22)])
    abModele = csl.CausalModel(ab)
    formula, impact, explanation = csl.causalImpact(abModele, on={"Bag on Plane"}, doing={
      "Elapsed time"}, knowing={"Bag on Carousel"}, values={"Elapsed time": 7, "Bag on Carousel": 0})
    self.assertAlmostEqual(impact[0], 0.7692, 4)

  def test_DoCalculusp213(self):
    fd = gum.fastBN("w->z->x->y")
    fdModele = csl.CausalModel(
      fd, [("u1", ["w", "x"]), ("u2", ["w", "y"])], True)
    formula, impact, explanation = csl.causalImpact(
      fdModele, on="y", doing="x")

ts = unittest.TestSuite()
addTests(ts, TestSimpson)
addTests(ts, TestFromUsers)
addTests(ts, TestFromR)
addTests(ts, TestsFromGumWhy)


from itertools import product
from pygame import Rect, RLEACCEL
import pygame

__all__ = ('GraphicBox', 'draw_text')

class GraphicBox(object):
    """Generic class for drawing graphical boxes

    box = GraphicBox('border.png')
    box.draw(rect)

    The border graphic must contain 9 tiles laid out in a box.
    Each tile must be the same size
    """
    def __init__(self, image, hollow=False):
        iw, ih = image.get_size()
        self.tw = int(iw / 3)
        self.th = int(ih / 3)
        self.hollow = hollow

        tiles = [image.subsurface((x, y, self.tw, self.th))
                 for x, y in product(range(0, iw, self.tw),
                                     range(0, ih, self.th))]

        self.tiles = dict(zip("nw w sw n c s ne e se".split(), tiles))
        self.background = self.tiles['c'].get_at((0, 0))

        if self.hollow:
            ck = self.tiles['c'].get_at((0, 0))
            [t.set_colorkey(ck, RLEACCEL) for t in self.tiles.values()]

    def draw(self, surface, rect=None):
        if rect is None:
            rect = surface.get_rect()

        ox, oy, w, h = Rect(rect)
        surface_blit = surface.blit
        tiles = self.tiles
        tw = self.tw
        th = self.th

        if not self.hollow:
            p = product(range(tw + ox, w - tw + ox, tw),
                        range(th + oy, h - th + oy, th))
            [surface_blit(tiles['c'], (x, y)) for x, y in p]

        for x in range(tw + ox, w - tw + ox, tw):
            surface_blit(tiles['n'], (x, oy))
            surface_blit(tiles['s'], (x, h - th + oy))

        for y in range(th + oy, h - th + oy, th):
            surface_blit(tiles['e'], (w - tw + ox, y))
            surface_blit(tiles['w'], (ox, y))

        surface_blit(tiles['nw'], (ox, oy))
        surface_blit(tiles['ne'], (w - tw + ox, oy))
        surface_blit(tiles['sw'], (ox, h - th + oy))
        surface_blit(tiles['se'], (w - tw + ox, h - th + oy))

def draw_text(surface, text, rect, font=None, fg_color=None, bg_color=None, aa=False):
    """ draw some text into an area of a surface

    automatically wraps words
    returns size and any text that didn't get blit
    passing None as the surface is ok
    """
    if fg_color is None:
        fg_color = (0, 0, 0)

    total_width = 0
    rect = Rect(rect)
    y = rect.top
    line_spacing = -2

    if font is None:
        full_path = pygame.font.get_default_font()
        font = pygame.font.Font(full_path, 16)

    # get the height of the font
    font_height = font.size("Tg")[1]

    # for very small fonts, turn off antialiasing
    if font_height < 16:
        aa = 0
        bg_color = None

    while text:
        char_index = 1

        # determine if the row of text will be outside our area
        if y + font_height > rect.bottom:
            break

        # determine maximum width of line
        line_width = font.size(text[:char_index])[0]
        while line_width < rect.width and char_index < len(text):
            if text[char_index] == "\n":
                text = text[:char_index] + text[char_index + 1:]
                break

            char_index += 1
            line_width = font.size(text[:char_index])[0]
            total_width = max(total_width, line_width)
        else:
            # if we've wrapped the text, then adjust the wrap to the last word
            if char_index < len(text):
                char_index = text.rfind(" ", 0, char_index) + 1

        if surface:
            # render the line and blit it to the surface
            if bg_color:
                image = font.render(text[:char_index], 1, fg_color, bg_color)
                image.set_colorkey(bg_color)
            else:
                image = font.render(text[:char_index], aa, fg_color)

            surface.blit(image, (rect.left, y))

        y += font_height + line_spacing

        # remove the text we just blitted
        text = text[char_index:]

    return total_width, text


""""
Performs the PCA to find the most relevant axis and compute the features of UFSR
on the points (000),mean(100,-100), mean(010,0-10), mean(001,00-1)

Compute distances
"""

import scipy as np
import os
import csv
from sklearn.decomposition import PCA
import pandas as pd
import time

# returns the centroid of an array
def centroidnp(arr):
    length, dim = arr.shape
    sums = np.array([np.sum(arr[:, i]) for i in range(dim)])
    center = sums / length
    return center

# takes an array of positions and returns the positions of the ufsr pivots
# distance_of_points represents the distance in Angstroms of the pivots to the centroids
def find_pivots(X, distance_of_points=4):
    center = centroidnp(X)
    # make PCA
    n_components = X.shape[1]
    pca = PCA(n_components=n_components)
    pca.fit(X)
    pca_vectors = pca.components_

    # find usfr normalized eigenvectors and add them to the centroid to find the USFR starting point
    full_vectors = np.concatenate((pca_vectors, -1 * pca_vectors))
    # print(full_vectors)
    full_points = distance_of_points * full_vectors + center
    return full_points

# random distributions of 30 nodes, 1000 examples
# find pivots : 0.28 seconds ---
# dist to pivots : 0.15 seconds ---
# moments : 1.26 (6 moments), 0.55 (3), 0.33 (2) seconds ---
# encode a matrix of positions with the distribution of its moments
# number_moments is the number of moments computed, for instance, [mu, sigma] means number_moments = 2
def encode(X, number_of_moments=3):
    n_dimension = X.shape[1]
    center = centroidnp(X)
    full_points = find_pivots(X)

    # get distance matrix where rows are pivot points and columns are data points
    dist_to_centroid = np.array([[np.linalg.norm(X[j] - center) for j in range(X.shape[0])]])
    dist_matrix = np.spatial.distance_matrix(full_points, X)
    # code à la main, 4 fois plus lent
    # dist_matrix = np.array(
    #     [[np.linalg.norm(X[j] - full_point) for j in range(X.shape[0])] for full_point in full_points])

    # aggregate the symetric pivots
    dist_ufsr = np.array([(dist_matrix[i] + dist_matrix[n_dimension + i]) * 0.5 for i in range(n_dimension)])

    # add the distance to center of mass, dist_ufsr is now a matrix with distribution of distances wrt
    # (000),mean(100,-100), mean(010,0-10), mean(001,00-1) as rows
    dist_ufsr = np.concatenate((dist_to_centroid, dist_ufsr))

    # get the features
    means = np.array([[np.mean(dist_ufsr[i]) for i in range(n_dimension + 1)]])
    means = np.transpose(means)
    moments = np.array(
        [[np.stats.moment(dist_ufsr[i], j) for j in range(2, number_of_moments + 1)] for i in range(n_dimension + 1)])
    ufsr_feature = np.concatenate((means, moments), axis=1)

    # mean, moment2, moment3..., moment6, mean, moment1... for each pivot
    ufsr_feature = ufsr_feature.ravel()

    return ufsr_feature

# returns the similarity measure of two arrays
def usfr_similarity(x, y):
    x = np.asarray(x)
    y = np.asarray(y)
    try:
        similarity_measure = 1 / (1 + np.sum(abs(x - y)))
    except:
        return None
    return similarity_measure

# copied from scipy documentation
def distance_matrix(x, y, output_name=0):
    x = np.asarray(x)
    m, k = x.shape
    y = np.asarray(y)
    n, kk = y.shape
    result = np.empty((m, n), dtype=float)  # FIXME: figure out the best dtype
    for i in range(m):
        result[i, :] = [usfr_similarity(x[i], y_j) for y_j in y]
        print(result[i, :])
        if output_name:
            with open(os.path.join('../data/output_csv', output_name + '.csv'), "a", newline='') as fp:
                wr = csv.writer(fp, dialect='excel')
                wr.writerow(result[i, :])
    return result

'''
apply these computations to data
'''

def build_colnames(moments_kept, centroids):
    # build the names of the columns
    lists = [['m' + str(i + 1) + 'c' + str(j + 1) for i in range(moments_kept)] for j in range(centroids)]
    L = []
    for list in lists:
        L += list
    colnames = ['pdb', 'ligand'] + L
    return colnames

def csv_reader(input_name):
    df = pd.read_csv(os.path.join('../data/output_csv', input_name + '.csv'))
    return df

# keep only a few moments from a pandas df
# returns a df with name, ligand and moments compressed
def reduce_number_of_moment(df, moments_after, moments_before=3, centroids=4):
    # keep the name and ligand, then select only the first moments for each feature
    criteria = [True, True] + [(i % moments_before < moments_after) for i in range(moments_before * centroids)]
    reduced_df = df[df.columns[criteria]]
    return reduced_df

def DM_from_csv(input_name, output_name, moments_kept=0):
    df = csv_reader(input_name)
    if moments_kept:
        df = reduce_number_of_moment(df, moments_kept)
    values = df[df.columns[2:]]
    DM = distance_matrix(values, values, output_name)

if __name__ == "__main__":
    import matplotlib.pyplot as plt

    X = np.array([[2, 1], [5, 2], [1, 1], [2, 2], [3, 2], [5, 5], [6, 6.57]])

    X_x = X[:, 0]
    X_y = X[:, 1]
    center = centroidnp(X)
    full_points = find_pivots(X)
    usfr_x = full_points[:, 0]
    usfr_y = full_points[:, 1]

    plt.scatter(X_x, X_y, alpha=0.5)
    plt.scatter(center[0], center[1], alpha=0.5)
    plt.scatter(usfr_x, usfr_y, alpha=0.5)
    plt.show()

'''
plot

x = X[:, 0]
y = X[:, 1]

fig, ax = plt.subplots(figsize=(10, 5), ncols=3, nrows=2)

left = 0.125  # the left side of the subplots of the figure
right = 0.9  # the right side of the subplots of the figure
bottom = 0.1  # the bottom of the subplots of the figure
top = 0.9  # the top of the subplots of the figure
wspace = .5  # the amount of width reserved for blank space between subplots
hspace = 1.1  # the amount of height reserved for white space between subplots

# This function actually adjusts the sub plots using the above paramters
plt.subplots_adjust(
    left=left,
    bottom=bottom,
    right=right,
    top=top,
    wspace=wspace,
    hspace=hspace
)

y_title_margin = 0.8
ax[0][0].set_title("zero", y=y_title_margin)
ax[0][1].set_title("first", y=y_title_margin)
ax[0][2].set_title("second", y=y_title_margin)

sns.distplot(dist_ufsr[0], ax=ax[0][0], kde=False, rug=True)
sns.distplot(dist_ufsr[1], ax=ax[0][1], kde=False, rug=True)
sns.distplot(dist_ufsr[2], ax=ax[0][2], kde=False, rug=True)

plt.show()

usfr_x = full_points[:, 0]
usfr_y = full_points[:, 1]
plt.scatter(x, y, alpha=0.5)
plt.scatter(center[0], center[1], alpha=0.5)
plt.scatter(usfr_x, usfr_y, alpha=0.5)
plt.show()

# print(preprocessing.normalize(pca.components_, norm='l2'))
'''


from django.contrib import admin
from .models import Pelicula, Sesiones, Sala, Butaca

# Register your models here.
class PeliculasAdmin(admin.ModelAdmin):
    readonly_fields = ('created', 'updated')
    list_display = ('titulo', 'created', 'updated')
    list_filter = ('titulo',) # Agrega el filtro por género

class SesionesAdmin(admin.ModelAdmin):
    list_display = ('pelicula', 'fecha', 'hora')
    list_filter = ('pelicula__titulo',) # Agrega el filtro por título de película

class SalaAdmin(admin.ModelAdmin):
    list_display = ('nombre', 'num_filas', 'num_columnas', 'pelicula')
    list_filter = ('nombre',) # Agrega el filtro por género

class ButacaAdmin(admin.ModelAdmin):
    list_display = ('fila', 'columna', 'num_butaca', 'sala', 'ocupada')
    list_filter = ('sala', 'ocupada')
    search_fields = ('fila', 'columna', 'num_butaca', 'sala__nombre')

admin.site.register(Pelicula, PeliculasAdmin)
admin.site.register(Sesiones, SesionesAdmin)
admin.site.register(Sala, SalaAdmin)
admin.site.register(Butaca, ButacaAdmin)


from __future__ import print_function
import os
import sys
import logging
import argparse
from  bam2x import IO,TableIO,DBI
from  bam2x.Annotation import BED6
from bam2x.Tools import _translate_to_meta,merge_bed,gini_coefficient
from math import log
from bam2x.gmm import model_str,fit_two_peaks_EM,bayes_p2
from numpy import array
import time
VERSION="0.2"
def help():
    return "merged tss or tts (Result from bam2ends.py)"

def set_parser(parser):
    #parser.add_argument("-m",type=str,choices=("seq","cDNA","cdna","cds","utr5","utr3"),dest="method")
    parser.add_argument("--gap",type=int,dest="gap",default=10,help="min gap default:%(default)s")
    parser.add_argument("--min",type=int,dest="min_reads_number",default=0,help="reads number threshold, default:%(default)s")
    parser.add_argument("--gene",type=str,dest="gene",default=0,help="known gene bed12 file")
    parser.add_argument("--tts",action="store_true",dest="tts",help="tts default: tss")
    parser.add_argument("--prefix",dest="prefix",help="prefix for bed name",default="meta")

def run(args):
    logging.basicConfig(level=logging.INFO)
    def process():
        if len(buff)==1: return 0
        max_score=0.0
        total_score=0.0
        e=[]
        for i in buff:
            total_score+=i.score
            e.append(i.score)
        e=[i/total_score for i in e]
        gini=gini_coefficient(e)
        if total_score < args.min_reads_number:
            return 0
        record={}
        meta=BED6(buff[0].chr,buff[0].start,buff[-1].stop,args.prefix+"."+str(group_id),total_score,buff[0].strand)
        peak=max(buff,key=lambda x:x.score)
        record["peak"]=peak._replace(score=peak.score/total_score)
        record["meta"]=meta._replace(strand=peak.strand)
        record["gini"]=gini
        records.append(record)
        return 1

    def simple_output():
        print("# formats: bayes_prob_model2, gini, [ region bed, score is total reads], [peak bed , score is proportion ]",file=out)
        for i,x in enumerate(records):
            print("{p2}\t{gini}\t{meta}\t".format(p2=p2[i],meta=x["meta"],gini=x["gini"]),end="",file=out)
            print(x["peak"],file=out)
    def bed12_output():
        print("# formats: bed12 , [R,G,B] are corresponding to [ TTS_GINI_PVALUE*200, TSS_GINI_PALUE*200, PROPORTION_OF_PEAK*200 ]",file=out)
        for i,x in enumerate(records):
            if args.tts:
                g=0
                r=int(p2[i]*200)
            else:
                g=int(p2[i]*200)
                r=0
            b=int(x["gini"]*200)
            if p2[i]>0.5:
                meta=x["meta"]._replace(id=x["meta"].id+".end")
            else:
                meta=x["meta"]
            rgb="{r},{g},{b}".format(r=r,g=g,b=b)
            print("{bed6}\t{thickStart}\t{thickEnd}\t{itemRgb}\t{blockCount}\t{blockSizes}\t{blockStarts}".format(bed6=meta,thickStart=x["peak"].start,thickEnd=x["peak"].end,itemRgb=rgb,blockSizes=x["meta"].stop-x["meta"].start,blockCount=1,blockStarts=0),file=out)

    records=[]
    GAP=args.gap
    fin=IO.fopen(args.input,"r")
    out=IO.fopen(args.output,"w")
    iterator=TableIO.parse(fin,"bed6")
    last=iterator.next()
    last_stop=last.stop
    group_id=0
    buff=[last]
    last_chr=last.chr
    for x,i in enumerate(iterator):
        if x%10000==0: logging.info("processing {x} reads".format(x=x));
        if i.chr!=last_chr or i.start-last_stop > GAP:
            group_id+=process()
            buff=[i]
            last_chr=i.chr
            last_stop=i.stop
        else:
            buff.append(i)
            if i.stop>last_stop:
                last_stop=i.stop

    process()
    gini=array([i["gini"] for i in records])
    model=fit_two_peaks_EM(gini)
    p2=bayes_p2(gini,model)
    print("# Date: ",time.asctime(),file=out)
    print("# Program Version ",VERSION,file=out)
    print("# The command line is :",file=out)
    print("#\t"," ".join(sys.argv),file=out)
    print("# learning model:",file=out)
    print("#",model_str(model),file=out)
    #simple_output()
    bed12_output()

if __name__=="__main__":
    from bam2x.IO import parser_factory
    p=parser_factory(description=help())
    set_parser(p)
    if len(sys.argv)==1:
        print(p.print_help())
        exit(0)
    run(p.parse_args())


"""Module defining Hotword component based on Snowboy"""
import logging
import os
import time
import wave

from tuxeatpi_common.daemon import TepBaseDaemon
from tuxeatpi_common.error import TuxEatPiError
from tuxeatpi_common.message import Message
from tuxeatpi_common.wamp import is_wamp_topic, is_wamp_rpc

from tuxeatpi_hotword_kittai.libs import snowboydecoder

LANGUAGES = {"en_US": "eng-USA",
             "fr_FR": "fra-FRA"}

class HotWord(TepBaseDaemon):
    """HotWord SnowBoy based component class

    This component waits for hotword and triggers nlu/audio topic message
    """
    def __init__(self, name, workdir, intent_folder, dialog_folder, logging_level=logging.INFO):
        self.name = "hotword"
        TepBaseDaemon.__init__(self, name, workdir, intent_folder, dialog_folder, logging_level)
        # Decoder
        self.disabled = False
        # Get from settings
        self._answer_sound_path = None
        self.sensitivity = 0.5
        self._model_file = None
        self.detector = None

    def _answering(self):
        """Play the hotword confirmation sound"""
        f_ans = wave.open(self._answer_sound_path, "rb")
        self._paudio = self.detector.audio
        stream = self._paudio.open(format=self._paudio.get_format_from_width(f_ans.getsampwidth()),
                                   channels=f_ans.getnchannels(),
                                   rate=f_ans.getframerate(),
                                   output=True)
        data = f_ans.readframes(1024)
        while data:
            stream.write(data)
            data = f_ans.readframes(1024)
        # Close file
        f_ans.close()
        # Close stream
        stream.stop_stream()
        stream.close()

    def _wake_up(self):
        """Wake up work capability

        Answer to the speaker and create a transmission for audio nlu
        """
        if not self.disabled:
            # answering
            self._answering()
            # create tranmission for audio nlu
            data = {"arguments": {"context_tag": "general"}}
            message = Message(topic="nlu.audio", data=data, context="general")
            self.publish(message)
        else:
            self.logger.debug("HotWord detected but hotword disabled")

    def set_config(self, config):
        """Save the configuration and reload the daemon"""
        # TODO improve this ? can be factorized ?
        for attr in ('sensitivity', 'sound_file', 'model_file'):
            if attr not in config.keys():
                self.logger.error("Missing parameter {}".format(attr))
                return False
        # Check params
        if not os.path.isfile(config.get("sound_file", "")):
            self.logger.error("Bad sound file: %s", config.get("sound_file"))
            return False
        if not os.path.isfile(config.get("model_file", "")):
            self.logger.error("Bad model file: %s", config.get("model_file"))
            return False
        # Set params
        self._answer_sound_path = config.get("sound_file")
        if self._model_file != config.get('model_file') or \
                self.sensitivity != config.get("sensitivity"):
            self._model_file = config.get('model_file')
            self.sensitivity = float(config.get("sensitivity"))
            if self.detector is not None:
                self.logger.info("Stopping hotword detector")
                self.detector.terminate()
                self.detector = None
            # Create a new detector
            self.logger.info("Initializing hotword detector")
            self.detector = snowboydecoder.HotwordDetector(self._model_file,
                                                           self.logger,
                                                           sensitivity=self.sensitivity)

        return True

    @is_wamp_rpc("help")
    @is_wamp_topic("help")
    def help_(self):
        pass

    @is_wamp_topic("shutdown")
    def shutdown(self):
        if hasattr(self.detector, 'terminate'):
            self.detector.terminate()
            self.detector = None
        super(HotWord, self).shutdown()

    @is_wamp_rpc("reload")
    @is_wamp_topic("reload")
    def reload(self):
        pass

    @is_wamp_rpc("disable")
    @is_wamp_topic("disable")
    def disable(self):
        """Disable hotword listening"""
        self.logger.info("Disabling listening for hotword")
        self.disabled = True

    @is_wamp_rpc("enable")
    @is_wamp_topic("enable")
    def enable(self):
        """Enable hotword listening"""
        self.logger.info("Enabling listening for hotword")
        self.disabled = False

    def main_loop(self):
        """Main Loop"""
        if self.detector is not None:
            try:
                self.detector.start(detected_callback=self._wake_up,
                                    sleep_time=0.03)
            except Exception as exp:  # pylint: disable=W0703
                self.logger.error(exp)
                time.sleep(5)
        else:
            self.logger.warning("Hotword detector not started, wait for settings")
            time.sleep(1)

class HotWordError(TuxEatPiError):
    """Base class for hotword exceptions"""
    pass


"""
Provide a class that can be iterated over all the combination of values in a Json list
"""

import json

iterables = []

def iterate(base_process, folder):
    """
    Create the list based on a json parsable list/dict
    :param base_process: the json parsable list/dict
    :param folder: the folder to output the Json to
    :return:
    """
    # check number generated
    l = 1
    for it in iterables:
        l *= len(it.r)

    print(l)
    if l > 10000:
        return

    current_int = 0
    index = 0
    filename = folder + "/processConfig%s.json"

    if len(iterables) == 0: #if no iteration needed just save one file
        j = IterEncoder().encode(base_process)
        with open(filename % index, 'w') as f:
            f.write(j)
        return

    while True:
        index += 1
        j = IterEncoder().encode(base_process)
        with open(filename % index, 'w') as f:
            f.write(j)
        while iterables[current_int].iter():
            current_int += 1
            if current_int == len(iterables):
                return  # end of process

        current_int = 0

class Iter:
    """
    Class implemeneting the itering functionality
    """

    def __init__(self, r):
        """
        :param r: list or range of value
        """
        global iterables
        self.r = r
        self.i = 0
        iterables.append(self)

    def iter(self):
        """
        travers all the values sequentielly,
        :return: True if wrapped over
        """
        self.i += 1
        if self.i == len(self.r):
            self.reset()
            return True
        return False

    def get_val(self):
        """
        :return: The value
        """
        return self.r[self.i]

    def reset(self):
        """
        reset the index to 0
        :return:
        """
        self.i = 0

class IterEncoder(json.JSONEncoder):
    """
    Json encoder that manage iterable
    """
    def default(self, o):
        if isinstance(o, Iter):
            return o.get_val()
        else:
            super().encode(o)


from kolla_cli.tests.functional.common import KollaCliTest

import logging
import os
import shutil
import unittest

from kolla_cli.api.client import ClientApi
from kolla_cli.common.ansible_inventory import AnsibleInventory
from kolla_cli.common.utils import get_kolla_cli_etc

INV_NAME = 'inventory.json'

CLIENT = ClientApi()
LOG = logging.getLogger(__name__)

class TestFunctional(KollaCliTest):
    """Test description

    This test will look for old version inventory files in the local current
    working directory. If none are found, it will look in the user's home
    directory. If none are found there too, it will print a warning and skip
    the test.

    Old version inventory files must be named inventory.json.v1,
    inventory.json.v2, etc.

    An upgrade test will be run on each old version inventory file that is
    found.
    """
    def test_upgrade(self):
        inv_fpaths = self._find_inv_fpaths()
        if not inv_fpaths:
            LOG.warning('No old version inventory files were found. '
                        'Skipping test.')
        for inv_fpath in inv_fpaths:
            version = self._get_version(inv_fpath)
            self._replace_inventory(inv_fpath)
            self._test_upgrade(version)

    def _get_version(self, inv_fpath):
        try:
            version = int(inv_fpath.split('.v')[1])
        except Exception:
            raise Exception('Invalid version number on old inventory file: %s'
                            % inv_fpath)
        return version

    def _find_inv_fpaths(self):
        """find old version inventories

        Look in order at these locations:
        - current working directory
        - home directory
        """
        fpaths = []
        search_dirs = [os.getcwd(), os.path.expanduser('~')]
        for search_dir in search_dirs:
            fpaths = self._get_inv_fpaths(search_dir)
            if fpaths:
                break
        return fpaths

    def _get_inv_fpaths(self, inv_dir):
        upg_inventory_paths = []
        fnames = os.listdir(inv_dir)
        for fname in fnames:
            if fname.startswith(INV_NAME + '.v'):
                path = os.path.join(inv_dir, fname)
                upg_inventory_paths.append(path)
        return upg_inventory_paths

    def _replace_inventory(self, old_version_inv_path):
        inv_path = os.path.join(get_kolla_cli_etc(),
                                'ansible', 'inventory.json')
        shutil.copyfile(old_version_inv_path, inv_path)

    def _test_upgrade(self, version):
        hostname = 'test_host_upg'

        # This host add will cause the inventory to be upgraded
        CLIENT.host_add([hostname])
        CLIENT.host_remove([hostname])

        # run tests for each version:
        if version <= 1:
            self._test_v1_upgrade()

        if version <= 2:
            self._test_v2_upgrade()

    def _test_v1_upgrade(self):
            # this is a v1 inventory
            # in v1 > v2, ceilometer was added, check that it's there
            # and verify that all ceilometer groups are in the same groups
            # as heat.
            ansible_inventory = AnsibleInventory()
            heat = CLIENT.service_get(['heat'])[0]
            expected_groups = sorted(heat.get_groups())
            ceilometer = ansible_inventory.services['ceilometer']
            expected_services = ceilometer.get_sub_servicenames()
            expected_services.append('ceilometer')
            expected_services = sorted(expected_services)
            services = CLIENT.service_get_all()
            services_found = []

            for service in services:
                servicename = service.get_name()
                if servicename.startswith('ceilometer'):
                    groups = sorted(service.get_groups())
                    if servicename == 'ceilometer':
                        self.assertEqual(expected_groups, groups,
                                         'groups mismatch between '
                                         'ceilometer '
                                         'and %s' % servicename)
                    elif servicename == 'ceilometer-compute':
                        self.assertEqual(['compute'], groups,
                                         'groups mismatch between '
                                         'ceilometer-compute '
                                         'and %s' % servicename)
                    else:
                        # sub-services should have no groups (they inherit)
                        self.assertEqual([], groups,
                                         '%s has unexpected groups'
                                         % servicename)
                    services_found.append(servicename)

            services_found = sorted(services_found)
            self.assertEqual(expected_services, services_found,
                             'ceilometer subservices mismatch')

    def _test_v2_upgrade(self):
        # this is a v2 inventory. In the v2 to v3 upgrade, all subservices were
        # fixed up to have a parent service
        services = CLIENT.service_get_all()
        servicenames = []
        for service in services:
            servicenames.append(service.name)
            if '-' in service.name:
                # this is a subservice
                parent = service.get_parent()
                self.assertIsNotNone(parent,
                                     'subservice: %s, is missing its parent'
                                     % service.name)

        # ceilometer-alarms were removed in kolla v3.0.1,
        # check that they're gone
        self.assertNotIn('ceilometer-alarm-evaluator', servicenames,
                         'ceilometer-alarm-evaluator still exists.')
        self.assertNotIn('ceilometer-alarm-notifier', servicenames,
                         'ceilometer-alarm-notifier still exists.')

        # aodh and ceph were added in 3.0.1
        self.assertIn('aodh', servicenames, 'aodh not in inventory')
        self.assertIn('ceph', servicenames, 'ceph not in inventory')

if __name__ == '__main__':
    unittest.main()


#Use the 'a' key to rotate left, 's' to rotate right, 'q' to exit program
#adjust speed variable to go faster or slower

from pyfirmata import Arduino, util, SERVO
import time
import keyboard

board = Arduino('COM4')
time.sleep(1)
print("Board On")
pin = 3

speed = .015 # increase to go slower, decrease to go faster
start_angle = 90

board.digital[pin].mode = SERVO
board.digital[pin].write(start_angle)

print("Servo home")
time.sleep(1)

def rotate(angle):
	print("Move servo to angle: ",angle)
	board.digital[pin].write(angle)
	time.sleep(speed)

while True:
	if keyboard.is_pressed("q"):
		board.exit()
		break
	if keyboard.is_pressed("l"):
		start_angle+=1
		rotate(start_angle)
		if start_angle > 180:
			start_angle = 180
	if keyboard.is_pressed("r"):
		start_angle-=1
		rotate(start_angle)
		if start_angle <= 1:
			start_angle = 1
	if keyboard.is_pressed("h"):
		start_angle = 90
		rotate(start_angle)
		time.sleep(1)


import torch
import numpy as np
import sys
import gym

sys.path.append("./")
from base_net.model import *
from torch import nn, optim
import torch.nn.functional as F
from torch.distributions import Categorical, Normal

class SAC(nn.Module):
    def __init__(self, args):
        super(SAC, self).__init__()
        self.input_size, self.output_size, self.toi, self.device, self.actor_lr, self.critic_lr = args
        self.min_log_std, self.max_log_std = -20, 2
        # policy
        self.actor = Policy_net(args = (self.input_size, 64))
        self.mu_head = nn.Linear(64, self.output_size)
        self.log_std_head = nn.Linear(64, self.output_size)

        self.q_net1 = Q_net(args = (self.input_size + self.output_size, 1))
        self.q_net2 = Q_net(args = (self.input_size + self.output_size, 1))

        self.v_net = Q_net(args = (self.input_size, 1))
        self.v_net_target = Q_net(args = (self.input_size, 1))

        self.replay_buffer = ReplayBuffer(args = (30000))
        self.optimizer_actor = optim.Adam(self.actor.parameters(), lr = self.actor_lr)
        self.optimizer_critic = optim.Adam(self.parameters(), lr = self.critic_lr)
        self.update_target_net(initialize = True)

    def update_target_net(self, initialize = False):
        if initialize:
            self.v_net_target.load_state_dict(self.v_net.state_dict())
        elif not initialize:
            for raw, target in zip(self.v_net.parameters(), self.v_net_target.parameters()):
                target.data.copy_(self.toi * raw.data + (1 - self.toi) * target.data)

    def get_policy(self, inputs):
        return self.actor(inputs)

    def save_trans(self, transition):
        self.replay_buffer.save_trans(transition)

    def to_tensor(self, items):
        s, a, r, s_next, done = items
        s = torch.FloatTensor(s).to(self.device)
        a = torch.FloatTensor(a).to(self.device)
        r = torch.FloatTensor(r).to(self.device)
        s_next = torch.FloatTensor(s_next).to(self.device)
        done = torch.FloatTensor(done).to(self.device)

        return s, a, r.unsqueeze(-1), s_next, done.unsqueeze(-1)

    def select_action(self, inputs):
        dist_param_op = self.get_policy(inputs)
        mu = self.mu_head(dist_param_op)
        log_sigma = torch.clamp(self.log_std_head(dist_param_op), self.min_log_std, self.max_log_std)
        sigma = torch.exp(log_sigma)
        dist = Normal(mu, sigma)
        z = dist.rsample()
        action = torch.tanh(z).detach().cpu().numpy()
        return action

    def get_action_vec(self, inputs):
        dist_param_op = self.get_policy(inputs)
        mu = self.mu_head(dist_param_op)
        log_sigma = torch.clamp(self.log_std_head(dist_param_op), self.min_log_std, self.max_log_std)
        sigma = torch.exp(log_sigma)
        dist = Normal(mu, sigma)
        z = dist.rsample()
        action_vec = torch.tanh(z)
        log_prob = dist.log_prob(z) - torch.log(1 - action_vec.pow(2) + torch.FloatTensor([1e-7]).to(self.device))
        return action_vec, log_prob

    def train(self, gamma = 0.98, batch_size = 32, alpha = 0.6):
        s, a, r, s_next, done = self.to_tensor(self.replay_buffer.sample_batch(batch_size = batch_size))

        # loss v_net
        rsample_action, log_action_prob = self.get_action_vec(s)
        v_target = torch.min(self.q_net1(torch.cat([s, rsample_action], -1)), self.q_net2(torch.cat([s, rsample_action], -1))) - alpha * log_action_prob
        loss_v_net = (self.v_net(s) - v_target.detach()) ** 2
        # loss actor  gradient ascent
        loss_actor = (-(self.q_net1(torch.cat([s, rsample_action], -1)) - alpha * log_action_prob)).mean()
        self.optimizer_actor.zero_grad()
        loss_actor.backward()
        self.optimizer_actor.step()

        # loss q_net
        q_target = r + gamma * self.v_net_target(s_next) * (1 - done)                     # have problem
        loss_q_net1 = (self.q_net1(torch.cat([s, a], -1)) - q_target.detach()) ** 2
        loss_q_net2 = (self.q_net2(torch.cat([s, a], -1)) - q_target.detach()) ** 2

        loss_critic = loss_q_net1.mean() + loss_q_net2.mean() + loss_v_net.mean()
        self.optimizer_critic.zero_grad()
        loss_critic.backward()
        self.optimizer_critic.step()

        self.update_target_net()

class NormalizedActions(gym.ActionWrapper):
    def action(self, action):
        low = self.action_space.low[0]
        high = self.action_space.high[0]

        action = low + (action + 1.0) * 0.5 * (high - low)
        action = np.clip(action, low, high)

        return [action]

    def reverse_action(self, action):
        low = self.action_space.low[0]
        high = self.action_space.high[0]

        action = 2 * (action - low) / (high - low) - 1
        action = np.clip(action, low, high)

        return [action]

'''
SAC test
'''
if __name__ == "__main__":
    # hyper param
    batch_size = 32
    render = False
    lr = 5e-4
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    train_flag = False

    total_step = 0
    env = NormalizedActions(gym.make("Pendulum-v0"))
    model = SAC(args = (3, 1, 0.01, device, lr, lr)).to(device)

    for i in range(10000):
        s = env.reset()
        score = 0.

        for t in range(200):
            if render:
                env.render()

            total_step += 1
            action = model.select_action(torch.FloatTensor(s).to(device))

            s_next, reward, done, info = env.step(action[0])
            model.save_trans((s, action, reward, s_next, done))
            score += reward
            s = s_next

            if len(model.replay_buffer.buffer) > 60:
                train_flag = True
                model.train(batch_size = batch_size)
            if done:
                break
        print("Epoch:{}    Score:{}    training:{}    total_step:{}".format(i+1, score, train_flag, total_step))


#!/usr/bin/python

import cgi
import cgitb
import sqlite3
cgitb.enable()
import sessions

def main():
    conn = sqlite3.connect("../www/forum.db")
    cursor = conn.cursor()
    sessions.deleteSession(conn, cursor)
    # turns out the spec-compliant way of deleting a cookie is setting it to expire in the past
    print("Set-Cookie: sid=farts; expires=Thu, 01 Jan 1970 00:00:00 GMT")
    print("Location: index.py\n")
try:
    main()
except Exception as ex:
    print("Content-type: text/html\n")
    raise


from unittest.mock import Mock

import numpy as np
import pytest

from tests.test_pipelines.conftest import DummyDataset, DummyOptimizablePipeline
from tpcp._utils._score import _score

class TestScoreMock:
    @pytest.fixture(autouse=True)
    def create_paras(self):
        dataset = DummyDataset()
        # We mock the scorer and just return the dataset itself and 1 as agg score
        scorer = Mock(return_value=(1, np.asarray(dataset.group_labels)))
        pipe = DummyOptimizablePipeline()

        self.dummy_paras = (pipe, dataset, scorer)

    @pytest.mark.parametrize(
        ("enable_output", "out_para"),
        (("return_parameters", "parameters"), ("return_data_labels", "data_labels"), ("return_times", "score_time")),
    )
    def test_result_params(self, enable_output, out_para):
        result = _score(*self.dummy_paras, parameters=None, **{enable_output: True})
        assert out_para in result

    def test_parameter_set(self):
        """Test that the parameters are set before score is called."""
        paras = {"para_1": "para_1_val", "para_2": "para_2_val"}
        _score(*self.dummy_paras, parameters=paras)
        scorer = self.dummy_paras[2]

        out_paras = scorer.call_args[0][0].get_params()
        assert {k: out_paras[k] for k in paras} == paras
        assert id(scorer.call_args[0][0]) == id(self.dummy_paras[0])

    def test_parameter_clone(self):
        nested_obj = DummyOptimizablePipeline()
        paras = {"para_1": "para_1_val", "para_2": nested_obj}
        _score(*self.dummy_paras, parameters=paras)
        scorer = self.dummy_paras[2]

        nested_obj_after_set = scorer.call_args[0][0].get_params()["para_2"]
        assert nested_obj_after_set.get_params() == nested_obj.get_params()
        assert id(nested_obj_after_set) != id(nested_obj)