import pwd
import subprocess

from datetime import datetime, timedelta

import iso8601  # https://bitbucket.org/micktwomey/pyiso8601
from enum import Enum  # https://pypi.python.org/pypi/enum34

QuotaType = Enum('block', 'inode')
QuotaState = Enum('no_quota', 'under_quota', 'soft_limit', 'hard_limit', 'grace_expired')

def parse_datetime(field):
    """Parses an ISO-8601-formatted datetime.  Returns None for None."""
    if field:
        return iso8601.parse_date(field).replace(tzinfo=None)
    else:
        return None

def list_quota_filesystems():
    filesystems = set()
    mtab = open('/etc/mtab')
    try:
        for line in mtab:
            dev, mountpoint, fstype, options, dump, fsck = line.split()
            if 'usrquota' in options.split(','):
                filesystems.add(mountpoint)
    finally:
        mtab.close()
    return filesystems

class QuotaInfo:
    """Information about a specific type of quota (block or inode) for a
    specific account on a specific filesystem.

    Attributes:
        uid         The UID of the account to which this quota applies.
        filesystem  The filesystem to which this quota applies.
        quota_type  A member of the QuotaType enum indicating whether this is a
                    block quota or inode quota.
        used        The number of resources (blocks or inodes) currently in use.
        soft_limit  The soft limit for this resource.
        hard_limit  The hard limit for this resource.
        grace_expires  A datetime indicating when the grace period for exceeding
                       the soft limit will expire.  If the soft limit is not
                       exceeded, the value of this attribute will be None.
        last_notify_date  A datetime indicating the date and time when the
                          account owner was last contacted about their quota
                          usage.
        last_notify_state  A member of the QuotaState enum indicating the state
                           of the account's quota at the time given by
                           last_notify_date.
        current_state  A member of the QuotaState enum indicating the current
                       state of this quota.
        bytes_used  For block quotas, the number of bytes currently in use.
        byte_soft_limit  For block quotas, the soft limit in bytes.
        byte_hard_limit  For block quotas, the hard limit in bytes.
    """

    def __init__(self, uid, filesystem, quota_type, db_cursor):
        self.uid = uid
        self.filesystem = filesystem
        self.quota_type = quota_type
        self.db_cursor = db_cursor
        self.refresh()

    def __repr__(self):
        return '<QuotaInfo(%s, %s, %s): %s %s/%s/%s>' % (self.uid, self.filesystem, self.quota_type.key, self.current_state.key, self.used, self.soft_limit, self.hard_limit)

    def refresh(self):
        self.db_cursor.execute('SELECT * FROM entry WHERE uid = ? AND filesystem = ? AND quota_type = ?',
                               (self.uid, self.filesystem, self.quota_type.index))
        # RHEL 5's pysqlite is too old to have indexing by field name, so we
        # have to fake it.
        indices = {}
        for i in xrange(0, len(self.db_cursor.description)):
            indices[self.db_cursor.description[i][0]] = i

        row = self.db_cursor.fetchone()
        if row:
            self.used = row[indices['used']]
            self.soft_limit = row[indices['soft_limit']]
            self.hard_limit = row[indices['hard_limit']]
            self.grace_expires = parse_datetime(row[indices['grace_expires']])
            self.last_notify_date = parse_datetime(row[indices['last_notify_date']])
            last_notify_state = row[indices['last_notify_state']]
            if last_notify_state:
                self.last_notify_state = QuotaState[last_notify_state]
            else:
                # Pretend everything's okay.
                self.last_notify_state = QuotaState.under_quota
        else:
            self.used = None
            self.soft_limit = None
            self.hard_limit = None
            self.grace_expires = None
            self.last_notify_date = None
            self.last_notify_state = None

    def set_from_quotatool(self, used, soft_limit, hard_limit, grace):
        """Update this object's quota information from the strings parsed from
        quotatool's output."""
        self.used = int(used)
        self.soft_limit = int(soft_limit)
        self.hard_limit = int(hard_limit)
        if int(grace) == 0:
            self.grace_expires = None
        else:
            self.grace_expires = \
                datetime.now().replace(microsecond=0) + timedelta(seconds=int(grace))

    @property
    def current_state(self):
        if self.soft_limit == 0:
            return QuotaState.no_quota
        if self.used < self.soft_limit:
            return QuotaState.under_quota
        if self.used < self.hard_limit and datetime.now() < self.grace_expires:
            return QuotaState.soft_limit
        if self.used >= self.hard_limit:
            return QuotaState.hard_limit
        return QuotaState.grace_expired

    @property
    def bytes_used(self):
        return self.used * 1024

    @property
    def byte_soft_limit(self):
        return self.soft_limit * 1024

    @property
    def byte_hard_limit(self):
        return self.hard_limit * 1024

    def update(self):
        self.db_cursor.execute(
            """UPDATE entry
                 SET used = ?,
                     soft_limit = ?,
                     hard_limit = ?,
                     grace_expires = ?,
                     last_notify_date = ?,
                     last_notify_state = ?,
                     last_update = ?
                 WHERE uid = ?
                   AND filesystem = ?
                   AND quota_type = ?""",
            (self.used, self.soft_limit, self.hard_limit,
             self.grace_expires and self.grace_expires.isoformat(),
             self.last_notify_date and self.last_notify_date.isoformat(),
             self.last_notify_state and self.last_notify_state.index,
             datetime.now().isoformat(),
             self.uid, self.filesystem, self.quota_type.index))
        if self.db_cursor.rowcount == 0:
            self.db_cursor.execute(
                """INSERT INTO entry
                     (used, soft_limit, hard_limit, grace_expires,
                      last_notify_date, last_notify_state, last_update,
                      uid, filesystem, quota_type)
                     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
                (self.used, self.soft_limit, self.hard_limit,
                 self.grace_expires and self.grace_expires.isoformat(),
                 self.last_notify_date and self.last_notify_date.isoformat(),
                 self.last_notify_state and self.last_notify_state.index,
                 datetime.now().isoformat(),
                 self.uid, self.filesystem, self.quota_type.index))

    def set_notify(self):
        """Update this object with a new notification date."""
        self.last_notify_state = self.current_state
        self.last_notify_date = datetime.now()

class AccountInfo:
    """Quota information about a particular account.

    Attributes:
        uid     The UID of the account.
        quotas  A nested dictionary of QuotaInfo objects.  The first set of keys
                are the filesystems for which quota information exists.  The
                second set of keys are the values of the QuotaType enum.  Thus,
                to access the block quotas for the /home filesystem, you would
                use `obj.quotas['/home'][QuotaType.block]`.
    """

    @staticmethod
    def all(db_cursor):
        """Generator that yields all entries in the cache."""
        db_cursor.execute('SELECT DISTINCT uid FROM entry')
        results = db_cursor.fetchall()
        for row in results:
            yield AccountInfo(row[0], db_cursor)

    def __init__(self, uid, db_cursor):
        self.uid = uid
        self.db_cursor = db_cursor

        self.refresh_from_db()

    @property
    def username(self):
        try:
            return pwd.getpwuid(self.uid).pw_name
        except KeyError:
            return '#%d' % self.uid

    @property
    def iter_quotas(self):
        """Generator to iterate through all quota objects in a flat manner."""
        for filesystem in sorted(self.quotas.keys()):
            for area in QuotaType:
                yield self.quotas[filesystem][area]

    def refresh_from_db(self):
        self.quotas = {}
        self.db_cursor.execute(
            'SELECT DISTINCT filesystem FROM entry WHERE uid = ?', (self.uid,))
        rows = self.db_cursor.fetchall()
        for row in rows:
            self.quotas[row[0]] = {}
            self.quotas[row[0]][QuotaType.block] = QuotaInfo(self.uid, row[0], QuotaType.block, self.db_cursor)
            self.quotas[row[0]][QuotaType.inode] = QuotaInfo(self.uid, row[0], QuotaType.inode, self.db_cursor)

    def refresh_from_system(self):
        self.quotas = {}
        for filesystem in list_quota_filesystems():
            self.quotas[filesystem] = {}

            bqi = QuotaInfo(self.uid, filesystem, QuotaType.block, self.db_cursor)
            iqi = QuotaInfo(self.uid, filesystem, QuotaType.inode, self.db_cursor)

            qt = subprocess.Popen(['quotatool', '-u', str(self.uid),
                                   '-d', filesystem],
                                  stdout=subprocess.PIPE)
            stdout, stderr = qt.communicate()
            qt_uid, qt_fs, \
                blocks_used, block_quota, block_limit, block_grace, \
                inodes_used, inode_quota, inode_limit, inode_grace = \
                stdout.split()

            bqi.set_from_quotatool(blocks_used, block_quota, block_limit, block_grace)
            iqi.set_from_quotatool(inodes_used, inode_quota, inode_limit, inode_grace)

            self.quotas[filesystem][QuotaType.block] = bqi
            self.quotas[filesystem][QuotaType.inode] = iqi

    def update(self):
        """Update the cache file with the current object's information."""
        for quota in self.iter_quotas:
            quota.update()

    def set_notify(self, quotas_notified):
        """Update all supplied quotas with a new notification date."""
        self.refresh_from_db()
        for q in quotas_notified:
            self.quotas[q.filesystem][q.quota_type].set_notify()
        self.update()


from __future__ import print_function

import os, math
from pyspark.sql import SparkSession

# Map 1: extract words from a file
# input: file_name
# output: (term, doc_name), 1

def map1(doc_name):
    file = open(doc_name)
    while True:
        line = file.readline()
        if line == '':
            break
        terms = line.split()
        for term in terms:
            yield (term, doc_name), 1

# Reduce 1: calculate tf for terms in each document
# input: (term, doc_name), 1
# output: (term, doc_name), n

def reduce1(x, y):
    return x + y

# Map 2
# input: (term, doc_name), n
# output: doc_name, ([(term, n)], n)

def map2(x):
    term = x[0][0]
    doc_name = x[0][1]
    n = x[1]
    return doc_name, ([(term, n)], n)

# Reduce 2
# input: doc_name, ([(term, n)], n)
# output: doc_name, ([list of [term, n]], N)

def reduce2(x, y):
    return (x[0] + y[0], x[1] + y [1])

# Map 3
# input: doc_name, ([list of [term, n]], N)
# output: term, ([(n, doc_name, N)], n)

def map3(x):
    doc_name = x[0]
    terms = x[1][0]
    N = x[1][1]
    for item in terms:
        term = item[0]
        n = item[1]
        yield term, ([(n, doc_name, N)], 1)

# Reduce 3:
# input: term, ([(n, doc_name, N)], 1)
# output: term, ([(n, doc_name, N)], m)

def reduce3(x, y):
    return (x[0] + y[0], x[1] + y[1])

# Final map
# input: term, ([(n, doc_name, N)], m)
# output: term, (doc_name, n, N, m, tf score, idf score, tf-idf score)

def map4(x, D):
    term = x[0]
    docs = x[1][0]
    m = x[1][1]

    for item in docs:
        n = item[0]
        doc_name = item[1]
        N = item[2]

        tf = float(n) / N
        idf = math.log(float(D) / m)
        tfidf = tf * idf

        yield term, (doc_name, n, N, m, tf, idf, tfidf)

# main program
if __name__ == "__main__":

    # create spark context
    spark = SparkSession.builder.appName("TfIdf-Exercise").getOrCreate()

    # retrieve all files in the data input directory
    input_folder = "input_txt"
    input_files = [os.path.join(input_folder, file_name) for file_name in os.listdir(input_folder)]

    # get D = total number of documents
    D = len(input_files)

    # to avoid cases where a term appearing in all documents
    # idf = log(D/m) = log(1) = 0
    # we increase D by 1

    D = D + 1

    # put list of files into rdd for parallel processing
    files = spark.sparkContext.parallelize(input_files)

    # calculate terms and their number of occurrences in each document (tf)
    terms_in_docs = files.flatMap(lambda x: map1(x)).reduceByKey(lambda x, y: reduce1(x, y))

    # calculate number of occurrences of all terms in each document (N)
    docs_have_terms = terms_in_docs.map(lambda x: map2(x)).reduceByKey(lambda x, y: reduce2(x, y))

    # calculate number of documents containing specific terms (idf)
    terms_all = docs_have_terms.flatMap(lambda x: map3(x)).reduceByKey(lambda x, y: reduce3(x, y))

    # calculate tf-idf
    terms_final = terms_all.flatMap(lambda x: map4(x, D))

    # call collect() to output the result
    print(terms_final.collect())

    # stop spark context
    spark.stop()


import sys
from collections import deque

N,M= map(int,sys.stdin.readline().split()) #row,col
maps=[]
for _ in range(N):
    a=list(sys.stdin.readline().strip())
    maps.append(list(map(int,a)))

state=deque()
state.append((1,0,0))#cnt,row,col

dx=[0,0,1,-1]
dy=[1,-1,0,0]
while state:
    d,x,y=state.popleft()
    for i in range(4):
        nx=x+dx[i]
        ny=y+dy[i]
        if nx<0 or nx>=N or ny<0 or ny>=M: continue
        if maps[nx][ny]==0: continue
        if maps[nx][ny]==1 or maps[nx][ny]>d+1:
            maps[nx][ny]=d+1
            state.append((d+1,nx,ny))
print(maps[N-1][M-1])

# 다시 공부하고 해볼 것
'''def moving(x,y,table_map,load,fail):
    #동남서북
    x_move=[1,0,-1,0]
    y_move=[0,-1,0,1]
    for x_m,y_m in zip(x_move,y_move):
        if table_map[x+x_m][y+y_m]=='1' and ((x+x_m,y+y_m) not in fail):
            if (x,y) in load:
                load.remove((x,y))
                fail.append((x,y))
            else:
                load.append((x+x_m,y+y_m))
            x=x+x_m
            y=y+y_m
    return x,y,load,fail'''

'''N,M= map(int, sys.stdin.readline().split())
table_map=[]

for _ in range(N):
    table_map.append(list(sys.stdin.readline().split()))
x_move=[1,0,-1,0]
y_move=[0,1,0,-1]
x,y=0,0
load=[(0,0)]
fail=[]
while x!=N-1 or y!=M-1:
    cnt=0
    for x_m,y_m in zip(x_move,y_move):
        if x+x_m>=0 and y+y_m>=0 and x+x_m<N and y+y_m<M:
            if table_map[x+x_m][y+y_m]=='1' and ((x+x_m,y+y_m) not in load) and ((x+x_m,y+y_m) not in fail):
                load.append((x+x_m,y+y_m))
                x=x+x_m
                y=y+y_m
                break
            else: cnt+=1
        else: cnt+=1
    if cnt==4:
        load.remove((x,y))
        fail.append((x,y))
        x=load[-1][0]
        y=load[-1][1]
print(load)
print(len(load))'''


from jbi100_app.main import app
from jbi100_app.data import Data
from jbi100_app.visualizations.map import Map_Visualization

from jbi100_app.visualizations.heatmap import HeatMap
from jbi100_app.visualizations.stackedareachart import StackedAreaChart
from jbi100_app.visualizations.barchart2 import BarChart

from jbi100_app.views.layout import generate_help_layout, generate_about_layout, generate_nav_bar, generate_basic_layout, generate_new_layout

from dash import html, dcc, dash_table
import plotly.express as px
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
import pandas as pd
from datetime import date

# Get data by making a data object and getting the required dfs from it.
data = Data()

df_date, df_severity, df_conditions, df_location, df_heatmap, df_heatmap_speeds = data.get_dataframes()

# Get filter settings
range_filter_global_settings = data.get_range_filter_global_settings()
date_filter_global_settings = data.get_date_filter_global_settings()

# Map dataframes
df_map = df_location.join(df_severity, rsuffix='_b')
df_map = df_map.join(df_date, rsuffix='_c')
df_map['hour_time'] = pd.to_datetime(df_map['time'], format='%H:%M').dt.hour

# Computes data points per year, used for ensuring not too many data points on map
years = list(df_map.drop_duplicates(subset=['accident_year'])['accident_year'])
yearCount = {}
for year in years:
    count = df_map[df_map['accident_year'] == year]['accident_year'].count()
    yearCount[year] = count

# Create geo map
print('Starting map')
m = Map_Visualization(df_map[(df_map['accident_year'] >= 2019) & (df_map['accident_year'] <= 2020)],
                      range_filter_global_settings, yearCount)
map = m.get_map_vis()
print('Map finished')

# Bar chart
df_bar = df_conditions.join(df_severity, rsuffix='_b')
df_bar = df_bar.join(df_date, rsuffix = '_c')
df_bar['hour_time'] = pd.to_datetime(df_bar['time'], format='%H:%M').dt.hour

bar = BarChart("weather_conditions", "accident_index", df_bar)

# Make heat map
heatmap = HeatMap(range_filter_global_settings)

# Make stacked area chart
df_merged_area_cond = df_date.join(df_conditions, lsuffix='_date', rsuffix='_conditions')
grouped_area_cond = df_merged_area_cond.groupby(['accident_year', 'weather_conditions']).size()
grouped_area_cond = grouped_area_cond.reset_index(name='count_weather')

df_merged_area_manu = df_date.join(df_severity, lsuffix='_date', rsuffix='_severity')
grouped_area_manu = df_merged_area_manu.groupby(['accident_year', 'vehicle_manoeuvre']).size()
grouped_area_manu = grouped_area_manu.reset_index(name='count_manoeuvre')

stacked_area_chart = StackedAreaChart('accident_year', 'count_weather', 'weather_conditions', None, grouped_area_cond, 'Weather Conditions')

# Declare visualizations
# vis is a tuple consiting of the visualization itself and the visualization object.

vis1 = (heatmap.get_heatmap(), heatmap)

vis2 = (map, m)

vis3 = (bar.get_barchart(), bar)

# stacked_area_chart is implemented slightly differently so its technically both.
vis4 = (stacked_area_chart, stacked_area_chart)

app.layout = html.Div(
    id="app-container",
    children=[
        html.Div(
            id="main",
            children=[
                generate_nav_bar(),
                # main div that holds all content
                html.Div(
                    id='vis-main'
                )
            ]
        ),
    ],
)

# create page content
main_page_layout = generate_new_layout(range_filter_global_settings, date_filter_global_settings, vis1, vis2, vis3, vis4)
about_layout = generate_about_layout()
help_layout = generate_help_layout()

# Update the index
@app.callback(
    Output('vis-main', 'children'),
    [Input('url', 'pathname')]
)
def display_page(pathname):
    if pathname == '/about':
        return about_layout
    elif pathname == '/help':
        return help_layout
    elif pathname == '/':
        return main_page_layout
    else:
        # handle not known URL
        return html.H1("Error 404: page not found.", style={'color': 'red'})

# Keeps track of map slider
@app.callback(
    Output('map-info', 'children'),
    Output('map-info', 'style'),
    Output('map-tool-tip', 'style'),
    Input('map-range-slider', 'value')
)
def slider(value):
    # Size is approx from year counts
    size = m.compute_size(value[0], value[1])

    error_style_font = {'color': 'red'}
    error_style_visibility = {'visibility': 'visible', 'opacity': '1'}

    if size > 500000:
        return 'Data points loaded: EXCEEDED', error_style_font, error_style_visibility
    else:
        return 'Data points loaded: %s' % size, {}, {}

# Does actual map computing
@app.callback(
    Output('map', 'figure'),
    Output('loading-1-1', 'children'),
    Input('map-info', 'children'),
    Input('map-range-slider', 'value'),
    Input('time-filter-global', 'value'),
    Input('vehicles-slider-global', 'value'),
    Input('color-dropdown', 'value'),
    Input('size-dropdown', 'value'),
)
def do_map(txt, range, time_range, vehicle_no, color_drop, size_drop):
    print(time_range)
    if txt != 'Data points loaded: EXCEEDED':
        # 15 means 15 and more
        if vehicle_no[1] == 15:
            vehicle_no[1] = 1000

        df_map_filtered = df_map[(df_map['accident_year'] >= range[0]) &
                                 (df_map['accident_year'] <= range[1]) &
                                 (df_map['hour_time'] >= time_range[0]) &
                                 (df_map['hour_time'] <= time_range[1]) &
                                 (df_map['number_of_vehicles'] >= vehicle_no[0]) &
                                 (df_map['number_of_vehicles'] <= vehicle_no[1])
                                 ]
        print('Updating map!')

        return m.create_figure(df_map_filtered, color_drop, size_drop), ''
    else:
        # prevent update
        raise PreventUpdate

# Get channel options for map
@app.callback(
    Output('map-hidden-panel', 'style'),
    Output('color-dropdown', 'options'),
    Output('size-dropdown', 'options'),
    Input('options-button', 'n_clicks')
)
def openOptions(value):
    columns = [
            {'label': 'Police Force', 'value': 'police_force'},
            {'label': 'Number of Vehicles', 'value': 'number_of_vehicles'},
            {'label': 'Deaths', 'value': 'number_of_casualties'},
            {'label': 'Day of Week', 'value': 'day_of_week'},
        ]

    # Makes pop up visible/ hidden
    if value is not None:
        if value % 2 == 1:
            return {'visibility': 'visible', 'opacity': '1'}, columns, columns

    return {'visibility' : 'hidden', 'opacity': '0'}, columns, columns

# Barchart
@app.callback(
    Output('barchart-graph', 'figure'),
    #Input = dropdown/ slider etc.
    Input('year-filter-global', 'value'),
    Input('time-filter-global', 'value'),
    Input('vehicles-slider-global', 'value'),

    Input('xaxis', 'value'),
    Input('yaxis', 'value')
 )

def update_barchart(year_range, time_range, vehicle_no, x_select_dropdown, y_select_dropdown):
    # Update the df_bar to match the input
    df_barfilter = df_bar[(df_bar['accident_year'] <= year_range[1]) & (df_bar['accident_year'] >= year_range[0])].copy()
    df_barfilter = df_barfilter[(df_barfilter['hour_time'] <= time_range[1]) & (df_barfilter['hour_time'] >= time_range[0])].copy()
    df_barfilter = df_barfilter[(df_barfilter['number_of_vehicles'] <= vehicle_no[1]) & (df_barfilter['number_of_vehicles'] >= vehicle_no[0])].copy()

    # return the graph with correseponding values
    return bar.update(x_select_dropdown, y_select_dropdown, df_barfilter)

# Global filter callback function
@app.callback(
    Output('heatmap-graph', 'figure'), # heatmap output
    Output('map-range-slider', 'value'), # map range updater
    Input('year-filter-global', 'value'),
    Input('time-filter-global', 'value'),
    Input('vehicles-slider-global', 'value'),
    Input('color', 'value')
)
def global_filter(year_range, time_range, vehicle_no, heatmap_color):
    # global year range is used right now
    heatmap = update_figure(year_range, heatmap_color)

    map_range = m.check_size_old(year_range[0], year_range[1])[:2]

    return heatmap, map_range

# Heatmap updater
def update_figure(value, color):
    if color == 'count':
        filtered_df = df_heatmap[(df_heatmap['accident_year'] <= value[1]) & (df_heatmap['accident_year'] >= value[0])]
        filtered_df = filtered_df.pivot_table('count', 'accident_year', 'weekNum')
    else:
        filtered_df = df_heatmap_speeds[(df_heatmap_speeds['accident_year'] <= value[1]) & (df_heatmap_speeds['accident_year'] >= value[0])]
        filtered_df = filtered_df.pivot_table('speed_limit', 'accident_year', 'weekNum')

    fig = px.imshow(filtered_df,color_continuous_scale=px.colors.sequential.Bluyl, title='Heat Map')
    fig.update_yaxes(title='Accident Year')
    fig.update_xaxes(title='Week number')
    if(color == "count"):
        fig.update_traces(hoverongaps=False,
                      hovertemplate="Accident Year: %{y}"
                                    "
Week number: %{x}"
                                    "
Number of accidents: %{z}<extra></extra>"
                      )
    else:
        fig.update_traces(hoverongaps=False,
                  hovertemplate="Accident Year: %{y}"
                                "
Week number: %{x}"
                                "
Average Speed Limit: %{z}<extra></extra>"
                  )
    fig.update_layout(transition_duration=500, margin=dict(l=5, r=5, t=35, b=5))
    return fig

# Stacked bar chart
@app.callback(
    Output('stacked-area-chart', 'figure'),
    Input('area_select_dropdown', 'value'),
    Input('year-filter-global', 'value'),
    Input('time-filter-global', 'value'),
    Input('vehicles-slider-global', 'value'),
)

def update_stacked_area_chart(area_select_dropdown, year_range, time_range, vehicles_range):
    if vehicles_range[1] == 15:
        vehicles_range[1] = 1000

    if area_select_dropdown == 'weather_conditions':
        df_merged_area_cond = df_date.join(df_conditions, lsuffix='_date', rsuffix='_conditions').join(df_severity, rsuffix='_sev')
        df_merged_area_cond['hour_time'] = pd.to_datetime(df_merged_area_cond['time'], format='%H:%M').dt.hour

        # filter
        df_merged_area_cond = df_merged_area_cond[(df_merged_area_cond['accident_year'] >= year_range[0]) &
                                                  (df_merged_area_cond['accident_year'] <= year_range[1]) &
                                                  (df_merged_area_cond['hour_time'] >= time_range[0]) &
                                                  (df_merged_area_cond['hour_time'] <= time_range[1]) &
                                                  (df_merged_area_cond['number_of_vehicles'] >= vehicles_range[0]) &
                                                  (df_merged_area_cond['number_of_vehicles'] <= vehicles_range[1])
                                                  ]

        grouped_area_cond = df_merged_area_cond.groupby(['accident_year', 'weather_conditions']).size()
        grouped_area_cond = grouped_area_cond.reset_index(name='count_weather')

        return stacked_area_chart.update(area_select_dropdown, grouped_area_cond)
    elif area_select_dropdown == 'vehicle_manoeuvre':
        df_merged_area_manu = df_date.join(df_severity, lsuffix='_date', rsuffix='_severity').join(df_severity, rsuffix='_sev')
        df_merged_area_manu['hour_time'] = pd.to_datetime(df_merged_area_manu['time'], format='%H:%M').dt.hour

        # filter
        df_merged_area_manu = df_merged_area_manu[(df_merged_area_manu['accident_year'] >= year_range[0]) &
                                                  (df_merged_area_manu['accident_year'] <= year_range[1]) &
                                                  (df_merged_area_manu['hour_time'] >= time_range[0]) &
                                                  (df_merged_area_manu['hour_time'] <= time_range[1]) &
                                                  (df_merged_area_manu['number_of_vehicles'] >= vehicles_range[0]) &
                                                  (df_merged_area_manu['number_of_vehicles'] <= vehicles_range[1])
                                                  ]

        grouped_area_manu = df_merged_area_manu.groupby(['accident_year', 'vehicle_manoeuvre']).size()
        grouped_area_manu = grouped_area_manu.reset_index(name='count_manoeuvre')

        return stacked_area_chart.update(area_select_dropdown, grouped_area_manu)

if __name__ == '__main__':
    app.run_server(debug=False, host='0.0.0.0')  # why debug not working :(


import pandas as pd
import time
import requests
from pyquery import PyQuery as pq

# 定义一个字母列表
Fam_List = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
            'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z']

# 定义基础网站地址
base_url = 'https://commons.wikimedia.org'

# 定义查询的HTML
middle_url = '/w/index.php?title=Category:Google_Art_Project_works_by_artist&from='
# 定义headers
headers = {'user-agent':
               'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
           }
# 定义首页的css查询路径
css_path = '#content #mw-content-text .mw-category-generated .mw-content-ltr li'
# 定义二级界面image查询路径
css_path_image = None
# 定义二级界面summary查询路径
css_path_summary = None
# 定义一个csv文件用来存放所有需要爬取的html的地址
file_name = 'Art_List.cvs'

# 定义一个写入文件的函数
def write_to_file(content):
    with open(file_name, 'a', encoding='utf-8') as f:
        f.write(content[0] + ',' + content[1] + '\n')

# 定义一个写成excel的函数
def creat_excel(file_name):
    df = pd.DataFrame(pd.read_csv(file_name, encoding='utf-8', names=['Name', 'URL']))
    # 丢弃重复的URL地址行
    df.drop_duplicates(subset='URL', keep='last', inplace=True)
    df.to_excel('Art_List.xlsx')

# 定义一个获取单页html的函数
def get_one_page(i):
    try:
        # request获取网页的响应
        url = base_url + middle_url + i
        response = requests.get(url, headers=headers)
        # 将响应的解码方式转换为自身
        print("成功进入页面")
        response.encoding = response.apparent_encoding
        # 获取网页本身的html文本
        content = response.text
        # 将获取的html文本传递给pyquery
        doc = pq(content)
        # 返回一个所有页面的生成器
        for item in doc(css_path).items():
            yield (
                i,
                base_url + (item('a').attr('href')),
            )
    except Exception as e:
        print('Error', e.args)

def main():
    for i in Fam_List:
        print('即将下载:%s页' % i)
        for content in get_one_page(i):
            print(content)
            write_to_file(content)
        time.sleep(1)
    creat_excel(file_name)

if __name__ == '__main__':
    main()


import cv2
import numpy as np

original = cv2.imread("C:/Users/gkami/Documents/GitHub/ImageComparissonDualCam/test_files/1.jpg")
duplicate = cv2.imread("images/duplicate.jpg")

def testShow():
    cv2.imshow("1", original)
    cv2.waitKey(0)


from django.db import models

class TgUser(models.Model):
    tg_id = models.IntegerField()
    first_name = models.CharField(max_length=64, blank=True, null=True)
    username = models.CharField(max_length=64, blank=True, null=True)
    admin = models.BooleanField(blank=True)
    tz_info = models.CharField(max_length=5, blank=True, null=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        if self.username:
            return self.username
        else:
            return str(self.id)

class Subscription(models.Model):
    title = models.CharField(max_length=256)
    users = models.ManyToManyField("TgUser", blank=True, related_name="subscriptions", verbose_name="Subscriptions")

    def __str__(self):
        return self.title

class UserEvent(models.Model):
    title = models.CharField(max_length=256, blank=True)
    remind_time = models.TimeField(verbose_name="Remind Time", blank=True)
    times = models.IntegerField(blank=True)
    user = models.ForeignKey("TgUser", on_delete=models.CASCADE, related_name="events", blank=False)

    def __str__(self):
        return self.title

class MailingArcticle(models.Model):
    body = models.CharField(max_length=4096)
    remind_time = models.TimeField(verbose_name="Remind Time", blank=True)
    remind = models.BooleanField(default=True)

    def __str__(self):
        return self.body[:20] + "..."


import numpy as np
from sklearn.metrics import roc_curve,  auc
from scipy.interpolate import interp1d
from scipy.optimize import brentq

def calculate_accuracy(threshold, dist, actual_issame):
    predict_issame = np.less(1-dist, 1-threshold)
    tp = np.sum(np.logical_and(predict_issame, actual_issame))
    fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))
    tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame)))
    fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))
    tpr = 0 if (tp +fn==0) else float(tp) / float(tp +fn)
    fpr = 0 if (fp +tn==0) else float(fp) / float(fp +tn)
    acc = float(tp +tn ) /dist.shape[0]
    return tpr, fpr, acc

def eer_auc(y, y_score):
    fpr, tpr, _ = roc_curve(y, y_score, pos_label=1)
    eer = brentq(lambda x : 1. - x - interp1d(fpr, tpr)(x), 0., 1.)
    AUC = auc(fpr, tpr)
    return eer, AUC

def get_metrics(pred, gt, thre):
    gt_bool = (gt>0.5)
    _,_,ACC = calculate_accuracy(thre, pred, gt_bool)
    _, AUC = eer_auc(gt, pred)
    return AUC, ACC


from subfind_provider_subscene import get_short_lang

__author__ = 'hiepsimu'
import logging
import unittest

logging.basicConfig(level=logging.DEBUG)

class LangTestCase(unittest.TestCase):
    def test_01(self):
        self.assertEqual('vi', get_short_lang('vietnamese'))
        self.assertEqual('vi', get_short_lang('Vietnamese'))
        self.assertEqual('en', get_short_lang('English'))
        self.assertEqual(None, get_short_lang('InvalidLang'))

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


from Code.Scripts.popularity_calculator import calculate_popularity,freq_of_popularity
import xlrd
import matplotlib.pyplot as plt

file_name = 'D:\\Users\\yashk\\Campaign-Assistant\\Data\\Annotated\\graph_month_input.xls'
workbook = xlrd.open_workbook(file_name)
sheet = workbook.sheet_by_index(0)
rows = sheet.nrows
print(rows)
month = {}
for i in range(1,rows):
    month_value = sheet.cell_value(i,1)
    if month_value not in month.keys():
        month[month_value] = [sheet.cell_value(i,0)]
    else:
        month[month_value].append(sheet.cell_value(i,0))
print(month[1])
print(month[2])
print(month[3])
x_axis = [1,2,3]
month1 = freq_of_popularity(month[1])
month2 = freq_of_popularity(month[2])
month3 = freq_of_popularity(month[3])
y_axis = [calculate_popularity(month1['pos'],month1['nut'],month1['neg'],month1['nut']),
          calculate_popularity(month2['pos'],month2['nut'],month2['neg'],month2['nut']),
          calculate_popularity(month3['pos'],month3['nut'],month3['neg'],month3['nut'])
          ]
print(x_axis)
print(y_axis)
plt.plot(x_axis,[item*100 for item in y_axis])
plt.show()


import http.client

# Create a large sample HTTP request with a size larger than 1024 bytes
large_request = "GET /example HTTP/1.1\r\n" + ("X" * 1500)  # Total size exceeds 1024 bytes

# Set up the HTTP connection to your server
conn = http.client.HTTPConnection("localhost", 6789)  # Replace with your server's host and port

# Send the large request to the server
conn.request("GET", "/", large_request)
response = conn.getresponse()

# Read and print the response from the server
print(response.read().decode())

# Close the connection
conn.close()


import pytest
import struct
import json
import os.path
from iotile.core.hw.hwmanager import HardwareManager
from iotile.core.dev.registry import ComponentRegistry
from iotile.core.hw.exceptions import RPCNotFoundError, RPCInvalidArgumentsError
from typedargs.exceptions import KeyValueException
from iotile.core.hw.virtual import VirtualTile

@pytest.fixture
def registry():
    reg = ComponentRegistry()
    reg.clear()
    reg.clear_components()
    path = os.path.join(os.path.dirname(__file__), 'rpc_proxy.py')
    reg.register_extension('iotile.proxy', 'virtual_tile', path)

    yield reg

@pytest.fixture
def p(tmpdir):

    path = os.path.join(os.path.dirname(__file__), 'rpc_device.py')
    config = {
        "device":
            {
                "tiles":
                    [
                        {
                            "address": 10,
                            "name": path,
                            "args": {}
                        }
                    ],
                "iotile_id": 1
            }
    }

    config_path_obj = tmpdir.join('tasks.json')
    config_path_obj.write(json.dumps(config))

    config_path = str(config_path_obj)

    hw = HardwareManager(port='virtual:tile_based@%s' % config_path)
    hw.connect_direct(1)
    tile = hw.get(10)
    yield tile
    hw.disconnect()

def test_add_rpc(registry, p):
    res1 = p.test_add_v1(1, 2)
    assert res1 == 3
    res2 = p.test_add_v2(1, 2)
    assert res2 == 3

def test_null_rpc(registry, p):
    p.test_null_v1()
    p.test_null_v2()

def test_invalid_rpc_args_length(registry, p):
    with pytest.raises(RPCInvalidArgumentsError) as e:
        p.test_invalid_arg_length_rpc_v2()
    assert e.type == RPCInvalidArgumentsError

    with pytest.raises(RPCInvalidArgumentsError):
        p.test_invalid_arg_length_rpc_v1()

def test_invalid_rpc_args(registry, p):
    with pytest.raises(RPCInvalidArgumentsError) as e:
        p.test_invalid_args_missing_rpc_v2()
    assert e.type == RPCInvalidArgumentsError

    with pytest.raises(RPCInvalidArgumentsError) as e:
        p.test_invalid_args_missing_rpc_v1()
    assert e.type == RPCInvalidArgumentsError

def test_rpc_does_not_exist(registry, p):
    with pytest.raises(RPCNotFoundError) as e:
        p.test_rpc_does_not_exist_v1()
    assert e.type == RPCNotFoundError

    with pytest.raises(RPCNotFoundError) as e:
        p.test_rpc_does_not_exist_v2()
    assert e.type == RPCNotFoundError


from math import factorial as fact
import common as c

'''
main block that uses is_strong() to check if its strong number
'''
def main() :
    num = c.read('Enter the number.\n')
    if is_strong(num) :
        print(f'{num} is a strong number.')
    else :
        print(f'{num} isn\'t a strong number.')

# is_strong() returns if true or false based on caluclate result from calculate()
def is_strong(num:int)-> bool:
    if calculate(num) == num:
        return True
    return False

# does necessary calculation for finding if it is a strong number
def calculate(num:int)-> int:
    res = 0
    while num :
        res = c.add(res, fact(c.digit_retriver(num)))
        num = c.num_truncate(num)
    return res

if __name__ == '__main__' :
    main()


from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from meals.models import Meals
from order.models import orderDetail

# Create your views here.

@login_required
def add_user_order(request):
    count_product = int(request.POST.get("count"))
    product_ID = request.POST.get("product_id")
    product = Meals.objects.filter(id=product_ID).first()
    orderDetail.objects.create(name=product.slug, price=product.price, count=count_product)
    return redirect("/meals")

def order_list(request):
    count = 0
    for order in orderDetail.objects.all():
        count += (int(float(order.price)) * int(float(order.count)))

    context= {
        "orderlist" : orderDetail.objects.all(),
        "all_food":count
    }
    return render(request, "orderlist.html", context)


import asyncio

import aioconsole
import json
from abc import abstractmethod
from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import FormattedText
from monstr.event.event import Event
from monstr.encrypt import Keys
from monstr.inbox import Inbox
from monstr.client.client import Client
from monstr.ident.profile import Profile, NIP5Helper, NIP5Error
from monstr.ident.event_handlers import ProfileEventHandler
from monstr.signing import SignerInterface
from monstr.entities import Entities
from monstr.util import util_funcs

class EventPrinter:

    # print the event
    @abstractmethod
    async def aprint_event(self, the_client: Client, sub_id, evt: Event):
        pass

    # any other msgs
    @abstractmethod
    async def astatus(self, status: str):
        pass

class WrappedEventPrinter(EventPrinter):
    """
        support events that have been wrapped inside a public inbox
        also adds method for getting the decrypted content of an event
    """
    def __init__(self,
                 as_sign: SignerInterface = None,
                 inboxes: [Inbox] = None,
                 # kinds to output - probably a filter would be more flexible here... None will not restrict at all
                 kinds: {int} = None,
                 # kinds that we'll be decrypted
                 encrypted_kinds: {int} = None
                 ):

        # if given will be used for decrypting
        self._as_sign = as_sign

        self._inboxes = inboxes
        # lookups for dealing with inboxes
        c_i: Inbox
        self._inbox_view_keys = {}
        self._inbox_decode_map = {}

        asyncio.create_task(self._ready_inboxes())

        self._kinds = kinds

        self._encrypted_kinds = {}
        # by default nothing will be decrypted - probably at least want to set as {Event.KIND_ENCRYPT}
        if encrypted_kinds is not None:
            self._encrypted_kinds = encrypted_kinds

        self._ready = False

    async def wait_ready(self):
        while not self._ready:
            await asyncio.sleep(0.1)

    async def _ready_inboxes(self):
        # lookups for dealing with inboxes
        if self._inboxes:
            c_i: Inbox
            self._inbox_view_keys = {await c_i.pub_key for c_i in self._inboxes}
            self._inbox_decode_map = {await c_i.pub_key: c_i for c_i in self._inboxes}
        self._ready = True

    def event_needs_unwrap(self, evt: Event) -> bool:
        return evt.pub_key in self._inbox_view_keys

    async def get_unwrapped_event(self, evt) -> Event:
        """
        unwraps evt, if unable you just get the orignal event back
        if you need to know that you have an event that needed unwrapping and it failed you can check

        if event_needs_unwrap(evt) is True and evt.id == ret.id then we failed to unwrap an event that needed unwrap

        :param evt:
        :return:
        """

        ret = evt
        if self.event_needs_unwrap(evt):
            unwrapped_evt = await self._inbox_decode_map[evt.pub_key].unwrap_event(evt=evt,
                                                                                user_sign=self._as_sign)
            if unwrapped_evt:
                ret = unwrapped_evt

        return ret

    def event_needs_decrypt(self, evt: Event) -> bool:
        # if we've been given a signer and the event is in kinds we have been told are encrypted
        # we'll attempt to decrypt it with _as_sign
        return self._as_sign and evt.kind in self._encrypted_kinds

    async def get_decrypted_event(self, evt: Event) -> Event:
        """
        decrypts evt, if unable you just get the orignal event back
        checking failed to decrypt works same as unwrap except you need to compare the event content
        :param evt:
        :return:
        """
        # copy the event so we're working on a new obj
        ret = Event.from_JSON(evt.event_data())

        if self.event_needs_decrypt(evt):
            # for the public key we'll try all p_tags and the events public key with
            # are priv key, so we have a chance to decrypt non standard events also
            # we just exit first time we don't cause exception
            # (Like we produce from poster)
            for c_p_tag in [evt.pub_key] + evt.p_tags:
                try:
                    ret.content = await self._as_sign.decrypt_text(encrypt_text=ret.content,
                                                                   for_pub_k=c_p_tag)
                    # if we got here then we manage to decrypt so exit
                    break
                except Exception as e:

                    pass

        return ret

    # will we output the event? This probably is mainly useful if dealing with wrapped events
    # where we may want to check again that they pass some filter after unwrapping
    def output_event(self, evt: Event) -> bool:
        return self._kinds is None or evt.kind in self._kinds

    # print the event
    async def aprint_event(self, the_client: Client, sub_id, evt: Event):
        # you probably want to override this
        aioconsole.aprint(await self.get_unwrapped_event(evt))

    # any other msgs
    @abstractmethod
    async def astatus(self, status: str):
        return

class JSONPrinter(WrappedEventPrinter):

    def __init__(self,
                 as_sign: SignerInterface = None,
                 inboxes: [Inbox] = None,
                 kinds=None,
                 encrypted_kinds: set = None
                 ):

        super().__init__(as_sign=as_sign,
                         inboxes=inboxes,
                         encrypted_kinds=encrypted_kinds)

    # outputs event in raw format
    async def aprint_event(self, the_client: Client, sub_id, evt: Event):
        # unwrap and decrypt event as required - if unable or uneeded left as is
        evt = await self.get_unwrapped_event(evt)
        if self.output_event(evt):
            evt = await self.get_decrypted_event(evt)
            await aioconsole.aprint(json.dumps(evt.event_data()))

    async def astatus(self, status: str):
        return

class ContentPrinter(WrappedEventPrinter):

    def __init__(self,
                 as_sign:SignerInterface = None,
                 inboxes: [Inbox] = None,
                 kinds=None,
                 encrypted_kinds: set = None
                 ):

        super().__init__(as_sign=as_sign,
                         inboxes=inboxes,
                         kinds=kinds,
                         encrypted_kinds=encrypted_kinds)

    # output just the content of an event
    async def aprint_event(self, the_client: Client, sub_id, evt: Event):
        # unwrap and decrypt event as required - if unable or uneeded left as is
        evt = await self.get_unwrapped_event(evt)
        if self.output_event(evt):
            evt = await self.get_decrypted_event(evt)
            content = evt.content
            await aioconsole.aprint(content)

    async def astatus(self, status: str):
        await aioconsole.aprint(status)

class FormattedEventPrinter(WrappedEventPrinter):

    def __init__(self,
                 profile_handler: ProfileEventHandler,
                 as_user: Profile = None,
                 as_sign: SignerInterface = None,
                 inboxes: [Inbox] = None,
                 show_pub_key: bool = False,
                 show_tags: [str] = None,
                 entities: bool = False,
                 nip5helper: NIP5Helper = None,
                 kinds=None,
                 encrypted_kinds=None):

        self._profile_handler = profile_handler

        self._as_user = as_user

        # styles for colouring user output
        # us
        self._as_user_style = 'bold ForestGreen'
        # someone we follow
        self._as_user_contact_style = 'ForestGreen'
        # anyone else
        self._as_user_non_contact_style = 'FireBrick bold'

        # output npub, note instead of hex for event_id and pks
        self._entities = entities

        # at end show pubkey
        self._show_pub_key = show_pub_key
        # output these tags or all if ['*']
        self._show_tags = show_tags
        if self._show_tags:
            self._show_tags = set(self._show_tags)

        # if supplied then any nip5s will be checked and colored green if good
        self._nip5helper = nip5helper
        # styles used when checking nip5s
        self._nip5_valid_style = 'ForestGreen'
        self._nip5_invalid_style = 'FireBrick bold'

        # events that we expect to be encrypted
        self._encrypted_kinds = encrypted_kinds
        if self._encrypted_kinds is None:
            self._encrypted_kinds = {Event.KIND_ENCRYPT}

        super().__init__(as_sign=as_sign,
                         inboxes=inboxes,
                         kinds=kinds,
                         encrypted_kinds=encrypted_kinds)

    async def aprint_event(self, the_client: Client, sub_id, evt: Event):
        unwrapped_evt = evt
        if self.event_needs_unwrap(evt):
            unwrapped_evt = await self.get_unwrapped_event(evt)

        if self.output_event(unwrapped_evt):
            print_formatted_text(FormattedText(await self.get_event_header(evt)))
            print_formatted_text(FormattedText(await self.get_event_content(evt, unwrapped_evt)))
            print_formatted_text(FormattedText(await self.get_event_footer(evt)))

    async def astatus(self, status: str):
        # anything thats not the event
        await aioconsole.aprint(status)

    async def _get_profile(self, key) -> Profile:
        # will error if key is not valid, doesn't break anything for us but maybe we should fix?
        ret = (await self._profile_handler.aget_profiles(pub_ks=key,
                                                         create_missing=True))[0]
        return ret

    def _is_user(self, key):
        return self._as_user is not None and self._as_user.public_key == key

    async def _is_contact(self, key):
        ret = False
        if self._as_user is not None:
            if not self._as_user.contacts_is_set():
                await self._profile_handler.aload_contacts(self._as_user)
            ret = key in self._as_user.contacts.follow_keys()

        return ret

    async def _get_pub_k_style(self, pub_k):
        ret = ''
        # no styling if no as_user
        if self._as_user:
            if self._is_user(pub_k):
                ret = self._as_user_style
            elif await self._is_contact(pub_k):
                ret = self._as_user_contact_style
            else:
                ret = self._as_user_non_contact_style

        return ret

    async def get_event_header(self,
                                     evt: Event,
                                     depth=0) -> []:
        p: Profile

        txt_arr = []
        depth_align = ''.join(['\t'] * depth)
        txt_arr.append(('', '\n%s--- ' % depth_align))
        create_p = await self._get_profile(evt.pub_key)

        style = await self._get_pub_k_style(evt.pub_key)

        name = create_p.name

        nip05_domain = None
        name_nip05match = False

        if create_p.nip05:
            nip05_split = create_p.nip05.split('@')
            if len(nip05_split) > 1:
                nip05_name = nip05_split[0]
                nip05_domain = nip05_split[1]
                if name is None and nip05_domain:
                    name = nip05_name
                name_nip05match = name.lower() == nip05_name.lower() or nip05_name == '_'

        if name is None or name.replace(' ', '') == '':
            name = util_funcs.str_tails(create_p.public_key)

        txt_arr.append((style, name))

        # nip5 info if any
        if create_p.nip05:
            nip5_style = ''

            if self._nip5helper:
                nip5_style = self._nip5_invalid_style
                try:
                    if await self._nip5helper.is_valid(create_p.nip05, create_p.public_key):
                        nip5_style = self._nip5_valid_style
                except NIP5Error as ne:
                    pass

            if name_nip05match:
                txt_arr.append((nip5_style, f'@{nip05_domain}'))
            else:
                txt_arr.append((nip5_style, f' ({create_p.nip05})'))

        txt_arr.append(('', ' ---'))

        to_list = []
        sep = False

        # this will force fetch if needed all the profiles we need
        # so that a fetch won't be made in the next loop for each p tag
        await self._profile_handler.aget_profiles(pub_ks=[pk for pk in evt.p_tags],
                                                 create_missing=True)

        for c_pk in evt.p_tags:
            style = await self._get_pub_k_style(c_pk)

            to_p = await self._get_profile(c_pk)
            if sep:
                to_list.append(('', ', '))

            to_list.append((style, to_p.display_name()))

            sep = True

        if to_list:
            txt_arr.append(('', '\n%s-> ' % depth_align, ))
            txt_arr = txt_arr + to_list

        subject_tags = evt.get_tags_value('subject')
        if subject_tags:
            txt_arr.append(('', '\n%s' % depth_align))
            txt_arr.append(('', '[subject - %s]' % ','.join(subject_tags)))

        txt_arr.append(('','\n%s' % depth_align))

        id = evt.id
        if self._entities:
            id = Entities.encode('note', id)

        txt_arr.append(('cyan', id))
        txt_arr.append(('','@'))
        txt_arr.append(('', '%s' % evt.created_at))

        # extra kind specific header
        if evt.kind == Event.KIND_CHANNEL_MESSAGE and evt.e_tags:
            txt_arr.append(('', f'\nchannel: {evt.e_tags[0]}'))

        return txt_arr

    async def get_event_footer(self,
                               evt: Event,
                               depth=0):

        txt_arr = []
        depth_align = ''.join(['\t'] * depth)

        if self._show_pub_key:
            txt_arr.append(('', f'\n{depth_align}'))
            txt_arr.append(('cyan', '-pubkey-\n'))
            out_pk = evt.pub_key
            if self._entities:
                out_pk = Entities.encode('npub', out_pk)
            txt_arr.append(('', depth_align))
            txt_arr.append((await self._get_pub_k_style(evt.pub_key), f'{out_pk}'))

        if self._show_tags:
            txt_arr.append(('', f'\n{depth_align}'))
            txt_arr.append(('cyan', f'-tags-'))

            all_tag_names = list(evt.tags.tag_names)
            all_tag_names.sort()

            for c_tag_name in all_tag_names:

                if '*' in self._show_tags or c_tag_name in self._show_tags:
                    # tag header
                    txt_arr.append(('cyan', f'\n{depth_align}{c_tag_name}'))

                    # now output values
                    for c_tag_v in evt.get_tags(c_tag_name):
                        v_style = ''
                        if c_tag_name == 'p':
                            v_style = await self._get_pub_k_style(c_tag_v[0])

                        txt_arr.append(('', f'\n{depth_align}['))
                        sep = ''
                        for i, item in enumerate(c_tag_v):
                            item_val = item
                            if self._entities:
                                try:
                                    if c_tag_name == 'p':
                                        item_val = Entities.encode('npub', item_val)
                                    elif c_tag_name == 'e':
                                        item_val = Entities.encode('note', item_val)

                                # invalid data prob?
                                except Exception as e:
                                    pass
                            if c_tag_name == 'p' and i == 0:
                                txt_arr.append((v_style, f'{item_val}'))
                            else:
                                txt_arr.append(('', f'{sep}{item_val}'))
                            sep = ','

                        txt_arr.append(('', ']'))

        # actualy do the output if any
        return txt_arr

    async def highlight_tags(self, evt: Event, default_style='', depth=0):
        replacements = {}
        arr_str = []
        ret = []
        p: Profile
        depth_align = ''.join(['\t'] * depth)

        # map tag replacements, only p tag currently
        # note this is for #[n] style to tags
        # there is also nostr:npub, etc.. maybe that is the new way? should be easy to add also...
        for i, tag_vals in enumerate(evt.tags):
            # def replacement is just grayed of the #[n] text
            r_v = {
                'text': f'#[{i}]',
                'style': 'gray'
            }

            if len(tag_vals) > 1:
                t_n = tag_vals[0]
                t_v = tag_vals[1]
                # we only do p replacements
                if t_n == 'p':
                    if Keys.is_valid_key(t_v):
                        p = await self._get_profile(t_v)

                        r_v = {
                            'text': p.display_name(),
                            'style': await self._get_pub_k_style(t_v)
                        }

                        # add replacements for npub and nostr:npub
                        if p.name:
                            npub = Entities.encode('npub', p.public_key)
                            replacements[f'nostr:{npub}'] = {
                                'text': f' {p.display_name()} ',
                                'style': await self._get_pub_k_style(t_v)
                            }

                replacements[f'#[{i}]'] = r_v

        for c_line in evt.content.splitlines():
            # ret.append(('', '\n'))
            ret.append(('', '\n'+depth_align))
            for c_word in c_line.split(' '):
                if c_word in replacements:
                    if arr_str:
                        ret.append((default_style, ' '.join(arr_str)))
                        arr_str = []

                    # TODO: cols should be based on if we follow
                    replacement = replacements[c_word]
                    ret.append((replacement['style'], replacement['text']))
                else:
                    arr_str.append(c_word)

            if arr_str:
                ret.append((default_style, ' '.join(arr_str)))
                arr_str = []

        return ret

    async def get_event_content(self, evt, unwrapped_evt):
        txt_arr = []
        print_depth = 0
        print_style = 'gray'
        decrypted_evt = await self.get_decrypted_event(unwrapped_evt)
        print_evt = evt
        content_done = False

        # FIXME - works but this logic is pretty crazy
        if self.event_needs_unwrap(evt):
            inbox_p: Profile = await self._get_profile(key=evt.pub_key)
            if evt.id != unwrapped_evt.id:
                print_depth = 1
                if self.event_needs_decrypt(unwrapped_evt):
                    txt_arr.append(('', f'\tencrypted evt in inbox({inbox_p.display_name()})-->'))
                    print_evt = decrypted_evt
                    if decrypted_evt.content != unwrapped_evt.content:
                        print_style = ''

                else:
                    txt_arr.append(('', '\tplaintext evt in inbox(%s)-->' % inbox_p.display_name()))
                    print_style = ''
                    print_evt = unwrapped_evt

                txt_arr += await self.get_event_header(print_evt, depth=print_depth)
                txt_arr += await self.highlight_tags(evt=print_evt,
                                                     default_style=print_style,
                                                     depth=print_depth)
                txt_arr += await self.get_event_footer(evt=print_evt,
                                                       depth=1)
                content_done = True

            else:
                txt_arr.append(('', f'\tunable to decrypt evt in inbox({inbox_p.display_name()})-->'))

        # basic events not via inbox
        else:
            if self.event_needs_decrypt(evt):
                print_evt = decrypted_evt
                if decrypted_evt.content != evt.content:
                    print_style = ''
            else:
                print_style = ''

        if not content_done:
            txt_arr += await self.highlight_tags(evt=print_evt,
                                                 default_style=print_style,
                                                 depth=print_depth)

        return txt_arr


import os
import tensorflow as tf
import xlsxwriter
from tflite import Model
from tflite.BuiltinOperator import BuiltinOperator

ignore = {
    # TF
    "Placeholder",
    "Const",
    "Identity",
    "Shape",
    "FIFOQueueV2",
    "QueueDequeueManyV2",
    "TensorArrayV3",
    "Enter",
    "Merge",
    "Range",
    "TensorArrayScatterV3",
    "TensorArraySizeV3",
    "TensorArrayReadV3",
    "TensorArrayWriteV3",
    "TensorArrayGatherV3",
    "NextIteration",
    "Less",
    "LoopCond",
    "Pack",
    "Unpack",
    "Switch",
    "Exit",
    "ExpandDims",
    "ZerosLike",
    "Tile",
    "Gather",
    "Assert",
    "Where",
    "TopKV2",
    "Fill",
    "Size",
    "NonMaxSuppressionV2",

    # TFLITE
    "DEQUANTIZE",
    "CUSTOM",
}

opMap = {
    "BiasAdd": "Add",
    "Add": "Add",
    "AddV2": "Add",
    "ADD": "Add",
    "RealDiv": "Div",
    "Equal": "Equal",
    "Exp": "Exp",
    "Greater": "Greater",
    "Mean": "Mean",
    "MEAN": "Mean",
    "Mul": "Mul",
    "MUL": "Mul",
    "Sub": "Sub",
    "SUB": "Sub",
    "Maximum": "Maximum",
    "Minimum": "Minimum",
    "AvgPool": "AvgPool",
    "AVERAGE_POOL_2D": "AvgPool",
    "MaxPool": "MaxPool",
    "MAX_POOL_2D": "MaxPool",
    "FusedBatchNorm": "BatchNorm",
    "FusedBatchNormV3": "BatchNorm",
    "ConcatV2": "Concat",
    "CONCATENATION": "Concat",
    "Cast": "Cast",
    "Conv2D": "Conv",
    "CONV_2D": "Conv",
    "DepthwiseConv2dNative": "GroupConv(Depthwise)",
    "DEPTHWISE_CONV_2D": "GroupConv(Depthwise)",
    "ResizeBilinear": "ResizeBilinear",
    "Relu": "Relu",
    "Relu6": "Relu6",
    "Sigmoid": "Sigmoid",
    "LOGISTIC": "Sigmoid",
    "Reshape": "Reshape",
    "RESHAPE": "Reshape",
    "Transpose": "Transpose",
    "Softmax": "Softmax",
    "SOFTMAX": "Softmax",
    "Squeeze": "Squeeze",
    "Pad": "Pad",
    "PAD": "Pad",
    "StridedSlice": "Slice",
    "Slice": "Slice",
    "Split": "Split",
}

opKey = list(dict.fromkeys(opMap.values()))

def parse_pb(path, worksheet, pos):
    f = open(path, "rb")
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())

    ops = []
    for node in graph_def.node:
        ops.append(node.op)

    #print(path)
    worksheet.write(0, pos[0], os.path.basename(path))
    for op in dict.fromkeys(ops):
        if op not in ignore:
            #print(opMap[op])
            worksheet.write(opKey.index(opMap[op])+1, pos[0], "○")
    pos[0] += 1

def parse_tflite(path, worksheet, pos):
    f = open(path, "rb")
    model = Model.Model.GetRootAsModel(f.read(), 0)

    # Code borrowed from https://github.com/apache/incubator-tvm
    ops = {}
    for field_name in dir(BuiltinOperator):
        if not field_name.startswith('_'):
            field_value = getattr(BuiltinOperator, field_name)
            if isinstance(field_value, int):
                ops[field_value] = field_name

    #print(path)
    worksheet.write(0, pos[0], os.path.basename(path))
    for i in range(0, model.OperatorCodesLength()):
        opcode = model.OperatorCodes(i).BuiltinCode()
        op = ops[opcode]
        if op not in ignore:
            #print(opMap[op])
            worksheet.write(opKey.index(opMap[op])+1, pos[0], "○")
    pos[0] += 1

if __name__ == "__main__":
    workbook = xlsxwriter.Workbook('table.xlsx')
    worksheet = workbook.add_worksheet()
    pos = [0]
    for i, k in enumerate(opKey, start=1):
        worksheet.write(i, pos[0], k)
    pos[0] += 1

    dirname = "models"
    for fname in os.listdir(dirname):
        path = os.path.join(dirname, fname)
        _, ext = os.path.splitext(path)
        if ext == ".pb":
            parse_pb(path, worksheet, pos)
        elif ext == ".tflite":
            parse_tflite(path, worksheet, pos)

    workbook.close()


import schedule
import vars
import time
import win32com.client
import logging
from datetime import datetime
from os import environ

def run_job(url, start_time, end_time):
    logging.info('Start job: %s', url)
    if start_time:
        t_now = datetime.now()
        t_start = datetime.strptime(start_time, '%H:%M')
        t_start = t_now.replace(hour=t_start.hour, minute=t_start.minute)
    else:
        t_start = datetime.min
    if end_time:
        t_end = datetime.strptime(end_time, '%H:%M')
        t_end = t_now.replace(hour=t_end.hour, minute=t_end.minute)
    else:
        t_end = datetime.max
    if (t_now >= t_start) and (t_now <= t_end):
        try:
            helpdesk.open("GET", url, False)
            helpdesk.send()
            logging.debug(helpdesk.responseText)
        except Exception as e:
            logging.error("ERROR: %s", e)
        finally:
            logging.info('Finish job: %s', url)

helpdesk = win32com.client.Dispatch('MSXML2.ServerXMLHTTP')

log_path = '{}\\Telebot\\Logs\\cron.log'.format(environ['PROGRAMDATA'])
logging.basicConfig(
        filename=log_path, format='%(asctime)s:%(process)d:%(levelname)s:%(message)s',
        level=vars.log_level)

fixed_time_jobs = [job for job in vars.crontab if job['interval'] == 0]
for job in fixed_time_jobs:
    logging.info('Found job: Run daily at %s, URL: %s', job['start_time'],
                 'http://{}/{}'.format(vars.server, job['url']))

interval_jobs = [job for job in vars.crontab if job['interval'] > 0]
for job in interval_jobs:
    logging.info('Found job: Run every %s minutes, URL: %s, From: %s, Till: %s', job['interval'],
                 'http://{}/{}'.format(vars.server, job['url']),
                 job['start_time'],
                 job['end_time']
                 )

for job in fixed_time_jobs:
    schedule.every().day.at(job['start_time']).do(
        run_job,
        url='http://{}/{}'.format(vars.server, job['url']),
        start_time=job['start_time'],
        end_time=job['end_time'])

for job in interval_jobs:
    schedule.every(job['interval']).minutes.do(
        run_job,
        url='http://{}/{}'.format(vars.server, job['url']),
        start_time=job['start_time'],
        end_time=job['end_time'])

while True:
    schedule.run_pending()
    time.sleep(1)


# -*- coding: utf-8 -*-
"""Classes for extinction calculation"""
from addict import Dict
from copy import deepcopy
from ELDAmwl.bases.factory import BaseOperation
from ELDAmwl.bases.factory import BaseOperationFactory
from ELDAmwl.component.interface import IExtOp
from ELDAmwl.component.interface import IMonteCarlo
from ELDAmwl.component.registry import registry
from ELDAmwl.extinction.product import Extinctions
from ELDAmwl.extinction.tools.operation import ExtinctionAutosmooth
from ELDAmwl.extinction.tools.operation import SignalSlope
from ELDAmwl.extinction.tools.operation import SlopeToExtinction
from ELDAmwl.utils.constants import ABOVE_MAX_ALT
from ELDAmwl.utils.constants import BELOW_OVL
from ELDAmwl.utils.constants import MC

import numpy as np
import zope

class CalcExtinction(BaseOperationFactory):
    """
    creates a class for the calculation of an extinction coefficient

    Returns an instance of BaseOperation which calculates the particle
    extinction coefficient from a  Raman signal. In this case, it
    will be always an instance of CalcExtinctionDefault().

    Keyword Args:
        ext_params (:class:`ELDAmwl.extinction.params.ExtinctionParams`): \
                retrieval parameter of the extinction product
        slope_routine (:class:`ELDAmwl.bases.factory.BaseOperation`):
            result of :class:`ELDAmwl.extinction.tools.operation.SignalSlope`
        slope_to_ext_routine (:class:`ELDAmwl.bases.factory.BaseOperation`):
            result of :class:`ELDAmwl.extinction.tools.operation.SlopeToExtinction`
        raman_signal (:class:`ELDAmwl.signals.Signals`): Raman signal
        empty_ext (:class:`ELDAmwl.extinction.product.Extinctions`): \
                instance of Extinctions which has all meta data but profile data are empty arrays

    Returns:
        instance of :class:`ELDAmwl.bases.factory.BaseOperation`

    """

    name = 'CalcExtinction'

    def __call__(self, **kwargs):
        assert 'ext_params' in kwargs
        assert 'slope_routine' in kwargs
        assert 'slope_to_ext_routine' in kwargs
        assert 'raman_signal' in kwargs
        assert 'empty_ext' in kwargs

        res = super(CalcExtinction, self).__call__(**kwargs)
        return res

    def get_classname_from_db(self):
        """

        return: always 'CalcExtinctionDefault' .
        """
        return 'CalcExtinctionDefault'

@zope.interface.implementer(IExtOp)
class CalcExtinctionDefault(BaseOperation):
    """
    Calculates particle extinction coefficient from Raman signal.

    The result is a copy of empty_ext, but its dataset (data, err, qf) is filled with the calculated values

    Keyword Args:
        ext_params (:class:`ELDAmwl.extinction.params.ExtinctionParams`): \
                retrieval parameter of the extinction product
        slope_routine (:class:`ELDAmwl.bases.factory.BaseOperation`):
            result of :class:`ELDAmwl.extinction.tools.operation.SignalSlope`
        slope_to_ext_routine (:class:`ELDAmwl.bases.factory.BaseOperation`):
            result of :class:`ELDAmwl.extinction.tools.operation.SlopeToExtinction`
        raman_signal (:class:`ELDAmwl.signals.Signals`): Raman signal
        empty_ext (:class:`ELDAmwl.extinction.product.Extinctions`): \
                instance of Extinctions which has all meta data but profile data are empty arrays

    Returns:
        profiles of particle extinction coefficients(:class:`ELDAmwl.extinction.product.Extinctions`)
    """

    name = 'CalcExtinctionDefault'

    ext_params = None
    signal = None
    slope_routine = None
    slope_to_ext_routine = None
    result = None
    x_data = None
    y_data = None
    yerr_data = None
    qf_data = None

    def __init__(self, **kwargs):
        super(CalcExtinctionDefault, self).__init__(**kwargs)
        self.signal = self.kwargs['raman_signal']
        self.ext_params = self.kwargs['ext_params']
        self.slope_routine = self.kwargs['slope_routine']
        self.slope_to_ext_routine = self.kwargs['slope_to_ext_routine']
        self.result = deepcopy(self.kwargs['empty_ext'])

    def calc_slope(self, t, lev, window, half_win):
        fb = lev - half_win
        lb = lev + half_win
        window_data = Dict({'x_data': self.x_data[t, fb:lb + 1],
                            'y_data': self.y_data[t, fb:lb + 1],
                            'yerr_data': self.yerr_data[t, fb:lb + 1],
                            })

        sig_slope = self.slope_routine.run(signal=window_data)
        qf = np.bitwise_or.reduce(self.qf_data[t, fb:lb + 1])

        self.result.ds['data'][t, lev] = sig_slope.slope
        self.result.ds['err'][t, lev] = sig_slope.slope_err
        self.result.ds['qf'][t, lev] = qf
        self.result.ds['binres'][t, lev] = window

    def prepare_data(self, data):
        self.x_data = np.array(data.range)
        self.y_data = np.array(data.ds.data)
        self.yerr_data = np.array(data.ds.err)
        self.qf_data = np.array(data.ds.qf)

    def calc_single_profile(self, t, data):
        fvb = data.first_valid_bin(t)
        lvb = data.last_valid_bin(t)
        for lev in range(fvb, lvb):
            window = int(data.ds.binres[t, lev])
            half_win = window // 2

            if lev < (fvb + half_win):
                self.result.set_invalid_point(t, lev, BELOW_OVL)

            elif lev >= (lvb - half_win):
                self.result.set_invalid_point(t, lev, ABOVE_MAX_ALT)

            else:
                self.calc_slope(t, lev, window, half_win)

    def run(self, data=None):
        """
        run the extinction calculation

        The the optional keyword arg 'data' allows to feed new raman signals into
        an existing instance of CalcExtinctionDefault and run a new calculation.
        This feature is used e.g., for Monte-Carlo error retrievals

        Keyword Args:
            data (:class:`ELDAmwl.signals.Signals`): Raman signal, default=None

        Returns:
            profiles of particle extinction coefficients(:class:`ELDAmwl.extinction.product.Extinctions`)

        """
        if data is None:
            data = self.signal

        self.prepare_data(data)

        for t in range(data.num_times):
            self.calc_single_profile(t, data)

        # extract relevant parameter for calculation of ext from signal slope
        # from ExtinctionParams into Dict
        param_dct = Dict({
            'detection_wavelength': data.detection_wavelength,
            'emission_wavelength': data.emission_wavelength,
            'angstroem_exponent': self.ext_params.ang_exp_asDataArray,
        })

        # SlopeToExtinction converts the slope into extinction coefficients
        self.slope_to_ext_routine(
            slope=self.result.ds,
            ext_params=param_dct).run()

        return self.result

class ExtinctionFactory(BaseOperationFactory):
    """
    optional argument resolution, can be LOWRES(=0) or HIGHRES(=1)
    """

    name = 'ExtinctionFactory'

    def __call__(self, **kwargs):
        assert 'data_storage' in kwargs
        assert 'ext_param' in kwargs
        assert 'autosmooth' in kwargs
        res = super(ExtinctionFactory, self).__call__(**kwargs)
        return res

    def get_classname_from_db(self):
        """

        return: always 'ExtinctionFactoryDefault' .
        """
        return ExtinctionFactoryDefault.__name__

class ExtinctionFactoryDefault(BaseOperation):
    """
    derives particle extinction coefficient.
    """

    name = 'ExtinctionFactoryDefault'
    param = None
    raman_sig = None
    smooth_res = None
    empty_ext = None
    prod_id = None
    resolution = None

    def get_smooth_res(self):
        if self.kwargs['autosmooth']:
            result = ExtinctionAutosmooth()(
                signal=self.raman_sig.ds,
                smooth_params=self.param.smooth_params,
            ).run()

        else:
            result = self.data_storage.binres_common_smooth(self.prod_id, self.resolution)

        self.smooth_res = result

    def prepare(self):
        self.param = self.kwargs['ext_param']
        self.prod_id = self.param.prod_id_str
        self.resolution = self.kwargs['resolution']

        # raman_sig is a deepcopy from data_storage
        self.raman_sig = self.data_storage.prepared_signal(
            self.param.prod_id_str,
            self.param.raman_sig_id_str)

        self.get_smooth_res()

        self.raman_sig.ds['binres'] = self.smooth_res

        self.empty_ext = Extinctions.init(self.raman_sig, self.param)

    def get_non_merge_product(self):

        calc_routine = CalcExtinction()(
            ext_params=self.param,
            slope_routine=SignalSlope()(prod_id=self.prod_id),
            slope_to_ext_routine=SlopeToExtinction(),
            raman_signal=self.raman_sig,
            empty_ext=self.empty_ext,
        )
        ext = calc_routine.run()

        if self.param.error_method == MC:
            adapter = zope.component.getAdapter(calc_routine, IMonteCarlo)
            ext.err[:] = adapter(self.param.mc_params)
        else:
            ext = ext

        del self.raman_sig
        return ext

    def get_product(self):
        self.prepare()

        if not self.param.includes_product_merging():
            ext = self.get_non_merge_product()
        else:
            # todo: result = Extinctions.from_merged_signals()
            ext = None
            pass

        return ext

registry.register_class(ExtinctionFactory,
                        ExtinctionFactoryDefault.__name__,
                        ExtinctionFactoryDefault)

registry.register_class(CalcExtinction,
                        CalcExtinctionDefault.__name__,
                        CalcExtinctionDefault)


"""website URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
    openapi.Info(
        title="API Блога",
        default_version="v1",
        description="Простой блог на Django и Django Rest Framework",
        # terms_of_service="https://www.google.com/policies/terms/",
        contact=openapi.Contact(email="darkus007@yandex.ru"),
        # license=openapi.License(name="BSD License"),
    ), public=True, permission_classes=[permissions.AllowAny, ],
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include('blog.urls')),
    path('api-auth/', include('rest_framework.urls')),  # добавляем вход и выход посредствам rest_framework
    path('api/v1/dj-rest-auth/', include('dj_rest_auth.urls')),     # адрес может быть любой
    # добавляем регистрацию пользователей
    path('api/v1/dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')),

    # Добавляем документацию
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]


from robotide.lib.robot.utils import seq2str
from robotide.lib.robot.errors import DataError

from .visitor import SuiteVisitor

class SuiteConfigurer(SuiteVisitor):

    def __init__(self, name=None, doc=None, metadata=None, set_tags=None,
                 include_tags=None, exclude_tags=None, include_suites=None,
                 include_tests=None, empty_suite_ok=False):
        self.name = name
        self.doc = doc
        self.metadata = metadata
        self.set_tags = set_tags or []
        self.include_tags = include_tags
        self.exclude_tags = exclude_tags
        self.include_suites = include_suites
        self.include_tests = include_tests
        self.empty_suite_ok = empty_suite_ok

    @property
    def add_tags(self):
        return [t for t in self.set_tags if not t.startswith('-')]

    @property
    def remove_tags(self):
        return [t[1:] for t in self.set_tags if t.startswith('-')]

    def visit_suite(self, suite):
        self._set_suite_attributes(suite)
        self._filter(suite)
        suite.set_tags(self.add_tags, self.remove_tags)

    def _set_suite_attributes(self, suite):
        if self.name:
            suite.name = self.name
        if self.doc:
            suite.doc = self.doc
        if self.metadata:
            suite.metadata.update(self.metadata)

    def _filter(self, suite):
        name = suite.name
        suite.filter(self.include_suites, self.include_tests,
                     self.include_tags, self.exclude_tags)
        if not (suite.test_count or self.empty_suite_ok):
            self._raise_no_tests_error(name, suite.rpa)

    def _raise_no_tests_error(self, suite, rpa=False):
        parts = ['tests' if not rpa else 'tasks',
                 self._get_test_selector_msgs(),
                 self._get_suite_selector_msg()]
        raise DataError("Suite '%s' contains no %s."
                        % (suite, ' '.join(p for p in parts if p)))

    def _get_test_selector_msgs(self):
        parts = []
        for explanation, selector in [('matching tags', self.include_tags),
                                      ('not matching tags', self.exclude_tags),
                                      ('matching name', self.include_tests)]:
            if selector:
                parts.append(self._format_selector_msg(explanation, selector))
        return seq2str(parts, quote='')

    def _format_selector_msg(self, explanation, selector):
        if len(selector) == 1 and explanation[-1] == 's':
            explanation = explanation[:-1]
        return '%s %s' % (explanation, seq2str(selector, lastsep=' or '))

    def _get_suite_selector_msg(self):
        if not self.include_suites:
            return ''
        return self._format_selector_msg('in suites', self.include_suites)


from pathlib import Path
import numpy as np
import re
from collections import defaultdict
import re
from collections import deque

reg = re.compile(
    r"p=< *(-?\d+), *(-?\d+), *(-?\d+)>, v=< *(-?\d+), *(-?\d+), *(-?\d+)>, a=< *(-?\d+), *(-?\d+), *(-?\d+)>"
)

def man_dist(v):
    return np.sum(np.abs(v))

def vel_crit(a,v):
    s = np.sign(a)
    crit = np.sum(s*v)
    crit += np.sum(np.where(a==0,1,0)*np.abs(v))
    return  crit

class Particles:
    def __init__(self, data):
        p = []
        v = []
        a = []
        for line in data.split("\n"):
            p.append([int(d) for d in reg.match(line).group(1, 2, 3)])
            v.append([int(d) for d in reg.match(line).group(4, 5, 6)])
            a.append([int(d) for d in reg.match(line).group(7, 8, 9)])
        self.n = len(a)
        self.p = np.array(p, dtype=int)
        self.v = np.array(v, dtype=int)
        self.a = np.array(a, dtype=int)

    def step(self):
        self.v += self.a
        self.p += self.v

    def resolve_col(self):
        index = np.full(self.n,fill_value=False,dtype=bool)
        for i in range(1,self.n):
            idx = np.r_[i:self.n,0:i]
            collision = np.all(self.p == self.p[idx],axis=1)
            index = np.logical_or(index,collision)
        self.p = self.p[~index]
        self.v = self.v[~index]
        self.a = self.a[~index]

        self.n = np.sum(~index)

    def n_possible_collisions(self):
        possible_collisons = 0
        for i in range(1,self.n):
            idx = np.r_[i:self.n,0:i]
            p_s = self.p<self.p[idx]
            v_s = self.v<=self.v[idx]
            a_s = self.a<=self.a[idx]
            left_not_collision = np.stack((p_s,v_s,a_s),axis=-1)
            left_not_collision = np.all(left_not_collision,axis=2)
            left_not_collision = np.any(left_not_collision,axis=1)

            p_s = self.p>self.p[idx]
            v_s = self.v>=self.v[idx]
            a_s = self.a>=self.a[idx]
            right_not_collision = np.stack((p_s,v_s,a_s),axis=-1)
            right_not_collision = np.all(right_not_collision ,axis=2)
            right_not_collision = np.any(right_not_collision ,axis=1)

            not_collision = np.logical_or(left_not_collision,right_not_collision)
            possible_collisons += np.sum(~not_collision)
        return possible_collisons

    def evolve_until_collisions(self):
        self.resolve_col()
        while self.n_possible_collisions() > 0:
            self.step()
            self.resolve_col()

    def find_closest_particle(self):
        min_ind = 0
        min_a = man_dist(self.a[0])
        min_v = vel_crit(self.a[0],self.v[0])
        for i in range(1, self.n):
            a_norm = man_dist(self.a[i])
            v_crit = vel_crit(self.a[i],self.v[i])
            if (a_norm < min_a) or ((a_norm == min_a) and (v_crit < min_v)):
                min_a = a_norm
                min_v = v_crit
                min_ind = i
                duplicate_min = 1
            elif (a_norm == min_a) and (v_crit == min_v):
                duplicate_min += 1
        if duplicate_min > 1:
            raise RuntimeError("Unable to find a unique minimum")
        return min_ind

def main():
    data_folder = Path(".").resolve()
    data = data_folder.joinpath("input.txt").read_text()
    par = Particles(data)
    print("Part 1")
    print(
        f"The {par.find_closest_particle()}th particle will stay closest to <0,0,0> in the long term"
    )
    print()

    print("Part 2")
    par.evolve_until_collisions()
    print(f"{par.n} particles remain after all collisions are resolved")

if __name__ == "__main__":
    main()


import requests
import os
import subprocess

def download_file(url, local_fname=None, force_write=False):
    if local_fname is None:
        local_fname = url.split('/')[-1]
    if not force_write and os.path.exists(local_fname):
        return local_fname

    r = requests.get(url, stream=True)
    assert r.status_code == 200, "failed to open %s" % url
    with open(local_fname, 'wb') as f:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk: # filter out keep-alive new chunks
                f.write(chunk)
    return local_fname

def get_gpus():
    """
    return a list of GPUs
    """
    try:
        re = subprocess.check_output(["nvidia-smi", "-L"], universal_newlines=True)
    except OSError:
        return []
    return range(len([i for i in re.split('\n') if 'GPU' in i]))


# -*- coding: utf-8 -*-
from node.test.base_test import BaseTestCase
from node.plugins.uptime import Plugin
from mock import Mock, patch

class UptimeTest(BaseTestCase):

    def set_up_mock(self, filemock):
        fs_mock = Mock()
        filemock.return_value = fs_mock
        fs_mock.readline.return_value = '344.12 422.12\n'
        data = Plugin.data()
        return data

    @patch('__builtin__.file')
    def test_plugin_open_uptime_file(self, filemock):
        fs_mock = Mock()
        filemock.return_value = fs_mock
        fs_mock.readline.return_value = '342.11 423.12\n'
        Plugin.data()
        filemock.assert_called_with('/proc/uptime')

    @patch('__builtin__.file')
    def test_plugin_correct_parse_uptime_file(self, filemock):
        data = self.set_up_mock(filemock)
        self.assertEqual(data, 344.12)

    @patch('__builtin__.file')
    def test_plugin_generate_correct_output(self, filemock):
        data = self.set_up_mock(filemock)
        self.assertTrue(isinstance(data, float))


import requests
from random import randint
class Person:

    def __init__(self,imya="", falimia="", login="", parol=""):
        self.__data = requests.get("https://api.randomdatatools.ru/").json()
        self.__lorem="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tempor dictum quam, ut tincidunt purus vestibulum sed. Proin mattis hendrerit pharetra. Cras fermentum est magna, ac congue enim bibendum in. Curabitur luctus fermentum lacus, ac laoreet augue tempus a. Sed tempus vulputate ornare. Phasellus accumsan volutpat urna sed pretium. Mauris."
        self.imya = self.__data['FirstName'] if not imya else imya
        #  имя = случайному если атрибут =""(пустое if not) иначе передаваем
        self.falimia = self.__data['LastName']if not falimia else falimia
        self.login = self.__data['Login']if not login else login
        self.__parol = self.__data['FirstName']if not parol else parol
        self.podpiski = []
        self.podpiskishiki = []
        self.posts = [self.__lorem[randint(1,20):randint(20,40)] for i in range(1, 10)]

    def log_in(self, parol, login):
        if self.login == login and self.__parol == parol:
            return True
        else:
            return False


import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
import datetime as dt

fig=plt.figure()
axl=fig.add_subplot(1,1,1)

ser=serial.Serial("COM4",115200)
beat=[]
avg_beat=[]
xs=[]
ys=[]
y_range=[30,150]

def mov_avg (mylist):
    N = 3
    cumsum, moving_aves = [0], []

    for i, x in enumerate(mylist, 1):
        cumsum.append(cumsum[i-1] + x)
        if i>=N:
            moving_ave = (cumsum[i] - cumsum[i-N])/N
            if (moving_ave)<140:
                moving_aves.append(moving_ave)
    return moving_aves

while 1:
    while(ser.inWaiting() >0):
        def animate(i, xs, ys):
            # Read temperature (Celsius) from TMP102
            #temp_c = round(tmp102.read_temp(), 2)

            dat= round(int(ser.readline()),2)

            beat.append(dat)
            if len(beat)>15:
                beat.pop(0)

            # Add x and y to lists
            xs.append(dt.datetime.now().strftime('%H:%M:%S.%f'))
            ys.append(dat)

            # Limit x and y lists to 20 items
            xs = xs[-20:]
            ys = ys[-20:]

            # Draw x and y lists
            axl.clear()
            axl.plot(xs, ys)

            # Format plot
            plt.xticks(rotation=45, ha='right')
            plt.subplots_adjust(bottom=0.30)
            plt.title('Heart pulse rate moniter')
            plt.ylabel('Heart Pulse')
            axl.set_ylim(y_range)

            print(beat)
            m_beat=mov_avg(mov_avg(beat))

            print (m_beat)

            for i in m_beat:
                if (i>m_beat[(m_beat.index(i))-1] and i>120):
                    plt.text(4,3,"drowsy pulse region",ha='left',fontsize=15,wrap=True)
                    print ('drowsy')
        ani = animation.FuncAnimation(fig, animate, fargs=(xs, ys), interval=1000)
        plt.show()

        ##        ab= sum(beat)/len(beat)
        ##        avg_beat.append(ab)
        ##        for i in avg_beat:
        ##            if i>avg_beat[avg_beat.index(i)-1] and i>135:
        ##                print ('drowsy')


import fcsparser
import numpy as np
from numpy import genfromtxt
from auto_encoder_updated import file_io as io
import os.path
import sklearn.preprocessing as prep
from sklearn.model_selection import train_test_split

class Sample:
    x = None
    y = None

    def __init__(self, x, y=None):
        self.x = x
        self.y = y

def preprocess_samples(sample):
    sample.x = np.log(1 + np.abs(sample.x))
    return sample

def standard_scale(sample, preprocessor=None):
    if preprocessor is None:
        preprocessor = prep.StandardScaler().fit(sample.x)
    sample.x = preprocessor.transform(sample.x)
    return sample, preprocessor

def load_data(data_path, data_index, relevant_markers, mode, skip_header=0):
    if mode == 'CSV':
        data_filename = data_path + '/sample' + str(data_index) + '.csv'
        x = genfromtxt(os.path.join(io.deep_learning_root(), data_filename), delimiter=',', skip_header=skip_header)
    if mode == 'FCS':
        files = [file for file in os.listdir(data_path) if '.fcs' in file]
        data_filename = os.path.join(data_path, files[data_index])
        _, x = fcsparser.parse(os.path.join(io.deep_learning_root(), data_filename), reformat_meta=True)
        x = x.as_matrix()
    x = x[:, relevant_markers]
    #label_filename = data_path + '/labels' + str(data_index) + '.csv'
    #labels = genfromtxt(os.path.join(io.deep_learning_root(), label_filename), delimiter=',')
    #labels = np.int_(labels)
    sample = Sample(x)

    return sample

def load_data_tsv(data_path, data_index, relevant_markers, skip_header=0):
    print('Loading data from .tsv')
    files = [os.path.join(data_path, file) for file in os.listdir(data_path) if '.tsv' in file]
    samples = []
    for i in data_index:
        x = genfromtxt(os.path.join(io.deep_learning_root(), files[i]), delimiter='\t', skip_header=skip_header)
        x = x[:, relevant_markers]
        sample = Sample(x)
        samples.append(sample)
    return samples

def split_data(sample, test_size):
    data_train, data_test, label_train, label_test = train_test_split(sample.x, sample.y, test_size=test_size)

    train_sample = Sample(data_train, label_train)
    test_sample = Sample(data_test, label_test)
    return train_sample, test_sample

def choose_reference_sample(data_path, relevant_markers, mode):
    samples = load_data(data_path, relevant_markers, mode)
    samples = [preprocess_samples(sample) for sample in samples]

    num_samples = len(samples)
    norms = np.zeros(shape=[num_samples, num_samples])
    for i in range(num_samples):
        cov_i = np.cov(samples[i].x, rowvar=False)
        for j in range(num_samples):
            cov_j = np.cov(samples[j].x, rowvar=False)
            cov_diff = cov_i - cov_j
            norms[i, j] = np.linalg.norm(cov_diff, ord='fro')
            norms[j, i] = norms[i, j]
            avg = np.mean(norms, axis=1)
            ref_sample_ind = np.argmin(avg)
    return ref_sample_ind


import datetime
import json
import os

import pandas as pd
import twitter

def create_twitter_api():
    """Check environment and return appropriate twitter API"""

    # API CREDENTIALS
    path = "twitter-credentials.json"
    # if running from local machine
    if os.path.exists(path):
        with open(path, "r") as file:
            creds = json.load(file)
        CONSUMER_KEY = creds['CONSUMER_KEY']
        CONSUMER_SECRET = creds['CONSUMER_SECRET']
        ACCESS_KEY = creds['ACCESS_TOKEN']
        ACCESS_SECRET = creds['ACCESS_SECRET']
    # if running from Heroku
    else:
        CONSUMER_KEY = os.environ['CONSUMER_KEY']
        CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
        ACCESS_KEY = os.environ['ACCESS_TOKEN']
        ACCESS_SECRET = os.environ['ACCESS_SECRET']
    api = twitter.Api(consumer_key=CONSUMER_KEY,
                      consumer_secret=CONSUMER_SECRET,
                      access_token_key=ACCESS_KEY,
                      access_token_secret=ACCESS_SECRET,
                      tweet_mode='extended',
                      sleep_on_rate_limit=True)

    return api

def fix_dates(df):
    """fixes dates for twitter dataframe"""
    df['date_time'] = pd.to_datetime(df['created_at'])
    df['date'] = pd.to_datetime(df['date_time'].dt.date)

    def find_monday(d):
        """Receives a date and returns the date of the preceding Monday."""
        while d.weekday() != 0:
            d += datetime.timedelta(-1)
        return d
    df['date_week'] = df['date'].apply(find_monday)
    return df

def load_tweets(api, user_name, num, n_max_id=0):
    """
    Get raw data from twitter. See api.GetUserTimeline
    https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline.html

    Paramaters
    ----------
    api : twitter.Api
        Twitter api class
    user_name : str
        A twitter handle. Do not include the "@"
    num : int
        The number of tweets to get (max 200)
    n_max_id : int
        Returns only statuses with an ID less than (that is, older than) or
        qual to the specified ID. By default, 0.

    Returns
    -------
    twitter_data
    """
    raw = api.GetUserTimeline(
        screen_name=user_name,
        count=num,
        exclude_replies=True,
        include_rts=False,
        trim_user=True,
        max_id=n_max_id
    )
    return raw

def tweets_get(user_name, num=200, start_date=datetime.date(2019, 9, 11)):
    '''
    Gets tweets and returns a DataFrame.

    Parameters
    ----------
    user_name : str
        The user you would like to get twitter data from (e.g. "JustinTrudeau")
    num : int
        The number of tweets you would like to return (max is 200)
    loops: int
        Because the max number of tweets is only 200, loops will indicate how many sets of "num" tweets you would like to return.
        For example num=200 and loops=2 would get 400 tweets

    Returns
    -------
    Dataframe with twitter data
    '''

    api = create_twitter_api()

    # get the first batch of twitter data
    print(f"Getting tweets for: {user_name}...")
    raw = load_tweets(api=api, user_name=user_name, num=num)
    df = pd.DataFrame.from_dict([i.AsDict() for i in raw])
    df = fix_dates(df)

    # loop through the dataframe x number of times based on the smallest id
    # from the dataframe
    max_id = df['id'].min()-1
    min_date = df['date'].min()
    while min_date > start_date:
        raw = load_tweets(
            api=api, user_name=user_name, num=num, n_max_id=max_id
        )
        temp_df = pd.DataFrame.from_dict([i.AsDict() for i in raw])
        try:
            temp_df = fix_dates(temp_df)
        except KeyError:
            print(f"\terror fixing dates for {user_name}...")
            return df
        df = pd.concat([df, temp_df], sort=False)
        max_id = df['id'].min()-1
        min_date = df['date'].min()

    df = df[df['date'] >= pd.to_datetime(start_date)]
    df = df[df['lang'] == 'en']  # keep only english langauge tweets
    return df


from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from Grid import Grid

class GraphicGrid(object):
    colours = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
    colours_redundant = [el + '--' for el in colours]

    def __init__(self, grid=None, union_find = None, **kwargs):
        self.grid = grid
        if grid != None:
            self.info = grid.State_info(grid, union_find)
        if kwargs.has_key('representations'):
            self.representations = kwargs['representations']
        if kwargs.has_key('zlim'):
            self.zlim = kwargs['zlim']
        else:
            self.zlim = None

    def update_frame(self, framedata, patches, lines, redundant_lines,  axes):
        result = self.update_figures(self.representations[framedata], patches, lines, redundant_lines, axes)
        return result

    def update_figures(self, representation, patches, lines, redundant_lines,  helper_axes):
        xes = [-1]*(representation.dimension**2)
        yes = [-1]*(representation.dimension**2)
        zes = [0]*(representation.dimension**2)
        if len(representation.z_s) > 0:
            zes = representation.z_s

        c = [0]*(representation.dimension**2)

        if len(representation.colours) > 0:
            c = representation.colours

        for index in range(0, representation.dimension ** 2):
                    y, x = self.grid.index_map(index)
                    xes[index] = x
                    yes[index] = y

        helper_axes.cla()
        helper_axes.grid(False)
        if self.zlim != None:
            helper_axes.set_zlim3d([0.0, self.zlim])
        patches = helper_axes.scatter(xes, yes, zes, c=c, s=2.8)

        lines = []
        for connection in representation.connections:
                    points = list(connection)

                    x_f, y_f =  points[0]
                    x_s, y_s = points[1]

                    zf_index, zs_index = self.grid.get_index_by_coords(x_f, y_f), self.grid.get_index_by_coords(x_s, y_s)
                    z_f = zes[zf_index]
                    z_s = zes[zs_index]
                    component_num = c[zf_index]
                    colour = GraphicGrid.colours[component_num%len(GraphicGrid.colours)]
                    lines.append(helper_axes.plot([x_f, x_s], [y_f, y_s], [z_f, z_s], colour, linewidth=0.55))

        redundant_lines = []
        for connection in representation.redundant_connections:
                    points = list(connection)

                    x_f, y_f =  points[0]
                    x_s, y_s = points[1]

                    zf_index, zs_index = self.grid.get_index_by_coords(x_f, y_f), self.grid.get_index_by_coords(x_s, y_s)
                    z_f = zes[zf_index]
                    z_s = zes[zs_index]
                    component_num = c[zf_index]
                    colour = GraphicGrid.colours_redundant[component_num%len(GraphicGrid.colours_redundant)]
                    redundant_lines.append(helper_axes.plot([x_f, x_s], [y_f, y_s], [z_f, z_s], colour, linewidth=0.55))
        return patches, lines, redundant_lines

    def drawGrid_alt(self):
        representation = self.info.get_represantation()
        fig = plt.figure(figsize=(16,9), dpi=200)
        ax = plt.axes(projection='3d')
        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')
        ax.set_title('3D Test')
        patches = ax.scatter(0, 0, 0)
        lines = ax.plot([0, 1], [0, 1], [0, 1], linewidth=0.55)
        redundant = ax.plot([0, 1], [0, 1], [0, 1], linewidth=0.55)
        self.update_figures(representation, patches, lines, redundant, ax)

        plt.show()

gridishe = GraphicGrid(Grid(5), representations=[])

# grid = Grid(5)
# element = 1, 6
# grid.connections.add(element)
# element = 1, 7
# grid.connections.add(element)
# element = 6, 7
# grid.redundant_connections.add(element)
#
# graphical =  GraphicGrid(grid)
# graphical.drawGrid()