#library
import os
import pathlib
from dash_bootstrap_components._components.Card import Card
import numpy as np
from math import pow, sqrt
from scipy.sparse import csr_matrix
from sklearn.neighbors import NearestNeighbors
from dash.dependencies import Input, Output, State
from sklearn.decomposition import PCA
import plotly.graph_objs as go
import dash_daq as daq
import plotly.graph_objects as go
from dash_bootstrap_components._components.Col import Col
from dash_bootstrap_components._components.Row import Row
import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash_extensions import Lottie
import plotly.express as px
import plotly.figure_factory as ff
from wordcloud import WordCloud
import dash_bootstrap_components as dbc
import dash_table

ratingss=pd.read_csv('D:/retour/recommendation/ratingg.csv',index_col=0)
products=pd.read_csv('D:/retour/recommendation/products1.csv')
user=pd.read_csv('D:/retour/recommendation/user1.csv')
time=pd.read_csv('D:/retour/recommendation/time_serie.csv')

options = dict(loop=True, autoplay=True, rendererSettings=dict(preserveAspectRatio='xMidYMid slice'))
#lutties
url_1='https://assets1.lottiefiles.com/packages/lf20_xtzoykx4.json'
url_2='https://assets1.lottiefiles.com/packages/lf20_udjnduhz.json'
url_3='https://assets8.lottiefiles.com/packages/lf20_rrw4rw07.json'

app = dash.Dash(
    __name__,
    external_stylesheets=[dbc.themes.SKETCHY],
)

app.layout = dbc.Container([

    dbc.Row([
        dbc.Col([

        ], width=1),
        dbc.Col([
            dbc.Card([
                dbc.CardHeader(Lottie(options=options, width="100%", height="100%", url=url_3)),
                dbc.CardBody([
                    html.H6('Brand'),
                    dcc.Dropdown(
                        id='brand_id',
                        options=[{'label': x, 'value': x}
                            for x in products['brand'].unique()],
                        value='Adidas',

                        style={'width' : '100%',
                            'text-align': 'center',
                            }

                    ),
                ], style={'textAlign':'center'})
            ]),
        ], width=2),

        dbc.Col([
            dbc.Card([
                dbc.CardHeader(Lottie(options=options, width="100%", height="100%", url=url_1)),
                dbc.CardBody([
                    html.H6('Products'),
                    html.H2(id='content-connections1')
                ], style={'textAlign': 'center'})
            ]),
        ], width=2),

        dbc.Col([
            dbc.Card([
                dbc.CardHeader(Lottie(options=options, width="100%", height="100%", url=url_2)),
                dbc.CardBody([
                    html.H6('Ratings'),
                    html.H2(id='content-connections2')
                ], style={'textAlign':'center'})
            ]),
        ], width=2),

        dbc.Card([
            html.H3('Top 5 pickers'),
                dcc.Dropdown(
                    id='user_id',
                    options=[{'label': x, 'value': x}
                        for x in user['user_id'].unique()],
                    value=5,

                    style={'width' : '100%',
                        'text-align': 'center',
                        }

                ),
            ]),

            dbc.Card([]),

            dbc.Card([
            html.H3('Select a product'),
                dcc.Dropdown(
                    id='name_id',
                    options=[{'label': x, 'value': x}
                        for x in products['name'].unique()],
                    value='Sport Inspired Duramo Lite 2.0 Shoes',

                    style={'width' : '100%',
                        'text-align': 'center',
                        }

                ),
            ]),

    ],className='mb-2'),
    dbc.Row([
        dbc.Col([

        ], width=1),

        dbc.Col([
            dbc.Card([
                    html.H3('Most popular products'),
                    dcc.Graph(id="wordcloud",figure={}),
                dbc.CardBody([

                ])
            ]),
        ], width=3),
        dbc.Col([
            dbc.Card([
                    html.H3('Competitors performance'),
                    dcc.Graph(id="Scatter plot",figure={}),
                dbc.CardBody([

                ])
            ]),
        ], width=7),

    ],className='mb-2'),

    dbc.Row([
        dbc.Col([

        ], width=1),
        dbc.Col([
            dbc.Card([

                dbc.CardBody([
                    html.H3('Age distribution'),
                    dcc.Graph(id="bar_knn",figure={})
                ])
            ]),
        ], width=3),
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    html.H3('Score distribution'),
                    dcc.Dropdown(
                        id='sex',
                        options=[{'label': x, 'value': x}
                            for x in user['sex'].unique()],
                        value='F',

                        style={'width' : '100%',
                            'text-align': 'center',
                            }

                    ),
                    dcc.Graph(id="scatte",figure={})

                ])
            ]),
        ], width=3),

        dbc.Col([
            dbc.Card([

                dbc.CardBody([
                    html.H3('Gender'),
                    dcc.Graph(id="sexpie",figure={})
                ])
            ]),
        ], width=5),

    ],className='mb-2'),

     dbc.Row([

        dbc.Col([
            dbc.Card([

                dbc.CardBody([
                    html.H3('Localisation'),
                    dcc.Graph(id="map",figure={})
                ])
            ]),
        ], width=6),
        dbc.Col([
            dbc.Card([

                dbc.CardBody([
                    html.H3('Rating trend'),
                    dcc.Graph(id="time_seri",figure={})
                ])
            ]),
        ], width=6),

    ],className='mb-2'),

], fluid=True)

#-------------------
@app.callback(

    Output('content-connections1','children'),
    [Input(component_id='brand_id', component_property='value')]
)

def leng(tweet):
    return(len(products.loc[products.brand==tweet]))

@app.callback(

    Output('content-connections2','children'),
    [Input(component_id='brand_id', component_property='value')]
)

def rat(tweet):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']=='Adidas']
    return(len(df1.rating))

#Worldcloud-----------------------------------------

@app.callback(

    Output('wordcloud','figure'),
    [Input(component_id='brand_id', component_property='value')]
)

def update_worldcloud( tweet):

    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']==tweet]
    df2=df1[['user_avg_rating','name']]
    df3=df2.drop_duplicates()
    df4=df3.sort_values(by=['user_avg_rating'],ascending=False)

    my_wordcloud = WordCloud(
        background_color='white',
        height=500
    ).generate(''.join( df4.name))

    fig_wordcloud = px.imshow(my_wordcloud, template='ggplot2')
    fig_wordcloud.update_layout(margin=dict(l=20, r=20, t=30, b=20))
    fig_wordcloud.update_xaxes(visible=False)
    fig_wordcloud.update_yaxes(visible=False)

    return fig_wordcloud

@app.callback(

    Output('Scatter plot','figure'),
    [Input(component_id='name_id', component_property='value')],
    [Input(component_id='brand_id', component_property='value')]

)

def branding(name,brand):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['name']==name]

    df2=df1[['user_avg_rating','brand']]
    df2['Score']=df2['user_avg_rating']*20
    df3=df2.drop_duplicates()
    df4=df3.sort_values(by=['Score'],ascending=False)
    df4['rank']=[1, 2, 3, 4,5,6,7,8]
    rank=df4[df4.brand == brand]['rank'].values
    df5=df4[df4.brand==brand]
    df4['Brand']=df4['brand']

    if brand in df4[:5].Brand.values:

        fig = px.bar(df4[:5],
                     x="Score",
                     y='Brand',
                     #range_x=[0,100],
                     range_x=[0,100],
                     color='Brand'
                     )
    else:
        fig = px.bar(df4[:5],
                     x="Score",
                     y='Brand',
                     #range_x=[0,100],
                     range_x=[0,100],
                     color='Brand'
                     )
        fig.update_layout(
            height=500,
            title_text='The brand is ranked '+str(rank)[1:2]+', with a average rating of '+ str(df5.Score.values)[1:3]+'%'
        )
    return(fig)

@app.callback(

    Output('bar_knn','figure'),
    [Input(component_id='brand_id', component_property='value')],
    [Input('sex','value')]
)

def update_pie(tweet1,tweet2):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']==tweet1]
    df2=pd.merge(df1,user,on='user_id')
    dff=df2.loc[df2.sex==tweet2]
    fig_pie =px.pie(
        dff,
        values='age',

        names=dff.age,
        hole=.5,
        color_discrete_sequence=['maroon','red','coral']
        )
    return(fig_pie)

@app.callback(

    Output('scatte','figure'),
    [Input(component_id='brand_id', component_property='value')],
    [Input('user_id','value')]
)

def update_pie(name,tweet):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']==name]
    df1['pourcen']=df1['rating']*20
    df2=pd.merge(df1,user,on='user_id')

    dff=df2.loc[df2['user_id']==tweet]
    fig_pie =px.pie(
            dff,
            values='pourcen',
            names=dff.pourcen,
            hole=.5,
            color_discrete_sequence=['deeppink','darkviolet']
            )
    return(fig_pie)

@app.callback(

    Output('map','figure'),
    [Input(component_id='brand_id', component_property='value')],
    [Input('user_id','value')]
)

def map(name, tweet):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']==name]
    df2=pd.merge(df1,user,on='user_id')
    dff=df2.loc[df2.user_id==tweet]
    dff['count']=dff.groupby('iso_id')['iso_id'].transform(len)

    fig = px.scatter_geo(dff, locations="iso_id",hover_name="Residence",size='count',
                     projection="natural earth")
    return(fig)

@app.callback(

    Output('sexpie','figure'),
    [Input(component_id='brand_id', component_property='value')]
)

def update_pie(tweet1):
    ratings=ratingss.copy()
    ratings['user_avg_rating'] = ratings.groupby('product_id')['rating'].transform('mean').round(2)
    df=pd.merge(ratings,products,left_on='product_id',right_on='ID_product')
    df1=df[df['brand']==tweet1]
    dff=pd.merge(df1,user,on='user_id')
    dfff=dff['sex'].value_counts()
    fig_pie =px.pie(
            dfff,
            values='sex',
            names=dfff.index,
            hole=.5,
            color_discrete_sequence=['gold','lemonchiffon']
            )
    return(fig_pie)

@app.callback(

    Output('time_seri','figure'),
    [Input(component_id='brand_id', component_property='value')]
)

def time_serie(brand):
    times=time.copy()
    times=times[times['brand']==brand]
    times['pourcen']=times['rating']*20
    fig = go.Figure([go.Scatter(x=times['day'], y=times['pourcen'])])
    return(fig)

# Running the server
if __name__ == "__main__":
    app.run_server(debug=True)


import os
import pickle

import numpy as np
import torch
from tqdm import tqdm
from torch.utils import data

from Models import CNNEncoder, RNNDecoder
from sklearn.preprocessing import LabelEncoder
import torchvision.transforms as transforms

from Models.DataSetLoader import DataSetLoader

class CRNN():

    def __init__(self):
        # use same encoder CNN saved!
        self.CNN_fc_hidden1, self.CNN_fc_hidden2 = 1024, 768
        self.CNN_embed_dim = 512  # latent dim extracted by 2D CNN
        self.res_size = 224  # ResNet image size
        self.dropout_p = 0.0  # dropout probability

        self.RNN_hidden_layers = 3
        self.RNN_hidden_nodes = 512
        self.RNN_FC_dim = 256

        self.k = 101  # number of target category
        self.batch_size = 40
        self.begin_frame, self.end_frame, self.skip_frame = 1, 29, 1

        self.label_encoder = LabelEncoder()
        self.action_category = []

        use_cuda = torch.cuda.is_available()  # check if GPU exists
        device = torch.device("cuda" if use_cuda else "cpu")

        self.encoder = CNNEncoder.CNNEncoder(self.CNN_fc_hidden1, self.CNN_fc_hidden2, self.dropout_p,
                                             self.CNN_embed_dim).to(device)

        self.decoder = RNNDecoder.RNNDecoder(self.CNN_embed_dim, self.RNN_hidden_layers, self.RNN_hidden_nodes,
                                             self.RNN_FC_dim, self.dropout_p, self.k).to(device)

    def load(self):
        project_path = os.getcwd()
        save_model_path = project_path + '/cached'
        self.encoder.load_state_dict(
            torch.load(os.path.join(save_model_path, 'cnn_encoder_epoch63_singleGPU.pth'), map_location='cpu'))
        self.decoder.load_state_dict(
            torch.load(os.path.join(save_model_path, 'rnn_decoder_epoch63_singleGPU.pth'), map_location='cpu'))

        with open(save_model_path + '/UCF101actions.pkl', 'rb') as f:
            action_names = pickle.load(f)  # load UCF101 actions names

        # convert labels -> category
        self.label_encoder.fit(action_names)
        self.action_category = self.label_encoder.transform(action_names).reshape(-1, 1)

    def run(self, path, x, y):
        # data loading parameters
        use_cuda = torch.cuda.is_available()  # check if GPU exists
        device = torch.device("cuda" if use_cuda else "cpu")  # use CPU or GPU
        params = {'batch_size': self.batch_size, 'shuffle': True, 'num_workers': 4,
                  'pin_memory': True} if use_cuda else {}

        transform = transforms.Compose([transforms.Resize([self.res_size, self.res_size]),
                                        transforms.ToTensor(),
                                        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])

        selected_frames = np.arange(self.begin_frame, self.end_frame, self.skip_frame).tolist()

        # reset data loader
        all_data_params = {'batch_size': self.batch_size, 'shuffle': False, 'num_workers': 4,
                           'pin_memory': True} if use_cuda else {}

        y = self.label_encoder.transform(y)

        data_loader = data.DataLoader(
            DataSetLoader(path, x, y, selected_frames, transform=transform), **all_data_params)

        self.encoder.eval()
        self.decoder.eval()

        all_y_pred = []
        with torch.no_grad():
            for batch_idx, (X, y) in enumerate(tqdm(data_loader)):
                # distribute data to device
                X = X.to(device)
                output = self.decoder(self.encoder(X))
                y_pred = output.max(1, keepdim=True)[1]  # location of max log-probability as prediction
                all_y_pred.append(y_pred.cpu().data.squeeze().numpy().tolist())

        return self.label_encoder.inverse_transform(all_y_pred)


import os
from telethon.sync import TelegramClient, events, types, functions
import logging
from datetime import date, datetime, timezone
import asyncio
from pathlib import Path

logging.basicConfig(filename="./logs.txt", filemode='a',
                    format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s',
                    level=logging.WARNING)

API_ID = os.environ["TG_API_ID"]
API_HASH = os.environ["TG_API_HASH"]
PARSE_CHAT_ID = int(os.environ["TG_PARSE_CHAT_ID"])
FORWARD_CHAT_ID = int(os.environ["TG_FORWARD_CHAT_ID"])
SESSION = "SOPHIEPALEOLOG"
INTERVAL_IN_SEC = 10
MESSAGE_MIN_LIVE_IN_SEC = 120
LAST_MESSAGE_ID = 0
GET_MESSAGE_CNT_LIMIT = 300

client = None
forward_chat = None
last_msg_file = Path("./lastmsg.txt")

# forward message if contains url
async def forward_message(message):
    for ent, _ in message.get_entities_text():
        if isinstance(ent, types.MessageEntityUrl) or isinstance(ent, types.MessageEntityTextUrl):
            try:
                await message.forward_to(forward_chat)
            except Exception as e:
                logging.error(e)
                logging.warning(message)
            finally:
                return

# gets now and date timedelta in seconds
def last_from_date_in_secs(date):
    return (datetime.now(timezone.utc) - date).seconds

def save_last_messsage_id():
    last_msg_file.write_text(str(LAST_MESSAGE_ID))

def get_last_message_id():
    global LAST_MESSAGE_ID
    if not last_msg_file.is_file():
        save_last_messsage_id()

    LAST_MESSAGE_ID = int(last_msg_file.read_text())

# check for new messages and if it lasts > MESSAGE_MIN_LIVE_IN_SEC and id > LAST_MESSAGE_ID
async def forward_new_messages():
    global LAST_MESSAGE_ID, client
    client = TelegramClient(SESSION, API_ID, API_HASH)
    await client.start()
    messages = [m async for m in client.iter_messages(PARSE_CHAT_ID, limit=GET_MESSAGE_CNT_LIMIT)
    if m.id > LAST_MESSAGE_ID and last_from_date_in_secs(m.date) > MESSAGE_MIN_LIVE_IN_SEC]
    for message in reversed(messages):
        await forward_message(message)

    if len(messages) > 0:
        LAST_MESSAGE_ID = messages[0].id
    save_last_messsage_id()

    await client.disconnect()

# # update client and start because it somehow stops working
# async def update_client():
#     global last_client_update_time
#     if last_from_date_in_secs(last_client_update_time) < CLIENT_UPDATE_INTERVAL_IN_SEC:
#         return
#     if client.is_connected():
#         await client.start()
#     last_client_update_time = datetime.now(timezone.utc)

async def main():
    global forward_chat, client, last_msg_file
    get_last_message_id()
    client = TelegramClient(SESSION, API_ID, API_HASH)
    await client.start()
    forward_chat = await client.get_entity(FORWARD_CHAT_ID)
    await client.disconnect()

    while True:
        await asyncio.gather(
            asyncio.sleep(INTERVAL_IN_SEC),
            forward_new_messages()
        )

if __name__ == '__main__':
    asyncio.run(main())


import cv2
import time
import os
import handDetector as hd
import facerecognition

class GestureDetector():
    def __init__(self):
        self.wCam, self.hCam = 640, 480
        self.cap = cv2.VideoCapture(0)
        self.pTime = 0
        self.detector = hd.handDetector(detectionCon=0.75)
        self.tipIds = [4, 8, 12, 16, 20]
        self.message = ''

    def gestureDetection(self):

        while True:
            self.facerecognition = facerecognition.FaceRecognition(self.cap)
            self.img = self.facerecognition
            #self.img = cv2.flip(self.img,1)
            self.img = self.detector.findHands(self.img)
            lmList = self.detector.findPosition(self.img, draw=False)
            # print(lmList)

            if len(lmList) != 0:
                self.fingers = []

                # Thumb
                if lmList[self.tipIds[0]][1] > lmList[self.tipIds[0] - 1][1]:
                    self.fingers.append(1)
                else:
                    self.fingers.append(0)

                # 4 Fingers
                for id in range(1, 5):
                    if lmList[self.tipIds[id]][2] < lmList[self.tipIds[id] - 2][2]:
                        self.fingers.append(1)
                    else:
                        self.fingers.append(0)

                totalFingers = self.fingers.count(1)
                #print(totalFingers)

                if self.fingers == [0,1,0,0,1] or self.fingers == [1,1,0,0,0] or self.fingers == [0,1,1,0,0] or self.fingers == [1,1,0,0,1] or self.fingers == [0,0,0,0,1]:
                    self.message = 'HELP!!!'
                else:
                    self.message == "IT'S OK!!"

                #h, w, c = overlayList[totalFingers - 1].shape
                #img[0:h, 0:w] = overlayList[totalFingers - 1]

                #cv2.rectangle(self.img, (20, 225), (170, 425), (0, 255, 0), cv2.FILLED)
                #cv2.putText(self.img, str(totalFingers), (45, 375), cv2.FONT_HERSHEY_PLAIN,
                #            10, (255, 0, 0), 25)

            cTime = time.time()
            fps = 1 / (cTime - self.pTime)
            pTime = cTime

            #cv2.imshow('Image', self.img)
            cv2.waitKey(1)
            return self.message, self.img

    def gestureMessage(self):
        pass


import uuid
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.validators import ArrayMinLengthValidator

# Create your models here.
class Contact(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.TextField()
    numbers = ArrayField(
        models.CharField(
            max_length=11
        ),
        blank=False,
        null=False,
        validators=[
            ArrayMinLengthValidator(1)
        ]
    )


'''
#1: Verify the Continuity of a Function at a Point
Your challenge here is to write a program that will (1) accept a single variable function and a value of that variable as inputs and (2) check
whether the input function is continuous at the point where the variable
assumes the value input.
'''

from sympy import Derivative, Limit, Symbol, S, sympify, solve

def check_continuity(f, var, point):
	f = sympify(f)
	lp = Limit(f, var, point, dir='+').doit()
	ln = Limit(f, var, point, dir='-').doit()
	if lp == ln:
		print("{0} is continuous at {1}".format(f, point))
	else:
		print("{0} is discontinuous at {1}".format(f, point))

f = input('Enter a function in one variable: ')
var = input('Enter the variable to differentiate with respect to: ')
point = float(input('Enter the point to check continuity at: '))

check_continuity(f, var, point)

07. Solving Calculus Problems/verify_continuity.py


'''
Function:
    setup
Author:
    Charles
微信公众号:
    Charles的皮卡丘
GitHub:
    https://github.com/CharlesPikachu/codefree
'''
import codefree
from setuptools import setup, find_packages

'''readme'''
with open('README.md', 'r', encoding='utf-8') as f:
    long_description = f.read()

'''setup'''
setup(
    name=codefree.__title__,
    version=codefree.__version__,
    description=codefree.__description__,
    long_description=long_description,
    long_description_content_type='text/markdown',
    classifiers=[
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python :: 3',
        'Intended Audience :: Developers',
        'Operating System :: OS Independent'
    ],
    author=codefree.__author__,
    url=codefree.__url__,
    author_email=codefree.__email__,
    license=codefree.__license__,
    include_package_data=True,
    install_requires=[lab.strip('\n') for lab in list(open('requirements.txt', 'r').readlines())],
    zip_safe=True,
    packages=find_packages()
)


import torch
import torch.nn as nn
import torchvision
import numpy as np
from torch.autograd import Variable
import torch.autograd as autograd
import torch.nn.functional as F

class ConvBlock(nn.Module):
    """
    Helper module that consists of a Conv -> BN -> ReLU
    """

    def __init__(self, in_channels, out_channels, padding=1, kernel_size=3, stride=1, with_nonlinearity=True):
        super(ConvBlock,self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, padding=padding, kernel_size=kernel_size, stride=stride)
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU()
        self.with_nonlinearity = with_nonlinearity

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        if self.with_nonlinearity:
            x = self.relu(x)
        return x

def compute_gradient_penalty(D, real_samples, fake_samples, cond=None, mode="wgan"):

    """Calculates the gradient penalty loss for WGAN GP"""
    # Random weight term for interpolation between real and fake samples
    Tensor = torch.cuda.FloatTensor
    if mode == "wgan":
        alpha = Tensor(np.random.random((real_samples.size(0), 1, 1, 1)))
    else:
        alpha = Tensor(np.random.random((real_samples.size(0), 1)))

    # Get random interpolation between real and fake samples
    interpolates = alpha * real_samples + ((1 - alpha) * fake_samples)
    interpolates = Variable(interpolates, requires_grad=True)

    d_interpolates = D(interpolates)
    fake = Variable(Tensor(real_samples.shape[0], 1).fill_(1.0), requires_grad=False)
    # Get gradient w.r.t. interpolates
    gradients = autograd.grad(
        outputs=d_interpolates,
        inputs=interpolates,
        grad_outputs=fake,
        create_graph=True,
        retain_graph=True,
        only_inputs=True,
    )[0]
    gradients = gradients.view(gradients.size(0), -1)
    gradient_penalty = ((gradients.norm(2, dim=1) - 1) ** 2).mean()
    return gradient_penalty

def run_wgan(G, D, optimizer_D, penality, critic, h, v):

    Tensor = torch.cuda.FloatTensor
    bs = h.size(0)

    #confidional is last hidden state
    cond = h

    #tiling h to match v dimension
    cond_tiled = cond.view(bs, cond.size(1), 1, 1)
    tiled_dims = [-1, -1, 6, 6]
    cond_tiled = cond_tiled.expand(*tiled_dims)
    #reshaping v
    v = v.permute(0,2,1).view(bs, -1, 6, 6).contiguous().detach()

    z = Variable(Tensor(np.random.normal(0, 1, (bs, 512))))
    G.zero_grad()
    ret_fake_imgs = G(h)
    g_loss = -torch.mean(D(ret_fake_imgs))

    d_loss = torch.zeros(1)
    for _ in range(critic):

        if(g_loss<1.0):

            optimizer_D.zero_grad()
            D.zero_grad()
            # Generate a batch of images
            z = Variable(Tensor(np.random.normal(0, 1, (bs, 512))))
            # g_input = torch.cat((cond.detach(), z), dim=-1)
            fake_imgs = G(cond.detach())

            # Real images
            d_input1 = v
            d_input2 = fake_imgs
            real_validity = D(d_input1)
            fake_validity = D(d_input2)

            # Gradient penalty
            gradient_penalty = compute_gradient_penalty(D, v.data, fake_imgs.data, None, mode="wgan")
            # Adversarial loss
            d_loss = -torch.mean(real_validity) + torch.mean(fake_validity) + penality * gradient_penalty
            d_loss.backward()
            optimizer_D.step()

    # print(g_loss, d_loss)
    return g_loss, d_loss, ret_fake_imgs, v
#
# def run_waae(G, D, optimizer_D, penality, critic, h, v):
#     import math
#     def log_density_igaussian(z, z_var):
#         """Calculate log density of zero-mean isotropic gaussian distribution given z and z_var."""
#         assert z.ndimension() == 2
#         assert z_var > 0
#
#         z_dim = z.size(1)
#
#         return -(z_dim / 2) * math.log(2 * math.pi * z_var) + z.pow(2).sum(1).div(-2 * z_var)
#
#     Tensor = torch.cuda.FloatTensor
#     z_sample = h
#     bs = h.size(0)
#
#     ones = Variable(torch.ones(z_sample.shape[0], 1)).cuda()
#     zeros = Variable(torch.zeros(z_sample.shape[0], 1)).cuda()
#
#     # z = Variable(Tensor(np.random.normal(0, 1, (z_sample.shape[0], self.num_hid))))
#     z = Variable(math.sqrt(2) * torch.randn(z_sample.shape[0], 1024)).cuda()
#     log_p_z = log_density_igaussian(z, 2).view(-1, 1)
#
#     D_fake = D(z)
#     D_real = D(z_sample.detach())
#     if critic == 5:
#         loss_d = F.binary_cross_entropy_with_logits(D_fake + log_p_z, ones) + \
#                  F.binary_cross_entropy_with_logits(D_real + log_p_z, zeros)
#     else:
#         loss_d = F.binary_cross_entropy_with_logits(D_fake, ones) + \
#                  F.binary_cross_entropy_with_logits(D_real, zeros)
#
#     gradient_penalty = compute_gradient_penalty(D, z_sample.data, z.data, mode="waae")
#
#     D_loss = loss_d + penality * gradient_penalty
#
#     optimizer_D.zero_grad()
#     loss_d.backward()
#     optimizer_D.step()
#
#     # enc-dec part
#     fake_imgs = G(z_sample)
#     if critic == 5:
#         G_loss = F.binary_cross_entropy_with_logits(D_real.detach() + log_p_z, ones)
#     else:
#         G_loss = F.binary_cross_entropy_with_logits(D_real.detach(), ones)
#     v = v.permute(0,2,1).view(bs,-1, 6, 6)
#     return G_loss, D_loss, fake_imgs, v

def run_waae(G, D, optimizer_D, penality, critic, h, v):
    Tensor = torch.cuda.FloatTensor
    bs = h.size(0)
    z_sample = h.detach()

    ones = Variable(torch.ones(z_sample.shape[0], 1)).cuda()
    zeros = Variable(torch.zeros(z_sample.shape[0], 1)).cuda()

    # enc-dec part
    fake_imgs = G(h)
    D_fake = D(h)
    # print(D[0].weight)
    G_loss = F.binary_cross_entropy_with_logits(D_fake, ones)
    v = v.permute(0,2,1).view(bs,-1, 6, 6)

    D_loss = torch.zeros(1)
    for _ in range(critic):

        if(G_loss<1.0):

            optimizer_D.zero_grad()
            D.zero_grad()

            z = Variable(Tensor(np.random.normal(0, 1, (z_sample.shape[0], 1024))), requires_grad=False)

            D_real = D(z)
            D_fake = D(z_sample)

            gradient_penalty = compute_gradient_penalty(D, z_sample.data, z.data, mode="waae")

            D_loss = F.binary_cross_entropy_with_logits(D_fake, zeros) + \
                                 F.binary_cross_entropy_with_logits(D_real, ones)  + penality * gradient_penalty

            D_loss.backward()
            optimizer_D.step()

    # print(G_loss, D_loss)
    return G_loss, D_loss, fake_imgs, v

class Generator(nn.Module):
    def __init__(self, noise_dim):
        super(Generator, self).__init__()
        self.noise_dim = noise_dim
        # self.up_block = nn.Sequential(
        #         ConvBlock(1024+self.noise_dim, 512, kernel_size=2),
        #         nn.ConvTranspose2d(512, 512, kernel_size=3, stride=2),
        #         ConvBlock(512, 256, kernel_size=2),
        #         nn.ConvTranspose2d(256, 256, kernel_size=3, stride=2),
        #         ConvBlock(256, 256, kernel_size=2),
        #     )

        # self.up_block = nn.Sequential(
        #         nn.ConvTranspose2d(1024+self.noise_dim, 512, kernel_size=3),
        #     nn.ConvTranspose2d(512, 512, kernel_size=2, stride=2),
            # ConvBlock(512, 256, kernel_size=2),
            # nn.ConvTranspose2d(256, 256, kernel_size=2, stride=2),
            # ConvBlock(256, 512, kernel_size=2),
            # nn.ConvTranspose2d(512, 512, kernel_size=2, stride=2),
            # ConvBlock(512, 1024, kernel_size=3),
        #     )

        #feat36
        self.up_block = nn.Sequential(
        ConvBlock(1024+self.noise_dim, 512, kernel_size=2),
        nn.ConvTranspose2d(512, 512, kernel_size=3, stride=2),
        ConvBlock(512, 2048, kernel_size=2),

        )

    def forward(self, x):
        bs = x.size(0)
        x = x.view(bs, -1, 1, 1)
        x = self.up_block(x)
        return x

class Discriminator(nn.Module):
    def __init__(self, num_hid=1024):

        super(Discriminator, self).__init__()
        self.num_hid = num_hid

        # basic_block = torchvision.models.resnet.BasicBlock
        # self.layer4 = _make_layer(1024+256, basic_block, 512, 2, stride=2)
        # self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        # self.fc = nn.Linear(512, 1)
        #

        # self.layer4 = _make_layer(1024, basic_block, 512, 6, stride=2)
        # self.avgpool = nn.AdaptiveAvgPool2d((1, 1))

        # self.down_blocks = nn.Sequential(
        #     ConvBlock(256, 256, kernel_size=3),
        #     nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        #     ConvBlock(256, 128, kernel_size=3),
        #     nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        #     ConvBlock(128, 128, kernel_size=3)
        # )
        # self.fc = nn.Linear(2048, 1)

        #36 feat
        # self.down_blocks = nn.Sequential(
        #
        #     ConvBlock(2048+self.num_hid, 512, kernel_size=3),
        #     nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        #     ConvBlock(512, 256, kernel_size=3),
        #     nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        #     ConvBlock(256, 128, kernel_size=3),
        #
        # )
        # self.fc = nn.Linear(512, 1)

        self.input = nn.Sequential(
            nn.Linear(2048 + self.num_hid, 512),
            nn.ReLU(),
        )

        self.down_blocks = nn.Sequential(
            ConvBlock(512, 256, kernel_size=3),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
            ConvBlock(256, 128, kernel_size=3),

        )

        self.fc = nn.Linear(128*3*3, 1)

    def forward(self, x):
        x = x.view(x.size(0), -1, x.size(1))
        x = self.input(x)
        x = x.view(x.size(0), x.size(2), 6, 6)
        x = self.down_blocks(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x


from torch.utils import data
import os
import torchvision.transforms as transforms
import numpy as np
import cv2

class Dataset(data.Dataset):

    def __init__(self, path,folder_list):
        self.path = path
        self.images_folder = folder_list   #图片文件夹，每个小文件夹是一个样本（包含五张）
        self.size = 320

    def __len__(self):
        return len(self.images_folder)

    def load_image(self,path):
        # image = cv2.cvtColor(cv2.imread(path))
        image=cv2.imread(path)
        image = cv2.resize(image, (self.size, self.size))
        # 图像归一化
        transform_GY = transforms.ToTensor()#将PIL.Image转化为tensor，即归一化。
        # 图像标准化
        transform_BZ= transforms.Normalize(
        mean=[0.5, 0.5, 0.5],# 取决于数据集
        std=[0.5, 0.5, 0.5]
        )
        # transform_compose
        transform_compose= transforms.Compose([
        # 先归一化再标准化
            transform_GY,
            transform_BZ
        ])
        # (H, W, C)变为(C, H, W)
        img_normalize = transform_compose(image)
        img_normalize=img_normalize.numpy()
        return img_normalize

    def __getitem__(self, index):
        images_path=os.path.join(self.path,self.images_folder[index])
        images=os.listdir(images_path)
        #找出target
        target=None   #此时的target是路径
        images_without_target=[]
        for image in images:
            if image.endswith('F.png'):
                target=image
            else:
                images_without_target.append(image)
        images=images_without_target

        #加载图片为numpy数组
        if target is not None:
            target=self.load_image(os.path.join(images_path,target))
        tmp=[]

        for i in range(len(images)):
            burst_i=self.load_image(os.path.join(images_path,images[i]))
            tmp.append(burst_i)

        burst=np.array(tmp) #转换成numpy格式

        if target is None:
            return burst, self.images_folder[index]
        else:
            #return两个，一个是x，另一个是label标签
            return burst, target, self.images_folder[index]


from importlib_metadata import requires
import numpy as np
import torch
import pytest
import json

from torch import nn
from .literal import Literal
from .constraint import Constraint
from .constraints_group import ConstraintsGroup
from .profiler import Profiler

class ConstraintsModule(nn.Module):
    profiler = Profiler.shared().branch('cm')

    @profiler.wrap
    def __init__(self, constraints_group, num_classes):
        super(ConstraintsModule, self).__init__()
        head, body = constraints_group.encoded(num_classes)
        pos_head, neg_head = head
        pos_body, neg_body = body

        # Compute necessary atoms
        self.atoms = nn.Parameter(torch.tensor(list(constraints_group.atoms())), requires_grad=False)
        reindexed = { float(atom): i for i, atom in enumerate(self.atoms) }
        if len(self.atoms) == 0: return

        # Reduce tensors to minimal size and reindex heads
        pos_head, neg_head = self.to_minimal(pos_head), self.to_minimal(neg_head)
        pos_body, neg_body = self.to_minimal(pos_body), self.to_minimal(neg_body)

        heads = [constraint.head for constraint in constraints_group]
        self.heads = [Literal(reindexed[head.atom], head.positive) for head in heads]

        # Module parameters
        self.pos_head = nn.Parameter(torch.from_numpy(pos_head).float(), requires_grad=False)
        self.neg_head = nn.Parameter(torch.from_numpy(neg_head).float(), requires_grad=False)
        self.pos_body = nn.Parameter(torch.from_numpy(pos_body).float(), requires_grad=False)
        self.neg_body = nn.Parameter(torch.from_numpy(neg_body).float(), requires_grad=False)

        # Precomputed parameters
        self.symm_body = nn.Parameter((self.pos_body - self.neg_body).t(), requires_grad=False)
        self.symm_head = nn.Parameter((self.pos_head - self.neg_head).t(), requires_grad=False)
        self.literals_count = nn.Parameter(self.pos_body.sum(dim=1) + self.neg_body.sum(dim=1), requires_grad=False)

    def dimensions(self, pred):
        batch, num = pred.shape[0], pred.shape[1]
        cons = self.pos_head.shape[0]
        return batch, num, cons

    @staticmethod
    @profiler.wrap
    def from_symmetric(preds):
        return (preds + 1) / 2

    @staticmethod
    @profiler.wrap
    def to_symmetric(preds):
        return 2 * preds - 1

    @profiler.wrap
    def to_minimal(self, tensor, atoms = None):
        if atoms is None: atoms = self.atoms
        return tensor[:, atoms].reshape(tensor.shape[0], len(atoms))

    @profiler.wrap
    def from_minimal(self, tensor, init, atoms = None):
        if atoms is None: atoms = self.atoms
        return init.index_copy(1, atoms, tensor)

    # Get constraints with full sat body and those with unsat head
    @profiler.wrap
    def active_constraints(self, goal):
        symm_goal = ConstraintsModule.to_symmetric(goal)
        full_body = torch.matmul(symm_goal, self.symm_body) == self.literals_count
        unsat_head = torch.matmul(symm_goal, self.symm_head) == -1
        return full_body, unsat_head

    # Apply constraints together with 3D tensors
    @profiler.wrap
    def apply_tensor(self, preds, active_constraints=None, body_mask=None):
        batch, num, cons = self.dimensions(preds)

        # batch x cons x num: prepare (preds x body)
        exp_preds = preds.unsqueeze(1).expand(batch, cons, num)
        pos_body = self.pos_body.unsqueeze(0).expand(batch, cons, num)
        neg_body = self.neg_body.unsqueeze(0).expand(batch, cons, num)

        # batch x cons x num: ignore literals from constraints
        if body_mask != None:
            body_mask = body_mask.unsqueeze(1).expand(batch, cons, num)
            pos_body = pos_body * (1 - body_mask)
            neg_body = neg_body * body_mask

        # batch x cons: compute body minima
        body_rev = pos_body + exp_preds * (neg_body - pos_body)
        body_min = 1. - torch.max(body_rev, dim=2).values

        # batch x cons: ignore constraints
        if active_constraints != None:
            body_min = body_min * active_constraints.float()

        # batch x cons x num: prepare (body_min x head)
        body_min = body_min.unsqueeze(2).expand(batch, cons, num)
        pos_head = self.pos_head.unsqueeze(0).expand(batch, cons, num)
        neg_head = self.neg_head.unsqueeze(0).expand(batch, cons, num)

        # batch x num: compute head lower and upper bounds
        lb = torch.max(body_min * pos_head, dim=1).values
        ub = 1 - torch.max(body_min * neg_head, dim=1).values
        lb, ub = torch.minimum(lb, ub), torch.maximum(lb, ub)

        preds = torch.maximum(lb, torch.minimum(ub, preds))
        return preds

    # Apply constraints iteratively with 2D matrices
    @profiler.wrap
    def apply_iter(self, preds, active_constraints=None, body_mask=None, in_bounds=None, out_bounds=False):
        batch, num, cons = self.dimensions(preds)
        device = preds.device

        if not active_constraints is None: active_constraints = active_constraints.float()
        zeros = torch.zeros(batch, 1, device=device)

        profiler = ConstraintsModule.profiler.branch('iter')

        with profiler.watch('init'):
            if in_bounds is None:
                lb = [torch.zeros(preds.shape[0], device=device) for i in range(preds.shape[1])]
                ub = [torch.ones(preds.shape[0], device=device) for i in range(preds.shape[1])]
            else:
                lb, ub = in_bounds

        with profiler.watch('precompute'):
            bool_pos_body = self.pos_body.bool()
            bool_neg_body = self.neg_body.bool()

            full_pos_body = 1 - preds
            full_neg_body = preds

            if not body_mask is None:
                full_pos_body = (1 - preds) * (1 - body_mask)
                full_neg_body = preds * body_mask

        for c, lit in enumerate(self.heads):
            # slice positive and negative body preds
            with profiler.watch('where'):
                pos_where = bool_pos_body[c]
                neg_where = bool_neg_body[c]

            # body predictions (possibly masked)
            with profiler.watch('body'):
                pos_body = full_pos_body[:, pos_where]
                neg_body = full_neg_body[:, neg_where]

            # compute maximal inverted values
            with profiler.watch('candidate'):
                candidate = torch.cat((zeros, pos_body, neg_body), dim=1)
                candidate = 1 - candidate.max(dim=1).values

            # clear inactive constraints
            with profiler.watch('active_cons'):
                if not active_constraints is None:
                    candidate = candidate * active_constraints[:, c]

            # update preds
            with profiler.watch('min_max'):
                if lit.positive:
                    lb[lit.atom] = torch.maximum(lb[lit.atom], candidate)
                else:
                    ub[lit.atom] = torch.minimum(ub[lit.atom], 1 - candidate)

        with profiler.watch('lb_ub'):
            if out_bounds:
                return lb, ub

            lb, ub = torch.stack(lb, dim=1), torch.stack(ub, dim=1)
            lb, ub = torch.minimum(lb, ub), torch.maximum(lb, ub)
            updated = torch.maximum(lb, torch.minimum(ub, preds))

            return updated

    @profiler.wrap
    def apply(self, preds, iterative):
        if iterative:
            return self.apply_iter(preds)
        else:
            return self.apply_tensor(preds)

    @profiler.wrap
    def apply_goal(self, preds, goal, iterative):
        full_body, unsat_head = self.active_constraints(goal)
        body_mask = goal

        if iterative:
            bounds = self.apply_iter(preds, active_constraints=full_body, out_bounds=True)
            updated = self.apply_iter(preds, active_constraints=unsat_head, body_mask=body_mask, in_bounds=bounds)
        else:
            updated = self.apply_tensor(preds, active_constraints=full_body)
            updated = self.apply_tensor(updated, active_constraints=unsat_head, body_mask=body_mask)

        return updated

    @profiler.wrap
    def forward(self, preds, goal = None, iterative=True):
        if len(preds) == 0 or len(self.atoms) == 0:
            return preds

        updated = self.to_minimal(preds)

        if goal is None:
            updated = self.apply(updated, iterative=iterative)
            return self.from_minimal(updated, preds)
        else:
            goal = self.to_minimal(goal)
            updated = self.apply_goal(updated, goal=goal, iterative=iterative)
            return self.from_minimal(updated, preds)

def test_symmetric():
    pos = torch.from_numpy(np.arange(0., 1., 0.1))
    symm = torch.from_numpy(np.arange(-1., 1., 0.2))
    assert torch.isclose(ConstraintsModule.to_symmetric(pos), symm).all()
    assert torch.isclose(ConstraintsModule.from_symmetric(symm), pos).all()

def run_cm(cm, preds, goal=None, device='cpu'):
    cm, preds = cm.to(device), preds.to(device)
    if not goal is None: goal = goal.to(device)

    iter = cm(preds, goal=goal, iterative=True)
    tens = cm(preds, goal=goal, iterative=False)
    assert torch.isclose(iter, tens).all()
    return iter.cpu()

def _test_no_goal(device):
    group = ConstraintsGroup([
        Constraint('1 :- 0'),
        Constraint('2 :- n3 4'),
        Constraint('n5 :- 6 n7 8'),
        Constraint('2 :- 9 n10'),
        Constraint('n5 :- 11 n12 n13'),
    ])
    cm = ConstraintsModule(group, 14)
    preds = torch.rand((5000, 14))
    updated = run_cm(cm, preds, device=device).numpy()
    assert group.coherent_with(updated).all()

def _test_positive_goal(device):
    group = ConstraintsGroup([
        Constraint('0 :- 1 n2'),
        Constraint('3 :- 4 n5'),
        Constraint('n7 :- 7 n8'),
        Constraint('n9 :- 10 n11')
    ])

    cm = ConstraintsModule(group, 12)
    preds = torch.rand((5000, 12))
    goal = torch.tensor([1., 1., 0., 1., 1., 1., 0., 1., 0., 0., 0., 0.]).unsqueeze(0).expand(5000, 12)
    updated = run_cm(cm, preds, goal=goal, device=device).numpy()
    assert (group.coherent_with(updated).all(axis=0) == [True, False, True, False]).all()

def _test_negative_goal(device):
    group = ConstraintsGroup([
        Constraint('0 :- 1 n2 3 n4'),
        Constraint('n5 :- 6 n7 8 n9')
    ])
    reduced_group = ConstraintsGroup([
        Constraint('0 :- 1 n2'),
        Constraint('n5 :- 6 n7')
    ])

    cm = ConstraintsModule(group, 10)
    preds = torch.rand((5000, 10))
    goal = torch.tensor([0., 0., 1., 1., 0., 1., 0., 1., 1., 0.]).unsqueeze(0).expand(5000, 10)
    updated = run_cm(cm, preds, goal=goal, device=device).numpy()
    assert reduced_group.coherent_with(updated).all()

def test_goal_cpu():
    _test_no_goal('cpu')
    _test_negative_goal('cpu')
    _test_positive_goal('cpu')

@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
def test_goal_cuda():
    _test_no_goal('cuda')
    _test_negative_goal('cuda')
    _test_positive_goal('cuda')
    print(json.dumps(ConstraintsModule.profiler.combined(), indent=4, sort_keys=True))

def _test_empty_preds(device):
    group = ConstraintsGroup([
        Constraint('0 :- 1')
    ])

    cm = ConstraintsModule(group, 2)
    preds = torch.rand((0, 2))
    goal = torch.rand((0, 2))
    updated = run_cm(cm, preds, goal=goal, device=device)
    assert updated.shape == torch.Size([0, 2])

def _test_no_constraints(device):
    group = ConstraintsGroup([])
    cm = ConstraintsModule(group, 10)
    preds = torch.rand((500, 10))
    goal = torch.rand((500, 10))

    updated = run_cm(cm, preds, device=device)
    assert (updated == preds).all()
    updated = run_cm(cm, preds, goal=goal, device=device)
    assert (updated == preds).all()

def test_empty_preds_constraints_cpu():
    _test_empty_preds('cpu')
    _test_no_constraints('cpu')

@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
def test_empty_preds_constraints_cuda():
    _test_empty_preds('cuda')
    _test_no_constraints('cuda')

def test_lb_ub():
    group = ConstraintsGroup([
        Constraint('0 :- 1'),
        Constraint('n0 :- 2')
    ])
    cm = ConstraintsModule(group, 3)
    preds = torch.tensor([
        [0.5, 0.6, 0.3],
        [0.65, 0.6, 0.3],
        [0.8, 0.6, 0.3],
        [0.5, 0.7, 0.4],
        [0.65, 0.7, 0.4],
        [0.8, 0.7, 0.4],
    ])

    updated = run_cm(cm, preds)
    assert (updated[:, 0] == torch.tensor([0.6, 0.65, 0.7] * 2)).all()

def _test_time(iterative, device):
    group = ConstraintsGroup('../constraints/full')
    cm = ConstraintsModule(group, 41).to(device)
    preds = torch.rand(5000, 41, device=device)
    cm(preds, iterative=iterative)

def test_time_iterative_cpu():
    for i in range(10):
        _test_time(True, 'cpu')

def test_time_tensor_cpu():
    for i in range(10):
        _test_time(False, 'cpu')

@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
def test_time_iterative_cuda():
    for i in range(10):
        _test_time(True, 'cuda')

@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
def test_time_tensor_cuda():
    for i in range(10):
        _test_time(False, 'cuda')


import RandomGraph as rg
import plotGraph as pg
import des
import numpy as np
import matplotlib.pyplot as plt
import random

def random_color():
    rgbl = [255, 0, 0]
    random.shuffle(rgbl)
    return tuple(rgbl)

n = 10
m = 1
scheduleTimeout = 5
collectorTimeout = 5
knowledgeTimeout = 10
iteratorTimeout = 15
distance = 1
seed = 6
loss_probability = 1
regenGraphTimeout = 15000
deltaValue = 10
terminationError = 0.01

values = []

Y = list()
Z = list()
X = range(4, 20)
H = list()

for i in X:
    res = []
    missess = []
    exchange = []
    snap = i
    for _ in range(m):
        graph = rg.RandomGraph(i)
        graph.create_graph()
        graph.add_connections()
        nodes = graph.nodes_list()
        edges = graph.edges_dic(distance)
        simulation = des.Sim(nodes, edges, loss_probability, regenGraphTimeout,
                             collectorTimeout, knowledgeTimeout,
                             scheduleTimeout, iteratorTimeout,
                             distance, deltaValue, rg.Types.AVERAGE,
                             terminationError, snap)
        simulation.start()
        des.printNodes(simulation.nodes)
        values.append(simulation.getValues())
        res.append(simulation.time)
        exchange.append(simulation.exchange)
        missess.append(simulation.missess)
    Y.append(np.average(res))
    Z.append(np.average(missess))
    H.append(np.average(exchange))

pg.generateRoundsGraph(X, Y)
pg.generateMissessGraph(X, Z)
pg.generateExchangeGraph(X, H)

snapshot = simulation.snapshot

plt.figure(1)
for key in snapshot.keys():
    if key != 'time':
        plt.plot(snapshot['time'], snapshot[key], "r")

plt.show()

print(values)


import logging

import boto3
from botocore.client import BaseClient
from botocore.exceptions import ClientError
from decouple import config
from fastapi import UploadFile

from app.utils.date_utils import D

class S3:
    s3_client: BaseClient = boto3.client(
        service_name="s3",
        aws_access_key_id=config("AWS_ACCESS_KEY"),
        aws_secret_access_key=config("AWS_SECRET_KEY")
    )
    BUCKET_NAME = "fleapto-files"
    url = "https://{bucket}.s3.ap-northeast-2.amazonaws.com/{filename}"

    @classmethod
    def upload_file_to_bucket(cls, file: UploadFile):
        filename = f"{D.datetimenum()}_{file.filename}"
        try:
            response = cls.s3_client.upload_fileobj(
                file.file,
                cls.BUCKET_NAME,
                filename,
                ExtraArgs={'ACL': 'public-read'}
            )
        except ClientError as e:
            logging.error(e)
            return None

        url = cls.url.format(bucket=cls.BUCKET_NAME, filename=filename)
        return url


# -*- coding: utf-8 -*-
from flask import Flask, render_template, jsonify, Response
from dht import Sensor
import logging
import pigpio
import json
import redis
import time
import ast
import os
import re
import itertools
import datetime
from collections import namedtuple

app = Flask(__name__)
app.debug = True
r = redis.StrictRedis(host='localhost', port=6379, db=0)
Conditions = namedtuple('Conditions', 'temperature humidity message')
logging.basicConfig(level=logging.DEBUG)

pi = pigpio.pi()
CACHE_TIME = 5

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

@app.route("/history")
def history():
    cached_json = r.get('history_cache')
    if cached_json:
        return Response(cached_json, mimetype='application/json')

    samples = r.hgetall('tempsamples')
    if samples:
        samples = ast.literal_eval(samples['samples'])
        logging.debug(type(samples))
        samples = sorted(samples, key=lambda item: datetime.datetime.strptime(
            item['datetime'], '%Y-%m-%d %H:%M:%S'))
        output = {
            'temp': [{
                'x': time.mktime(datetime.datetime.strptime(d['datetime'], '%Y-%m-%d %H:%M:%S').timetuple()),
                'y': float(d['temperature'])
            } for d in samples],
            'humidity': [{
                'x': time.mktime(datetime.datetime.strptime(d['datetime'], '%Y-%m-%d %H:%M:%S').timetuple()),
                'y': float(d['humidity'])
            } for d in samples]
        }
        cache_json = json.dumps(output)
        r.set('history_cache', cache_json, ex=500)
        return jsonify(output)
    else:
        return "Data not available"

@app.route("/current")
def conditions():
    last_reading_str = r.get('last_reading')
    if last_reading_str:
        try:
            last_reading = ast.literal_eval(last_reading_str)
        except:
            logging.warn(
                "Last info from redis was bad. Ignoring and discarding")
            last_reading = None
            r.delete('last_reading')
    else:
        last_reading = None
    if not last_reading or time.time() - last_reading[3] > CACHE_TIME:
        logging.debug("Getting new readings")
        sensor = Sensor(pi, 25)
        sensor.read()
        RETRIES = 4
        sleep = 0.1
        time.sleep(sleep)
        times = 0
        while times < RETRIES and sensor.temperature == -999:
            sleep = sleep * 2
            time.sleep(sleep)
            times += 1
        r.set('last_reading', (sensor.temperature,
                               sensor.humidity, sensor.message, time.time()))
        conditions = Conditions(
            sensor.temperature, sensor.humidity, sensor.message)
        sensor.cancel()
    else:
        logging.debug("Using cached readings")
        conditions = Conditions(
            last_reading[0], last_reading[1], last_reading[2])
    d = {'temperature': str(round(conditions.temperature, 1)),
         'humidity': str(round(conditions.humidity, 1)),
         'message': conditions.message}

    return jsonify(d)

if __name__ == "__main__":
    app.run(host='0.0.0.0')


import requests
import json
import tabulate

def pin_me(pincode):
    url="https://api.postalpincode.in/pincode/"+pincode
    x = requests.get(url)
    print(x.status_code)
    val1=x.text
    val2=json.loads(val1)[0]['PostOffice']
    header=val2[0].keys()
    rows =  [x.values() for x in val2]

    print(tabulate.tabulate(rows,header))

pincode=str(input("Enter pincode:"))
pin_me(pincode)


import _thread
import time
import curses
# import term_io as ti
import subprocess as sp
import os
# Define a function for the thread
# import re

class chatroom:
    def __init__(self, name="default"):
        self.name = name
        stdscr = curses.initscr()
        curses.cbreak()
        curses.noecho()
        stdscr.keypad(1)
        curses.start_color()
        stdscr.erase()

        height, width = stdscr.getmaxyx()
        self.running = True
        self.input_width = width - 10

        self.name_win = curses.newwin(1, 7, 1, 1)
        self.name_win.addstr("INPUT:", curses.A_STANDOUT)
        self.name_win.refresh()

        self.man_win = curses.newwin(2, width, 3, 1)
        self.man_win.addstr(
            "press ENTER to send message. BACKSPACE to modify. type \"exit\" and ENTER to exit...", curses.A_DIM)
        self.man_win.refresh()
        self.input_win = curses.newwin(1, self.input_width, 1, 9)
        self.log_win = curses.newwin(min(40, height - 6), width - 2, 5, 1)
        self.log_win.scrollok(True)
        self.log_win.box()

        try:
            _thread.start_new_thread(self.timer1, ("Thread-1", 0.5, ))
        except:
            print("Error: unable to start thread")

    def close(self):
        self.running = False
        time.sleep(1)
        curses.endwin()

    def timer1(self, threadName, delay):
        while self.running:
            time.sleep(delay)
            self.log_win.clear()
            chatlog = sp.check_output(
                ['tail', '-n', '40', 'vending_accounts/chat.log']).decode("utf-8")
            # self.log_win.addstr("%s: %s\n" % ( threadName, time.ctime(time.time()) ))
            self.log_win.addstr(chatlog)
            self.log_win.refresh()

def post_message(name="default", message="xxx"):
    output = "[" + time.ctime(time.time())[
        4:-8] + "] " + name + ": " + message.replace("\\", "\\\\").replace("\"", "\\\"")
    os.system("echo \"" + output
              + "\" >> vending_accounts/chat.log")

def run_chatroom(name="default"):
    room = chatroom(name)
    cursor = 0
    square = "|"
    inputstr = ""
    post_message(name, "< Came to the message board. >")
    # room.input_win.nodelay(1)
    while 1:
        room.input_win.clear()
        room.input_win.addstr(inputstr, curses.A_BOLD)
        # room.input_win.refresh()
        # time.sleep(0.2)
        room.input_win.addstr(square, curses.A_BLINK)
        # time.sleep(0.2)
        room.input_win.refresh()
        char = room.input_win.getch()
        if char in [curses.KEY_ENTER, ord('\n')]:
            if inputstr.upper() in ["EXIT", "QUIT"]:
                post_message(name, "< Walked away... >")
                room.close()
                return
            post_message(name, inputstr)
            cursor = 0
            inputstr = ""
        elif char in [127, ord('\b'), curses.KEY_BACKSPACE, 'KEY_BACKSPACE', '\b', '\x7f']:
            if cursor > 0:
                cursor -= 1
                inputstr = inputstr[:-1]
        elif char != -1:
            if cursor < room.input_width - 3:
                if char == 27:
                    room.input_win.getch()
                    room.input_win.getch()
                else:
                    inputstr += chr(char)
                    cursor += 1

def main():
    run_chatroom("Test")
    # print(file_num)

if __name__ == "__main__":
    main()


#Import Support Vector Machine code from sklearn
from sklearn import svm

#The SVC module under SVC does classifications
from sklearn.svm import SVC

#import matplotlib
#matplotlib.use('Agg')
#matplot lib plots help us visualize what is going on
#import matplotlib.pyplot as plt

#X are the training rows 2 dimensions, x and y
X = [[0, 0], [1, 1]]

#y is the target classifications 0 and 1
y = [0, 1]

#reveal the training data input
#plt.plot(X, y, 'ro')
#plt.margins(1, 1)
#plt.show()

#Instantiate a new Support Vector Machine Classifier
clf = svm.SVC()

#fit the hyperplane between the clouds of data, should be fast as hell
clf.fit(X, y)

#specify config options, read the docs
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)

#After being fitted, the model can then be used to predict new values:

#If we pass in unseen row x=2 and y=2 then the answer should be classification 1
print("Answer: " + str(clf.predict([[2., 2.]])))
#array([1])  #yeah!

#SVMs decision function depends on some subset of the training data, called the
#support vectors. Some properties of these support vectors can be found in
#members support_vectors_, support_ and n_support:

#here is what is going on in the SVM's brain, it's just a definition of a hyperplane,
#in 2 dimensions, it's just a line, y=mx + b

# get support vectors
#print(clf.support_vectors_)
#array([[ 0.,  0.],
#       [ 1.,  1.]])

# get indices of support vectors
#print(clf.support_)
#array([0, 1]...)

# get number of support vectors for each class
#print(clf.n_support_)
#array([1, 1]...)


from threading import Lock
import os
from termcolor import colored

class Logger():
    def __init__(self):
        self.__loading = "|/-\\"
        self.__step = 0
        self.__lock = Lock()

    class Level():
        SUCCESS = ('+', 'green')
        INFO = ('!', 'yellow')
        FAIL = ('-', 'red')
        IMPORTANT = ('!', 'magenta')

    def __clear_line(self):
        (width, _) = os.get_terminal_size()
        print(f"\r" + width * " ", end = "")

    def display_loadbar(self, message:str):
        self.__lock.acquire()
        self.__clear_line()
        self.__step += 1
        print(f"\r[{self.__loading[self.__step%len(self.__loading)]}] {message}", end="")
        self.__lock.release()

    def log(self, message:str, level:Level = Level.SUCCESS):
        self.__lock.acquire()
        self.__clear_line()
        print(colored(f"\r[{level[0]}] {message}", level[1]))
        self.__lock.release()


import pandas as pd
import numpy as np
import logging

logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
logging.info('hh')

from pyecharts.charts import Bar, Grid, Line,Page
from pyecharts import options as opts
from pyecharts.charts import Bar

# 读取数据
sample = pd.read_csv('/home/bb5/xw/mxg_scores/20210120_pg_v3_old.csv',encoding='gbk')

sample['y']=sample['age'].map(lambda x: 1 if x>=7 else 0)

train = sample.fillna(-999)  # None填充

# 读取保存好的 model 和feature names
path ='/home/bb5/xw/mxg_scores'
input_xgb_features_path=path+'/lgbm_v1_features.csv'
chosen_feature_pd=pd.read_csv(input_xgb_features_path,encoding='UTF-8')
chosen_feature=list(np.array(chosen_feature_pd.iloc[:,0],dtype='str'))
print('chosen_feature: ' ,chosen_feature)

page = Page()
print('模型bin分布 *******************')

# bin 分布
#
# df_bin = pd.read_csv('/home/bb5/xw/mxg_scores/monitor/v3_bin.csv', encoding='gbk')
# bins = ['bin1', 'bin2', 'bin3', 'bin4', 'bin5', 'bin6', 'bin7','bin8', 'bin9', 'bin10', 'bin11', 'bin12', 'bin13', 'bin14', 'bin15']
# bar_bin = Bar()
# bar_bin.add_xaxis(list(df_bin['apply_time']))
# for bin in bins:
#     bar_bin.add_yaxis(bin, list(df_bin[bin]), stack="stack1")
# bar_bin.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
# bar_bin.set_global_opts(title_opts=opts.TitleOpts(title='v3_bin'),
#                         datazoom_opts = [opts.DataZoomOpts(range_start=0, range_end=100), ],
#                         legend_opts = opts.LegendOpts(pos_left="right", orient='vertical'), )
# bar_bin.render("v3_bin.html")
#
# page.add(bar_bin)

# 模型特征变量分布
print('模型特征变量分布 *******************')

num=0
for feature in chosen_feature:
    num+=1

    feature_value = sample[feature].unique()
    feature_value.sort()
    if len(feature_value)>=15:
        _, bin = pd.qcut(sample[feature], 10, retbins=True, duplicates='drop')
    else: bin = list(feature_value)

    bin = list(bin)
    bin.insert(0, -999999)
    bin.pop()
    bin.append(float('inf'))

    col_list = [str(i) for i in bin]
    train['bin'] = pd.cut(train[feature], bin, right=False, labels=col_list[0:-1])
    tmp = train.groupby(['apply_time', 'bin'])['y'].count()
    tmp = tmp.reset_index()
    tmp = pd.DataFrame(tmp)
    tmp = pd.pivot(tmp, index="apply_time", columns="bin", values="y")
    tmp.columns = tmp.columns.astype(str)
    tmp['total'] = tmp.apply(lambda x: x.sum(), axis=1)

    col_list = tmp.columns.to_list()
    bar = Bar()
    bar.add_xaxis(list(tmp.index))
    for i in range(len(col_list[0:-1])):
        bar.add_yaxis(col_list[i], list(tmp[col_list[i]] / tmp['total']), stack="stack1")

    bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    bar.set_global_opts(title_opts=opts.TitleOpts(title=feature),
                        datazoom_opts=[opts.DataZoomOpts(range_start=0,range_end=100), ],
                        #toolbox_opts=opts.ToolboxOpts(),
                        legend_opts=opts.LegendOpts(pos_left="right",orient='vertical'),)

    page.add(bar)
    logger.info('数量 {}  完成 {}'.format(num,feature))

page.render("v3_old.html")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 24 10:36:29 2019

@author: hao
"""
from dataDecode import dataDecode
import requests
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy import signal
import math
from numpy.fft import fft, fftshift

urlstart="http://xds.ym.edu.tw/01530055/191224b.153"
    #前面都是做例外處理，確認設備是否在線上或者，這裡是正式下載資料
r = requests.get(urlstart)
rawtxt=r.content #content:二進制

Data,sampling_rate=dataDecode.rawdataDecode(rawtxt)
data_sam = sampling_rate/2
duration=int(len(Data[0])/(data_sam))
Data_len=int(data_sam)*duration
Data_from=len(Data[0])-Data_len

vector=Data[0][Data_from:Data_from+Data_len]#-medfilt(np.array(Data[0][Data_from:Data_from+Data_len]),125)
#plt.plot(vector)
fc = 45
w = fc/(sampling_rate/4)
b, a = signal.butter(2, w)
vector_filt = signal.filtfilt(b, a, vector)
#plt.plot(medfilt(np.array(Data[0][Data_from:Data_from+Data_len]),125))
col = {"HR" : vector_filt}
#col2 = {"HR" : vector}
data = pd.DataFrame(col)
#plt.plot(vector_filt)
#data2 = pd.DataFrame(col2)
xs = [i for i in range(Data_len)]
x1 = np.linspace(0, duration, len(xs))  #x軸，將point轉換成time
x_time = []     #存入x_time這個list
for x in x1:
    x_time.append(x)

hrw = 0.3 #One-sided window size, as proportion of the sampling frequency
fs = sampling_rate/2 #The example dataset was recorded at 100Hz
#fs = sampling_rate/2
mov_avg = data['HR'].rolling(int(hrw*fs)).mean()
#Calculate moving average
#Impute where moving average function returns NaN, which is the beginning of the signal where x hrw
avg_hr = (np.mean(data.HR))
mov_avg = [avg_hr if math.isnan(x) else x for x in mov_avg]
mov_avg = [x*1.13 for x in mov_avg]
#For now we raise the average by 4% to prevent the secondary heart contraction from interfering, in part 2 we will do this dynamically
data['HR_rollingmean'] = mov_avg

#Append the moving average to the dataframe
window = []
peaklist = []
listpos = 0 #We use a counter to move over the different data columns
for datapoint in data.HR:
    rollingmean = data.HR_rollingmean[listpos] #Get local mean
    if (datapoint < rollingmean) and (len(window) < 1): #If no detectable R-complex activity -> do nothing
        listpos += 1
    elif (datapoint > rollingmean): #If signal comes above local mean, mark ROI
        window.append(datapoint)
        listpos += 1
    else: #If signal drops below local mean -> determine highest point
        #maximum = max(window)
        beatposition = listpos - len(window) + (window.index(max(window))) #Notate the position of the point on the X-axis
        peaklist.append(beatposition) #Add detected peak to list
        window = [] #Clear marked ROI
        listpos += 1
ybeat = [data.HR[x] for x in peaklist] #Get the y-value of all peaks for plotting purposes
peaklist_time = [x_time[j] for j in peaklist]

px = []
py = []
qx = []
qy = []
sx = []
sy = []
tx = []
ty = []

prx = []
qrsx = []
qtx = []

thershold = [30, 80, 120]

for index3 in peaklist:

    ##------peak------##
    # P-wave
    if index3 < thershold[1]:
        p_list = vector[0:(index3 - thershold[0])]
        p_x = max(p_list)
        p_index = p_list.index(max(p_list))
        p_y = 0 + p_index

    else:
        p_list = vector[(index3 - thershold[1]):(index3 - thershold[0])]
        p_y = max(p_list)
        p_index = p_list.index(max(p_list))
        p_x = index3 - thershold[1] + p_index
    px.append(p_x)
    py.append(p_y)

    # Q-wave
    q_list = vector[(index3 - thershold[0]):index3]
    q_y = min(q_list)
    q_index = q_list.index(min(q_list))
    q_x = index3 - thershold[0] + q_index
    qx.append(q_x)
    qy.append(q_y)

    # S-wavw
    s_list = vector[index3:(index3 + thershold[0])]
    s_y = min(s_list)
    s_index = s_list.index(min(s_list))
    s_x = index3 + s_index
    sx.append(s_x)
    sy.append(s_y)

    # T-wave
    t_list = vector[(index3 + thershold[0]):(index3 + thershold[2])]
    t_y = max(t_list)
    t_index = t_list.index(max(t_list))
    t_x = index3 + t_index + thershold[0]
    tx.append(t_x)
    ty.append(t_y)
#
#    ##------interval------##
#    # P-R interval
#    pr_time = ((q_x - p_x)/sampling_rate)*1000
#    prx.append(pr_time)
#
#    # QRS complex
#    qrs_time = ((s_x - q_x)/sampling_rate)*1000
#    qrsx.append(qrs_time)
#
#    # Q-T interval
#    qt_time = ((t_x - q_x)/sampling_rate)*1000
#    qtx.append(qt_time)
#
#
#
px_time = [x_time[a] for a in px]
qx_time = [x_time[b] for b in qx]
sx_time = [x_time[c] for c in sx]
tx_time = [x_time[d] for d in tx]

ticks_size = 14
label_size = 18

plt.figure(1)
plt.title("Detected peaks in signal", fontsize = 20)
plt.xticks(fontsize = ticks_size)
plt.yticks(fontsize = ticks_size)
plt.xlabel('Time (s)', fontsize = label_size)
plt.ylabel('Amplitude (mV)', fontsize = label_size)
#plt.plot(x_time, data2.HR)
plt.plot(x_time, data.HR) #Plot semi-transparent HR
plt.scatter(peaklist_time, ybeat, c='red') #Plot detected peaks
#plt.scatter(px_time, py, c='blue')
#plt.scatter(qx_time, qy, c='red')
#plt.scatter(sx_time, sy, c='red')
#plt.scatter(tx_time, ty, c='y')
plt.show()
#%%
'''----------------
Interval extraction
-------------------'''

#P-R interval

p0 = []

#for index4 in px:
#    pr_list = vector[(index4 - 40):index4]
#    p_0 = (statistics.median(pr_list))
#    for index5 in (pr_list):
#        if (index5 - p_0) <= 0:
#            p0.append(pr_list.index(index5))
#    prxx = p0[-1]; pryy = (vector[prx])

'''--------------
Cut each cycle
-----------------'''

#------------cut R peak------------#
plt.figure(2)
sub = 1
sub2 = 0
epoch = 150

for index in peaklist:

    #add subplot
    column = math.ceil(len(peaklist)/6)
    plt.subplot(6, column, sub + sub2)  #set row & column

    #cut R peak，計算切割區間(以R peak為中心的300ms)
    cut1 = (x_time[index] - (epoch/1000))*sampling_rate
    cut2 = (x_time[index] + (epoch/1000))*sampling_rate
    y = []
    for k in range(len(vector[int(cut1):int(cut2)])):
        k = (k/sampling_rate)
        y.append(k)

    plt.plot(y, vector[int(cut1):int(cut2)])
#    plt.xticks([])
#    plt.yticks([])

    sub2 = sub2 + 1     #畫完一張圖，新增一個subplot
#%%
#plt.xlabel('Time (ms)', fontsize = label_size)
#plt.ylabel('Amplitude (mV)', fontsize = label_size)

##-------------filter------------##
#fc = 40
#w = fc/(samplingrate/2)
#b, a = signal.butter(5, w)
#y = signal.filtfilt(b, a, vector)
#
#vector2 = [a for a in vector_filt]
#plt.figure(3)
#plt.plot(x_time, vector, 'b', alpha=0.75)
#plt.plot(x_time, vector2, 'k')
#plt.legend(('noisy signal','filtfilt'), loc='best')
##plt.grid(True)
#plt.show()

##--time domain--##

plt.figure(4)

peak_diff = [peaklist[i+1]-peaklist[i] for i in range(len(peaklist)-1)]
RR = [(i/sampling_rate)*1000 for i in peak_diff]
RR_sample = 4
time_new = np.arange(0,duration,1/RR_sample)
RR_interval = signal.resample(RR,len(time_new))
plt.plot(time_new, RR_interval,'o-',color = 'g')
Mean_RR = np.mean(RR_interval)
SD_RR = np.std(RR_interval)
RMSSD = np.sqrt(np.mean(np.array(SD_RR)**2))

plt.title("R-R interval", fontsize = 20)
plt.xticks(fontsize = ticks_size)
plt.yticks(fontsize = ticks_size)
plt.xlabel('Time (s)', fontsize = label_size)
plt.ylabel('Interval (ms)', fontsize = label_size)

##--frequency domain--##
#%%
plt.figure(5)

RR_frq = fft(RR_interval)      #快速傅立葉變換
RR_real = RR_frq.real    # 獲取實數部分
RR_conj = RR_frq.imag    # 獲取虛數部分
RR_time = len(time_new)
power_RR = abs(np.multiply(RR_frq,RR_conj/RR_time))
fsb = RR_sample/RR_time
f = fsb*time_new[0:round(RR_time/2)]
#%%
def band(low,high,x):
    output1 = []
    for i in range(len(x)):
        if x[i] <= high and low <= x[i]:
            output1.append(i)
    return output1
vl = band(0,0.04,f)
lf = band(0.04,0.15,f)
hf = band(0.15,0.4,f)
LF = sum(power_RR[lf])*fsb
HF = sum(power_RR[hf])*fsb
VLF = sum(power_RR[vl])*fsb
TP = LF+HF+VLF
LHratio=LF/HF

#plt.plot(f[findex],power_RR[findex])
plt.plot(f[hf],power_RR[hf],label='HF')
plt.plot(f[lf],power_RR[lf],label="LF")
plt.legend()
plt.title('Power spectral density')
plt.xlabel('Frequency (Hz)')
#    testData=pd.DataFrame(vector_filt[int(cut1):int(cut2)])


import pathlib
from shutil import copyfile

import numpy as np

p4_sys_names = [
    "FT_EFF_B_systematics__1",
    "FT_EFF_C_systematics__1",
    "FT_EFF_Light_systematics__1",
    "FT_EFF_extrapolation__1",
    "FT_EFF_extrapolation_from_charm__1",
    "MUON_EFF_ISO_STAT__1",
    "MUON_EFF_ISO_SYS__1",
    "MUON_EFF_RECO_STAT__1",
    "MUON_EFF_RECO_STAT_LOWPT__1",
    "MUON_EFF_RECO_SYS__1",
    "MUON_EFF_RECO_SYS_LOWPT__1",
    "MUON_EFF_TTVA_STAT__1",
    "MUON_EFF_TTVA_SYS__1",
    "MUON_ID__1",
    "MUON_MS__1",
    "MUON_SAGITTA_RESBIAS__1",
    "MUON_SAGITTA_RHO__1",
    "MUON_SCALE__1",
    "PRW_DATASF__1",
]

# parameters
fit_ntup_dir = "/data/zprime/ntuples_fit/22-0120-sys"
mass_points_low = [5, 7, 9, 11, 13, 15, 17, 19, 23, 27, 31, 35, 39, "42_low"]
mass_points_high = ["42_mz2", 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75]

mass_points_low_num = [5, 7, 9, 11, 13, 15, 17, 19, 23, 27, 31, 35, 39, 42]
mass_points_high_num = [42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75]

dnn_cut_dict = {
    5: 0.46,
    7: 0.58,
    9: 0.50,
    11: 0.60,
    13: 0.52,
    15: 0.54,
    17: 0.54,
    19: 0.65,
    23: 0.54,
    27: 0.65,
    31: 0.68,
    35: 0.72,
    39: 0.74,
    "42_low": 0.74,
    "42_mz2": 0.24,
    42: 0.16,
    45: 0.10,
    48: 0.10,
    51: 0.14,
    54: 0.12,
    57: 0.12,
    60: 0.12,
    63: 0.14,
    66: 0.12,
    69: 0.16,
    72: 0.20,
    75: 0.14,
}

def get_sigma(mass):
    # sigma_range = 3.0 * (0.0401444 + 0.0122949 * mass + 0.000140695 * mass * mass)  # @ Bing Li
    # sigma_range = 3.0 * (0.193 - 0.002 * mass + 0.00035 * mass * mass)  # @ Shuzhou Zhang
    sigma = np.poly1d(
        [
            5.20753537e-08,
            3.34322964e-08,
            -2.17314377e-04,
            2.26208490e-02,
            -1.81540253e-02,
        ]
    )
    return sigma(mass)

def get_mass_cut(mass):
    sigma_range = 3 * get_sigma(mass)
    return (
        np.around(mass - sigma_range, decimals=2),
        np.around(mass + sigma_range, decimals=2),
    )

def get_bin_dict(mass):
    bin_dict_SR = {}
    bin_dict_CR = {}

    # 1D case
    # 10 bins
    # bin_dict_SR["10bins"], bin_dict_CR["10bins"] = 10, 10
    # 20 bins
    # bin_dict_SR["20bins"], bin_dict_CR["20bins"] = 20, 20

    # 10 bins
    # bin_dict_SR["10bins_auto"] = 'Binning: "AutoBin","TransfoD", 5, 5'
    # bin_dict_CR["10bins_auto"] = 'Binning: "AutoBin","TransfoD", 5, 5'
    # 20 bins
    bin_dict_SR["20bins_auto"] = 'Binning: "AutoBin","TransfoD", 10, 10'
    bin_dict_CR["20bins_auto"] = 'Binning: "AutoBin","TransfoD", 10, 10'

    return bin_dict_SR, bin_dict_CR

# Script to create config files

with open("config_template_morph.config", "r") as f:
    config_temp = f.read()
with open("config_template_overall_sys_module.config", "r") as f:
    config_overall_sys_temp = f.read()
with open("config_template_wt_sys_module.config", "r") as f:
    config_wt_sys_temp = f.read()
with open("config_template_p4_sys_module.config", "r") as f:
    config_p4_sys_temp = f.read()

def prepare_config(
    mass,
    region,
    dnn_cut,
    mass_left,
    mass_right,
    sig_scale_left,
    sig_scale_right,
    shift_left,
    shift_right,
):
    # Setups
    if region == "low_mass":
        fit_var = "mz2"
    else:
        fit_var = "mz1"
    mass_str = f"m_{mass:05.2f}"
    # regular settings
    m_low, m_high = get_mass_cut(mass)
    bin_sr = 'Binning: "AutoBin","TransfoD", 10, 10'
    bin_cr = 'Binning: "AutoBin","TransfoD", 10, 10'
    dnn_label = f"p{int(dnn_cut*100):02d}"
    if region == "low_mass":
        p_cr_low = 0
        p_cr_high = 45
    else:
        p_cr_low = 30
        p_cr_high = 85

    # Folders
    stats_dir = pathlib.Path(f"stats_morph/{mass_str}")
    stats_dir.mkdir(parents=True, exist_ok=True)
    sys_dir = pathlib.Path(f"sys_morph/{mass_str}")
    sys_dir.mkdir(parents=True, exist_ok=True)

    # Stats config
    stats_config = config_temp.format(
        p_job="default",
        p_mass=mass,
        p_dnn_label=dnn_label,
        p_fit_var=fit_var,
        p_ntuple_path=f"{fit_ntup_dir}/{region}/tree_NOMINAL",
        p_mass_cut_low=m_low,
        p_mass_cut_high=m_high,
        p_dnn_cut=dnn_cut,
        p_dnn_cut_label=dnn_label,
        p_region=region,
        p_window=np.around(m_high - m_low, decimals=2),
        p_cr_cut_low=p_cr_low,
        p_cr_cut_high=p_cr_high,
        p_cr_low=p_cr_low,
        p_cr_high=p_cr_high - (m_high - m_low),
        p_cr_bin=10,
        p_sr_bin=10,
        p_binning_cr=bin_sr,
        p_binning_sr=bin_cr,
        # For the morphing
        p_mass_left=mass_left,
        sig_scale_left=str(sig_scale_left),
        p_mass_right=mass_right,
        sig_scale_right=str(sig_scale_right),
        p_shift_left=str(shift_left),
        p_shift_right=str(shift_right),
    )
    config_name = f"{mass_str}_cut_{dnn_label}_stats.config"
    with stats_dir.joinpath(config_name).open("w", encoding="utf-8") as f:
        f.write(stats_config)

    # Sys config
    # add overall sys
    sys_config = stats_config[:]
    sys_config += config_overall_sys_temp[:]
    # add weight systematic config
    config_wt_config = config_wt_sys_temp.format(
        p_mass=mass,
        p_ntuple_path=f"{fit_ntup_dir}/{region}/tree_NOMINAL",
        p_region=region,
        p_qcd_var=fit_var,
    )
    sys_config += config_wt_config
    # add p4 systematic config
    for sys_name in p4_sys_names:
        ntuple_path_up_sig = f"{fit_ntup_dir}/{region}/tree_{sys_name}up"
        ntuple_path_down_sig = f"{fit_ntup_dir}/{region}/tree_{sys_name}down"
        # sig
        sys_entry = config_p4_sys_temp.format(
            p_sys_name=sys_name[5:],
            p_sample="Zprime_left",
            p_ntuple_path_up=ntuple_path_up_sig,
            p_ntuple_path_down=ntuple_path_down_sig,
            p_ntuple_files=f"sig_Zp{mass_left:03d}",
            p_weight_str=f"weight * {sig_scale_left}",
        )
        sys_config += sys_entry

        sys_entry = config_p4_sys_temp.format(
            p_sys_name=sys_name[5:],
            p_sample="Zprime_right",
            p_ntuple_path_up=ntuple_path_up_sig,
            p_ntuple_path_down=ntuple_path_down_sig,
            p_ntuple_files=f"sig_Zp{mass_right:03d}",
            p_weight_str=f"weight * {sig_scale_right}",
        )
        sys_config += sys_entry

        # bkg
        ntuple_path_up_bkg = f"{fit_ntup_dir}/{region}/tree_{sys_name}up"
        ntuple_path_down_bkg = f"{fit_ntup_dir}/{region}/tree_{sys_name}down"
        ## add qcd
        sys_entry = config_p4_sys_temp.format(
            p_sys_name=sys_name,
            p_sample="ZZ4l",
            p_ntuple_path_up=ntuple_path_up_bkg,
            p_ntuple_path_down=ntuple_path_down_bkg,
            p_ntuple_files="bkg_qcd",
            p_weight_str="weight",
        )
        sys_config += sys_entry
        ## add ggZZ
        sys_entry = config_p4_sys_temp.format(
            p_sys_name=sys_name,
            p_sample="ggZZ",
            p_ntuple_path_up=ntuple_path_up_bkg,
            p_ntuple_path_down=ntuple_path_down_bkg,
            p_ntuple_files="bkg_ggZZ",
            p_weight_str="weight",
        )
        sys_config += sys_entry
    # save
    config_name = f"{mass_str}_cut_{dnn_label}_sys.config"
    with sys_dir.joinpath(config_name).open("w", encoding="utf-8") as f:
        f.write(sys_config)

    fit_script_name = "fit_all.sh"
    copyfile(f"./{fit_script_name}", stats_dir.joinpath(fit_script_name))
    copyfile(f"./{fit_script_name}", sys_dir.joinpath(fit_script_name))


import pytest
# import requests_mock

from page_analyzer.html import (
    normalize_url,
    validate_url,
    # get_page_data,
)

@pytest.mark.parametrize(
    'url_entered, url_name',
    [
        ('https://ru.hexlet.io/courses/python-basics',
         'https://ru.hexlet.io'),
        ('https://translate.google.com/?hl=ru&sl=ru&tl=en&op=translate',
         'https://translate.google.com'),
    ]
)
def test_normalize_url(url_entered, url_name):
    url_parsed = normalize_url(url_entered)
    assert url_name == url_parsed

class TestValidateUrl:
    urls = [
        ('htp://sorry.jo', 'https://yandex.ru'),
        ('http://benq,ru', 'https://github.com'),
    ]
    empty_url = ''
    not_empty_url = 'https://mail.ru'
    too_long_url = 'o' * 256
    short_url = 'https://itisshorturl.com'

    @pytest.mark.parametrize('url_incorrect, url_correct', urls)
    def test_validate_incorrect_url(self, url_incorrect, url_correct):
        assert ('Некорректный URL', 'danger') in validate_url(url_incorrect)
        assert ('Некорректный URL', 'danger') not in validate_url(url_correct)

    def test_validate_empty_url(self):
        assert ('URL обязателен', 'danger') in validate_url(self.empty_url)
        assert ('URL обязателен', 'danger') not in validate_url(self.not_empty_url)

    def test_validate_too_long_url(self):
        assert ('URL превышает 255 символов', 'danger') in validate_url(self.too_long_url)
        assert ('URL превышает 255 символов', 'danger') not in validate_url(self.short_url)

class TestGetPageData:
    fixture_page = './tests/fixtures/page.html'
    page_url = 'https://ru.hexlet.io'
    expected_page_data = {
        'status_code': 200,
        'h1': 'Test h1',
        'title': 'Test title',
        'description': 'Test content',
    }

    # def test_get_page_data1(self):
    #     with open(self.fixture_page) as fp:
    #         current_page = fp.read()
    #     with requests_mock.Mocker() as mock:
    #         mock.get(
    #             self.page_url,
    #             text=current_page
    #         )
    #         current_data = get_page_data(self.page_url)
    #
    #     assert self.expected_page_data == current_data


from click.testing import CliRunner
import click
import importlib
from sqlite_utils import cli, Database, hookimpl, plugins

def test_register_commands():
    importlib.reload(cli)
    assert plugins.get_plugins() == []

    class HelloWorldPlugin:
        __name__ = "HelloWorldPlugin"

        @hookimpl
        def register_commands(self, cli):
            @cli.command(name="hello-world")
            def hello_world():
                "Print hello world"
                click.echo("Hello world!")

    try:
        plugins.pm.register(HelloWorldPlugin(), name="HelloWorldPlugin")
        importlib.reload(cli)

        assert plugins.get_plugins() == [
            {"name": "HelloWorldPlugin", "hooks": ["register_commands"]}
        ]

        runner = CliRunner()
        result = runner.invoke(cli.cli, ["hello-world"])
        assert result.exit_code == 0
        assert result.output == "Hello world!\n"

    finally:
        plugins.pm.unregister(name="HelloWorldPlugin")
        importlib.reload(cli)
        assert plugins.get_plugins() == []

def test_prepare_connection():
    importlib.reload(cli)
    assert plugins.get_plugins() == []

    class HelloFunctionPlugin:
        __name__ = "HelloFunctionPlugin"

        @hookimpl
        def prepare_connection(self, conn):
            conn.create_function("hello", 1, lambda name: f"Hello, {name}!")

    db = Database(memory=True)

    def _functions(db):
        return [
            row[0]
            for row in db.execute(
                "select distinct name from pragma_function_list order by 1"
            ).fetchall()
        ]

    assert "hello" not in _functions(db)

    try:
        plugins.pm.register(HelloFunctionPlugin(), name="HelloFunctionPlugin")

        assert plugins.get_plugins() == [
            {"name": "HelloFunctionPlugin", "hooks": ["prepare_connection"]}
        ]

        db = Database(memory=True)
        assert "hello" in _functions(db)
        result = db.execute('select hello("world")').fetchone()[0]
        assert result == "Hello, world!"

        # Test execute_plugins=False
        db2 = Database(memory=True, execute_plugins=False)
        assert "hello" not in _functions(db2)

    finally:
        plugins.pm.unregister(name="HelloFunctionPlugin")
        assert plugins.get_plugins() == []


__copyright__ = "Copyright 2017 Birkbeck, University of London"
__author__ = "Martin Paul Eve & Andy Byers"
__license__ = "AGPL v3"
__maintainer__ = "Birkbeck Centre for Technology and Publishing"

import errno
import io
import os
import warnings

from django.conf import settings
from django.core.exceptions import SuspiciousFileOperation
from django.template import Origin, TemplateDoesNotExist
from django.template.loaders.base import Loader as BaseLoader
from django.utils._os import safe_join
from django.utils.deprecation import RemovedInDjango20Warning

from utils import setting_handler, function_cache, logic as utils_logic

class Loader(BaseLoader):

    @staticmethod
    @function_cache.cache(120)
    def journal_theme(journal):
        return setting_handler.get_setting('general', 'journal_theme', journal).value

    @staticmethod
    @function_cache.cache(120)
    def base_theme(journal):
        return setting_handler.get_setting('general', 'journal_base_theme', journal).value

    def get_theme_dirs(self):
        from core import models as core_models
        request = utils_logic.get_current_request()
        base_theme, theme_setting = None, None

        if request:
            if request.journal:
                # this is a journal and we should attempt to retrieve any theme settings
                try:
                    theme_setting = self.journal_theme(request.journal)
                except core_models.Setting.DoesNotExist:
                    pass

                try:
                    base_theme = self.base_theme(request.journal)
                except core_models.Setting.DoesNotExist:
                    pass

            elif request.repository:
                # only the material theme supports repositories at the moment.
                theme_setting = 'material'
            else:
                # this is the press site
                theme_setting = request.press.theme

        # allows servers in debug mode to override the theme with ?theme=name in the URL
        if settings.DEBUG and request and request.GET.get('theme'):
            theme_setting = request.GET.get('theme')

        # order up the themes and return them with engine dirs
        themes_in_order = list()

        if theme_setting:
            themes_in_order.append(
                os.path.join(settings.BASE_DIR, 'themes', theme_setting, 'templates')
            )
        if base_theme:
            themes_in_order.append(
                os.path.join(settings.BASE_DIR, 'themes', base_theme, 'templates')
            )

        # if the base_theme and INSTALLATION_BASE_THEME are different,
        # append the INSTALLATION_BASE_THEME.
        if not base_theme == settings.INSTALLATION_BASE_THEME:
            themes_in_order.append(
                os.path.join(settings.BASE_DIR, 'themes', settings.INSTALLATION_BASE_THEME, 'templates')
            )

        return themes_in_order + self.engine.dirs

    def get_dirs(self):
        return self.get_theme_dirs()

    def get_contents(self, origin):
        try:
            with io.open(origin.name, encoding=self.engine.file_charset) as fp:
                return fp.read()
        except IOError as e:
            if e.errno == errno.ENOENT:
                raise TemplateDoesNotExist(origin)
            raise

    def get_template_sources(self, template_name, template_dirs=None):
        """
        Return an Origin object pointing to an absolute path in each directory
        in template_dirs. For security reasons, if a path doesn't lie inside
        one of the template_dirs it is excluded from the result set.
        """
        if not template_dirs:
            template_dirs = self.get_dirs()
        for template_dir in template_dirs:
            try:
                name = safe_join(template_dir, template_name)
            except SuspiciousFileOperation:
                # The joined path was located outside of this template_dir
                # (it might be inside another one, so this isn't fatal).
                continue

            yield Origin(
                name=name,
                template_name=template_name,
                loader=self,
            )

    def load_template_source(self, template_name, template_dirs=None):
        warnings.warn(
            'The load_template_sources() method is deprecated. Use '
            'get_template() or get_contents() instead.',
            RemovedInDjango20Warning,
        )
        for origin in self.get_template_sources(template_name, template_dirs):
            try:
                return self.get_contents(origin), origin.name
            except TemplateDoesNotExist:
                pass
        raise TemplateDoesNotExist(template_name)


import cv2
import numpy as np
from scipy.spatial import ConvexHull
from scipy.stats import norm
from scipy.stats import truncnorm

from matplotlib import pyplot as plt

class GroupShapeGeneration(object):

    # This class takes the information from grouping and
    # generates social group shapes.
    # Group shapes are generated by calling the generate_group_shape
    # method after classs initialization.
    #
    # Group shapes are formatted as either a sequence of coordinates
    # in the counter clock direction representing the convex shape blob,
    # or, if an image is given, formatted as drawing the blob on the image.

    def __init__(self, msg):
        # Initialization
        # Inputs:
        # msg: message class object (should have data loaded first)

        if msg.if_processed_data:
            self.video_position_matrix = msg.video_position_matrix
            self.video_velocity_matrix = msg.video_velocity_matrix
            self.video_pedidx_matrix = msg.video_pedidx_matrix
        else:
            raise Exception('Data has not been loaded!')
        if msg.if_processed_group:
            self.video_labels_matrix = msg.video_labels_matrix
        else:
            raise Exception('Grouping has not been performed!')

        if (msg.dataset == 'ucy') and (msg.flag == 2):
            self.const = 0.25
        else:
            self.const = 0.35
        return

    def _find_label_properties(self, frame_idx, label):
        # Given a frame index and a group membership label (group id),
        # find information (positions, velocities, person ids) of
        # all the pedestrians in that group and that frame.
        # Inputs:
        # frame_idx: frame index of the video
        # label: group membership label
        # Outputs:
        # positions: positions of the pedestrians in the given group and frame index.
        # velocities: velocities of the pedestrians in the given group and frame index.
        # pedidx: person ids of the pedestrians in the given group and frame index.

        positions = []
        velocities = []
        pedidx = []
        labels = self.video_labels_matrix[frame_idx]
        for i in range(len(labels)):
            if label == labels[i]:
                positions.append(self.video_position_matrix[frame_idx][i])
                velocities.append(self.video_velocity_matrix[frame_idx][i])
                pedidx.append(self.video_pedidx_matrix[frame_idx][i])
        return positions, velocities, pedidx

    @staticmethod
    def draw_social_shapes(position, velocity, const):
        # This function draws social group shapes
        # given the positions and velocities of the pedestrians.

        # Parameters from Rachel Kirby's thesis
        front_coeff = 1.0
        side_coeff = 2.0 / 3.0
        rear_coeff = 0.5
        safety_dist = 0.5
        total_increments = 20 # controls the resolution of the blobs
        quater_increments = total_increments / 4
        angle_increment = 2 * np.pi / total_increments

        # Draw a personal space for each pedestrian within the group
        contour_points = []
        for i in range(len(position)):
            center_x = position[i][0]
            center_y = position[i][1]
            velocity_x = velocity[i][0]
            velocity_y = velocity[i][1]

            velocity_magnitude = np.sqrt(velocity_x ** 2 + velocity_y ** 2)
            velocity_angle = np.arctan2(velocity_y, velocity_x)
            variance_front = max(0.5, front_coeff * velocity_magnitude)
            variance_side = side_coeff * variance_front
            variance_rear = rear_coeff * variance_front

            # Draw four quater-ovals with the axis determined by front, side and rear "variances"
            # The overall shape contour does not have discontinuities.
            for j in range(total_increments):
                if (j // quater_increments) == 0:
                    prev_variance = variance_front
                    next_variance = variance_side
                elif (j // quater_increments) == 1:
                    prev_variance = variance_rear
                    next_variance = variance_side
                elif (j // quater_increments) == 2:
                    prev_variance = variance_rear
                    next_variance = variance_side
                else:
                    prev_variance = variance_front
                    next_variance = variance_side
                value = np.sqrt(const / ((np.cos(angle_increment * j) ** 2 / (2 * prev_variance)) + (np.sin(angle_increment * j) ** 2 / (2 * next_variance))))
                value = max(safety_dist, value)
                #value = 0.5

                addition_angle = velocity_angle + angle_increment * j
                x = center_x + np.cos(addition_angle) * value
                y = center_y + np.sin(addition_angle) * value
                contour_points.append((x, y))

        #plt.scatter(np.array(contour_points)[:, 0], np.array(contour_points)[:, 1])
        #plt.gca().set_aspect('equal', adjustable='box')
        #plt.draw()
        #plt.show()

        # Get the convex hull of all the personal spaces
        convex_hull_vertices = []
        hull = ConvexHull(np.array(contour_points))
        for i in hull.vertices:
            hull_vertice = (contour_points[i][0], contour_points[i][1])
            convex_hull_vertices.append(hull_vertice)

        return convex_hull_vertices

    def generate_group_shape(self, frame_idx, group_label):
        # Method that generates group shape
        # Inputs
        # frame_idx: frame number
        # group_label: group id
        # frame(optional): an image in numpy array (opencv image format)
        # Outputs
        # If an image frame is not provided
        # vertices: coordinates (in meters) that draws a convex shape blob
        #           in the clockwise direction.
        # If an image frame is provided
        # frame: an updated image with a group shape drawn on it.
        # (Regardless) pedidx: the person ids of the pedestrians in the given group.

        positions, velocities, pedidx = self._find_label_properties(frame_idx, group_label)
        if len(positions) == 0:
            raise Exception('Group does not exist in the given frame!')
        vertices = self.draw_social_shapes(positions, velocities, self.const)
        return vertices, (positions, velocities, pedidx)


import argparse
import sys
from pathlib import Path

from nsrr_data.preprocessing.process_functions import process_fns
from nsrr_data.utils.logger import get_logger

AVAILABLE_COHORTS = set(process_fns.keys())
logger = get_logger()

def process_cohort(cohort, *args, **kwargs):
    process_fns[cohort](*args, **kwargs)

if __name__ == "__main__":
    # fmt: off
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--cohort', type=str, required=True, choices=AVAILABLE_COHORTS, help='Available cohorts.')
    parser.add_argument("-d", "--data_dir", type=Path, required=True, help="Path to EDF data.")
    parser.add_argument("-o", "--output_dir", type=Path, default=True, help="Where to store H5 files.")
    parser.add_argument("--fs", type=int, default=128, help="Desired resampling frequency.")
    parser.add_argument("--subjects", type=int, default=None, help='Number of subjects to process. If None, all are processed.')
    parser.add_argument('--splits', type=int, default=1, help="If processing on multiple computers, use this parameter to control the total number of splits.")
    parser.add_argument('--current_split', type=int, default=1, help="Use this to indicate the current split out of the total number of splits.")
    parser.add_argument('--duration', type=float, default=None, help='Duration of segments in seconds.')
    parser.add_argument('--overlap', type=float, default=None, help='Duration of overlap between segments in seconds.')
    parser.add_argument('--event_type', type=str, default=None, choices=['ar', 'lm', 'sdb'], help='Type of event to extract.')
    args = parser.parse_args()
    # fmt: on

    logger.info(f'Usage: {" ".join([x for x in sys.argv])}\n')
    logger.info("Settings:")
    logger.info("---------------------------")
    for idx, (k, v) in enumerate(sorted(vars(args).items())):
        if idx == (len(vars(args)) - 1):
            logger.info(f"{k:>15}\t{v}\n")
        else:
            logger.info(f"{k:>15}\t{v}")

    process_cohort(**vars(args))


#! /usr/bin/python3

import logging
import socket
import time
import sys

LOG_DIR = "/var/log/demoLogger/"
HOSTNAME = socket.gethostname()
LOG_FILE = LOG_DIR + HOSTNAME + ".log"

def initialize_logger():
    log = logging.getLogger("demo-logger")
    log.setLevel(level=logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh = logging.FileHandler(LOG_FILE)
    fh.setLevel(level=logging.DEBUG)
    fh.setFormatter(formatter)
    log.addHandler(fh)
    return log

def infi_logger(logger=None):
    i = 0
    while True:
        logline = f"Logging count {i}"
        if logger:
            logger.info(logline)
        else:
            print(logline)
        time.sleep(20)
        i += 1

if __name__ == "__main__":
    try:
        logger = initialize_logger()
        infi_logger(logger)
    except KeyboardInterrupt:
        print("Stopping the demoLogger.")
        sys.exit(0)
    except Exception as err:
        print(err)
        sys.exit(1)