#!/usr/bin/env python
# coding: utf-8

# In[4]:

# importing libraries

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

import warnings
warnings.filterwarnings('ignore')

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from lightgbm import LGBMClassifier
from sklearn.metrics import accuracy_score, roc_auc_score, roc_curve, confusion_matrix, auc

# In[5]:

# reading data
df = pd.read_csv('../PROJECT/hotel_bookings.csv')
df.head()

# In[6]:

df.describe()

# In[7]:

df.info()

# In[8]:

# checking for null values

null = pd.DataFrame({'Null Values' : df.isna().sum(), 'Percentage Null Values' : (df.isna().sum()) / (df.shape[0]) * (100)})
null

# In[9]:

# filling null values with zero

df.fillna(0, inplace = True)

# In[11]:

# adults, babies and children cant be zero at same time, so dropping the rows having all these zero at same time

filter = (df.children == 0) & (df.adults == 0) & (df.babies == 0)
df[filter]

# In[12]:

df = df[~filter]
df

# # EDA

# # From where the most guests are coming ?
#
#

# In[13]:

country_wise_guests = df[df['is_canceled'] == 0]['country'].value_counts().reset_index()
country_wise_guests.columns = ['country', 'No of guests']
country_wise_guests

# # How much do guests pay for a room per night?

# In[15]:

df.head()

# # How does the price vary per night over the year

# In[17]:

data_resort = df[(df['hotel'] == 'Resort Hotel') & (df['is_canceled'] == 0)]
data_city = df[(df['hotel'] == 'City Hotel') & (df['is_canceled'] == 0)]

# In[18]:

resort_hotel = data_resort.groupby(['arrival_date_month'])['adr'].mean().reset_index()
resort_hotel

# In[19]:

city_hotel=data_city.groupby(['arrival_date_month'])['adr'].mean().reset_index()
city_hotel

# In[20]:

final_hotel = resort_hotel.merge(city_hotel, on = 'arrival_date_month')
final_hotel.columns = ['month', 'price_for_resort', 'price_for_city_hotel']
final_hotel

# # DATA PRE PROCESSING

# In[21]:

plt.figure(figsize = (24, 12))

corr = df.corr()
sns.heatmap(corr, annot = True, linewidths = 1)
plt.show()

# In[22]:

correlation = df.corr()['is_canceled'].abs().sort_values(ascending = False)
correlation

# In[25]:

# dropping columns that are not useful

useless_col = ['days_in_waiting_list', 'arrival_date_year', 'arrival_date_year', 'assigned_room_type', 'booking_changes',
               'reservation_status', 'country', 'days_in_waiting_list']

df.drop(useless_col, axis = 1, inplace = True)

# In[26]:

df.head()

# In[27]:

# creating numerical and categorical dataframes

cat_cols = [col for col in df.columns if df[col].dtype == 'O']
cat_cols

# In[28]:

cat_df = df[cat_cols]
cat_df.head()

# In[29]:

cat_df['reservation_status_date'] = pd.to_datetime(cat_df['reservation_status_date'])

cat_df['year'] = cat_df['reservation_status_date'].dt.year
cat_df['month'] = cat_df['reservation_status_date'].dt.month
cat_df['day'] = cat_df['reservation_status_date'].dt.day

# In[30]:

cat_df.drop(['reservation_status_date','arrival_date_month'] , axis = 1, inplace = True)

# In[31]:

cat_df.head()

# In[32]:

# printing unique values of each column
for col in cat_df.columns:
    print(f"{col}: \n{cat_df[col].unique()}\n")

# In[33]:

# encoding categorical variables

cat_df['hotel'] = cat_df['hotel'].map({'Resort Hotel' : 0, 'City Hotel' : 1})

cat_df['meal'] = cat_df['meal'].map({'BB' : 0, 'FB': 1, 'HB': 2, 'SC': 3, 'Undefined': 4})

cat_df['market_segment'] = cat_df['market_segment'].map({'Direct': 0, 'Corporate': 1, 'Online TA': 2, 'Offline TA/TO': 3,
                                                           'Complementary': 4, 'Groups': 5, 'Undefined': 6, 'Aviation': 7})

cat_df['distribution_channel'] = cat_df['distribution_channel'].map({'Direct': 0, 'Corporate': 1, 'TA/TO': 2, 'Undefined': 3,
                                                                       'GDS': 4})
cat_df['reserved_room_type'] = cat_df['reserved_room_type'].map({'C': 0, 'A': 1, 'D': 2, 'E': 3, 'G': 4, 'F': 5, 'H': 6,
                                                                   'L': 7, 'B': 8})

cat_df['deposit_type'] = cat_df['deposit_type'].map({'No Deposit': 0, 'Refundable': 1, 'Non Refund': 3})

cat_df['customer_type'] = cat_df['customer_type'].map({'Transient': 0, 'Contract': 1, 'Transient-Party': 2, 'Group': 3})

cat_df['year'] = cat_df['year'].map({2015: 0, 2014: 1, 2016: 2, 2017: 3})

# In[34]:

cat_df.head()

# In[35]:

num_df = df.drop(columns = cat_cols, axis = 1)
num_df.drop('is_canceled', axis = 1, inplace = True)
num_df

# In[ ]:

# In[36]:

num_df.var()

# In[37]:

# normalizing numerical variables

num_df['lead_time'] = np.log(num_df['lead_time'] + 1)
num_df['arrival_date_week_number'] = np.log(num_df['arrival_date_week_number'] + 1)
num_df['arrival_date_day_of_month'] = np.log(num_df['arrival_date_day_of_month'] + 1)
num_df['agent'] = np.log(num_df['agent'] + 1)
num_df['company'] = np.log(num_df['company'] + 1)
num_df['adr'] = np.log(num_df['adr'] + 1)

# In[38]:

num_df.var()

# In[39]:

num_df['adr'] = num_df['adr'].fillna(value = num_df['adr'].mean())

# In[40]:

num_df.head()

# In[41]:

X = pd.concat([cat_df, num_df], axis = 1)
y = df['is_canceled']

# In[42]:

X.shape, y.shape

# In[43]:

# splitting data into training set and test set

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30)

# In[44]:

X_train.head()

# In[45]:

X_test.head()

# In[46]:

y_train.head(), y_test.head()

# # MODEL BUILDING

# # LOGISTIC REGRESSION
# This type of statistical model (also known as logit model) is often used for classification and predictive analytics. Logistic regression estimates the probability of an event occurring based on a given dataset of independent variables. Since the outcome is a probability, the dependent variable is bounded between 0 and 1. In logistic regression, a logit transformation is applied on the odds—that is, the probability of success divided by the probability of failure.
#
# This is also commonly known as the log odds, or the natural logarithm of odds, and this logistic function is represented by the following formulas:
# Logit(pi) = 1/(1+ exp(-pi))
#
#
# ln(pi/(1-pi)) = Beta_0 + Beta_1*X_1 + … + B_k*K_k

# In[47]:

lr = LogisticRegression()
lr.fit(X_train, y_train)

y_pred_lr = lr.predict(X_test)

acc_lr = accuracy_score(y_test, y_pred_lr)
conf = confusion_matrix(y_test, y_pred_lr)
clf_report = classification_report(y_test, y_pred_lr)

print(f"Accuracy Score of Logistic Regression is : {acc_lr}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # DECISION TREE CLASSIFIER
# Decision Tree is a Supervised learning technique that can be used for both classification and Regression problems, but mostly it is preferred for solving Classification problems. It is a tree-structured classifier, where internal nodes represent the features of a dataset, branches represent the decision rules and each leaf node represents the outcome.
#
# In a Decision tree, there are two nodes, which are the Decision Node and Leaf Node. Decision nodes are used to make any decision and have multiple branches, whereas Leaf nodes are the output of those decisions and do not contain any further branches.
#
# The decisions or the test are performed on the basis of features of the given dataset.
# It is called a decision tree because, similar to a tree, it starts with the root node, which expands on further branches and constructs a tree-like structure.

# In[48]:

dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)

y_pred_dtc = dtc.predict(X_test)

acc_dtc = accuracy_score(y_test, y_pred_dtc)
conf = confusion_matrix(y_test, y_pred_dtc)
clf_report = classification_report(y_test, y_pred_dtc)

print(f"Accuracy Score of Decision Tree is : {acc_dtc}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # RANDOM FOREST
# Random forests is an ensemble learning method for classification that operate by constructing a multitude of decision trees at training time and outputting the class that is the mode of the classes (classification) of the individual trees.
# n_estimators is a parameter that specify number of trees in the forest.
# criterion is to specify what function to measure the quality of a split. “entropy” is for the information gain.

# In[49]:

rd_clf = RandomForestClassifier()
rd_clf.fit(X_train, y_train)

y_pred_rd_clf = rd_clf.predict(X_test)

acc_rd_clf = accuracy_score(y_test, y_pred_rd_clf)
conf = confusion_matrix(y_test, y_pred_rd_clf)
clf_report = classification_report(y_test, y_pred_rd_clf)

print(f"Accuracy Score of Random Forest is : {acc_rd_clf}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # KNN
# The k-nearest neighbors algorithm, also known as KNN or k-NN, is a non-parametric, supervised learning classifier, which uses proximity to make classifications or predictions about the grouping of an individual data point. While it can be used for either regression or classification problems, it is typically used as a classification algorithm, working off the assumption that similar points can be found near one another.

# In[50]:

knn = KNeighborsClassifier()
knn.fit(X_train, y_train)

y_pred_knn = knn.predict(X_test)

acc_knn = accuracy_score(y_test, y_pred_knn)
conf = confusion_matrix(y_test, y_pred_knn)
clf_report = classification_report(y_test, y_pred_knn)

print(f"Accuracy Score of KNN is : {acc_knn}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # Ada Boost Classifier
#
# AdaBoost algorithm, short for Adaptive Boosting, is a Boosting technique used as an Ensemble Method in Machine Learning. It is called Adaptive Boosting as the weights are re-assigned to each instance, with higher weights assigned to incorrectly classified instances.
#
# Boosting is used to reduce bias as well as variance for supervised learning. It works on the principle of learners growing sequentially. Except for the first, each subsequent learner is grown from previously grown learners. In simple words, weak learners are converted into strong ones

# In[51]:

ada = AdaBoostClassifier(base_estimator = dtc)
ada.fit(X_train, y_train)

y_pred_ada = ada.predict(X_test)

acc_ada = accuracy_score(y_test, y_pred_ada)
conf = confusion_matrix(y_test, y_pred_ada)
clf_report = classification_report(y_test, y_pred_ada)

print(f"Accuracy Score of Ada BooAdaBoost algorithm, short for Adaptive Boosting, is a Boosting technique used as an Ensemble Method in Machine Learning. It is called Adaptive Boosting as the weights are re-assigned to each instance, with higher weights assigned to incorrectly classified instances. Boosting is used to reduce bias as well as variance for supervised learning. It works on the principle of learners growing sequentially. Except for the first, each subsequent learner is grown from previously grown learners. In simple words, weak learners are converted into strong onesst Classifier is : {acc_ada}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # GRADIENT BOOSTING CLASSIFIER
#
# Gradient Boosting is a system of machine learning boosting, representing a decision tree for large and complex data. It relies on the presumption that the next possible model will minimize the gross prediction error if combined with the previous set of models. The decision trees are used for the best possible predictions.
#
# The gradient boosting is also known as the statistical prediction model. It works quite similarly to other boosting methods even though it allows the generalization and optimization of the differential loss functions. One uses gradient boosting primarily in the procedures of regression
#  and classification.

# In[52]:

gb = GradientBoostingClassifier()
gb.fit(X_train, y_train)

y_pred_gb = gb.predict(X_test)

acc_gb = accuracy_score(y_test, y_pred_gb)
conf = confusion_matrix(y_test, y_pred_gb)
clf_report = classification_report(y_test, y_pred_gb)

print(f"Accuracy Score of Ada Boost Classifier is : {acc_gb}")
print(f"Confusion Matrix : \n{conf}")
print(f"Classification Report : \n{clf_report}")

# # Models Comparison
#
#

# In[53]:

models = pd.DataFrame({
    'Model' : ['Logistic Regression', 'KNN', 'Decision Tree Classifier', 'Random Forest Classifier','Ada Boost Classifier',
             'Gradient Boosting Classifier',],
    'Score' : [acc_lr, acc_knn, acc_dtc, acc_rd_clf, acc_ada, acc_gb]
})

models.sort_values(by = 'Score', ascending = False)

# In[ ]:


from collections import deque

def bfs(graph, start_node, end_node):
    visited = [0 for _ in range(len(graph))]
    q = deque([start_node])

    while q:
        node = q.popleft()

        if node == end_node:
            return visited

        for edge in graph[node]:
            if visited[edge] == 0:
                q += [edge]
                visited[edge] = visited[node] + 1

    return visited


from abc import ABC, abstractmethod
import copy

from input_example import InputExample
from utils import augment_sentence, get_span

INPUT_FORMATS = {}

def register_input_format(format_class):
    INPUT_FORMATS[format_class.name] = format_class
    return format_class

class BaseInputFormat(ABC):
    name = None

    BEGIN_ENTITY_TOKEN = '['
    END_ENTITY_TOKEN = ']'
    SEPARATOR_TOKEN = '|'
    RELATION_SEPARATOR_TOKEN = '='
    QUERY_SEPARATOR_TOKEN = ':'

    def format_input(self, example: InputExample, multitask=False, task_descriptor=None):
        res = self._format_input(example=example)
        if multitask:
            name = task_descriptor or example.dataset.task_descriptor or example.dataset.name
            res = f'{name} {self.QUERY_SEPARATOR_TOKEN} ' + res
        return res

    @abstractmethod
    def _format_input(self, example: InputExample) -> str:
        raise NotImplementedError

@register_input_format
class PlainInputFormat(BaseInputFormat):
    """
    This format uses the plain sentence as input.
    """
    name = 'plain'

    def _format_input(self, example: InputExample) -> str:
        return ' '.join(example.tokens)

@register_input_format
class RelationClassificationInputFormat(BaseInputFormat):
    """
    Input format for relation classification.
    """
    name = 'rel_input'

    def _format_input(self, example: InputExample) -> str:
        en1_span = [example.entities[0].start, example.entities[0].end]
        en2_span = [example.entities[1].start, example.entities[1].end]
        words = example.tokens
        first, latter, head_first = (en1_span, en2_span, True) if en1_span[0] < en2_span[0] \
            else (en2_span, en1_span, False)

        s = " ".join(words[:first[0]]) \
            + f" {self.BEGIN_ENTITY_TOKEN} {get_span(words, first)} {self.END_ENTITY_TOKEN} " \
            + " ".join(words[first[1]:latter[0]])
        s += f" {self.BEGIN_ENTITY_TOKEN} {get_span(words, latter)} {self.END_ENTITY_TOKEN} " \
             + " ".join(words[latter[1]:])
        s += f" The relationship between {self.BEGIN_ENTITY_TOKEN} {get_span(words, en1_span)} " \
             f"{self.END_ENTITY_TOKEN} and {self.BEGIN_ENTITY_TOKEN} {get_span(words, en2_span)} " \
             f"{self.END_ENTITY_TOKEN} is"

        return s.strip()

@register_input_format
class EventInputFormat(BaseInputFormat):
    """
    Input format for event extraction, where an input example contains exactly one trigger.
    """
    name = 'ace2005_event_with_trigger'

    def _format_input(self, example: InputExample) -> str:
        triggers = example.triggers
        assert len(triggers) <= 1
        augmentations = [([(entity.type.natural,)], entity.start, entity.end) for entity in triggers]

        return augment_sentence(example.tokens, augmentations, self.BEGIN_ENTITY_TOKEN, self.SEPARATOR_TOKEN,
                                self.RELATION_SEPARATOR_TOKEN, self.END_ENTITY_TOKEN)

@register_input_format
class SRLInput(BaseInputFormat):
    """
    Input format for SRL, where the predicate is marked.
    """
    name = 'srl_input'

    def _format_input(self, example) -> str:
        assert len(example.sentence_level_entities) == 1
        start, end = example.sentence_level_entities[0].start, example.sentence_level_entities[0].end
        words = copy.copy(example.tokens)
        words.insert(end, self.END_ENTITY_TOKEN)
        words.insert(start, self.BEGIN_ENTITY_TOKEN)
        return ' '.join(words)


from utils.SiglentDevices import SDS5034
from flask import Blueprint, jsonify, request

oscilloscope_bp = Blueprint('oscilloscope', __name__)

# 示波器 routes
@oscilloscope_bp.route('/connect/<ip>', methods=['GET'])
def connect(ip):
    global handler
    try:
        handler = SDS5034(ip)
        if handler:
            return jsonify(result='Connection Successful')
        else:
            return jsonify(result='Connection Failed')
    except Exception:
        return jsonify(result='Connection Failed')

# API routes
@oscilloscope_bp.route('/run', methods=['GET'])
def api_run():
    result = handler.run()
    return jsonify(result=result)

# API routes
@oscilloscope_bp.route('/stop', methods=['GET'])
def api_stop():
    result = handler.stop()
    return jsonify(result=result)

@oscilloscope_bp.route('/get_time_scale', methods=['GET'])
def api_get_time_scale():
    result = handler.get_time_scale()
    return jsonify(result=result)

@oscilloscope_bp.route('/set_time_scale', methods=['POST'])
def api_set_time_scale():
    data = request.json
    scale = float(data['scale'])
    # scale = float(request.form['scale'])
    result = handler.set_time_scale(scale)
    return jsonify(result=result)

# 自动调整
is_running = False

def your_while_loop_function(direction):
    # 调用 api_get_time_scale 函数并获取其返回值
    response = api_get_time_scale()
    data = response.get_json()  # 获取 JSON 数据
    current_s = data['result']  # 获取具体的返回值
    print(current_s)
    mv = [
        0.00005, 0.00002, 0.00001, 0.0005, 0.0002, 0.0001, 0.005, 0.002, 0.001,
        0.05, 0.02, 0.01, 0.5, 0.2, 0.1
    ]
    index = mv.index(current_s)
    if direction == 'left':
        if index > 0:
            current_ss = mv[index - 1]
            print(current_ss)
            handler.set_time_scale(scale=current_ss)
    elif direction == 'right':
        if index < len(mv) - 1:
            current_ss = mv[index + 1]  # index = mv.index(current_s)
            print(current_ss)
            handler.set_time_scale(scale=current_ss)

@oscilloscope_bp.route('/leftmv')
def leftmv():
    global is_running
    is_running = True
    your_while_loop_function('left')
    return jsonify(status='success')

@oscilloscope_bp.route('/stopmv')
def stopmv():
    global is_running
    is_running = False
    return jsonify(status='success')

@oscilloscope_bp.route('/rightmv')
def rightmv():
    global is_running
    is_running = True
    your_while_loop_function('right')
    return jsonify(status='success')

@oscilloscope_bp.route('/get_ch_offset', methods=['GET'])
def api_get_ch_offset():
    ch = request.args.get('ch')
    result = handler.get_ch_offset(ch)
    return jsonify(result=result)

@oscilloscope_bp.route('/set_ch_offset', methods=['POST'])
def api_set_ch_offset():
    ch = int(request.form['ch'])
    offset = float(request.form['offset'])
    result = handler.set_ch_offset(ch, offset)
    return jsonify(result=result)

@oscilloscope_bp.route('/get_measurement', methods=['GET'])
def get_measurement():
    pos = request.args.get('pos')
    temp_result = handler.get_measurement_item_value(pos)
    # result = float(temp_result)
    result = format(float(temp_result), ".8f")
    print(result)
    return jsonify(result=result)

@oscilloscope_bp.route('/setscreenshot', methods=['POST'])
def set_screenshot():
    try:
        data = request.json
        phname = data['name']
        result = handler.get_screenshot(na=phname)
        return jsonify(result='sc')
    except Exception as e:
        pass


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

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

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Invoice',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('date_created', models.DateTimeField(auto_now_add=True)),
                ('total_amount', models.DecimalField(max_digits=10, decimal_places=2)),
                ('total_quantity', models.DecimalField(max_digits=10, decimal_places=2)),
                ('customer', models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Transaction',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('product', models.CharField(max_length=100)),
                ('quantity', models.IntegerField(max_length=10)),
                ('price', models.DecimalField(max_digits=10, decimal_places=2)),
                ('total', models.DecimalField(max_digits=10, decimal_places=2)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='invoice',
            name='transaction',
            field=models.ManyToManyField(to='customer.Transaction'),
            preserve_default=True,
        ),
    ]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# (c) @AlbertEinsteinTG

from pyrogram import filters, Client
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, CallbackQuery
from pyrogram.errors import UserNotParticipant
from bot import Translation # pylint: disable=import-error
from bot.database import Database # pylint: disable=import-error

db = Database()

@Client.on_message(filters.command(["start"]) & filters.private, group=1)
async def start(bot, update):
    update_channel = "@MG_MEDIA"
    if update_channel:
        try:
            user = await bot.get_chat_member(update_channel, update.chat.id)
            if user.status == "kicked out":
               await update.reply_text("🤭 Sorry Dude, You are B A N N E D 🤣🤣🤣")
               return
        except UserNotParticipant:
            #await update.reply_text(f"Join @{update_channel} To Use Me")
            await update.reply_text(
                text="Join Our Movie Channel 🤭   ചാനലിൽ നിങ്ങൾ ഉണ്ട് എങ്കിൽ മാത്രമേ ഈ ബോട്ട് വഴി നിങ്ങൾക്ക് സിനിമ കിട്ടുകയുളളൂ.അതുകൊണ്ട് ചാനെലിൽ ജോയിൻ ആവുക...😁😁",
                reply_markup=InlineKeyboardMarkup([
                    [ InlineKeyboardButton(text=" 🔰JOIN OUR CHANNEL🔰 ", url=f"https://t.me/MG_MEDIA")]
              ])
            )
            return
        except Exception:
            await update.reply_text("Something Wrong. Contact my Support Group")
            return
    try:
        file_uid = update.command[1]
    except IndexError:
        file_uid = False

    if file_uid:
        file_id, file_name, file_caption, file_type = await db.get_file(file_uid)

        if (file_id or file_type) == None:
            return

        caption = file_caption if file_caption != ("" or None) else ("" + file_name + "")

        if file_type == "document":

            await bot.send_document(
                chat_id=update.chat.id,
                document = file_id,
                caption = caption,
                parse_mode="html",
                reply_to_message_id=update.message_id,
                reply_markup=InlineKeyboardMarkup(
                    [
                        [
                            InlineKeyboardButton
                                (
                                    '⚠JOIN CHANNEL⚠', url="https://t.me/joinchat/nppwyzxMr8NhN2M9"
                                )
                        ]
                    ]
                )
            )

        elif file_type == "video":

            await bot.send_video(
                chat_id=update.chat.id,
                video = file_id,
                caption = caption,
                parse_mode="html",
                reply_markup=InlineKeyboardMarkup(
                    [
                        [
                            InlineKeyboardButton
                                (
                                    '⚠JOIN CHANNEL⚠', url="https://t.me/joinchat/nppwyzxMr8NhN2M9"
                                )
                        ]
                    ]
                )
            )

        elif file_type == "audio":

            await bot.send_audio(
                chat_id=update.chat.id,
                audio = file_id,
                caption = caption,
                parse_mode="html",
                reply_markup=InlineKeyboardMarkup(
                    [
                        [
                            InlineKeyboardButton
                                (
                                    '⚠JOIN CHANNEL⚠', url="https://t.me/joinchat/nppwyzxMr8NhN2M9"
                                )
                        ]
                    ]
                )
            )

        else:
            print(file_type)

        return

    buttons = [[
        InlineKeyboardButton('📣CHANNEL', url='https://t.me/joinchat/nppwyzxMr8NhN2M9'),
        InlineKeyboardButton('GROUP💬', url ='http://t.me/MGmoviegram')
    ],[
        InlineKeyboardButton('OWNER✨', url='https://t.me/Wafikh')
    ],[
        InlineKeyboardButton('Help ⚙', callback_data="help")
    ]]

    reply_markup = InlineKeyboardMarkup(buttons)

    await bot.send_message(
        chat_id=update.chat.id,
        text=Translation.START_TEXT.format(
                update.from_user.first_name),
        reply_markup=reply_markup,
        parse_mode="html",
        reply_to_message_id=update.message_id
    )

@Client.on_message(filters.command(["help"]) & filters.private, group=1)
async def help(bot, update):
    buttons = [[
        InlineKeyboardButton('Home ⚡', callback_data='start'),
        InlineKeyboardButton('About 🚩', callback_data='about')
    ],[
        InlineKeyboardButton('Close 🔐', callback_data='close')
    ]]

    reply_markup = InlineKeyboardMarkup(buttons)

    await bot.send_message(
        chat_id=update.chat.id,
        text=Translation.HELP_TEXT,
        reply_markup=reply_markup,
        parse_mode="html",
        reply_to_message_id=update.message_id
    )

@Client.on_message(filters.command(["about"]) & filters.private, group=1)
async def about(bot, update):

    buttons = [[
        InlineKeyboardButton('Home ⚡', callback_data='start'),
        InlineKeyboardButton('Close 🔐', callback_data='close')
    ]]
    reply_markup = InlineKeyboardMarkup(buttons)

    await bot.send_message(
        chat_id=update.chat.id,
        text=Translation.ABOUT_TEXT,
        reply_markup=reply_markup,
        disable_web_page_preview=True,
        parse_mode="html",
        reply_to_message_id=update.message_id
    )


from tensorflow.keras.models import load_model
from Modelo.clean import downsample_mono, envelope
from kapre.time_frequency import STFT, Magnitude, ApplyFilterbank, MagnitudeToDecibel
from sklearn.preprocessing import LabelEncoder
import numpy as np
from glob import glob
import argparse
import os
import pandas as pd
from tqdm import tqdm

def make_prediction():

    model = load_model("models/conv2d.h5",
        custom_objects={'STFT':STFT,
                        'Magnitude':Magnitude,
                        'ApplyFilterbank':ApplyFilterbank,
                        'MagnitudeToDecibel':MagnitudeToDecibel})
    wav_paths = glob('{}/**'.format("Audios"), recursive=True)
    wav_paths = sorted([x.replace(os.sep, '/') for x in wav_paths if '.wav' in x])
    classes = sorted(os.listdir('Classes'))
    labels = [os.path.split(x)[0].split('/')[-1] for x in wav_paths]
    le = LabelEncoder()
    y_true = le.fit_transform(labels)
    results = []

    for z, wav_fn in tqdm(enumerate(wav_paths), total=len(wav_paths)):
        rate, wav = downsample_mono(wav_fn, 16000)
        mask, env = envelope(wav, rate, threshold=20)
        clean_wav = wav[mask]
        step = int(16000*1.0)
        batch = []

        for i in range(0, clean_wav.shape[0], step):
            sample = clean_wav[i:i+step]
            sample = sample.reshape(-1, 1)
            if sample.shape[0] < step:
                tmp = np.zeros(shape=(step, 1), dtype=np.float32)
                tmp[:sample.shape[0],:] = sample.flatten().reshape(-1, 1)
                sample = tmp
            batch.append(sample)
        X_batch = np.array(batch, dtype=np.float32)
        y_pred = model.predict(X_batch)
        y_mean = np.mean(y_pred, axis=0)
        y_pred = np.argmax(y_mean)
        real_class = os.path.dirname(wav_fn).split('/')[-1]
        print('Actual class: {}, Predicted class: {}, Precentagem: {}'.format(real_class, classes[y_pred],y_mean))
        results.append(y_mean)

    print("OLA")
    # np.save(os.path.join('C:\\Users\\Raul\\PycharmProjects\\PyCharm PyQt5\\logs', y_pred), np.array(results))
    return y_pred


from litellm import completion_cost

import logging

def setup_logger(log_file):
    logging.basicConfig(
        filename=log_file,
        level=logging.DEBUG,
        format='%(asctime)s %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )

setup_logger('debug.log')

def print_basic_response_info(response):
    logging.info("Model Used: %s", response.get('model', 'N/A'))
    logging.info("Response Created At: %s", response.get('created', 'N/A'))
    logging.info("Token Usage: %s", response.get('usage', {}))

def print_detailed_choices_info(response):
    choices = response.get('choices', [])
    for i, choice in enumerate(choices):
        logging.info(f"Choice {i}:")
        logging.info("  Finish Reason: %s", choice.get('finish_reason', 'N/A'))
        message = choice.get('message', {})
        logging.info("  Role: %s", message.get('role', 'N/A'))
        logging.info("  Content: %s", message.get('content', 'N/A'))

def update_and_save_overall_cost(new_cost, filename="total_cost.txt"):
    try:
        with open(filename, 'r') as file:
            total_cost = float(file.read())
    except (FileNotFoundError, ValueError):
        total_cost = 0.0

    total_cost += new_cost

    with open(filename, 'w') as file:
        file.write(f"{total_cost}")

    logging.info(f"Updated Total Cost: ${total_cost:.10f}")

def calculate_and_update_cost(response, filename="total_cost.txt"):
    cost = completion_cost(completion_response=response)
    logging.info("Cost for this completion call: $%f", float(cost))
    update_and_save_overall_cost(cost, filename)


from download import ngram_labels
import os

import pdb
stop = pdb.set_trace

DATA_PATH = "./"
def get_file_list():
  isSplit = lambda x: (len(x.split('.')) == 3
                and x.split('.')[1] == 'bin'
                and len(x.split('.')[2]))
  pathify = lambda s: s
  files = os.listdir(DATA_PATH)
  files.sort()
  return map(pathify, filter(isSplit, files))

exclude = '0 1 2 3 4 5 6 7 8 9 _ADJ_'.split(' ')
labels = [x for x in ngram_labels if x not in exclude]
files = get_file_list()
for label in labels:
  relevant = [f for f in files if label in f]
  c = 0
  while c < len(relevant):
    prior = relevant[c - 1]
    suspect = relevant[c]
    with open(suspect, 'r') as f:
      head = f.readline()
      rest = f.read()
    with open(prior, 'a') as f:
      f.write(head)
    with open(suspect, 'w') as f:
      f.write(rest)
    c += 1


from os_helper import OsHelper
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns

def plot_sector_weights_over_time(df: pd.DataFrame, title: str = "Sector Weights Over Time") -> plt.Figure:
    """
    Plots the weights of sectors over time, ensuring that the X-axis displays the correct dates.

    Args:
    df (pd.DataFrame): The DataFrame containing the weights.
    title (str): The title of the plot.

    Returns:
    plt.Figure: The matplotlib figure object for further customization or saving.
    """
    # Ensure the DataFrame index is datetime
    if not pd.api.types.is_datetime64_any_dtype(df.index):
        df.index = pd.to_datetime(df.index)

    # Normalize the weights for plotting percentages
    df_norm = df.div(df.sum(axis=1), axis=0)

    # Prepare the plot
    plt.figure(figsize=(15, 8))
    sns.set(style="whitegrid")

    # Plot the data
    for column in df_norm.columns:
        plt.plot(df_norm.index, df_norm[column], label=column)

    # Formatting the x-axis to show years only
    plt.gca().xaxis.set_major_locator(mdates.YearLocator())
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y'))

    # Rotate dates for better readability
    plt.xticks(rotation=45)

    # Additional formatting
    plt.title(title)
    plt.xlabel('Year')
    plt.ylabel('Weight Percentage')
    plt.legend(title='Sectors', loc='upper left', bbox_to_anchor=(1, 1))
    plt.tight_layout()

    # Set a background color to the plot area
    plt.gca().set_facecolor('#eaeaf2')

    # Return the figure object
    return plt.gcf()

def plot_sector_cumulative_returns(df: pd.DataFrame, title: str = "Sector Cumulative Returns Over Time") -> plt.Figure:
    """
    Plots the cumulative returns of sectors over time, ensuring that the X-axis displays the correct dates.

    Args:
        df (pd.DataFrame): The DataFrame containing the cumulative returns.
        title (str): The title of the plot.

    Returns:
        plt.Figure: The matplotlib figure object for further customization or saving.
    """
    # Ensure the DataFrame index is datetime
    if not pd.api.types.is_datetime64_any_dtype(df.index):
        df.index = pd.to_datetime(df.index)

    # Prepare the plot
    plt.figure(figsize=(15, 8))
    sns.set(style="whitegrid")
    # use log scale
    plt.yscale('log')

    # Plot the data
    for column in df.columns:
        plt.plot(df.index, df[column], label=column)

    # Formatting the x-axis to show dates formatted by year
    plt.gca().xaxis.set_major_locator(mdates.YearLocator())
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y'))

    # Rotate dates for better readability
    plt.xticks(rotation=45)

    # Additional formatting
    plt.title(title)
    plt.xlabel('Year')
    plt.ylabel('Cumulative Return (log scale)')
    plt.legend(title='Sectors', loc='upper left', bbox_to_anchor=(1, 1))
    plt.tight_layout()

    # Set a background color to the plot area
    plt.gca().set_facecolor('#eaeaf2')

    # Return the figure object
    return plt.gcf()

def save_figure(fig: plt.Figure, folder_path: str, file_name: str):
    """
    Saves the figure to the specified folder with the given filename.

    Args:
    fig (plt.Figure): The figure object to save.
    folder_path (str): The relative or absolute path to the folder.
    file_name (str): The name of the file to save the figure as.
    """
    # Construct the full path
    full_path = f"{folder_path}/{file_name}"

    # Save the figure
    fig.savefig(full_path, bbox_inches='tight')

    print(f"Graph saved to {full_path}")

if __name__ == "__main__":
    os_helper = OsHelper()

    sectors_drifted_weights = os_helper.read_data(directory_name='final data', file_name='sectors_drifted_weights.csv', index_col=0)
    sectors_compounded_returns = os_helper.read_data(directory_name='final data', file_name='sectors_compounded_returns.csv', index_col=0)

    print(sectors_drifted_weights.head())
    print(sectors_compounded_returns.head())

    fig = plot_sector_weights_over_time(df=sectors_drifted_weights, title="Sectors Weights Over Time")
    save_figure(fig=fig, folder_path='../Graphs', file_name='sector_weights_over_time.png')

    # Plotting the sector cumulative returns
    fig_returns = plot_sector_cumulative_returns(df=sectors_compounded_returns, title="Sector Cumulative Returns Over Time")
    save_figure(fig=fig_returns, folder_path='../Graphs', file_name='sector_cumulative_returns_over_time.png')


import re
import os
from datetime import datetime
import pytz

ip = "51.161.117.73"

def get_data():
    stream = os.popen(f"ping -c 3 {ip}")
    output = stream.read()
    output = output.split(' ')
    output = parse_output(output)
    return output

def parse_output(output):

    for x in range(6):
        for i in output:
            if "time" not in i:
                output.remove(i)

    output.remove("time")

    return output

def get_ms(output, ping):
    for i in output:
        ms = float(re.search(r'\d+', i).group())
        ping.append(ms)

    return ping

def cal_average(ping):
    try:
        sum_num = 0
        for t in ping:
            sum_num = sum_num + t

        avg = sum_num / len(ping)
        return avg
    except:
        return ping[1]

def get_time_by_timezone():
    tz_EST = pytz.timezone('US/Eastern')
    dt_EST = datetime.now(tz_EST)
    est = dt_EST.strftime('%-I:%M:%S %p')

    tz_MDT = pytz.timezone('US/Mountain')
    dt_MDT = datetime.now(tz_MDT)
    mdt = dt_MDT.strftime('%-I:%M:%S %p')

    tz_PST = pytz.timezone('US/Pacific')
    dt_PST = datetime.now(tz_PST)
    pst = dt_PST.strftime('%-I:%M:%S %p')

    return str(est), str(mdt), str(pst)


import os
import shutil
import logging
from glob import glob
from pathlib import Path
import time
from pydub import AudioSegment
from dotenv import load_dotenv
import typer
from audiotools.audio_processor import align_audio
from audiotools.utils import export_audio

load_dotenv()

logging.basicConfig(level=logging.INFO)

LOCAL_DATA_DIR = os.environ.get("LOCAL_DATA_DIR", f"{Path.home()}/.cache/audios")
LOCAL_SEGMENTS_DIR = os.environ.get(
    "LOCAL_SEGMENTS_DIR", f"{Path.home()}/.cache/segments"
)
LOCAL_DONE_DIR = os.environ.get("LOCAL_DONE_DIR", f"{Path.home()}/.cache/done")
LOCAL_FAIL_DIR = os.environ.get("LOCAL_FAIL_DIR", f"{Path.home()}/.cache/fail")

Path(LOCAL_DONE_DIR).mkdir(parents=True, exist_ok=True)
Path(LOCAL_FAIL_DIR).mkdir(parents=True, exist_ok=True)
Path(LOCAL_SEGMENTS_DIR).mkdir(parents=True, exist_ok=True)

def main():
    start = time.time()
    logging.info("scanning fow wav in %s", LOCAL_DATA_DIR)
    files = glob(os.path.join(LOCAL_DATA_DIR, "*.wav"))
    logging.info("%i files found", len(files))
    N = len(files)
    if N > 0:
        logging.info("starting alignment")
        aligned_audios = align_audio(LOCAL_DATA_DIR)
        logging.info("exporting segments to %s", LOCAL_SEGMENTS_DIR)
        logging.info("moving done files to %s", LOCAL_DONE_DIR)
        for f, data in aligned_audios.items():
            for audio, label in data:
                export_audio(audio, os.path.join(LOCAL_SEGMENTS_DIR, f"{label}_{f}"))
                if os.path.exists(os.path.join(LOCAL_DATA_DIR, f"{f}.wav")):
                    shutil.move(
                        os.path.join(LOCAL_DATA_DIR, f"{f}.wav"),
                        os.path.join(LOCAL_DONE_DIR, f"{f}.wav"),
                    )
                    shutil.move(
                        os.path.join(LOCAL_DATA_DIR, f"{f}.txt"),
                        os.path.join(LOCAL_DONE_DIR, f"{f}.txt"),
                    )
    files = glob(os.path.join(LOCAL_DATA_DIR, "*.wav"))
    if len(files) > 0:
        logging.info("%i(%f) files failed", len(files), len(files) / N)
        logging.info("moving failed files to %s", LOCAL_FAIL_DIR)
        for f in files:
            shutil.move(
                os.path.join(LOCAL_DATA_DIR, f),
                os.path.join(LOCAL_FAIL_DIR, f"{Path(f).stem}.wav"),
            )
            try:
                shutil.move(
                    os.path.join(LOCAL_DATA_DIR, f"{Path(f).stem}.txt"),
                    os.path.join(LOCAL_FAIL_DIR, f"{Path(f).stem}.txt"),
                )
            except:
                logging.info(f"{f} doesnt have an transcription")
    logging.info("Finished: %i seconds", int(time.time() - start))

if __name__ == "__main__":
    typer.run(main)


from livedivulgador.service.streamers_service import StreamersService
from livedivulgador.database.entities.streamer import Streamer
from livedivulgador.service.streamers_service import StreamersService
from pytest import fixture, mark

@fixture(scope="module")
def created_streamer(twitch_id):
    streamer = Streamer(twitch_id=twitch_id, twitter_id=8250, name="Radhy")
    StreamersService.create_streamer(streamer)

    yield streamer

    StreamersService.delete_streamer(twitch_id)

@mark.parametrize("twitch_id", [89037])
def test_get_streamer(created_streamer, twitch_id):

    response = StreamersService.get_streamer(twitch_id)

    assert twitch_id == response[0].twitch_id

def test_database_get_streamers():
    streamers = StreamersService.get_streamers()

    assert len(streamers) > 0


# 충전소와 N개의 집 사이 거리의 합이 최소

# 충전소는 최소한의 개수만 지어야 하며, 최대 2개까지 지을 수 있다.
# 만약 충전소를 1개만 지어도, 마을 내 모든 집에 전기 자동차를 보급할 수 있다면, 충전소는 반드시 1개만 지어야 한다.

# -----------------------
# 풀이
# 충전소 위치를 set에 담아줌 (house면 제외)
# 충전소에서 1개를 고르는 경우와 2개를 고르는 경우를 순처적으로 탐색
# 1개를 고를 경우 모든 집과 거리를 비교하고 집의 허용 거리보다 큰 경우 바로 탈출 -> 아닌 경우 답 갱신 (하나라도 있는 경우 2개 할 필요 없음)
# 2개를 고를 경우 모든 집과 두 좌표를 비교하고 집의 허용 거리보다 큰 경우 바로 탈출

from itertools import combinations

def cal_dist(combi):
    sum_values = 0

    for i, j, dist in houses:
        distance = float('inf')
        for x, y in combi:
            distance = min(distance, abs(x - i) + abs(y - j))

        if distance > dist:
            return

        sum_values += distance

    global result
    result = min(result, sum_values)

T = int(input())

for tc in range(1, T+1):
    N = int(input())
    houses = [list(map(int, input().split())) for _ in range(N)]

    min_x = min_y = 15
    max_x = max_y = -15
    for i, j, d in houses:
        min_x = min(min_x, i-d)
        max_x = max(max_x, i+d)
        min_y = min(min_y, j-d)
        max_y = max(max_y, j+d)

    case = set()

    for i in range(max(-15, min_x), min(16, max_x+1)):
        for j in range(max(-15, min_y), min(16, max_y+1)):
            case.add((i, j))

    for i, j, _ in houses:
        case.remove((i, j))

    result = float('inf')

    for i in range(1, 3):
        for combi in combinations(case, i):
            cal_dist(combi)

        if result != float('inf'):
            break

    if result == float('inf'):
        result = -1

    print(f'#{tc} {result}')


import numpy as np

def read_file(filename):
    import json
    with open( filename, 'r') as f:
        data = [json.loads(line.strip()) for line in f if len(line) > 2]

    return data

def check(myanswer, answer):
    if not np.array_equal(myanswer, answer):
        print('\n' + 'ERROR'.center(50,'*'))
        print('Correct answer:')
        print(answer)
        print('Returned answer:')
    else:
        print('Check passed!')
    print(myanswer)

def compare(A, B):
    stack1 = A.copy()
    stack2 = B.copy()
    break_good = False
    break_bad = False

    while stack1 and stack2 and not break_good and not break_bad:
        item1 = stack1.pop(0)
        item2 = stack2.pop(0)

        if '~' in [item1, item2]:
            break_good = item2 != '~'  # left side ran out of items in this sublist first
            break_bad = item1 != '~'  # right side ran out of items in this sublist first
        elif isinstance(item1, int) and isinstance(item2, int):
            break_good = item1 < item2
            break_bad = item2 < item1
        else:
            if not isinstance(item1, list):
                item1 = [item1]

            if not isinstance(item2, list):
                item2 = [item2]

            stack1 = item1 + ['~'] + stack1
            stack2 = item2 + ['~'] + stack2

    finished_1_early = not stack1 and stack2
    finished_2_early = not stack2 and stack1

    if break_good or (not break_bad and finished_1_early):
        return -1  # a < b
    elif break_bad or finished_2_early:
        return 1  # a > b, bad b/c out of order
    else:
        return 0

def solve(data, is_part1=True):
    if is_part1:
        good_packets = []

        for idx in range(0, len(data), 2):
            # if the two line are in order or equal
            if compare(data[idx], data[idx+1]) < 1:
                good_packets.append(idx // 2 + 1)

        return sum(good_packets)
    else:
        dividers = [[[2]], [[6]]]
        message = dividers + data

        from functools import cmp_to_key
        message = sorted(message, key=cmp_to_key(compare))

        prod = 1
        for idx, line in enumerate(message, start=1):
            if line in dividers:
                prod *= idx

        return prod

test_case = read_file('test_case.txt')
puzz_input = read_file('puzzle_input.txt')

print('Part 1'.center(50,'-'))
check( solve(test_case), 13 )
print(solve(puzz_input))

print('\n\n' + 'Part 2'.center(50,'-'))
check( solve(test_case, False), 140 )
print(solve(puzz_input, False))


import pygame
import numpy as np
import sys

np.tau = 2 * np.pi

N  = 300
s  = 2  # Kachelgröße
dt = 0.002

x = np.random.rand(N,N)**2*10
v = np.zeros((N,N))
k = 1
h = 1 / N

pygame.init()
screen       = pygame.display.set_mode((N*s, N*s))
small_screen = pygame.Surface((N,N))
clock        = pygame.time.Clock()

userTime      = 0
simulatedTime = 0
FPS           = 100
speedup       = 0.1

slow = False

r = 4
if False:
    for i in range(int(N/2)-r,int(N/2)+r+1):
        for j in range(int(N/2)-r,int(N/2)+r+1):
            x[i,j] = (1 - np.sqrt((i-int(N/2))**2 + (j-int(N/2))**2) / (np.sqrt(2) * r)) * 100

while True:
    userTime = userTime + clock.tick(FPS) / 1000 * speedup

    a = 0
    while simulatedTime < userTime:
        a += 1

        if slow:
            z = np.zeros((N,N))
            for i in range(1,N-1):
                for j in range(1,N-1):
                    v[i,j] = v[i,j] + dt * k * (x[i+1,j] + x[i,j+1] + x[i-1,j] + x[i,j-1] - 4 * x[i,j]) / h**2
                    z[i,j] = x[i,j] + dt * v[i,j]
            x = z
        else:
            x += dt * v
            v[1:N-1, 1:N-1] += (dt * k / h**2) * (x[2:N, 1:N-1] + x[0:N-2, 1:N-1] + x[1:N-1, 0:N-2] + x[1:N-1, 2:N] - 4*x[1:N-1, 1:N-1])
            v *= 0.995

        if False:
            i = int(N/2)*0
            ω = 40
            if True:
                for j in range(int(N/2)-r*10,int(N/2)+r*10+1):
                    x[j-int(N/2)+r*10,j-int(N/4)] = np.sin(np.tau * simulatedTime*ω) * 10
                    v[j-int(N/2)+r*10,j-int(N/4)] = np.cos(np.tau * simulatedTime*ω) * 10 * ω

        ω = 20
        x[0,int(3*N/8)] = np.sin(np.tau * simulatedTime * ω) * 100
        x[0,int(5*N/8)] = np.sin(np.tau * simulatedTime * ω) * 100

        simulatedTime = simulatedTime + dt
    print(a)

    screen.fill((255,255,255))
    pygame.surfarray.blit_array(small_screen, np.minimum(np.maximum((x*10+128).astype(int),0),255) * 0x10000)
    pygame.transform.scale(small_screen, (N*s,N*s), screen)
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

# Aufgetretene Fehler:
# * Vorzeichen in der Wellenungleichung
# * Falsche Updatereihenfolge
# * Metallplatte außerhalb der Physik-for-Schleife
# * Größe von dt


from icecream import ic
import sqlite3
from openpyxl.worksheet import worksheet
from openpyxl.utils.cell import column_index_from_string

from sqlite_tools import dbControl, sql_machines
from excel_tools.machines.excel_machines_layout import fonts

def _output_statistic_header(item_code: str, period: int, sheet: worksheet, row: int) -> int:
    """ Записывает заголовок статистики лист sheet начиная со строки row. """
    sheet.cell(row=row, column=column_index_from_string('B')).value = f"период:"
    sheet.cell(row=row, column=column_index_from_string('C')).value = f"{period}"
    sheet.cell(row=row+1, column=column_index_from_string('B')).value = f"глава:"
    sheet.cell(row=row+1, column=column_index_from_string('C')).value = f"{item_code}"
    return row + 2

def _output_statistic_item(data: sqlite3.Row, sheet: worksheet, row: int) -> int:
    """ Записывает статистику лист sheet начиная со row. """
    sheet.cell(row=row, column=column_index_from_string('B')).value = f"{data['item']}"
    sheet.cell(row=row, column=column_index_from_string('C')).value = f"{data['count']}"
    return row + 1

def _output_statistic_machines(data: sqlite3.Row, sheet: worksheet, row: int) -> int:
    """ Записывает статистику расценок на лист sheet начиная со row.  {'count': 3182} """
    sheet.cell(row=row, column=column_index_from_string('B')).value = f"машина"
    sheet.cell(row=row, column=column_index_from_string('C')).value = f"{data['count']}"
    sheet.cell(row=row, column=column_index_from_string('C')).font = fonts["bold_font"]
    return row + 1

def output_statistic_machines_chapter(
        sheet: worksheet, db_file_name: str, start_line: int, chapter_code: str, period: int
) -> bool:
    """ Записывает статистику (глава, раздел...) по Машинам
    для периода period на лист sheet начиная со строки start_line. """
    # ic.disable()
    with dbControl(db_file_name) as db:
        like_template = f"{chapter_code}.%"
        row = start_line
        result = db.run_execute(sql_machines["count_catalog_period_code_mask"], (period, like_template))
        if result:
            lines = result.fetchall()
            row = _output_statistic_header(chapter_code, period, sheet, row) + 1
            for line in lines:
                ic(line['item'], line['count'])
                # ic(dict(line))
                row = _output_statistic_item(line, sheet, row)
        result = db.run_execute(sql_machines["count_machines_period_code"], (period, like_template))
        if result:
            line = result.fetchone()
            ic(dict(line))
            _output_statistic_machines(line, sheet, row)

    return False


#!/bin/python3

import math
import threading

days = 0
hours = 0
minutes = 0

def format_uptime(ms):
    minutes = math.floor(ms / 60)
    hours = math.floor(minutes / 60)
    minutes = minutes % 60
    days = math.floor(hours / 24)
    hours = hours % 24

    return f"Uptime: {days}d {hours}h {minutes}m \n"

def get_uptime():
    with open("/proc/uptime", "r") as f:
        uptime_seconds = float(f.readline().split()[0])

    return uptime_seconds

def write_uptime_file():
    threading.Timer(1, write_uptime_file).start()
    with open("/tmp/uptime", "w") as f:
        f.write(format_uptime(get_uptime()))
        f.close()

write_uptime_file()


"""flash_messages: Flash messages for the HTML web package."""
from enum import Enum
from typing import cast

from fastapi import Request
from pydantic import BaseModel

MESSAGES = "_messages"

class FlashCategory(str, Enum):
    """Categories for flash messages.

    Categories are used to style the flash message.
    """

    ERROR = "error"
    SUCCESS = "success"
    INFO = "info"
    WARNING = "warning"

class FlashMessage(BaseModel):
    """Message to be flashed to the user."""

    msg: str
    category: FlashCategory = FlashCategory.INFO
    timeout: int | None = None

    def flash(self, request: Request) -> None:
        """Add this message to the session."""
        if MESSAGES not in request.session:
            request.session[MESSAGES] = []
        request.session[MESSAGES].append(self.model_dump())

def get_flashed_messages(request: Request) -> list[FlashMessage]:
    """Get flashed messages from the session."""
    message = cast(list[dict], request.session.pop(MESSAGES, []))
    return [FlashMessage(**msg) for msg in message]


# -*- coding: utf-8 -*-

import jieba
import jieba.analyse
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text  import  TfidfTransformer
from sklearn.cluster import KMeans

def creat_TwoDimensionalArray(number) :
    array = []
    for index in range(number):
        item = []
        array.append(item)
    return array

data = pd.read_csv('Data/dataset-utf8.csv')
dataContent = data['postContent']
dataContent_array = []
replaceText_array = []

for item in dataContent :
#   取代文字 stopword 放置於replaceText 等待替換
#    for text in replaceText_array :
#        item = item.replace(text , '')
#  精確切割
#    seg_list = jieba.cut(item , cut_all=False)
#  關鍵詞抽取
    # topK限定最大的抽取詞彙數量
    # withWeight決定抽取的關鍵詞彙是否包含權重
    # allowPOS是否針對特定
    seg_list = jieba.analyse.extract_tags(item, topK=20, withWeight=False, allowPOS=())
# dataContent_array是儲存需切割後的字串，以空白區隔，vectorizer會將字串進行切割轉為斷詞陣列
    dataContent_array.append(" ".join(seg_list))
# 計算開始
# 內文篩選與擷取相關資料
vectorizer = CountVectorizer()
# 詞彙出現頻率
word_feq = vectorizer.fit_transform(dataContent_array)
# 出現的詞彙
word = vectorizer.get_feature_names()
# 分數計算
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(word_feq)
# 分群
clusterNumber = 10
kmeans = KMeans(n_clusters=clusterNumber, random_state=0).fit(tfidf)
number = 0
content_list = creat_TwoDimensionalArray(clusterNumber)
for label in kmeans.labels_ :
    content_list[label].append(dataContent[number])
    print ('PostContent index-%d : %s' %(number+1 , dataContent[number]))
    number = number + 1
for cluster in range(clusterNumber) :
    print('Cluster %d' %(cluster))
    for content in content_list[cluster] :
        print(content)


from termcolor import colored
import os
import time
import random
import plotille
import pprint
import inspect
import re

def valuePrint(x):
    frame = inspect.currentframe().f_back
    s = inspect.getframeinfo(frame).code_context[0]
    r = re.search(r"\((.*)\)", s).group(1)
    yellowPrint("{} = {}".format(r, x))

def errorPrint(message):
    # os.system('color')
    print(colored(message, 'red'))
    return message

# grey.
# red.
# green.
# yellow.
# blue.
# magenta.
# cyan.
# white.
def colorPrint(message, color):
    # os.system('color')
    print(colored(message, color))
    return message

def pPrint(message):
    print("\n")
    pprint.pprint(message)
    print("\n")

def yellowPrint(message):
    # os.system('color')
    print(colored(message, "yellow"))
    return message

def passPrint(message):
    # os.system('color')
    print(colored(message, 'green'))
    return message

def completePrint(message):
    # os.system('color')
    print("--------------------------------{}--------------------------------".format(colored(message, 'green')))
    return message

def splitLine(string, color="white"):
    print("\n")
    colorPrint(
        "--------------------------------{}--------------------------------".format(string), color)
    print("\n")
    return string

def histogramsPrint(data, type="vertical"):
    if type == "vertical":
        print(plotille.histogram(data))
    else:
        print(plotille.hist(data))

            #
# --------------------------------------------time--------------------------------------------------------

def printTimeList(self,current_milli_time,checkPointList=[],updateCheckPointList=[]):
    for i in checkPointList:
        if i in self.checkPointTime:
            tmpCheckTime=self.checkPointTime[i]
            passPrint("check    {:3d}:            {:6d}ms, {:6.2f}s".format(i ,current_milli_time-tmpCheckTime,float(current_milli_time-tmpCheckTime)/1000))
        else:
            errorPrint("No check {:3d}~ New one check point".format(i))
            self.checkPointTime[i]=current_milli_time
    for i in updateCheckPointList:
        if i in self.checkPointTime:
            tmpCheckTime=self.checkPointTime[i]
            colorPrint("update   {:3d}:            {:6d}ms, {:6.2f}s".format(i ,current_milli_time-tmpCheckTime,float(current_milli_time-tmpCheckTime)/1000),"magenta")
        else:
            errorPrint("NoUpdate {:3d}~ New one check point".format(i))
        self.checkPointTime[i]=current_milli_time

class globalTimeClass:
    count=0
    beginTime =-1
    lastTime =-1
    def __init__(self,time=0):
        self.checkPointTime=dict()
        self.beginTime = time
        self.lastTime = time
    def updateTime(self,message,checkPointList=[],updateCheckPointList=[]):
        if self.beginTime==-1 and self.lastTime==-1:
            splitLine("start time check")
            current_milli_time = round(time.time() * 1000)
            printTimeList(self,current_milli_time,checkPointList,updateCheckPointList)
            self.beginTime =current_milli_time
            self.lastTime =current_milli_time
            self.count =0
        else:
            print(message)
            current_milli_time = round(time.time() * 1000)
            yellowPrint("passTime {:3d} from Last:  {:6d}ms, {:6.2f}s".format(self.count,current_milli_time-self.lastTime,float(current_milli_time-self.lastTime)/1000))
            yellowPrint("passTime {:3d} from start: {:6d}ms, {:6.2f}s".format(self.count,current_milli_time-self.beginTime,float(current_milli_time-self.beginTime)/1000))
            printTimeList(self,current_milli_time,checkPointList,updateCheckPointList)
            self.lastTime =current_milli_time
            self.count+=1

globalTime = globalTimeClass(-1)

def passTime(message="passTime:",CP=[],UP=[]):
    globalTime.updateTime(message,CP,UP)

def sleepRandom(seconds):
    time.sleep(round(random.uniform(0.15, seconds+0.15), 2))

def testTime(whileTimes, function):
    histogramsData = []
    begin = time.time()
    while whileTimes:
        beforeFunction = time.time()
        function()
        afterFunction = time.time()
        deltatime = afterFunction - beforeFunction
        colorPrint("delta time ONECE {}".format(
            deltatime), "yellow")
        histogramsData.append(deltatime)
        whileTimes -= 1
    end = time.time()
    colorPrint("ALL {}".format(end-begin), "red")
    histogramsPrint(histogramsData, "horizontal")

# --------------------------------------------valueCMP--------------------------------------------------------

def Random(num):
    return round(random.uniform(0, num), 2)

def textBelong(small, big):
    for i in small:
        if i in big:
            return 1
    return 0

def isArround(listA, listB, delta):
    if len(listA) != len(listB):
        errorPrint("isArround inputLength not equal!!!")
        return 0
    for i in range(0, len(listA)):
        a = listA[i]
        b = listB[i]
        if a < b-delta or a > b+delta:
            errorPrint("not Arround")
            return 0
    passPrint("isArround")
    return 1


import sys
import math
import numpy as np
import torch

sys.path.append('./pool')
import config
import dqn

class Algorithms:
	def __init__(self, algo, numStates, numActions, initState, numAngles=20, numForces=5, train=True):
		self.algorithm = algo
		self.numAngles = numAngles
		self.numForces = numForces
		self.numActions = numAngles*numForces
		# self.numActions = numAngles*numForces
		# self.numStates = numStates
		self.epsilon = 0
		# S
		self.state = None
		# A
		self.action = None

		if algo == "semi-grad-sarsa":
			self.alpha = 0.5
			self.epsilon = 0.5
			if train == False:
				self.epsilon = 0
			self.gamma = 1.0
			self.state = initState
			self.numFeatures = 16
			self.action = np.random.randint(0,self.numActions)
			self.w = np.random.randn(self.numFeatures)
			# print(self.state)
			# self.action = self.oneHotEncode(self.state)
		elif algo == "dqn":
			self.state = self.normalize(initState)
			# print(self.state.shape)
			self.alpha = 0.05
			self.epsilon = 0.3
			if train == False:
				self.epsilon = 0
			self.nn = dqn.NeuralNetwork(self.state.size, [64,128],self.numActions)
			self.action = self.epsilonGreedy(self.nn(self.state)[0].detach().numpy())

	def saveModel(self):
		if self.algorithm == "dqn":
			torch.save(self.nn, "dqnModel")

	def takeAction(self, nextState, reward):
		# algorithms should update state and action
		if self.algorithm == "random":
			self.action = self.randomAgent(nextState, reward)
		elif self.algorithm == "dqn":
			nextState = self.normalize(nextState)
			self.action = self.deepQAgent(nextState, reward)
		elif self.algorithm == "semi-grad-sarsa":
			self.action = self.semiGradientSarsa(nextState, reward)
		elif self.algorithm == "closest-greedy":
			self.action = self.closestGreedy(nextState, reward)
		self.epsilon -= self.epsilon/1000
		# elif self.algorithm == "semi-gradient-sarsa":
		# 	self.action = self.semiGradientSarsa(nextState, reward)
		self.state = nextState
		return self.action

	def randomAgent(self, nextState, reward):
		angle = np.random.uniform(-math.pi,math.pi)
		distance = np.random.randint(config.cue_max_displacement/2,config.cue_max_displacement)
		return angle, distance

	def closestGreedy(self, nextState, reward):
		numBalls = 7
		# Potted balls to be ignored
		distances = np.zeros([numBalls])
		flag = False
		for i in range(numBalls):
			j = i+9
			if nextState[j][2] == 0:
				distances[i] = math.inf
			else:
				flag = True
				diff = np.array([nextState[j][0]-nextState[0][0], nextState[j][1]-nextState[0][1]])
				distances[i] = diff@diff
		# print(distances)
		if flag:
			idx = 9+np.argmin(distances)
		else:
			idx = 8
		# print(idx)
		displacement = np.array([nextState[idx][0]-nextState[0][0], nextState[idx][1]-nextState[0][1]])
		displacement = displacement/np.linalg.norm(displacement)
		# print(displacement)
		angle = math.asin(displacement[0])
		if displacement[1] > 0:
			angle = math.pi - angle
		angle = 2*math.pi - angle
		# print(angle)
		distance = np.random.randint(config.cue_max_displacement/2,config.cue_max_displacement)
		return angle, distance

	def semiGradientSarsa(self, nextState, reward):
		# Some computation
		# if nextState is terminal:
		# 	self.w += self.alpha*(reward - )
		# aprime = self.epsilonGreedy(nextState)
		# self.w[self.state][self.action] += self.alpha * (reward + self.gamma*self.qvalue(nextState,aprime) - self.qvalue(self.state,self.action))
		X_s = self.getStateFeatures(self.state,self.action)

		values = []
		for action_num in range(self.numActions):
			values.append(self.w@self.getStateFeatures(nextState, action_num))
		aprime = self.epsilonGreedy(values)
		X_sprime = self.getStateFeatures(nextState, aprime)

		self.w += self.alpha*(reward + self.w@X_sprime - self.w@X_s)*X_s
		return aprime

	def getStateFeatures(self, curState, action_num):
		angle = (self.action//self.numForces)*(2*math.pi)/self.numAngles - math.pi
		direction = np.array([math.sin(angle), math.cos(angle)])
		features = np.zeros(curState.shape[0])
		for i in range(1,curState.shape[0]):
			if curState[i][2] == 0:
				continue
			if direction@np.array([curState[i][0]-curState[0][0], curState[i][1]-curState[0][1]]) > 0:
				features[i] = 1
		return features

	def deepQAgent(self, nextState, reward):
		with torch.no_grad():
			out_stPrime = self.nn(nextState)[0]
		out_st = self.nn(self.state)[0]
		aprime = self.epsilonGreedy(out_st.detach().numpy())

		gradient = torch.autograd.grad(out_st[self.action], self.nn.parameters())

		for grad, param in zip(gradient, self.nn.parameters()):
			param.data.sub_(self.alpha*(reward + out_stPrime[aprime] - out_st[self.action])*grad)

		return aprime

	def normalize(self, curState):
		state = np.zeros(curState.shape)
		for i in range(curState.shape[0]):
			state[i][0] = 2*curState[i][0]/config.resolution[0] - 1
			state[i][1] = 2*curState[i][1]/config.resolution[1] - 1
			state[i][2] = curState[i][2]
		return state.reshape(1,-1)

	# def getFeatures(self, state, action):
	# 	dimensions = self.state.shape
	# 	features = [0 for _ in range(15)]
	# 	angle = (self.action//self.numForces)*(2*math.pi)/self.numAngles - math.pi
	# 	# distance = (self.action%self.numForces)*(config.cue_max_displacement/(2*self.numForces)) + config.cue_max_displacement/2
	# 	for i in range(1,16):
	# 		displacement = self.state[i]-self.state[0]
	# 		direction = np.array([math.sin(self.angle), math.cos(self.angle)])

	# def qvalue(self, state, action):
	# 	# assuming one-hot encoded input
	# 	return self.w[state][action]

	def epsilonGreedy(self, values):
		a = None
		if np.random.random() < self.epsilon:
			a = np.random.randint(0,len(values))
		else:
			a = int(np.argmax(values))
			# print(type(a),a,values[a])
		return a

	# def greedy(self, state):
	# 	# assuming feature encoding is one-hot.
	# 	return np.argmax(self.w[state])

	# def oneHotEncode(self, idx, total):
	# 	one_hot_vector = np.zeros([total])
	# 	one_hot_vector[idx] = 1
	# 	return one_hot_vector


# capture a frame from the camera and save it to the file as a png
import cv2
import numpy as np
import os

cap = cv2.VideoCapture(0)
cap.set(3,1280)
cap.set(4,720)
count = 0
while(True):
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    #with each space key is pressed, save the current frame to a file
    if cv2.waitKey(1) & 0xFF == ord(' '):
        cv2.imwrite('frame%d.png' % count, frame)
        count += 1
        print(count)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()


import itertools

import hypothesis
import hypothesis.extra.numpy as st_np
import hypothesis.strategies as st
import numpy as np
import scipy.ndimage

from .._binlets import binlets, max_level

@hypothesis.given(
    data=st_np.arrays(
        np.float64,
        shape=st_np.array_shapes(min_dims=2, max_dims=4, max_side=16),
        elements=st.floats(-1e6, 1e6, allow_infinity=False, allow_nan=False),
    )
)
def test_round_trip(data):
    """As the test always returns False,
    it never thresholds any coefficient,
    and it must reconstruct the same input.
    """

    def always_false(x, y):
        return np.zeros_like(x, bool)

    for level in range(max_level(data)):
        rec = binlets(data, levels=level, test=always_false, linear=False)
        assert np.allclose(rec, data)

@hypothesis.given(
    size=st.integers(0, 4),
    ndim=st.integers(2, 4),
    seed=st.integers(0),
)
def test_full_threshold_power_of_two(size, ndim, seed):
    """As the test always returns True,
    all detail coefficients are thresholded,
    resulting in a full (ie, non-adaptive) binning of the input."""

    def always_true(x, y):
        return np.ones_like(x, bool)

    def average(data):
        return np.mean(data, axis=tuple(range(1, data.ndim)), keepdims=True)

    size = 2**size
    data = np.random.default_rng(seed).random(size=(size,) * ndim)

    level = max_level(data)
    rec = binlets(data, levels=level, test=always_true, linear=False)
    expected = average(data)
    assert np.allclose(rec, expected)

@hypothesis.given(
    data=st_np.arrays(
        np.float64,
        shape=st_np.array_shapes(
            min_dims=2,
            max_dims=4,
            min_side=2,  # nothing to do for "one pixel".
            max_side=8,
        ),
        elements=st.floats(-1e6, 1e6, allow_infinity=False, allow_nan=False),
    )
)
def test_full_threshold(data):
    """As the test always returns True,
    all detail coefficients are thresholded,
    resulting in a full (ie, non-adaptive) binning of the input."""

    def always_true(x, y):
        return np.ones_like(x, bool)

    def local_average(data, level):
        size = 2**level
        N = size ** (data.ndim - 1)
        shifts = itertools.product(
            *[range(-size // 2, size // 2) for _ in range(1, data.ndim)]
        )
        axis = tuple(range(1, data.ndim))
        filter_size = (1,) + (size,) * (data.ndim - 1)
        return (
            sum(
                scipy.ndimage.uniform_filter(
                    np.roll(data, shift, axis),
                    size=filter_size,
                    mode="wrap",
                )
                for shift in shifts
            )
            / N
        )

    level = max_level(data)
    rec = binlets(data, levels=level, test=always_true, linear=False)
    expected = local_average(data, level)
    assert np.allclose(rec, expected)

def test_maximum_norm_1d():
    data = np.array([[0, 0], [2, 2], [100, 100], [102, 200]]).T
    expected = np.array([[0.5, 0.5], [1.5, 1.5], [100, 100], [102, 200]]).T

    def maximum_norm(x, y):
        return np.all(np.abs(x - y) < 10, axis=0, keepdims=True)

    result = binlets(data, test=maximum_norm, linear=False)
    assert np.all(result == expected)


"""
    Classifiers.
"""

from abc import ABC, abstractmethod
from binascii import hexlify
from datetime import datetime, timedelta
from enum import Enum

import ahocorasick
import pandas
from fet.pstats import extract_features, feature_cols, swap_directions

from bota.anomaly import SimpleExpSmoothing
from bota.filter import IPListFilter

def flow_reason(data):
    """Base reason for flow-related detections.

    Includes:

    - time_first
    - time_last
    - dst_ip
    - src_ip
    - dst_port
    - src_port
    - protocol

    Args:
        data (dict): Received message's data.

    Returns:
        dict: Reason dictionary.
    """
    reason_keys = [
        "time_first",
        "time_last",
        "dst_ip",
        "src_ip",
        "dst_port",
        "src_port",
        "protocol",
    ]

    return {k: data[k] for k in reason_keys}

class Classifier(ABC):
    """Base classifier class.

    Attributes:
        positive (bool): Positiveness of the classification decision.
        reason (dict): Classification explanation.
    """

    def __init__(self):
        self.positive = False
        self.reason = {}

    @abstractmethod
    def on_message(self, message):
        """Abstract on_message method.

        Receives message and should process according to the
        classifier's purpose.

        Args:
            message (dict): Message including message type and data.

        Raises:
            NotImplementedError: Abstract method.
        """
        raise NotImplementedError

    def sync(self, time_new):
        """Synchronize time within the classifier.

        Empty implementation in the base class. Derived classes
        should implement their own sync function based on their needs.

        Args:
            time_new (datetime.datetime): Synced time.
        """
        pass

    def flush(self):
        """Reset classification decision."""
        self.positive = False
        self.reason = {}

class DHTClassifier(Classifier):
    """DHT classifier.

    Consumes idpcontent messages and detects
    BitTorrent DHT data prefix.
    """

    #: DHT prefix.
    prefix = hexlify(b"d1:ad2:id20:").decode()

    def on_message(self, message):
        """DHT classifier message processing.

        Records the first positive reason (flow) with
        DHT prefix in idp_content.

        Args:
            message (dict): Message with idpcontent type data.
        """
        if self.positive:
            return

        content = message["data"]["idp_content"]

        if content.startswith(self.prefix):
            self.positive = True
            self.reason = flow_reason(message["data"])

class StratumClassifier(Classifier):
    """Stratum classifier.

    Consumes idpcontent messages and is able to detect
    Stratum content by implementing a set of boolean
    AND pattern rules.
    """

    #: Matching patterns.
    patterns = {
        0: b'"id":',
        1: b'"jsonrpc":',
        2: b'"method":',
        3: b'"params":',
        4: b'"login"',
        5: b'"job"',
    }

    #: Boolean AND patterns rules.
    rules = {"stratum_login": {0, 1, 2, 3, 4}, "stratum_job": {1, 2, 3, 5}}

    def __init__(self):
        super().__init__()

        self.automaton = ahocorasick.Automaton()

        for i, p in self.patterns.items():
            self.automaton.add_word(hexlify(p).decode(), i)

        self.automaton.make_automaton()

    def on_message(self, message):
        """Stratum classifier message processing.

        Records the first positive reason (flow) matching
        any of class rules.

        Args:
            message (dict): Message with idpcontent type data.
        """
        if self.positive:
            return

        content = message["data"]["idp_content"]

        matches = set([x[1] for x in self.automaton.iter(content)])

        for name, rule in self.rules.items():
            if rule.issubset(matches):
                self.positive = True
                self.reason = flow_reason(message["data"])
                self.reason["rule"] = name

class TorClassifier(Classifier):
    """Tor classifier.

    Consumes basic messages and detects Tor relays present
    in already initialized relays_filter.
    """

    #: IP list filter updated with prepared Tor relays.
    relays_filter = IPListFilter([])

    def on_message(self, message):
        """Tor classifier message processing.

        Records the first flow with either the source or the destination
        IP address present in the list of Tor relays.

        Args:
            message (dict): Message with basic type data.
        """
        if self.positive:
            return

        # prefilter
        if message["data"]["packets"] + message["data"]["packets_rev"] < 3:
            return

        dst_ip = message["data"]["dst_ip"]
        src_ip = message["data"]["src_ip"]

        if self.relays_filter.apply(dst_ip) or self.relays_filter.apply(src_ip):
            self.positive = True
            self.reason = flow_reason(message["data"])

    @classmethod
    def update_relays(cls, relays):
        """Update global list of relays for the classifier.

        Args:
            relays (list): List of string represented IP addresses.
        """
        cls.relays_filter = IPListFilter(relays)

cnc_removed_cols = ["bytes_rev_rate", "bytes_total_rate"]

class CNCClassifier(Classifier):
    """CNC traffic classifier.

    Consumes pstats messages, extracts features and evaluates
    message instance through pre-fitted machine learning
    classifier.
    """

    #: CNC classification model.
    model = None

    #: DataFrame columns.
    cols = [x for x in feature_cols if x not in cnc_removed_cols]

    def on_message(self, message):
        """CNC classifier message processing.

        Records the first positive flow predict as cnc traffic by
        the underlying machine learning classifier. Flows with fewer
        packets than 3 or flows shorted than 30 seconds are filtered out.

        Args:
            message (dict): Message with pstats type data.
        """
        if self.positive:
            return

        # prefilter
        if message["data"]["packets"] + message["data"]["packets_rev"] < 3:
            return

        if message["data"]["ppi_pkt_times"] == "[]":
            return

        df = pandas.DataFrame(message["data"], index=[0])

        # swap directions
        if message["direction_role"] == "destination":
            swap_directions(df, [True], inplace=True)

        extract_features(df, inplace=True, min_packets=3)

        # consider only flows longer than 50 seconds
        duration = df.iloc[0]["duration"]
        if duration < 50:
            return

        if self.model.predict(df[self.cols].iloc[0:1]) == ["cnc"]:
            proba = self.model.predict_proba(df[self.cols].iloc[0:1])
            self.positive = True
            self.reason = flow_reason(message["data"])
            self.reason["probability"] = round(proba[0][1], 6)

    @classmethod
    def update_model(cls, model):
        """Update global model for the classifier.

        Args:
            model (object): Object with a predict method.
        """
        cls.model = model

class AnomalyAgg(Enum):
    """Aggregation types enumeration."""

    SUM = 1
    UNIQUE = 2

class AnomalyClassifier(Classifier):
    """Time series anomaly detection classifier.

    Consumes basic messages where the endpoint acts as
    a source of the communication. Uses simple exponential
    smoothing and base minimal thresholds to detect
    anomalies.

    Args:
        field (string): Data field to monitor (e.g. bytes).
        agg (string): Aggregate function (sum or unique).
        threshold (int): Minimum threshold to trigger anomaly.

    Raises:
        ValueError: Invalid aggregate function.
    """

    #: Aggregation window interval in seconds.
    interval = 60

    #: Time format present in the data.
    time_fmt = "%Y-%m-%dT%H:%M:%S.%f"

    def __init__(self, field, agg, threshold):
        self.threshold = threshold
        self.field = field

        self.time_next = None

        if agg == "sum":
            self.kind = AnomalyAgg.SUM
        elif agg == "unique":
            self.kind = AnomalyAgg.UNIQUE
        else:
            raise ValueError(f"unsupported {agg}")

        self._reset()

        self.smoothing = SimpleExpSmoothing(0.1)
        self.anomalies = {"prediction": 0, "threshold": 0}
        self.windows = 0
        self.max = 0

    @property
    def positive(self):
        """Positiveness of the classification decision.

        Evaluated as the presence of at least one statistical
        anomaly and at least three threshold anomalies.
        """
        if self.anomalies["prediction"] > 0 and self.anomalies["threshold"] > 1:
            return True
        else:
            return False

    @property
    def reason(self):
        """Classification explanation - dict with field and its maximum value."""
        if self.positive:
            return {
                "max": self.max,
                "over_prediction": self.anomalies["prediction"],
                "over_threshold": self.anomalies["threshold"],
            }
        else:
            return {}

    def on_message(self, message):
        """Anomaly classifier message processing.

        Expects outgoing flows (endpoint is a source of the communication).
        Aggregates values within class-specific interval.

        Args:
            message (dict): Message with basic data.
        """
        time_last = datetime.strptime(message["data"]["time_last"], self.time_fmt)

        if time_last < self.time_next:
            self._aggregate(message["data"])
        else:
            self._process_window(time_last)
            self._reset()
            self._aggregate(message["data"])

    def sync(self, time_new):
        """Overridden implementation of the synchronization procedure.

        Args:
            time_new (datetime.datetime): Synced time.
        """
        if self.time_next and self.time_next < time_new:
            self._process_window(time_new)
            self._reset()

        self.time_next = time_new + timedelta(seconds=self.interval)

    def flush(self):
        """Overridden classification decision reset."""
        self.max = 0
        self.anomalies = {"prediction": 0, "threshold": 0}

    def _reset(self):
        if self.kind == AnomalyAgg.SUM:
            self.current = 0
        if self.kind == AnomalyAgg.UNIQUE:
            self.current = set()

    def _aggregate(self, data):
        if self.kind == AnomalyAgg.SUM:
            self.current += data[self.field]
        elif self.kind == AnomalyAgg.UNIQUE:
            self.current.add(data[self.field])

    def _process_window(self, time_last):
        self.windows += 1

        if self.kind == AnomalyAgg.SUM:
            current = self.current
        elif self.kind == AnomalyAgg.UNIQUE:
            current = len(self.current)

        # prediction-based anomaly
        if self.windows > 2:
            pred_upper = self.smoothing.pred + 5 * self.smoothing.std_e
            if current > pred_upper:
                self.anomalies["prediction"] += 1

        # threshold-based anomaly
        if current > self.threshold:
            self.anomalies["threshold"] += 1

        # update maximum for explanation
        self.max = max(self.max, current)

        # smooth
        self.smoothing.update(current)

        # smooth missing intervals
        missing = (time_last - self.time_next).seconds // self.interval
        for _ in range(missing):
            self.windows += 1
            self.smoothing.update(0)

        self.time_next += timedelta(seconds=self.interval) * (missing + 1)


# BOJ 4963
# 풀이횟수 2
import sys
sys.setrecursionlimit(10000)
# 매번 입력을 마칠 때마다 answer에 섬의 개수를 append하면 될듯?
answer = []
# 상하좌우 대각선에 대해서 모두 dfs호출하는데, 이 때 인덱스 검사를 한다.
# 이미 graph[y][x]가 1인 시점에서 True 반환은 확정되어있고, 붙어있는 섬을 하나로 인식하기 위해, 붙어있는 섬들을 모두 0으로 만들어줘야함.

# 상하좌우 좌상, 우상, 좌하, 우하
dx = [0, 0, -1, 1, -1, 1, -1, 1]
dy = [-1, 1, 0, 0, 1, 1, -1, -1]

# dfs
def dfs(x, y):
    if graph[y][x] == 1:
        graph[y][x] = 0
        for i in range(8):
            nx = x + dx[i]
            ny = y + dy[i]
            if (-1 < nx < w) and (-1 < ny < h):
                dfs(nx, ny)
        return True
    return False

while True:
    result = 0
    w, h = map(int, input().split())
    if w == h == 0:
        break
    graph = [[] for _ in range(h)]
    for i in range(h):
        a = list(map(int, input().split()))
        graph[i] = a
    for x in range(h):
        for y in range(w):
            if dfs(y, x):
                result += 1
    answer.append(result)
for i in answer:
    print(i)


"""Define a simple example plugin."""

# ba_meta require api 6

from __future__ import annotations

from typing import TYPE_CHECKING

import random
from don import tintColor
import don

import ba
ba.screenmessage('Spaz Mods is created by PCModder for FRIENDS to use',color=(3,-4,8))#created by PCModder full rights to me. :)
ba.screenmessage('Use don.py to use specific settings',color=(3,-4,8))#I believe now i am gone with the wind
from _ba import chatmessage as cmsg, get_foreground_host_activity
import _ba
from bastd.actor.spaz import Spaz, SpazFactory, BombDiedMessage, CurseExplodeMessage, PunchHitMessage, PickupMessage
import bastd.actor.spaz
from bastd.actor.popuptext import PopupText
from bastd.gameutils import SharedObjects
from bastd.actor import bomb as stdbomb

if TYPE_CHECKING:
    from typing import Any, Type, Optional, Tuple, List, Dict

# ba_meta export plugin
class spazMOD(ba.Plugin):
    """My first ballistica plugin!"""

    Spaz._old_init = Spaz.__init__
    def _new_init(self,
                 color: Sequence[float] = (1.0, 1.0, 1.0),
                 highlight: Sequence[float] = (0.5, 0.5, 0.5),
                 character: str = 'Spaz',
                 source_player: ba.Player = None,
                 start_invincible: bool = True,
                 can_accept_powerups: bool = True,
                 powerups_expire: bool = False,
                 demo_mode: bool = False):
        self._old_init(color,highlight,character,source_player,
                       start_invincible,can_accept_powerups,
                       powerups_expire,demo_mode)

        if don.light:
            self.light = ba.newnode('light',
                           owner=self.node,
                           attrs={
                               'position': self.node.position,
                               'radius': 0.1,#ahem pc was here
                               'volume_intensity_scale':0.1,
                               'height_attenuated': False,
                               'color': ((0+random.random()*6.0),(0+random.random()*6.0),(0+random.random()*6.0))})
            self.node.connectattr('position', self.light, 'position')
            ba.animate_array(self.light, 'color', 3,{0:(1,0,0),0.2:(1,0.5,0),0.4:(1,1,0),0.6:(0,1,0),0.8:(0,1,1),1.0:(0,0,1),1.2:(1,0,0)},True)

        def _new_hp():
            if not self.node:
                return
            hp = ba.newnode('math',
                            owner=self.node,
                            attrs={'input1': (0, 0.65, 0),'operation': 'add'})
            self.node.connectattr('torso_position', hp, 'input2')
            self.hp = ba.newnode('text',
                                 owner=self.node,
                                 attrs={
                                    'text': '',
                                    'in_world': True,
                                    'shadow': 1.0,
                                    'flatness': 1.0,
                                    'scale': 0.008,
                                    'h_align': 'center',
                                 })
            hp.connectattr('output', self.hp, 'position')
            #ba.animate(self.hp, 'scale', {0:0, 0.2:0, 0.6:0.018, 0.8:0.012})
            activity = get_foreground_host_activity()
            if don.tint:
                activity.globalsnode.tint=(tintColor)

            def _update():
                if not self.hp:
                    return
                if self.shield:
                    hptext = int(
                        (self.shield_hitpoints/self.shield_hitpoints_max)*100)
                else:
                    hptext = int(self.hitpoints*0.1)
                if hptext >= 75:
                    color = (1, 1, 1)
                elif hptext >= 50:
                    color = (1, 1, 1)
                elif hptext >= 25:
                    color = (1, 1, 1)
                else:
                    color = (1, 1, 1)
                self.hp.text = 'HP:' + str(hptext)
                self.hp.color = (0.2, 1.0, 0.8) if self.shield else color
            ba.timer(0.05, _update, repeat=True)
        _new_hp()
        app = _ba.app
        cfg = app.config
        new_hp = cfg.get('New HP', True)
        if new_hp:
            _new_hp()

    def on_punch_press(self) -> None:
        """
        Called to 'press punch' on this spaz;
        used for player or AI connections.
        """
        if not self.node or self.frozen or self.node.knockout > 0.0:
            return
        t_ms = ba.time(timeformat=ba.TimeFormat.MILLISECONDS)
        assert isinstance(t_ms, int)
        if t_ms - self.last_punch_time_ms >= self._punch_cooldown:
            if self.punch_callback is not None:
                self.punch_callback(self)
            self._punched_nodes = set()  # Reset this.
            self.last_punch_time_ms = t_ms
            self.node.color = ((0+random.random()*6.5),(0+random.random()*6.5),(0+random.random()*6.5))
            self.node.highlight = ((0+random.random()*6.5),(0+random.random()*6.5),(0+random.random()*6.5))
            ba.emitfx(position=self.node.position,velocity=self.node.velocity,count=35,scale=0.5,spread=2,chunk_type='spark')
            self.node.punch_pressed = True
            if not self.node.hold_node:
                ba.timer(
                    0.1,
                    ba.WeakCall(self._safe_play_sound,
                                SpazFactory.get().swish_sound, 0.8))
        self._turbo_filter_add_press('punch')

    def on_jump_press(self) -> None:
        """
        Called to 'press jump' on this spaz;
        used by player or AI connections.
        """
        if not self.node:
            return
        if don.jumpFly:
            self.node.handlemessage("impulse",self.node.position[0],self.node.position[1]-2,self.node.position[2],self.node.velocity[0]*0,20 +0.01,self.node.velocity[2]*0,10,5,0,0,self.node.velocity[0]*-0.1,20 + 0.01,self.node.velocity[2]*0)
            self.node.handlemessage("impulse",self.node.position[0],self.node.position[1],self.node.position[2],self.node.velocity[0]*0,20 +0.01,self.node.velocity[2]*0,10,5,0,0,self.node.velocity[0]*-0.1,20 + 0.01,self.node.velocity[2]*0)
        self.node.color = ((0+random.random()*6.5),(0+random.random()*6.5),(0+random.random()*6.5))
        self.node.highlight = ((0+random.random()*6.5),(0+random.random()*6.5),(0+random.random()*6.5))
        self.node.jump_pressed = True
        self._turbo_filter_add_press('jump')

    def equip_shields(self, decay: bool = False) -> None:
        """
        Give this spaz a nice energy shield.
        """

        if not self.node:
            ba.print_error('Can\'t equip shields; no node.')
            return

        factory = SpazFactory.get()
        if self.shield is None:
            self.shield = ba.newnode('shield',
                                     owner=self.node,
                                     attrs={
                                         'color': ((0+random.random()*6.5),(0+random.random()*6.5),(0+random.random()*6.5)),
                                         'radius': 1.3
                                     })
            self.node.connectattr('position_center', self.shield, 'position')
            #ba.animate_array(self.shield, 'color', 3,{0:(1,0,0),0.2:(1,0.5,0),0.4:(1,1,0),0.6:(0,1,0),0.8:(0,1,1),1.0:(0,0,1),1.2:(1,0,0)},True)
        self.shield_hitpoints = self.shield_hitpoints_max = 650
        self.shield_decay_rate = factory.shield_decay_rate if decay else 0
        self.shield.hurt = 0
        ba.playsound(factory.shield_up_sound, 1.0, position=self.node.position)

        if self.shield_decay_rate > 0:
            self.shield_decay_timer = ba.Timer(0.5,
                                               ba.WeakCall(self.shield_decay),
                                               repeat=True)
            # So user can see the decay.
            self.shield.always_show_health_bar = True

    Spaz.__init__ = _new_init
    Spaz.on_punch_press = on_punch_press
    Spaz.on_jump_press = on_jump_press
    Spaz.equip_shields = equip_shields


from __future__ import division, print_function, absolute_import

import sys
from random import randint, random, shuffle
from turtle import TurtleScreen, RawTurtle, TK
from contextlib import contextmanager

if sys.version_info[0] < 3:
    from Tkinter import Tk, mainloop
else:
    from tkinter import Tk
    mainloop = False

DEBUG = False

def noisy(value, variance=0.01):
    """Add a small amount of noise to a value.

    TODO: use proper gaussian noise"""
    size = value * variance
    return value + (random() * size * 2) - size

@contextmanager
def disable_turtle(t):
    down = t.isdown()
    if down:
        t.penup()
    yield
    if down:
        t.pendown()

def wrap(turtle, half_width, half_height):
    """Provide an pac-man style wrap-around world"""
    x, y = turtle.pos()
    new_x = new_y = None
    if x > half_width:
        new_x = x - half_width * 2
    elif x < -half_width:
        new_x = x + half_width * 2

    if y > half_height:
        new_y = y - half_height * 2
    elif y < -half_height:
        new_y = y + half_height * 2

    with disable_turtle(turtle):
        if new_x is not None:
            turtle.setx(new_x)
        if new_y is not None:
            turtle.sety(new_y)

def clamp(turtle, half_width, half_height):
    """Clamp turtle to window"""
    x, y = turtle.pos()
    new_x = new_y = None
    if x > half_width:
        new_x = half_width
    elif x < -half_width:
        new_x = -half_width

    if y > half_height:
        new_y = half_height
    elif y < -half_height:
        new_y = -half_height

    with disable_turtle(turtle):
        if new_x is not None:
            turtle.setx(new_x)
        if new_y is not None:
            turtle.sety(new_y)

class TurtleWorld(object):

    def __init__(self, width, height, borders=wrap, title="TurtlePower"):
        self.width = width
        self.half_width = width // 2
        self.height = height
        self.half_height = height // 2
        self.borders = borders
        self.window_title = title

        self.init_screen()

        self.fps = 0
        self.done = True
        self.turtles = []

    def init_screen(self):
        # intialise screen and turn off auto-render
        root = Tk()
        root.wm_title(self.window_title)
        window = TK.Canvas(master=root, width=self.width, height=self.height)
        window.pack()
        self.screen = TurtleScreen(window)
        self.screen.tracer(0, 0)

    def position_turtle(self, t, pos=None, angle=None):
        # move to location
        t.hideturtle()
        t.penup()
        if pos is None:
            pos = (randint(-self.half_width, self.half_width),
                   randint(-self.half_height, self.half_height))
        x, y = pos
        t.goto(x, y)
        if angle is None:
            angle = random() * 360
        t.setheading(angle)
        # ready to go
        t.showturtle()
        t.pendown()
        return t

    def random_position(self, turtle):
        return self.position_turtle(turtle)

    def _print_fps(self):  # pragma: no cover
        if not self.done:
            print(self.fps)
            self.screen.ontimer(self._print_fps, 1000)
        self.fps = 0

    def create_turtle(self, callback, pos=None, angle=None):
        t = PowerTurtle(self)
        t.set_callback(callback)
        self.position_turtle(t, pos, angle)
        self.add_turtle(t)
        return t

    def add_turtle(self, turtle):
        turtle.clear()
        self.turtles.append(turtle)

    def remove_turtle(self, turtle):
        turtle.hideturtle()
        turtle.clear()
        self.turtles.remove(turtle)

    def run(self, ticks=1000):
        # run for 1000 ticks
        self.done = False
        if DEBUG:
            self.screen.ontimer(self._print_fps, 1000)
        self.ticks = ticks
        self.screen.ontimer(self.tick, 33)
        self.screen.update()
        if mainloop:
            mainloop()
        else:
            self.screen.mainloop()

    def tick(self):
        shuffle(self.turtles)
        for t in self.turtles:
            t._do_callback()
            self.borders(t, self.half_width, self.half_height)
        self.screen.update()
        self.fps += 1
        self.ticks -= 1
        if self.ticks == 0:
            self.done = True
        else:
            self.screen.ontimer(self.tick, 33)

class PowerTurtleMixin(object):
    """An extension of the basic turtle class.

    Provides some extra methods to make things easy, plus senses and
    integraton with TurtleWorld"""

    # this string type is can be used as a simple type check for user code,
    # rather than having to know about isinstance
    type = "turtle"

    def __init__(self, world, *args, **kwargs):
        self.world = world
        # pass arbitrary args to specific Turtle base class
        super(PowerTurtleMixin, self).__init__(**kwargs)
        self.setup()

    def setup(self):
        """User-defined initialisation function, called once"""

    def callback(self):
        """User-defined act function"""

    def set_callback(self, callback):
        """Set the callback to a function, for classless usage"""
        self.callback = lambda: callback(self)

    def turn_towards(self, desired, amount):
        """Helper to to turn a small amount towards a heading"""
        heading = self.heading()
        angle = desired - heading
        angle = (angle + 180) % 360 - 180
        if angle >= 0:
            amount = min(amount, angle)
        else:
            amount = max(-amount, angle)
        self.left(amount)
        return amount

    def get_neighbours(self, distance=60, angle=120):
        """Other turtles you can see that are with distance and angle of your
        current heading"""
        neighbours = []
        for t in self.world.turtles:
            if t is not self:
                a = abs(self.heading() - self.towards(t))
                if a < angle and self.distance(t) < distance:
                    neighbours.append(t)
        return neighbours

    # Framework methods
    def _do_callback(self):
        """Framework-level callback. Designed to be overridden in subclasses.

        Can be use to provide extra functionality without affect tthe
        user-defined callback() function."""
        self.callback()

class PowerTurtle(PowerTurtleMixin, RawTurtle):
    """PowerTurtle based on stdlib turtle module"""

    def __init__(self, world):
        super(PowerTurtle, self).__init__(world, canvas=world.screen)


from pathlib import Path
import shutil

dirs = [
    'frames_blah_2',
    'frames_converge_fast',
    'frames_converge_slow',
    'frames_decay_into_noise',
    'frames_default',
    'frames_double_center_knob',
    'frames_fast_to_noise',
    'frames_stuff',
]
dirs = [Path(d) for d in dirs]

out_dir = Path('combined_frames')

i = 0
for d in dirs:
    for frame_path in d.glob("*.png"):
        shutil.copy(frame_path, out_dir/ ('%04d.png' % i))
        i += 1