# -*- coding: utf-8 -*-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ParseMode, InputMediaPhoto, ChatAction
from telegram.ext import Updater, CommandHandler, MessageHandler, CallbackQueryHandler, Filters, run_async
from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, NetworkError)
import sys
import os
import time
import re
import matplotlib.pyplot as plt
import matplotlib as mpl
from datetime import datetime
from models import User, Show, Jubilee
from constants import help_msg, about_msg, building_msg, houses_arr, greeting_msg
from classes import filt_integers, filt_call_err, block_filter
from config import log, log_chat, log_msg
from functools import wraps

KEY = sys.argv[1]
ADMIN_ID = sys.argv[2]
print('key ...' + KEY[-6:] + ' successfully used')

def send_typing_action(func):
    """Sends typing action while processing func command."""

    @wraps(func)
    def command_func(*args, **kwargs):
        bot, update = args
        bot.send_chat_action(chat_id=update.effective_message.chat_id, action=ChatAction.UPLOAD_DOCUMENT)
        return func(bot, update, **kwargs)

    return command_func

def chosen_owns(update):
    user_id = update.effective_user.id
    try:
        user = User.select().where(User.user_id == user_id)[Show.get(user_id=user_id).owns or 0]
    except IndexError:
        user = User.select().where(User.user_id == user_id)[0]
    return user

def is_changed(update):
    log.info(log_msg(update))
    # check if user exist in DB (both tables). If not - create
    username = update.effective_user.username
    user_id = update.effective_user.id
    full_name = update.effective_user.full_name

    user, created = User.get_or_create(user_id=user_id)
    Show.get_or_create(user_id=update.effective_user.id)

    if not created:
        # check if user changed own name attributes. If so - update
        if user.username != username or user.full_name != full_name:
            for user in User.select().where(User.user_id == user_id):
                user.username = username
                user.full_name = full_name
                if user.updated:
                    user.updated = datetime.now().strftime('%y.%m.%d %H:%M:%S.%f')[:-4]
                user.save()
    else:
        user.username = update.effective_user.username
        user.full_name = full_name
        user.save()

def start_command(bot, update):
    """handle /start command"""
    log.info(log_msg(update))
    is_changed(update)
    if update.callback_query:
        update.callback_query.answer()
    menu_kbd(bot, update)

def help_command(bot, update):
    """handle /help command"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])
    bot.sendMessage(chat_id=update.effective_user.id, text=help_msg, parse_mode=ParseMode.HTML,
                    reply_markup=reply_markup)

def about_command(bot, update):
    """handle /about command"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])
    bot.sendMessage(chat_id=update.effective_user.id, text=about_msg,
                    parse_mode=ParseMode.HTML, disable_web_page_preview=True, reply_markup=reply_markup)

def building(bot, update):
    """CallbackQueryHandler. pattern ^building$"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])
    bot.sendMessage(chat_id=update.effective_user.id, text=building_msg,
                    parse_mode=ParseMode.HTML, disable_web_page_preview=True, reply_markup=reply_markup)
    update.callback_query.answer()

def new_neighbor_report(bot, update, created_user):
    """Send message for users who enabled notifications"""
    log.info(log_msg(update))
    # query for users who set notifications as _notify_house
    query_params = Show.select(Show.user_id).where(Show.notification_mode == '_notify_house')
    query_users = User.select(User.user_id).where(User.house == created_user.house)
    query = query_params & query_users
    # prevent telegram blocking spam
    for i, user in enumerate(query):
        if i % 29 == 0:
            time.sleep(1)
        try:
            bot.sendMessage(chat_id=user.user_id, parse_mode=ParseMode.HTML,
                            text=f'Новий сусід\n{created_user.joined_str()}')
        except BadRequest as err:
            bot.sendMessage(chat_id=ADMIN_ID, text=f'failed to send notification for user {user.user_id} {err}',
                            parse_mode=ParseMode.HTML)

    # query for users who set notifications as _notify_section
    query_params = Show.select(Show.user_id).where(Show.notification_mode == '_notify_section')
    query_users = query_users.where(User.section == created_user.section)
    query = query_params & query_users
    for i, user in enumerate(query):
        if i % 29 == 0:
            time.sleep(1)
        try:
            bot.sendMessage(chat_id=user.user_id, parse_mode=ParseMode.HTML,
                            text=f'Новий сусід\n{created_user.joined_str()}')
        except BadRequest as err:
            bot.sendMessage(chat_id=ADMIN_ID, text=f'failed to send notification for user {user.user_id} {err}',
                            parse_mode=ParseMode.HTML)

def user_created_report(bot, update, created_user, text):
    """when created new, or updated user - send report-message for admins"""
    bot.sendMessage(chat_id=ADMIN_ID, parse_mode=ParseMode.HTML, text=f'{text} {created_user.user_created()}')
    try:
        bot.sendMessage(chat_id=986555, parse_mode=ParseMode.HTML, text=f'{text} {created_user.user_created()}')
    except BadRequest:
        pass

def menu_kbd(bot, update):
    """show keyboard to chose: show neighbors or edit own info"""
    log.info(log_msg(update))
    if User.get(user_id=update.effective_user.id).house and User.get(user_id=update.effective_user.id).section:
        keyboard = [[InlineKeyboardButton('Дивитись сусідів 👫', callback_data='show')],
                    [InlineKeyboardButton('Змінити свої дані ✏', callback_data='edit')],
                    [InlineKeyboardButton('Важлива інфа ℹ', callback_data='building')],
                    [InlineKeyboardButton('Статистика бота 📊', callback_data='statistics')],
                    [InlineKeyboardButton('Мій будинок 🏠', callback_data='house_neighbors'),
                     InlineKeyboardButton('Мій під\'їзд 🔢', callback_data='section_neighbors')],
                    [InlineKeyboardButton('Сповіщення 🔔', callback_data='notifications')]]
    else:
        keyboard = [[InlineKeyboardButton('Додати свої дані 📝', callback_data='edit')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    bot.sendMessage(chat_id=update.effective_user.id, text='Меню:',
                    reply_markup=reply_markup, parse_mode=ParseMode.HTML)

def check_owns(bot, update):
    """check how many records for user in db"""
    log.info(log_msg(update))
    if not len(User.select().where(User.user_id == update.effective_user.id)) > 1:
        if update.callback_query.data == 'house_neighbors':
            show_house(bot, update)
            return
        elif update.callback_query.data == 'section_neighbors':
            show_section(bot, update)
            return
        else:
            if not User.get(user_id=update.effective_user.id).house:
                text = 'В якому Ви будинку? '
                set_houses_kbd(bot, update, text)
            else:
                text = 'Змінюємо Ваші дані:\n' + User.get(
                    user_id=update.effective_user.id).setting_str() + '\nВ якому Ви будинку? '
                set_houses_kbd(bot, update, text)
    # if more than 1 records for user, call func for select
    else:
        select_owns(bot, update)

def select_owns(bot, update):
    """if user have more than 1 records in db, select which one to show/edit"""
    log.info(log_msg(update))
    if update.callback_query.data == 'house_neighbors':
        text = 'Сусіди по якому будинку? '
        view_edit = 'view_my_house'
    elif update.callback_query.data == 'section_neighbors':
        text = 'Під\'їзд якої з Ваших квартир? '
        view_edit = 'view_my_secti'
    else:
        text = 'Яку адресу змінити? '
        view_edit = 'edit'
    keyboard = []
    user_owns = User.select().where(User.user_id == update.effective_user.id)
    for i, j in enumerate(user_owns):
        keyboard.append([InlineKeyboardButton(str(j.edit_btn_str()), callback_data='set_owns' + str(i) + view_edit)])
    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text(text=text, reply_markup=reply_markup, parse_mode=ParseMode.HTML)
    update.callback_query.answer()

def owns_selected(bot, update):
    """save params to db"""
    log.info(log_msg(update))
    view_edit = update.callback_query.data[-13:]
    owns = [s for s in list(update.callback_query.data) if s.isdigit()]
    owns = int(''.join(owns))
    user = Show.get(user_id=update.effective_user.id)
    user.owns = owns
    user.save()

    if view_edit == 'view_my_house':
        show_house(bot, update)
    elif view_edit == 'view_my_secti':
        show_section(bot, update)
    else:
        user = User.select().where(User.user_id == update.effective_user.id)[owns]
        text = 'Змінюємо Ваші дані:\n' + user.setting_str() + '\nВ якому Ви будинку ? '
        set_houses_kbd(bot, update, text)
    update.callback_query.answer()

def houses_kbd(bot, update):
    """show keyboard to chose house to show"""
    log.info(log_msg(update))
    keyboard = [[InlineKeyboardButton('Будинок 85', callback_data='p_h85'),
                 InlineKeyboardButton('Будинок 87', callback_data='p_h87')],
                [InlineKeyboardButton('Будинок 89', callback_data='p_h89')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text('Який будинок показати ? ', reply_markup=reply_markup)
    update.callback_query.answer()

def section_kbd(bot, update):
    user_query = Show.get(user_id=update.effective_user.id)
    user_query.house = int(update.callback_query.data[-2:])
    user_query.save()

    keyboard = [[InlineKeyboardButton('П-зд №1', callback_data='p_s1'),
                 InlineKeyboardButton('П-зд №2', callback_data='p_s2')],
                [InlineKeyboardButton('П-зд №3', callback_data='p_s3'),
                 InlineKeyboardButton('П-зд №4', callback_data='p_s4')],
                [InlineKeyboardButton('П-зд №5', callback_data='p_s5'),
                 InlineKeyboardButton('П-зд №6', callback_data='p_s6')],
                [InlineKeyboardButton('Показати всіх в цьому будинку? ', callback_data='show_this_house')]]

    if user_query.house == 87:
        del keyboard[1:3]

    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text('Який під\'їзд показати? ', reply_markup=reply_markup)
    update.callback_query.answer()

def save_params(bot, update):
    """callbackQuery from section_kbd(). save params to db table"""
    log.info(log_msg(update))
    user_query = Show.get(user_id=update.effective_user.id)
    user_query.section = int(update.callback_query.data[3])
    user_query.save()
    some_section = True
    show_section(bot, update, some_section)
    update.callback_query.answer()

def set_houses_kbd(bot, update, text=''):
    """show keyboard to chose its own house"""
    log.info(log_msg(update))
    if not User.get(user_id=update.effective_user.id).house:
        text = text
    elif len(User.select().where(User.user_id == update.effective_user.id)) > 1:
        text = text
    else:
        text = text
    keyboard = [[InlineKeyboardButton('Будинок №85', callback_data='_h85'),
                 InlineKeyboardButton('Будинок №87', callback_data='_h87')],
                [InlineKeyboardButton('Будинок №89', callback_data='_h89')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text(text=text, reply_markup=reply_markup, parse_mode=ParseMode.HTML)
    update.callback_query.answer()

def set_section_kbd(bot, update):
    user = chosen_owns(update)
    user.house = int(update.callback_query.data[-2:])
    user.save()

    keyboard = [[InlineKeyboardButton('П-зд №1', callback_data='_s1'),
                 InlineKeyboardButton('П-зд №2', callback_data='_s2')],
                [InlineKeyboardButton('П-зд №3', callback_data='_s3'),
                 InlineKeyboardButton('П-зд №4', callback_data='_s4')],
                [InlineKeyboardButton('П-зд №5', callback_data='_s5'),
                 InlineKeyboardButton('П-зд №6', callback_data='_s6')],
                [InlineKeyboardButton('Завершити редагування', callback_data='_section_reject')]]

    if user.house == 87:
        del keyboard[1:3]

    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text('В якому Ви під\'їзді? ', reply_markup=reply_markup)
    update.callback_query.answer()

def set_floor_kbd(bot, update):
    """callbackQuery from set_section_kbd(). show keyboard to chose its own floor"""
    log.info(log_msg(update))
    user = chosen_owns(update)
    user.section = int(update.callback_query.data[2])
    user.save()

    floors = houses_arr['house_' + str(user.house)]['section_' + str(user.section)]
    keyboard = []
    count_ = len(floors)
    while count_ > 0:
        floor = []
        for i in range(3):
            if count_ == 0:
                break
            floor.append(InlineKeyboardButton(str(floors[-count_]), callback_data='_f' + str(floors[-count_])))
            count_ -= 1
        keyboard.append(floor)

    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text('На якому Ви поверсі ? ', reply_markup=reply_markup)
    update.callback_query.answer()

def set_apartment_kbd(bot, update):
    """func show message with ask to tell its own appartment"""
    log.info(log_msg(update))
    update.callback_query.answer()
    floor = [s for s in list(update.callback_query.data) if s.isdigit()]
    floor = int(''.join(floor))

    user = chosen_owns(update)
    user.floor = floor
    user.save()

    user_mode = Show.get(user_id=update.effective_user.id)
    user_mode.msg_apart_mode = True
    user_mode.save()

    text = 'В якій ви квартирі? \nНапишіть в повідомленні номер квартири, або натисніть кнопку відмови:'
    keyboard = [[InlineKeyboardButton('Не хочу вказувати квартиру', callback_data='_apart_reject')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    update.callback_query.message.reply_text(text=text, reply_markup=reply_markup)

def msg_handler(bot, update):
    """handle all text msg except other filters do"""
    msg = update.message.text
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])
    bot.sendPhoto(chat_id=update.effective_user.id, photo=open(os.path.join('img', 'maybe.jpg'), 'rb'),
                  reply_markup=reply_markup,
                  caption=f'Я ще не розумію людської мови, але вчусь, і скоро буду розуміть деякі слова і фрази\n'
                  f'Краще скористайтесь меню')
    log.info(log_msg(update) + f' text: {msg}')

def group_chat_logging(bot, update):
    """handle text msgs in group chat. MessageHandler((Filters.text & Filters.group)"""
    msg = update.message.text
    log_chat.info(log_msg(update) + f' msg: {msg}')

def jubilee(bot, update, created_user):
    """Check if new added user is 'hero of the day' i.e some round number in db"""
    log.info(log_msg(update))
    celebration_count = [i for i in range(0, 2000, 50)]
    query = User.select().where(User.house, User.section)

    check_list = {85: query.where(User.house == 85).count(),
                  87: query.where(User.house == 87).count(),
                  89: query.where(User.house == 89).count()}
    total = query.count()
    text = f'сусідів 🎇 🎈 🎉 🎆 🍹\nВітаємо\n{created_user.joined_str()}'

    for house in check_list.items():
        if house[1] in celebration_count:
            x, created = Jubilee.get_or_create(house=house[0], count=house[1])
            if created:
                text = f'В будинку № {house[0]} Вже зареєстровано {house[1]} ' + text
                try:
                    bot.sendMessage(chat_id=-1001076439601, text=text, parse_mode=ParseMode.HTML)  # test chat
                except BadRequest:
                    bot.sendMessage(chat_id=-1001118126927, text=text, parse_mode=ParseMode.HTML)  # group chat
                return

    if total in celebration_count:
        text = f'Вже зареэстровано {total} сусідів 🎇 🎈 🎉 🎆 🍹\nВітаємо\n{created_user.joined_str()}'
        x, created = Jubilee.get_or_create(house=0, count=total)
        if created:
            try:
                bot.sendMessage(chat_id=-1001076439601, text=text, parse_mode=ParseMode.HTML)  # test chat
            except BadRequest:
                bot.sendMessage(chat_id=-1001118126927, text=text, parse_mode=ParseMode.HTML)  # group chat

def apartment_save(bot, update):
    """integer text handler"""
    log.info(log_msg(update))
    user_mode = Show.get(user_id=update.effective_user.id)
    text_success = 'Дякую, Ваші дані збережені. Бажаєте подивитись сусідів?'
    if user_mode.msg_apart_mode:
        apartment = int(update.message.text)
        user = chosen_owns(update)
        user.apartment = apartment
        if not user.updated:
            text = 'В базу ДОДАНО сусіда:\n'
        else:
            text = 'В базі ОНОВЛЕНО сусіда:\n'
        user.updated = datetime.now().strftime('%y.%m.%d %H:%M:%S.%f')[:-4]
        user.save()
        bot.sendMessage(text=text_success, chat_id=update.effective_user.id, parse_mode=ParseMode.HTML)
        user_mode.msg_apart_mode = False
        user_mode.save()
        user_created_report(bot, update, created_user=user, text=text)
        new_neighbor_report(bot, update, created_user=user)
        menu_kbd(bot, update)

def save_user_data(bot, update):
    """callbackQuery from reject. save user data"""
    log.info(log_msg(update))
    user = chosen_owns(update)
    if not user.updated:
        text = 'В базу ДОДАНО сусіда:\n'
    else:
        text = 'В базі ОНОВЛЕНО сусіда:\n'

    if update.callback_query.data == '_apart_reject':
        user_mode = Show.get(user_id=update.effective_user.id)
        user_mode.msg_apart_mode = False
        user_mode.save()

        user.apartment = None

    user.updated = datetime.now().strftime('%y.%m.%d %H:%M:%S.%f')[:-4]
    user.save()

    update.callback_query.answer()
    user_created_report(bot, update, created_user=user, text=text)
    new_neighbor_report(bot, update, created_user=user)
    bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML,
                    text='Дякую, Ваші дані збережені. Бажаєте подивитись сусідів?')
    start_command(bot, update)

def show_house(bot, update):
    """callbackQuery handler """
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])

    if update.callback_query.data == 'show_this_house':
        # if user want see selected house
        user_query = Show.get(user_id=update.effective_user.id)
    else:
        # if user want see own house and have one
        user_query = chosen_owns(update)
    neighbors = []
    sections = User.select(User.section).where(User.house == user_query.house).distinct().order_by(User.section)
    for i in sections:
        neighbors.append('\n' + '📭 Під\'їзд '.rjust(30, ' ') + str(i.section) + '' + '\n')
        for user in User.select().where(User.house == user_query.house, User.section == i.section).order_by(User.floor):
            neighbors.append(str(user) + '\n')
    show_list = ('Мешканці будинку №' + str(user_query.house) + ':\n'
                 + '{}' * len(neighbors)).format(*neighbors)

    if len(show_list) < 6200:
        bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML, text=show_list,
                        reply_markup=reply_markup)
    else:
        part_1, part_2, part_3 = show_list.partition('📭 Під\'їзд №4'.rjust(30, ' ') + '' + '\n')
        bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML, text=part_1[:-2])
        # to do: remove "." from 2nd msg. Without that dot, rjust not works
        bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML, text='.' + part_2 + part_3,
                        reply_markup=reply_markup)
    update.callback_query.answer()

def show_section(bot, update, some_section=False):
    """Here need some documentation"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])

    if not some_section:
        user_query = chosen_owns(update)
    else:
        user_query = Show.get(user_id=update.effective_user.id)

    query = User.select().where(
        User.house == user_query.house,
        User.section == user_query.section).order_by(User.floor)
    neighbors = [str(user) + '\n' for user in query]

    show_list = (
            'Мешканці під\'їзду № ' + str(user_query.section) + ' Будинку № ' + str(user_query.house) + ':\n'
            + '{}' * len(neighbors)).format(*neighbors)

    bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML,
                    disable_web_page_preview=True, text=show_list, reply_markup=reply_markup)
    update.callback_query.answer()

def catch_err(bot, update, error):
    """handle all telegram errors end send report. There is no 'update' so can't logging much info"""
    log.info(f'{error} {type(error)}')
    user_id = update.effective_user.id if update else 'no update'
    try:
        raise error
    except Unauthorized:
        bot.sendMessage(chat_id=ADMIN_ID, text=f'ERROR:\n {error}\n type {type(error)} id: {user_id}')
    except BadRequest:
        bot.sendMessage(chat_id=ADMIN_ID, text=f'ERROR:\n {error}\n type {type(error)} id: {user_id}')
    except (TimedOut, NetworkError, TelegramError):
        bot.sendMessage(chat_id=ADMIN_ID, text=f'ERROR:\n {error}\n type {type(error)} id: {user_id}')

# to do: apply to more then 1 custom filter
@run_async
def del_msg(bot, update):
    """message text handler for specific words in group chats MessageHandler((Filters.group & block_filter).
    See filters in classes module
    """
    chat_id = update.message.chat_id
    message_id = update.message.message_id
    pattern = block_filter(update.message)
    warn_msg = f'Повідомлення які містять {pattern} видаляються автоматично'

    bot.deleteMessage(chat_id=chat_id, message_id=message_id)
    deleted_msg = bot.sendMessage(chat_id=chat_id, parse_mode=ParseMode.HTML, text=warn_msg)
    time.sleep(5)
    bot.deleteMessage(chat_id=chat_id, message_id=deleted_msg.message_id)
    log.info(log_msg(update) + f' {pattern}')

@run_async
def greeting(bot, update):
    """handle new chat members, and sent greeting message. Delete after delay. Running async"""
    log.info(log_msg(update))
    new_member_name = update.message.new_chat_members[0].full_name
    text = greeting_msg.format(new_member_name)
    update.message.reply_text(text=text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)

def prepare_data():
    """Create show_list (string) for statistic message, and pie_values (list) for chart.
    return from func if no users in db"""
    log.info('this func has no update')
    query = User.select()
    query_with = query.where(User.house, User.section)
    query_without = query.where(User.house.is_null() | User.section.is_null())
    houses = query_with.select(User.house).distinct().order_by(User.house)

    # did users indicate their info
    introduced = {'Yes': query_with.count(), 'No': query_without.count()}
    # last 3 joined users
    last_3_users = list(reversed(query_with.order_by(User.id)[-3:]))

    if not last_3_users:
        return

    neighbors = []
    pie_values = []
    bars_values = {}
    for house_ in houses:
        count = query_with.where(User.house == house_.house).count()
        pie_values.append((house_.house, count))
        neighbors.append('\n' + '🏠 Будинок '.rjust(30, ' ') + f'{house_.house} ({count})\n')
        sections = query_with.select(User.section).where(User.house == house_.house).distinct().order_by(User.section)
        section_dict = {}
        for section_ in sections:
            count = query_with.where(User.house == house_.house, User.section == section_.section).count()
            neighbors.append(f'П-зд {section_.section} ({count})\n')
            section_dict[section_.section] = count
        bars_values[house_.house] = section_dict

    show_list = (f'Всього користувачів: {query.count()}\n'
                 f'Дані вказані {introduced["Yes"]}\n'
                 f'Дані не вказані {introduced["No"]}\n'
                 + '{}' * len(neighbors)).format(*neighbors) + '\nНові сусіди'

    # add to msg last 3 joined users
    for i in range(len(last_3_users)):
        show_list += f'\n{last_3_users[i].joined_str()}'

    return {'show_list': show_list, 'pie_values': pie_values, 'bars_values': bars_values, 'introduced': introduced}

def statistics(bot, update):
    """callbackQuery handler. pattern:^statistics$"""
    log.info(log_msg(update))
    update.callback_query.answer()
    keyboard = [[InlineKeyboardButton('Меню', callback_data='_menu'),
                 InlineKeyboardButton('Графіка', callback_data='charts')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    show_list = prepare_data()['show_list']
    bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML, text=show_list,
                    reply_markup=reply_markup)

def make_pie(prepared_data):
    """create pie total by houses"""
    log.info('this func has no update')

    # func for setting values format on pie
    def make_autopct(values):
        def my_autopct(pct):
            total = sum(values)
            val = int(round(pct * total / 100.0))
            return val

        return my_autopct

    # pie by house
    values = [i[1] for i in prepared_data['pie_values']]
    labels = [f'Буд. {i[0]}' for i in prepared_data['pie_values']]

    fig = plt.figure(figsize=(10, 7))
    mpl.rcParams.update({'font.size': 20})
    plt.pie(values, autopct=make_autopct(values), radius=1.5, pctdistance=0.8,
            shadow=True, labels=labels, labeldistance=1.05)

    img_path = os.path.join('img', 'charts', '1_pie.png')
    fig.savefig(img_path)
    plt.clf()
    plt.close()

    # pie by introduced
    values = list(prepared_data['introduced'].values())
    labels = list(prepared_data['introduced'].keys())

    fig = plt.figure(figsize=None)
    mpl.rcParams.update({'font.size': 16})
    plt.title('Користувачі вказали свої дані', pad=15)
    plt.pie(values, autopct=make_autopct(values), radius=1.3, pctdistance=0.8,
            shadow=True, labels=labels, labeldistance=1.05)

    img_path = os.path.join('img', 'charts', '2_pie.png')
    fig.savefig(img_path)
    plt.clf()
    plt.close()

def make_bars(prepared_data):
    """create bars for houses sections count"""
    log.info('this func has no update')
    values_ = prepared_data['bars_values']

    def autolabel(rects, height_factor):
        for i, rect in enumerate(rects):
            height = rect.get_height()
            label = '%d' % int(height)
            ax.text(rect.get_x() + rect.get_width() / 2., height_factor * height,
                    '{}'.format(label),
                    ha='center', va='bottom')

    mpl.rcParams.update({'font.size': 15})

    for house in values_:
        sections = [f'П-зд {i[-1]}' for i in houses_arr[f'house_{house}']]
        values = [values_[house].get(int(i[-1]), 0) for i in sections]

        plt.bar(sections, values)
        ax = plt.gca()
        ax.set_title(f'Будинок {house}')
        autolabel(ax.patches, height_factor=0.85)

        img_path = os.path.join('img', 'charts', f'bar{house}.png')
        plt.savefig(img_path, dpi=200)
        plt.clf()
        plt.close()

@send_typing_action
def charts(bot, update):
    """callbackQuery handler. pattern:^charts$. Show chart"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])

    prepared_data = prepare_data()
    make_pie(prepared_data)
    make_bars(prepared_data)

    charts_dir = os.path.join('img', 'charts')
    charts_list = sorted([f for f in os.listdir(charts_dir) if not f.startswith('.')])
    media = [InputMediaPhoto(open(os.path.join('img', 'charts', i), 'rb')) for i in charts_list]

    bot.sendMediaGroup(chat_id=update.effective_user.id, media=media)
    bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML,
                    reply_markup=reply_markup, text='Повернутись в меню:')
    update.callback_query.answer()

def notifications_kbd(bot, update):
    """callbackQuery handler. pattern:^notifications$. Show notifications keyboard settings"""
    log.info(log_msg(update))
    keyboard = [[InlineKeyboardButton('В моєму будинку 🏠', callback_data='_notify_house')],
                [InlineKeyboardButton('В моєму під\'їзді 🔢', callback_data='_notify_section')],
                [InlineKeyboardButton('Вимкнути сповіщення 🔕', callback_data='_notify_OFF')],
                [InlineKeyboardButton('Меню', callback_data='_menu')]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    user = Show.get(user_id=update.effective_user.id)
    _dict = {None: 'Вимкнено', '_notify_OFF': 'Вимкнено',
             '_notify_section': 'В моєму під\'їзді 🔢', '_notify_house': 'В моєму будинку 🏠'}
    text = f'Зараз сповіщення встановленні в режим\n' \
        f'{_dict[user.notification_mode]}\nОтримувати сповіщення коли з\'явиться новий сусід:'
    bot.editMessageText(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML,
                        text=text, reply_markup=reply_markup, message_id=update.effective_message.message_id)
    update.callback_query.answer()

def notifications_save(bot, update):
    """callbackQuery handler. pattern: from notifications_kbd func. Save notifications settings to db"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])

    user = Show.get(user_id=update.effective_user.id)
    user.notification_mode = update.callback_query.data
    user.save()
    bot.editMessageText(text='Ок! Налаштування збережено', chat_id=update.effective_chat.id, parse_mode=ParseMode.HTML,
                        message_id=update.effective_message.message_id, reply_markup=reply_markup)
    update.callback_query.answer()

def del_command(bot, update):
    """For deleting commands sent in group chat. MessageHandler(Filters.command & Filters.group).
    If so - delete message from group chat. """
    command = re.sub(r'@.*', '', update.message.text)
    log.info(log_msg(update) + f' DEL {command}')
    chat_id = update.message.chat_id
    message_id = update.message.message_id
    bot.deleteMessage(chat_id=chat_id, message_id=message_id)
    commands = {'/start': start_command,
                '/help': help_command,
                '/about': about_command}
    try:
        commands[command](bot, update)
    except KeyError:
        pass

def talkative(bot, update):
    """Statistics for messaging in group chat. Show top 10 by msgs and by chars"""
    log.info(log_msg(update))
    reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('Меню', callback_data='_menu')]])

    log_files_list = [f for f in os.listdir('logfiles') if not f.startswith('.')]
    data = {}
    id_pattern = r' ([0-9]{6,10}) '
    pattern = r' ([0-9]{6,10}) name: (.*) usrnm: '

    for log_file in log_files_list:
        with open(os.path.join('logfiles', log_file), mode='r', encoding='utf-8') as file:
            text = file.read()
            match = list(set(re.findall(pattern, text)))
            data = {i[0]: [0, 0, i[1]] for i in match}

    for log_file in log_files_list:
        with open(os.path.join('logfiles', log_file), mode='r', encoding='utf-8') as file:
            for line in file.readlines():
                try:
                    id_ = re.search(id_pattern, line).group().strip()
                    data[id_][0] += len(line.split('msg: ')[1].strip())
                    data[id_][1] += 1
                except (KeyError, AttributeError):
                    pass

    by_chars = sorted(data.items(), key=lambda x: x[1][0], reverse=True)
    by_msgs = sorted(data.items(), key=lambda x: x[1][1], reverse=True)

    template = '{} {}'

    talkatives_chars = [template.format(user[0], user[1][2], user[1][0]) + '\n' for user in by_chars[:10]]
    talkatives_msgs = [template.format(user[0], user[1][2], user[1][1]) + '\n' for user in by_msgs[:10]]

    show_list = ('Лідери по кількості знаків\n' + '{}'
                 * len(talkatives_chars)).format(*talkatives_chars) + '\n' + \
                ('Лідери по кількості повідомлень\n' + '{}' * len(talkatives_msgs)).format(
        *talkatives_msgs)

    bot.sendMessage(chat_id=update.effective_user.id, parse_mode=ParseMode.HTML,
                    disable_web_page_preview=True, text=show_list, reply_markup=reply_markup)

def main():
    updater = Updater(KEY)

    dispatcher = updater.dispatcher
    # group filters
    dispatcher.add_handler(MessageHandler(Filters.status_update.new_chat_members, greeting))
    dispatcher.add_handler(MessageHandler((Filters.command & Filters.group), del_command))
    dispatcher.add_handler(MessageHandler((Filters.group & block_filter), del_msg))
    dispatcher.add_handler(MessageHandler((Filters.text & Filters.group), group_chat_logging))

    dispatcher.add_handler(CommandHandler("start", start_command))
    dispatcher.add_handler(CommandHandler("help", help_command))
    dispatcher.add_handler(CommandHandler("about", about_command))

    dispatcher.add_handler(MessageHandler(filt_integers, apartment_save))
    dispatcher.add_handler(MessageHandler(filt_call_err, talkative))
    dispatcher.add_handler(MessageHandler(Filters.text, msg_handler))
    dispatcher.add_handler(CallbackQueryHandler(callback=start_command, pattern='^_menu$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=building, pattern='^building$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=statistics, pattern='^statistics$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=charts, pattern='^charts$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=notifications_kbd, pattern='^notifications$'))
    dispatcher.add_handler(
        CallbackQueryHandler(callback=notifications_save, pattern='^_notify_section$|^_notify_house$|^_notify_OFF$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=houses_kbd, pattern='^show$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=show_house, pattern='^show_this_house$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=section_kbd, pattern='^p_h'))
    dispatcher.add_handler(CallbackQueryHandler(callback=save_params, pattern='^p_s'))
    dispatcher.add_handler(
        CallbackQueryHandler(callback=check_owns, pattern='^edit$|^house_neighbors$|section_neighbors'))
    dispatcher.add_handler(CallbackQueryHandler(callback=owns_selected, pattern='^set_owns'))
    dispatcher.add_handler(CallbackQueryHandler(callback=set_section_kbd, pattern='^_h'))
    dispatcher.add_handler(
        CallbackQueryHandler(callback=save_user_data, pattern='^_apart_reject$|^_floor_reject$|^_section_reject$'))
    dispatcher.add_handler(CallbackQueryHandler(callback=set_floor_kbd, pattern='^_s'))
    dispatcher.add_handler(CallbackQueryHandler(callback=set_apartment_kbd, pattern='^_f'))

    dispatcher.add_error_handler(catch_err)

    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()


import os
import time

from requests_html import HTMLSession
import re
import json

page = input("请输入你要爬取结束的页数")

content = {}
session = HTMLSession()
for k in range(1, int(page)+1):
    url = f'http://www.haoduanzi.com/category/?1-{k}.html'
    response = session.get(url=url)
    response.encoding = 'utf-8'

    # print(response.text)
    content_title = re.findall('
(.*?)
', response.text, re.S)
    content_text = re.findall('
(.*?)
', response.text, re.S)
    print(content_title)
    print(len(content_text))
    for i in range(len(content_title)):
        content[content_title[i]] = content_text[i]
    # print(re.findall('
(.*?)
', content_title))
    # print(content_title, content_text)
    content = {key: re.sub(r'\s|

', '', value) for key, value in content.items()}
    content = json.dumps(content, indent=4, ensure_ascii=False)
    print(content)
    time.sleep(3)
    file = os.getcwd() + r'\好段子'
    print(file)
    if not os.path.exists(file):
        os.mkdir(file)
    with open(file + rf'\好段子第{k}页.json', 'w', encoding='utf-8') as f:
        f.write(content)
    content = {}


# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score

def calculate_performance_metrics(y_true, y_predicted):
    """
    Calculate the R2 score and root mean squared error
    :param y_true: ground truth value
    :param y_predicted: predicted value
    :return:
    """
    r2 = r2_score(y_true, y_predicted)
    rmse = mean_squared_error(y_true, y_predicted, squared=False)
    print(f"R2 Score: {r2}")
    print(f"RMSE: {rmse}")

def clean_google_trends_data(df, start_date, max_date):
    """
    Convenience function to truncate and interpolate Google Trends data. We use linear
    interpolation, since the trends data only supplies information on a per-month, rather
    than per-day basis

    :param df: trends dataframe
    :param start_date: start date of the dataframe
    :param max_date: end date of the dataframe
    :return:
    """
    trends = df.copy()
    trends["Date"] = pd.to_datetime(trends["Month"], format="%Y-%m")
    trends.drop("Month", axis=1, inplace=True)

    # ensure maximum date matches up with price data
    trends = trends.loc[trends["Date"] >= start_date]
    trends = pd.concat(
        [trends, pd.DataFrame(data={"Date": [max_date], "Interest": [np.NaN]})],
        ignore_index=True,
    )

    # perform linear interpolation
    trends = trends.set_index("Date")
    trends = trends.resample("D").mean()
    trends = trends.interpolate()
    trends = trends.reset_index()
    return trends

def set_nonnegative_forecasts(forecast):
    """
    Set all FB Prophet values that are negative to 0

    :param forecast: time series input with yhat, yhat_lower, yhat_upper
    :return:
    """
    forecast.loc[forecast["yhat"] < 0, "yhat"] = 0
    forecast.loc[forecast["yhat_lower"] < 0, "yhat_lower"] = 0
    forecast.loc[forecast["yhat_upper"] < 0, "yhat_upper"] = 0


import falcon

try:
    import simplejson as json
except ImportError:
    import json

from didery.routing import *

def test_csvs_get(client):
    surveyResult = {
        "name": "Fred Astaire",
        "address": {
            "street": "546 N 798 W",
            "city": "Austin",
            "state": "TX",
            "zip": 84057
        },
        "details": {
            "education": {
                "college": {
                    "name": "UVU",
                    "address": {
                        "street": "546 N 798 W",
                        "city": "Austin",
                        "state": "TX",
                        "zip": 84057
                    },
                    "degree": "Computer Science"
                }
            },
            "favorite_food": "Pizza",
            "test_scores": [
                10,
                9,
                10,
                7
            ]
        },
        "image": [
            [1, 2, 3, 4],
            [5, 6, 7],
            [8, 9],
            [],
        ],
        "family": [
            {
                "name": "Frank Astaire",
                "age": 67,
                "relation": "Father"
            },
            {
                "name": "Wilma Astaire",
                "age": 62,
                "relation": "Mother"
            }
        ]
    }

    for i in range(0, 10):
        response = client.simulate_post(SURVEY_BASE_PATH, body=json.dumps(surveyResult).encode())
        assert response.status == falcon.HTTP_201

    response = client.simulate_get(CSVS_BASE_PATH)

    exp_response_headers = b'name,street,city,state,zip,name,street,city,state,zip,degree,favorite_food,test_scores,test_scores,test_scores,test_scores,image,image,image,image,image,image,image,image,image,name,age,relation,name,age,relation,ip_address,received'
    exp_response_value = b'Fred Astaire,546 N 798 W,Austin,TX,84057,UVU,546 N 798 W,Austin,TX,84057,Computer Science,Pizza,10,9,10,7,1,2,3,4,5,6,7,8,9,Frank Astaire,67,Father,Wilma Astaire,62,Mother,127.0.0.1'

    response_values = response.content.strip().split(b'\r\n')

    assert response.status == falcon.HTTP_200
    assert response_values[0] == exp_response_headers

    for value in response_values[1:]:
        assert exp_response_value in value


# encoding: utf-8

from fastreid.layers import *
from fastreid.utils.weight_init import weights_init_kaiming, weights_init_classifier
from .build import REID_HEADS_REGISTRY
from .classsifiers import get_classifier
import numpy as np
import torch.nn.functional as F

class ScaledDotProductAttention(nn.Module):
    ''' Scaled Dot-Product Attention '''

    def __init__(self, temperature, attn_dropout=0.1):
        super().__init__()
        self.temperature = temperature
        self.dropout = nn.Dropout(attn_dropout)
        self.softmax = nn.Softmax(dim=2)

    def forward(self, q, k, v):
        attn = torch.bmm(q, k.transpose(1, 2))
        attn = attn / self.temperature
        log_attn = F.log_softmax(attn, 2)
        attn = self.softmax(attn)
        attn = self.dropout(attn)
        output = torch.bmm(attn, v)
        return output, attn, log_attn

class MultiHeadAttention(nn.Module):
    ''' Multi-Head Attention module '''

    def __init__(self, n_head, d_model, d_k, d_v, dropout=0.1):
        super().__init__()
        self.n_head = n_head
        self.d_k = d_k
        self.d_v = d_v

        self.w_qs = nn.Linear(d_model, n_head * d_k, bias=False)
        self.w_ks = nn.Linear(d_model, n_head * d_k, bias=False)
        self.w_vs = nn.Linear(d_model, n_head * d_v, bias=False)
        nn.init.normal_(self.w_qs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k)))
        nn.init.normal_(self.w_ks.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k)))
        nn.init.normal_(self.w_vs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_v)))

        self.attention = ScaledDotProductAttention(temperature=np.power(d_k, 0.5))
        self.layer_norm = nn.LayerNorm(d_model)

        self.fc = nn.Linear(n_head * d_v, d_model)
        nn.init.xavier_normal_(self.fc.weight)
        self.dropout = nn.Dropout(dropout)

    def forward(self, q, k, v):
        d_k, d_v, n_head = self.d_k, self.d_v, self.n_head
        sz_b, len_q, _ = q.size()
        sz_b, len_k, _ = k.size()
        sz_b, len_v, _ = v.size()

        residual = q
        q = self.w_qs(q).view(sz_b, len_q, n_head, d_k)
        k = self.w_ks(k).view(sz_b, len_k, n_head, d_k)
        v = self.w_vs(v).view(sz_b, len_v, n_head, d_v)

        q = q.permute(2, 0, 1, 3).contiguous().view(-1, len_q, d_k)  # (n*b) x lq x dk
        k = k.permute(2, 0, 1, 3).contiguous().view(-1, len_k, d_k)  # (n*b) x lk x dk
        v = v.permute(2, 0, 1, 3).contiguous().view(-1, len_v, d_v)  # (n*b) x lv x dv

        output, attn, log_attn = self.attention(q, k, v)

        output = output.view(n_head, sz_b, len_q, d_v)
        output = output.permute(1, 2, 0, 3).contiguous().view(sz_b, len_q, -1)  # b x lq x (n*dv)

        output = self.dropout(self.fc(output))
        output = self.layer_norm(output + residual)

        return output

@REID_HEADS_REGISTRY.register()
class ProtoneckHead(nn.Module):
    def __init__(self, cfg, in_feat, num_classes, pool_layer):
        super().__init__()
        self.neck_feat = cfg.MODEL.HEADS.NECK_FEAT
        self.pool_layer = pool_layer
        self.cfg = cfg
        self.bnneck = get_norm(cfg.MODEL.HEADS.NORM, in_feat, cfg.MODEL.HEADS.NORM_SPLIT, bias_freeze=True)
        self.bnneck.apply(weights_init_kaiming)
        hdim = 2048
        self.slf_attn = MultiHeadAttention(1, hdim, hdim, hdim, dropout=0.5)
        # identity classification layer
        cls_type = cfg.MODEL.HEADS.CLS_LAYER
        if cls_type == 'linear':
            self.classifier = get_classifier(cfg, cls_type, in_feat, num_classes, bias=False)
        else:
            self.classifier = get_classifier(cfg, cls_type, in_feat, num_classes)

        self.classifier.apply(weights_init_classifier)

    def forward(self, features, targets=None):
        """
        See :class:`ReIDHeads.forward`.
        """
        global_feat = self.pool_layer(features)
        bn_feat = self.bnneck(global_feat)
        bn_feat = bn_feat[..., 0, 0]
        bn_feat = bn_feat.unsqueeze(0)
        bn_feat = self.slf_attn(bn_feat,bn_feat,bn_feat)
        bn_feat = bn_feat.squeeze(0)
        # Evaluation
        if not self.training:

            return bn_feat

        # Training

        # emb_dim = bn_feat.size(-1)
        # class_feat = bn_feat.view(self.cfg.SOLVER.IMS_PER_BATCH/self.cfg.DATALOADER.NUM_INSTANCE,self.cfg.DATALOADER.NUM_INSTANCE,-1)
        # fake_gallery = class_feat[:,:self.cfg.DATALOADER.NUM_INSTANCE//2,:]
        # fake_query = class_feat[:,self.cfg.DATALOADER.NUM_INSTANCE//2:,:]
        #
        #
        # num_query = np.prod(fake_query.shape[-2:])
        # fake_gallery = self.slf_attn(fake_gallery,fake_gallery,fake_gallery)
        # fake_query = fake_query.view(-1,emb_dim).unsqueeze(1)

        if self.classifier.__class__.__name__ == 'Linear':
            cls_outputs = self.classifier(bn_feat)
        else:
            cls_outputs = self.classifier(bn_feat, targets)

        pred_class_logits = F.linear(bn_feat, self.classifier.weight)

        if self.neck_feat == "before":  feat = global_feat[..., 0, 0]
        elif self.neck_feat == "after": feat = bn_feat
        else:
            raise KeyError("MODEL.HEADS.NECK_FEAT value is invalid, must choose from ('after' & 'before')")
        #fake_label_aux = torch.arange(4, dtype=torch.int8).repeat(10).view(10,4).transpose(0,1).contiguous().view(-1)

        return cls_outputs, pred_class_logits, feat


import uuid
import hashlib
import random
import requests

def encode_param(text):

  base = "PXhw7UT1B0a9kQDKZsjIASmOezxYG4CHo5Jyfg2b8FLpEvRr3WtVnlqMidu6cN"
  #print("base", base, len(base))
  base_ix = list(range(len(base)))

  out = ""
  arr = [ord(c) for c in text]
  for i in range(len(text)):

    t = text[i]

    num0 = base.find(t)
    if num0 == -1:
      code = t
    else:
      code = base[(num0+3)%62]

    num1 = random.choice(base_ix)
    num2 = random.choice(base_ix)

    a = base[num1] + code + base[num2]
    out = out + a

    #print("i=%s" % i, "a", a)

  return out

if __name__ == "__main__":

  address = "THQscEopvnPmTnWSBkSgDC9HE3m5SC2yyE"
  url = "https://back.quantum-us.org/index.php/Home/Tron/rechange"
  txid = "d63a0a2e753464247d5a594d4a44d7274e70902c33c6da6eaeb0fa5a488b3555"

  post_data = {
    "unknown": encode_param(address),
    "amount": 3500,
    "day": 12,
    "txid": txid,
  }
  rep = requests.get(url, params=post_data)
  print("rep1", rep, rep.content)
  rep_data = rep.json()
  print("rep2", rep_data)


#!/usr/bin/env python3

"""
script for converting a stockholm formatted alignment to single line
"""

import os
import re
import sys

def print_line(l):
    """
    print line if starts with ...
    """
    print_lines = ['# STOCKHOLM', '#=GF', '#=GS', ' ']
    if len(l.split()) == 0:
        return True
    for start in print_lines:
        if l.startswith(start):
            return True
    return False

def stock2one(stock):
    """
    convert stockholm to single line format
    """
    lines = {}
    for line in stock:
        line = line.strip()
        if print_line(line) is True:
            yield line
            continue
        if line.startswith('//'):
            continue
        ID, seq = line.rsplit(' ', 1)
        if ID not in lines:
            lines[ID] = ''
        else:
            # remove preceding white space
            seq = seq.strip()
        lines[ID] += seq
    for ID, line in lines.items():
        yield '\t'.join([ID, line])
    yield '\n//'

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('convert to single line stockholm formatted alignment')
        exit()
    stock = sys.argv[1]
    if stock == '-':
        stock = sys.stdin
    else:
        stock = open(stock)
    for line in stock2one(stock):
        print(line)


#!/usr/bin/env python
import rospy
import time
import math

from geometry_msgs.msg import Vector3
from geometry_msgs.msg import Pose
from std_msgs.msg import Empty
from pid_class import PID
from rosgraph_msgs.msg import Clock
from std_msgs.msg import String

class PositionController():

  def __init__(self):
    # When this node shutsdown
    rospy.on_shutdown(self.shutdown_sequence)

    # Set the rate
    self.rate = 100.0
    self.dt = 1.0 / self.rate

    # Getting the PID parameters
    stable_gains = rospy.get_param('/position_controller_node/gains/stable/', {'p': 1, 'i': 0.0, 'd': 0.0})
    Kp_s, Ki_s, Kd_s = stable_gains['p'], stable_gains['i'], stable_gains['d']

    unstable_gains = rospy.get_param('/position_controller_node/gains/unstable/', {'p': 1, 'i': 0.0, 'd': 0.0})
    Kp_u, Ki_u, Kd_u = unstable_gains['p'], unstable_gains['i'], unstable_gains['d']

    # Getting the save file parameters
    save_location = rospy.get_param("/position_controller_node/save_location")
    save_name = rospy.get_param("/position_controller_node/save_name")

    # Getting the requested speed
    self.speed = rospy.get_param('/position_controller_node/speed')

    # If the speed is set to unstable waypoint
    Kp, Ki, Kd = 0, 0, 0
    if self.speed == -2:
      Kp = Kp_u
      Ki = Ki_u
      Kd = Kd_u
    else:
      Kp = Kp_s
      Ki = Ki_s
      Kd = Kd_s

    # Display incoming parameters
    rospy.loginfo(str(rospy.get_name()) + ": Lauching with the following parameters:")
    rospy.loginfo(str(rospy.get_name()) + ": p - " + str(Kp))
    rospy.loginfo(str(rospy.get_name()) + ": i - " + str(Ki))
    rospy.loginfo(str(rospy.get_name()) + ": d - " + str(Kd))
    rospy.loginfo(str(rospy.get_name()) + ": rate - " + str(self.rate))
    rospy.loginfo(str(rospy.get_name()) + ": speed - " + str(self.speed))
    rospy.loginfo(str(rospy.get_name()) + ": save_location - " + str(save_location))
    rospy.loginfo(str(rospy.get_name()) + ": save_name - " + str(save_name))

    # File location of the goals
    file_location = save_location + "/" + save_name

    # Open a file writer to save the information
    self.filehandler = open(file_location, "w")

    # Creating the PID's
    self.pos_x_PID = PID(Kp, Ki, Kd, self.rate)
    self.pos_y_PID = PID(Kp, Ki, Kd, self.rate)
    self.pos_z_PID = PID(Kp, Ki, Kd, self.rate)

    # Get the setpoints
    self.x_setpoint = 0
    self.y_setpoint = 0
    self.z_setpoint = 0

    # Create the current output readings
    self.x_pos = 0
    self.y_pos = 0
    self.z_pos = 0

    # Used to save the clock
    self.current_time = rospy.Time()
    self.prev_time_check = rospy.Time()

    # Checks to see if the simulation has started
    self.started = False

    # Create the subscribers and publishers
    self.vel_set_sub = rospy.Publisher('/uav/input/velocity', Vector3, queue_size=1)
    self.gps_sub = rospy.Subscriber("uav/sensors/gps", Pose, self.get_gps)
    self.pos_set_sub = rospy.Subscriber("uav/input/position", Vector3, self.set_pos)
    self.col_pub = rospy.Subscriber('/uav/collision', Empty, self.collision_callback)
    self.shutdown_sub = rospy.Subscriber('/test/completed', Empty, self.completed_callback)
    self.navigation_start = rospy.Subscriber('/test/started', Empty, self.start_callback)
    self.clock_sub = rospy.Subscriber('/clock', Clock, self.clock_callback)
    self.order_pub = rospy.Publisher('/order', String, queue_size=10)

    # Run the communication node
    self.ControlLoop()

  # This is the main loop of this class
  def ControlLoop(self):
    # Set the rate
    rate = rospy.Rate(1000)

    # Keep track how many loops have happend
    loop_counter = 0

    # While running
    while not rospy.is_shutdown():

      if self.started:

        # Use a PID to calculate the velocity you want
        x_proportion = self.pos_x_PID.get_output(self.x_setpoint, self.x_pos)
        y_proportion = self.pos_y_PID.get_output(self.y_setpoint, self.y_pos)
        z_proportion = self.pos_z_PID.get_output(self.z_setpoint, self.z_pos)

        # Initialize the components of the vector
        x_vel = 0
        y_vel = 0
        z_vel = 0

        # If we are in waypoint mode
        if self.speed < 0:
          # Set the velocity based on distance
          x_vel = x_proportion
          y_vel = y_proportion
          z_vel = z_proportion

        # If we are in constant speed mode
        else:
          total = abs(x_proportion) + abs(y_proportion) + abs(z_proportion)

          # If we are not moving yet
          if total == 0:
            total = 1

          # Set the velocity to in m/s
          velocity_total = self.speed # m/s

          # Calculate the velocity in the x and y direction
          x_ratio = (x_proportion/total)
          y_ratio = (y_proportion/total)
          z_ratio = (z_proportion/total)

          # Compute the scaling factor
          scaling_factor = float(velocity_total) / math.sqrt(math.pow(x_ratio, 2) + math.pow(y_ratio, 2) + math.pow(z_ratio, 2))

          # Compute the velocity
          x_vel = x_ratio * scaling_factor
          y_vel = y_ratio * scaling_factor
          z_vel = z_ratio * scaling_factor

        # Create and publish the data
        velocity = Vector3(x_vel, -1* y_vel, z_vel)
        self.vel_set_sub.publish(velocity)
        order_string = "position controller: %s" % rospy.get_time()
        self.order_pub.publish(order_string)

        # Logging
        self.filehandler.write("-----------------------\n")
        self.filehandler.write("Loop Counter: " + str(loop_counter) + "\n")
        self.filehandler.write("Publishing Time: " + str(self.current_time.to_sec()) + "\n")
        self.filehandler.write("Velocity X: " + str(velocity.x) + "\n")
        self.filehandler.write("Velocity Y: " + str(velocity.y) + "\n")
        self.filehandler.write("Velocity Z: " + str(velocity.z) + "\n")

      # While we are waiting for our rate
      while self.current_time.to_sec() - self.prev_time_check.to_sec() < self.dt:
        # Sleep any excess time
        rate.sleep()
        # Check if ROS has shut down
        if rospy.is_shutdown():
          break

      # Save the start of the new loop
      self.prev_time_check = self.current_time
      loop_counter += 1

    # Close the file
    time.sleep(1)
    self.filehandler.close()

  # Used to save the time
  def clock_callback(self, clock_msg):
    self.current_time = clock_msg.clock

  # Call back to get the gps data
  def get_gps(self, msg):
    self.x_pos = msg.position.x
    self.y_pos = msg.position.y
    self.z_pos = msg.position.z

  # Call back to get the position setpoints
  def set_pos(self, msg):
    # If our set point changes reset the PID build up
    if self.x_setpoint != msg.x:
      self.pos_x_PID.remove_buildup()
      self.pos_y_PID.remove_buildup()
      self.pos_z_PID.remove_buildup()

    self.x_setpoint = msg.x
    self.y_setpoint = msg.y
    self.z_setpoint = msg.z

  # Called when the navigation is started
  def start_callback(self, msg):
    # Set the started flag to true
    rospy.loginfo(str(rospy.get_name()) + ": Position Controller")
    self.started = True

  # On collsion reset the PID's
  def collision_callback(self, msg):
    self.pos_x_PID.remove_buildup()
    self.pos_y_PID.remove_buildup()
    self.pos_z_PID.remove_buildup()

  # Called when the navigation is completed
  def completed_callback(self, msg):
    # Shutdown as there is nothing left to do
    rospy.signal_shutdown("Navigation Complete")

	# Called on ROS shutdown
  def shutdown_sequence(self):
    rospy.loginfo(str(rospy.get_name()) + ": Shutting Down")

def main():
  rospy.init_node('position_controller_node')
  try:
    poscon = PositionController()
  except rospy.ROSInterruptException:
    pass

if __name__ == '__main__':
  main()


import sys
sys.stdin = open('sw_5653.txt', 'r')

def ck_map(lst):
    for y in range(H):
        print(lst[y])

def sepo(kk):
    global cnt
    bu_lst = set()
    for y in range(K-kk, K+N+kk):
        for x in range(K-kk, K+M+kk):
            if ori_map[y][x] != 0:
                if ori_map[y][x][1] > 0:
                    if ori_map[y][x][1] == e_map[y][x]:
                        bunsik(y, x, bu_lst)
                    ori_map[y][x][1] -= 1
                    if ori_map[y][x][1] == 0:
                        cnt -= 1

                elif ori_map[y][x][0] > 0 and (y, x) not in bu_lst:
                    ori_map[y][x][0] -= 1
                    if ori_map[y][x][0] == 0:
                        ori_map[y][x][1] = e_map[y][x]

def bunsik(y, x, bu_lst):
    global cnt
    for dif in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
        yy = y + dif[0]
        xx = x + dif[1]
        if (yy, xx) in bu_lst:
            if e_map[y][x] > e_map[yy][xx]:
                e_map[yy][xx] = e_map[y][x]
                ori_map[yy][xx][0] = e_map[y][x]

        if ori_map[yy][xx] == 0:
            ori_map[yy][xx] = [e_map[y][x], 0]
            e_map[yy][xx] = e_map[y][x]
            bu_lst.add((yy, xx))
            cnt += 1

TC = int(input())
for testcase in range(1, TC+1):
    N, M, K = map(int, input().split())
    H = N + (2*K)
    W = M + (2*K)
    ori_map = [[0] * W for _ in range(H)]
    e_map = [[0] * W for _ in range(H)]
    cnt = 0
    for y in range(K, K+N):
        new_info = list(map(int, input().split()))
        for i in range(M):
            if new_info[i] != 0:
                ori_map[y][K + i] = [new_info[i], 0]
                cnt += 1
            e_map[y][K+i] = new_info[i]

    for kk in range(K):
        sepo(kk)

    print('#{} {}'.format(testcase, cnt))


n=input()
count = 0
m = []
temp = []

for i in n:
    m.append(i)

for i in range(len(m)):
    for j in range(i+1,len(m)+1):
        s = m[i:j]
        t = []
        count+=1
        for k in s:
            if k in t:
                count-=1
                break
            if k not in t:
                t.append(k)
        if s in temp:
            count-=1
        if s not in temp:
            temp.append(s)
print(count)


from django.conf.urls import patterns, include, url
from followthestory import views

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
                       (r'^search-form/$',views.search_form),
                       (r'^search/$',views.search),
                       (r'^search/result.png$',views.plot_graph),
                       (r'^search/twitterchart.png$',views.plot_twittergraph),
    # Examples:
    # url(r'^$', 'followthestory.views.home', name='home'),
    # url(r'^followthestory/', include('followthestory.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # url(r'^admin/', include(admin.site.urls)),
)


import os

from iotics.lib.identity.api.regular_api import get_rest_identity_api

RESOLVER_URL = os.environ.get('RESOLVER')
api = get_rest_identity_api(resolver_url=RESOLVER_URL)

# -- Create User ---------------------------------------------------------------------------------------------------- #
user_seed, user_key_name, user_name = api.create_seed(), '#MyUserKey', '#MyUserName'
user_registered_id = api.create_user_identity(user_seed=user_seed,
                                              user_key_name=user_key_name,
                                              user_name=user_name)

# -- Create Agent --------------------------------------------------------------------------------------------------- #
agent_seed, agent_key_name, agent_name = api.create_seed(), '#MyAgentKey', '#MyAgentName'
agent_registered_id = api.create_agent_identity(agent_seed=agent_seed,
                                                agent_key_name=agent_key_name,
                                                agent_name=agent_name)

# -- Delegate Authentication ---------------------------------------------------------------------------------------- #
api.user_delegates_authentication_to_agent(user_registered_identity=user_registered_id,
                                           agent_registered_identity=agent_registered_id,
                                           delegation_name='#AuthDeleg')

# -- Create token --------------------------------------------------------------------------------------------------- #
token = api.create_agent_auth_token(agent_registered_identity=agent_registered_id,
                                    user_did=user_registered_id.did,
                                    duration=3600)  # seconds

# -- Create Twin ---------------------------------------------------------------------------------------------------- #
twin_seed, twin_key_name, twin_name = api.create_seed(), '#MyTwinKey', '#MyTwinName'
twin_registered_id = api.create_twin_identity(twin_seed=twin_seed,
                                              twin_key_name=twin_key_name,
                                              twin_name=twin_name)

# -- Delegate Control ----------------------------------------------------------------------------------------------- #
api.twin_delegates_control_to_agent(twin_registered_identity=twin_registered_id,
                                    agent_registered_identity=agent_registered_id,
                                    delegation_name='#ControlDeleg')


# This problem was asked by Google.
# Given an array of integers and a number k, where 1 <= k <= length of the array, compute the maximum values of each subarray of length k.
# For example, given array = [10, 5, 2, 7, 8, 7] and k = 3, we should get: [10, 7, 8, 8], since:
# 10 = max(10, 5, 2)
# 7 = max(5, 2, 7)
# 8 = max(2, 7, 8)
# 8 = max(7, 8, 7)
# Do this in O(n) time and O(k) space. You can modify the input array in-place and you do not need to store the results. You can simply print them out as you compute them.

import basics

def printSubarrayMaxValues(input, k):
    n = len(input)
    if(k<n or k==0):
        print('Invalid value of K..')

    kArr = []
    for number in input:
        if(len(kArr)>=k):
            break
        kArr.append(number)

    iterations = n-k
    for i in range(iterations):
        print('Subarray ',i+1,': ',max(kArr))
        kArr.pop(0)
        kArr.append(input[k+i])

    print('Subarray ',n-k+1,': ',max(kArr))

def main():
    input = basics.getNumberList()
    printSubarrayMaxValues(input,3)

if __name__ == '__main__':
    main()


import argparse
import os

from flask import Flask, jsonify, request

from src.sketch_detection_rcnn.sketch_recognizer import SketchRecognizer

parser = argparse.ArgumentParser(description='Sketch Recognition Server')

parser.add_argument(
    '--port',
    type=int,
    required=False,
    help='Port to run the server on'
)

parser.add_argument(
    '--model',
    type=str,
    required=True,
    help='Model directory'
)

parser.add_argument(
    '--device',
    type=str,
    default='cpu',
    choices=['cpu', 'cuda'],
    required=False,
    help='Device to use for prediction'
)

args = parser.parse_args()

app = Flask("SketchRecognition")
sketch_recognizer = SketchRecognizer(args.model, device=args.device)

@app.route('/', methods=['POST'])
def upload():
    file = request.files['file']
    byt = file.stream.read()
    predictions = sketch_recognizer.predict_form_bytes(byt)

    return jsonify(predictions)

if __name__ == '__main__':
    port = args.port

    if not port:
        port = os.environ.get('PORT', 8000)

    # if port is str, convert to int
    if isinstance(port, str):
        port = int(port)

    app.run(debug=True, host='0.0.0.0', port=port)


import torch
import torch.nn as nn
import numpy as np

def conv3x3(in_planes, out_planes, stride=1):
    """3x3 convolution with padding"""
    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
                     padding=1, bias=False)

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                               padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class BBoxTransform(nn.Module):

    def __init__(self, mean=None, std=None):
        super(BBoxTransform, self).__init__()
        if mean is None:
            if torch.cuda.is_available():
                self.mean = torch.from_numpy(np.array([0, 0, 0, 0]).astype(np.float32)).cuda()
            else:
                self.mean = torch.from_numpy(np.array([0, 0, 0, 0]).astype(np.float32))

        else:
            self.mean = mean
        if std is None:
            if torch.cuda.is_available():
                self.std = torch.from_numpy(np.array([0.1, 0.1, 0.2, 0.2]).astype(np.float32)).cuda()
            else:
                self.std = torch.from_numpy(np.array([0.1, 0.1, 0.2, 0.2]).astype(np.float32))
        else:
            self.std = std

    def forward(self, boxes, deltas):

        widths  = boxes[:, :, 2] - boxes[:, :, 0]
        heights = boxes[:, :, 3] - boxes[:, :, 1]
        ctr_x   = boxes[:, :, 0] + 0.5 * widths
        ctr_y   = boxes[:, :, 1] + 0.5 * heights

        dx = deltas[:, :, 0] * self.std[0] + self.mean[0]
        dy = deltas[:, :, 1] * self.std[1] + self.mean[1]
        dw = deltas[:, :, 2] * self.std[2] + self.mean[2]
        dh = deltas[:, :, 3] * self.std[3] + self.mean[3]

        pred_ctr_x = ctr_x + dx * widths
        pred_ctr_y = ctr_y + dy * heights
        pred_w     = torch.exp(dw) * widths
        pred_h     = torch.exp(dh) * heights

        pred_boxes_x1 = pred_ctr_x - 0.5 * pred_w
        pred_boxes_y1 = pred_ctr_y - 0.5 * pred_h
        pred_boxes_x2 = pred_ctr_x + 0.5 * pred_w
        pred_boxes_y2 = pred_ctr_y + 0.5 * pred_h

        pred_boxes = torch.stack([pred_boxes_x1, pred_boxes_y1, pred_boxes_x2, pred_boxes_y2], dim=2)

        return pred_boxes

class ClipBoxes(nn.Module):

    def __init__(self, width=None, height=None):
        super(ClipBoxes, self).__init__()

    def forward(self, boxes, img):

        batch_size, num_channels, height, width = img.shape

        boxes[:, :, 0] = torch.clamp(boxes[:, :, 0], min=0)
        boxes[:, :, 1] = torch.clamp(boxes[:, :, 1], min=0)

        boxes[:, :, 2] = torch.clamp(boxes[:, :, 2], max=width)
        boxes[:, :, 3] = torch.clamp(boxes[:, :, 3], max=height)

        return boxes

"""FROM FASTER RCNN"""

def all_gather(data):
    """
    Run all_gather on arbitrary picklable data (not necessarily tensors)
    Args:
        data: any picklable object
    Returns:
        list[data]: list of data gathered from each rank
    """
    world_size = 1
    if world_size == 1:
        return [data]

    # serialized to a Tensor
    buffer = pickle.dumps(data)
    storage = torch.ByteStorage.from_buffer(buffer)
    tensor = torch.ByteTensor(storage).to("cuda")

    # obtain Tensor size of each rank
    local_size = torch.tensor([tensor.numel()], device="cuda")
    size_list = [torch.tensor([0], device="cuda") for _ in range(world_size)]
    dist.all_gather(size_list, local_size)
    size_list = [int(size.item()) for size in size_list]
    max_size = max(size_list)

    # receiving Tensor from all ranks
    # we pad the tensor because torch all_gather does not support
    # gathering tensors of different shapes
    tensor_list = []
    for _ in size_list:
        tensor_list.append(torch.empty((max_size,), dtype=torch.uint8, device="cuda"))
    if local_size != max_size:
        padding = torch.empty(size=(max_size - local_size,), dtype=torch.uint8, device="cuda")
        tensor = torch.cat((tensor, padding), dim=0)
    dist.all_gather(tensor_list, tensor)

    data_list = []
    for size, tensor in zip(size_list, tensor_list):
        buffer = tensor.cpu().numpy().tobytes()[:size]
        data_list.append(pickle.loads(buffer))

    return data_list


from __future__ import print_function

import glob
import os
import shutil
import subprocess
import sys

import numpy as np

def read_out(filename):
    # drop the first two columns
    array = np.loadtxt(filename, dtype="float").astype("float")
    return array

def read_param(filename):
    res = {}
    with open(filename) as f:
        for line in f:
            words = line.split()
            if len(words) <= 1:
                continue
            res[words[0]] = words[1]
    return res

def read_opt_def(filename, total_site):
    rf = open(filename, "r")
    _arr = np.zeros(total_site, dtype=complex)
    for line in rf.readlines()[5:]:
        line1 = line.split()
        _arr[int(line1[0])] = float(line1[1]) + 1j * float(line1[2])
    rf.close()
    return _arr

def read_trans_def(filename, total_site):
    rf = open(filename, "r")
    _arr = np.zeros(((total_site * 2) ** 2) * 2, dtype=complex).reshape(
        (total_site, 2, total_site, 2, 2)
    )
    for line in rf.readlines()[5:]:
        line1 = line.split()
        _arr[int(line1[0])][int(line1[1])][int(line1[2])][int(line1[3])] = float(
            line1[4]
        ) + 1j * float(line1[5])
    rf.close()
    return _arr

if len(sys.argv) == 1:
    print("usage: {} <model name>".format(sys.argv[0]))
    sys.exit(-1)

rootdir = os.getcwd()
refdir = os.path.join(rootdir, "data", sys.argv[1])
workdir = os.path.join(rootdir, "work", sys.argv[1])
if os.path.exists(workdir):
    shutil.rmtree(workdir)
os.makedirs(workdir)
os.chdir(workdir)

bin_to_test = os.path.join(rootdir, "..", "..", "src", "ComplexUHF", "UHF")

for _file in glob.glob("%s/*.def" % refdir):
    shutil.copyfile(_file, os.path.basename(_file))

# run
result = subprocess.call([bin_to_test, "namelist.def"])
if result != 0:
    sys.exit(result)

# get results
array_calc = read_out("./zvo_eigen.dat")
ref_ave = read_out("%s/ref/zvo_eigen.dat" % refdir)
for diff in array_calc - ref_ave:
    diff = abs(diff)
    if (diff >= 1e-8).any():
        sys.exit(-1)

param = read_param("modpara.def")
nsites = int(param["Nsite"])

# get results
array_calc = read_trans_def("./zvo_UHF_cisajs.dat", nsites)
ref_ave = read_trans_def("%s/ref/zvo_UHF_cisajs.dat" % refdir, nsites)
for diff in array_calc - ref_ave:
    diff = np.abs(diff)
    if (diff >= 1e-8).any():
        sys.exit(-1)

sys.exit(0)


#!/usr/bin/env python3

import sys

from gedcom.element.individual import IndividualElement
from gedcom.parser import Parser

def formatGedcomDate(date_string):
    return (date_string.lower()
            .replace('abt abt', 'abt')
            .replace('abt', 'ca.')
            .replace('bef bef', 'bef')
            .replace('bef ', 'before ')
            .replace('aft aft', 'aft')
            .replace('aft ', 'after')
            .replace('bet', '')
            .replace('and', '-')
            .replace('jan', 'Jan')
            .replace('feb', 'Feb')
            .replace('mar', 'Mar')
            .replace('apr', 'Apr')
            .replace('may', 'May')
            .replace('jun', 'Jun')
            .replace('jul', 'Jul')
            .replace('aug', 'Aug')
            .replace('sep', 'Sep')
            .replace('oct', 'Oct')
            .replace('nov', 'Nov')
            .replace('dec', 'Dec'))

def get_titles(element):
    titles = []

    if not element.is_individual():
        return titles

    for child in element.get_child_elements():
        if child.get_tag() == 'NOBI':
            titles.append(child.get_value())

    return titles

try: infile_path = sys.argv[1]
except IndexError: sys.exit("No gedcom defined!")

outfile_path = infile_path + '.csv'

gedcom_parser = Parser()

gedcom_parser.parse_file(infile_path)

root_child_elements = gedcom_parser.get_root_child_elements()

outfile_contents = []

outfile_contents.append(','.join(["id", "name", "gender", "birth date", "birth place", "death date", "place of death", "title"]))

for element in root_child_elements:

    if isinstance(element, IndividualElement):

        row = []

        name = element.get_name()

        if name[0] == 'Unnamed':
            continue

        record_id = element.get_pointer().replace('@', '').lower()

        row.append(record_id)
        row.append(' '.join(filter(None, name)))

        gender = element.get_gender()

        row.append(gender)

        birth_data = element.get_birth_data()

        row.append(formatGedcomDate(birth_data[0]))
        if birth_data[1] and birth_data[1].strip():
            row.append(format("\"%s\"" % birth_data[1]))
        else:
            row.append('')

        death_data = element.get_death_data()

        row.append(formatGedcomDate(death_data[0]))
        if death_data[1] and death_data[1].strip():
            row.append(format("\"%s\"" % death_data[1]))
        else:
            row.append('')

        titles = get_titles(element)
        titles_str = ','.join(filter(None, titles))
        if titles_str and titles_str.strip():
            row.append(format("\"%s\"" % titles_str))
        else:
            row.append('')

        outfile_contents.append(','.join(row))

#print('\n'.join(outfile_contents))

with open(outfile_path, 'w') as f:
    f.write('\n'.join(outfile_contents))


import copy

class Node:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.hallway = y == 1
        self.sideroom = y != 1
        self.neighbours = set()

    def __repr__(self):
        return f"Node({self.x}, {self.y})"

positions = {}
startPositions = {}
finalPositions = {"A": 3, "B": 5, "C": 7, "D": 9}

with open("inputSmall.txt", "r") as file:
    lines = file.readlines()
    for y, line in enumerate(lines):
        for x, char in enumerate(line[:-1]):
            if char=="#" or char == " ": continue
            if char.isalpha():
                if char not in startPositions: startPositions[char] = []
                startPositions[char].append((x, y))
            positions[(x, y)] = Node(x, y)

for position in positions.values():
    x, y = position.x, position.y
    for offsetX, offsetY in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
        if (x+offsetX, y+offsetY) in positions:
            positions[x, y].neighbours.add(positions[x+offsetX, y+offsetY])

finished = False
previousStates = set()

def findRoutes(amphipodPositions, energy = 0):
    global previousStates
    global finished
    if finished: return
    if energy > 12600: return

    # print("Now state")
    # printState(amphipodPositions)
    # print()
    # print(previousPositions)
    # print()
    if "".join(outputState(amphipodPositions)) == "##############...........####A#B#C#D######A#B#C#D################":
        finished = True
        print("FINISHED\n" *1000)
        return

    print("".join(outputState(amphipodPositions)))

    previousStates.add("".join(outputState(amphipodPositions)))

    for char in amphipodPositions:
        for i in range(0, len(amphipodPositions[char])):
            thisCharPosition = amphipodPositions[char][i]

            for newPosition in positions[thisCharPosition].neighbours:
                if isTaken(amphipodPositions, newPosition.x, newPosition.y):
                    #print("Spot is taken", thisCharPosition, newPosition)
                    continue

                if newPosition.sideroom and positions[thisCharPosition].hallway:
                    if newPosition.x != finalPositions[char]:
                        #print("Cant go here", char, thisCharPosition, newPosition, newPosition.sideroom)
                        continue

                newAmphipodPositions = copy.deepcopy(amphipodPositions)
                newAmphipodPositions[char][i] = (newPosition.x, newPosition.y)

                if "".join(outputState(newAmphipodPositions)) in previousStates:
                    # print("Been here before")
                    continue

                newEnergy = 1
                if char == "B": newEnergy = 10
                elif char == "C": newEnergy = 100
                elif char == "D": newEnergy = 1000

                # print("Now state")
                # printState(amphipodPositions)
                # print("Next state")
                # printState(newAmphipodPositions)

                findRoutes(newAmphipodPositions, energy + newEnergy)

def isTaken(amphipodPositions, x, y):
    for char, amphiPods in amphipodPositions.items():
        for amphiPod in amphiPods:
            if (x, y) == amphiPod: return True
    return False

def printState(amphipodPositions):
    width = max([node.x for node in positions.values()]) + 2
    height = max([node.y for node in positions.values()]) + 2

    outputLines = [["#" for x in range(0, width)] for y in range(0, height)]
    for (x, y) in positions:
        outputLines[y][x] = "."

    for char in amphipodPositions:
        for i in range(0, len(amphipodPositions[char])):
            x, y = amphipodPositions[char][i]
            outputLines[y][x] = char

    for outputLine in outputLines:
        print("".join(outputLine))

def outputState(amphipodPositions):
    width = max([node.x for node in positions.values()]) + 2
    height = max([node.y for node in positions.values()]) + 2

    outputLines = [["#" for x in range(0, width)] for y in range(0, height)]
    for (x, y) in positions:
        outputLines[y][x] = "."

    for char in amphipodPositions:
        for i in range(0, len(amphipodPositions[char])):
            x, y = amphipodPositions[char][i]
            outputLines[y][x] = char

    return ["".join(i) for i in outputLines]
findRoutes(startPositions)


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

# In[1]:

# Importing the important libraries
import os
import requests
import re
from bs4 import BeautifulSoup
import csv

# In[2]:

def restaurant_info(url_list, output_csv):

    allreviews = []

    for u in url_list:
        response = requests.get(u)

        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')

            restaurant_name = soup.find('h1', class_='css-1se8maq').text.strip()
            total_reviews = soup.find('a', class_='css-19v1rkv').text.strip()

            reviews = soup.find_all('li', class_='css-1q2nwpv')
            for review in reviews:
                review_text = review.find('span', {'lang': 'en'}).text.strip()
                reviewer = review.find('a', class_='css-19v1rkv').text.strip()
                rating = review.find('div', class_='five-stars__09f24__mBKym five-stars--regular__09f24__DgBNj css-1jq1ouh')['aria-label'].split()[0]
                allreviews.append([restaurant_name, total_reviews, review_text, reviewer, rating])

        else:
            print(f'Failed to retrieve data from {url}')

    with open(output_csv, mode='w', newline='', encoding='utf-8') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(['Restaurant Name', 'Total Reviews', 'Review Text', 'Reviewer', 'Rating'])
        writer.writerows(allreviews)
        print(f'Restaurant information have been saved to {output_csv}')

output_csv_file = 'Restaurant_Reviews.csv'

restaurant_list = ['https://www.yelp.ca/biz/pai-northern-thai-kitchen-toronto-5?osq=Restaurants',
                   'https://www.yelp.ca/biz/mira-toronto?osq=Restaurants',
                   'https://www.yelp.ca/biz/katsuya-toronto-5?osq=Restaurants',
                   'https://www.yelp.ca/biz/gusto-101-toronto?osq=Restaurants',
                   'https://www.yelp.ca/biz/the-rabbit-hole-toronto?osq=Restaurants'
                   ]

restaurant_info(restaurant_list, output_csv_file)

# In[ ]:


import requests
from bs4 import BeautifulSoup
def get_html(url):

   headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'}
   resp=requests.get(url,headers=headers).text
   return resp
def html_parse():
   for url in allpages():
      soup=BeautifulSoup(get_html(url),'lxml')
      ids=soup.find_all('div',class_='tit')

      for i in ids:
         id_=i.find('a').attrs['data-shopid']
         result=str(id_)
         f.writelines(result+'\n')

def allpages():
   baseurl='http://www.dianping.com/chengdu/ch10/g109p'#找到你需要的网页
   urllist=[]
   for page in range(1,8,1):#一共有n页，把8改成n+1
      allurl=baseurl+str(page)
      urllist.append(allurl)
   return urllist
filename='dianpu_id.txt'#电脑中保存的文件名
f=open(filename,'w',encoding='utf-8')
html_parse()
f.close()
print('ok!')


import turtle

startColor="lightgreen"
otherColor="black"

def drawSquare(t,length,color):
    t.fillcolor(color)
    t.begin_fill()
    for num in range(4):
        t.forward(length)
        t.right(90)
    t.end_fill()

def blackRedRow(t,length):
    for i in range(4):
        drawSquare(t,length,startColor)
        t.forward(length)
        drawSquare(t,length,otherColor)
        t.forward(length)

def redBlackRow(t,length):
    for i in range(4):
        drawSquare(t,length,otherColor)
        t.forward(length)
        drawSquare(t,length,startColor)
        t.forward(length)

def checkerboard(length,bob):
    bob.speed(0)
    for x in range(4):
        blackRedRow(bob,length)
        bob.backward(8*length)
        bob.right(90)
        bob.forward(length)
        bob.left(90)
        redBlackRow(bob,length)
        bob.backward(8*length)
        bob.right(90)
        bob.forward(length)
        bob.left(90)

def drawChecker(row,col,size):
    x=0
    y=0
    bob.fillcolor("red")
    bob.begin_fill()
    if(row==0):
        x=25
    else:
        x=25+row*50
    y=-(50*col+50)
    bob.penup()
    bob.goto(x,y)
    bob.pendown()
    bob.circle(25)
    bob.end_fill()

bob=turtle.Turtle()
checkerboard(50,bob)
drawChecker(1,1,50)


import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import sys
import os
import datetime

import settings_model
import preprocess_data
# from dataset_generator import create_predict_datasets_and_loaders
from dataset_generator import create_siamese_datasets_and_loaders, create_predict_datasets_and_loaders
from train_predict import *
from architectures.siamese_resnet import siamese_resnet18, siamese_resnet50, siamese_resnet101
from architectures.siamese_efficientnet import SiameseEfficientNet
from architectures.siamese_densenet import siamese_densenet121

from utils import ContrastiveLoss, CosineSimilarityLoss, seed_everything

sys.path.append(os.path.join(settings_model.root_path, "rxrx1-utils"))
from rxrx import io as rio

def main(data, model_id):

    seed_everything(42)

    # create dataloaders
    datasets_siam, loaders_siam = create_siamese_datasets_and_loaders(data, settings_model.batch_size // 2,
                                                                    settings_model.basepath_data,
                                                                    settings_model.original_image_size)
    datasets_pred, loaders_pred = create_predict_datasets_and_loaders(data, settings_model.batch_size,
                                                                      settings_model.basepath_data,
                                                                      settings_model.original_image_size)

    # define training parameters
    verbose = True
    # restore_file = None
    restore_file = "/jet/prs/workspace/models/siamese-cell/HEPG2_20190811_142600/loss.best.pth.tar"
    # model = SiameseEfficientNet.from_pretrained('efficientnet-b0').cuda()
    model = siamese_densenet121(pretrained=False, embedding_size=128, drop_rate=0.3).cuda()
    split_batch = 4
    # for param in model.parameters():
    #     param.requires_grad = False
    # for param in model.features.conv0.parameters():
    #     param.requires_grad = True
    # for param in model.classifier.parameters():
    #     param.requires_grad = True

    loss_fn = CosineSimilarityLoss(margin=0.)
    lr_init = 1.e-4
    threshold = 0.99
    num_epochs = 100
    num_steps_train = int(len(loaders_siam["train"]))
    num_steps_valid = int(len(loaders_siam["valid"]))
    output_dir = os.path.join(settings_model.root_path, "models", "siamese-cell",
                              model_id + "_" + datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
    print("\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n")
    print(f"====> Outputs will be saved to {output_dir}\n")
    print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n")
    # run train and evaluate
    train_and_evaluate(model, loaders_siam["train"], loaders_siam["valid"],
                       loaders_pred["train"], loaders_pred["valid"],
                       lr_init, loss_fn, threshold, num_epochs,
                       num_steps_train, num_steps_valid, settings_model.batch_size,
                       output_dir, verbose=verbose, restore_file=restore_file,
                       split_batch=split_batch)

def embeddings(data, model_id):
    datasets_pred, loaders_pred = create_predict_datasets_and_loaders(data, settings_model.batch_size,
                                                                      settings_model.basepath_data,
                                                                      settings_model.original_image_size)
    restore_file = f"/jet/prs/workspace/models/siamese-cell/{model_id}/acc.best.pth.tar"
    model = siamese_densenet121(pretrained=False, embedding_size=128).cuda()
    output_dir = os.path.join(settings_model.root_path, "models", "siamese-cell",
                              f"{model_id}", "emb")

    save_embeddings_for_clf(model, loaders_pred["train"], loaders_pred["valid"], output_dir)

if __name__ == "__main__":
    # preprocess data
    # data = preprocess_data.rxrx_all()
    # main(data, "all")

    # # 'HEPG2', 'HUVEC', 'RPE', 'U2OS'
    cell_type = 'HEPG2'
    # # data = preprocess_data.rxrx_control_cell_type(cell_type)
    data = preprocess_data.rxrx_cell_type(cell_type)
    main(data, cell_type)
    # embeddings(data, "U2OS_20190812_073705")


#Creating Multile EC2 Instances
import boto3

ec2_resource=boto3.resource("ec2")
ec2_resource.create_instances(ImageId='YourAMIId',
      InstanceType='t2.micro',
    MaxCount=3,
      MinCount=3)

#Getting Your Instance IDs
import boto3

ec2_client=boto3.client("ec2")
x=ec2_client.describe_instances()
data=x["Reservations"][0]
data_instance=data["Instances"]
for i in range (len(data_instance)):
    print(f"instance id is {data_instance[i]['InstanceId']}")

#Terminating Multiple EC2 Instances
import boto3

ec2_client=boto3.client("ec2")
x=ec2_client.describe_instances()
data=x["Reservations"]

li=[]
for instances in data:
    instance=instances["Instances"]
    for ids in instance:
        instance_id=ids["InstanceId"]
        li.append(instance_id)

ec2_client.terminate_instances(InstanceIds=li)


"""
Bioapp

@author: Enes Dilsiz
"""

# RNA kodon tablosu, dictionary formatında:

RNA_CODON_TABLE = {
    'UUU': 'F',     'CUU': 'L',     'AUU': 'I',     'GUU': 'V',
    'UUC': 'F',     'CUC': 'L',     'AUC': 'I',     'GUC': 'V',
    'UUA': 'L',     'CUA': 'L',     'AUA': 'I',     'GUA': 'V',
    'UUG': 'L',     'CUG': 'L',     'AUG': 'M',     'GUG': 'V',
    'UCU': 'S',     'CCU': 'P',     'ACU': 'T',     'GCU': 'A',
    'UCC': 'S',     'CCC': 'P',     'ACC': 'T',     'GCC': 'A',
    'UCA': 'S',     'CCA': 'P',     'ACA': 'T',     'GCA': 'A',
    'UCG': 'S',     'CCG': 'P',     'ACG': 'T',     'GCG': 'A',
    'UAU': 'Y',     'CAU': 'H',     'AAU': 'N',     'GAU': 'D',
    'UAC': 'Y',     'CAC': 'H',     'AAC': 'N',     'GAC': 'D',
    'UAA': 'Stop',  'CAA': 'Q',     'AAA': 'K',     'GAA': 'E',
    'UAG': 'Stop',  'CAG': 'Q',     'AAG': 'K',     'GAG': 'E',
    'UGU': 'C',     'CGU': 'R',     'AGU': 'S',     'GGU': 'G',
    'UGC': 'C',     'CGC': 'R',     'AGC': 'S',     'GGC': 'G',
    'UGA': 'Stop',  'CGA': 'R',     'AGA': 'R',     'GGA': 'G',
    'UGG': 'W',     'CGG': 'R',     'AGG': 'R',     'GGG': 'G'
}

def readFasta(path):
    """

    Fasta dosyası okumak için oluşturulmuş fonksiyon.

    Parameters
    ----------
    path : string
        Okunacak 'fasta' uzantılı dosyanın yolu.

    Returns
    -------
    dictionary : dictionary
        Okunan dosyadaki ekansları sözlük olarak döndürür.

    """
    with open(path) as fasta:
        genes = fasta.read().split('>')

    dictionary = {}

    for i in range(1, len(genes)):
        dictionary[genes[i].split('\n', 1)[0]] = ''.join(genes[i].split('\n')[1:]).replace(' ', '')

    return dictionary

def DNAcount(sequence):
    """

    Girilen sekanstaki baz sayılarını hesaplar.

    Parameters
    ----------
    sequence : string
        DNA dizisi

    Returns
    -------
    out : list
        DNA dizisindeki Adenin, Guanin, Sitozin ve Timin sayıalrını liste halinde döndürür.

    """

    A = sequence.count('A')
    C = sequence.count('C')
    G = sequence.count('G')
    T = sequence.count('T')

    out = [A, C, G, T]

    return f'Adenin: {out[0]}, Sitozin: {out[1]}, Guanin: {out[2]}, Timin: {out[3]}'

def DNAtoRNA(sequence):
    """

    Girilen DNA dizisinden RNA transkripsiyon işlemi yapar.

    Parameters
    ----------
    sequence : string
        DNA dizisi

    Returns
    -------
    out : string
        DNA dizisinden sentezlenen RNA dizisi

    """

    out = sequence.replace('T', 'U')

    return f'Transkripsiyon sonrası oluşan yeni RNA dizisi: {out}'

def reverseComplement(sequence):
    """

    DNA dizisine reverse complement işlemi uygular

    Parameters
    ----------
    sequence : string
        DNA dizisi

    Returns
    -------
    out : string
        DNA dizisinin reverse complement uygulanmış çıktısı

    """

    temp = []
    reverse = sequence[::-1]

    comp = {'A':'T', 'C':'G', 'G':'C', 'T':'A'}

    for i in reverse:

        temp.append(comp[i])

    out = "".join(temp)

    return f'DNA reverse complement: {out}'

def rabbit(n, k):
    """

    n sürede k tavşan çiftinin ulaşacağı popülasyonu hesaplar.

    Parameters
    ----------
    n : int
        geçen süre (ay) - n < 40
    k : int
        tavşan çifti - k < 5

    Returns
    -------
    int
        n ay sonra k tavşan çiftinden üreyen poülasyon

    """

    if n < 1:
        return 0
    if n == 1 or n == 2:
        return 1
    if n > 2 and n <= 40:
        return rabbit(n-1, k) + k*rabbit(n-2, k)
    else:
        return print("n must be smaller than 40")

def GCContent(sequence):
    """

    DNA dizisi içerisindeki Guanin ve Sitozin bazının tüm bazlara olan oranını hesaplar.

    Parameters
    ----------
    sequence : string
        DNA dizisi

    Returns
    -------
    float
        (Guanin+Sitozin)/(Adenin+Timin+Guanin+Sitozin)

    """
    A = sequence.count('A')
    C = sequence.count('C')
    G = sequence.count('G')
    T = sequence.count('T')

    result = (C+G)/(A+C+G+T)

    return f'DNA dizisindeki Guanin ve Sitozin bazlarının tüm bazlara oranı: {result}'

def countMutations(sequence1, sequence2):
    """
    İki DNA dizisini karşılaştırıp mutasyon sayısını hesaplar.

    Parameters
    ----------
    sequence1 : string
        DNA dizisi
    sequence2 : string
        DNA dizisi

    Returns
    -------
    counter : int
        Mutasyon sayısı

    """

    counter = 0

    if len(sequence1) == len(sequence2):
        for i in range(0, len(sequence1)):
            if sequence1[i] != sequence2[i]:
                counter+=1

    return f'İki dizi arasındaki toplam mutasyon sayısı: {counter}'

def RNAtoProtein(sequence):
    """

    RNA sekansından sentezlencek protein dizisini döndürür.

    Parameters
    ----------
    sequence : string
        RNA dizisi

    Returns
    -------
    protein : string
        Protein dizisi

    """

    protein = ""

    for i in range(0, len(sequence), 3):

        codon = RNA_CODON_TABLE[sequence[i:i+3]]

        if codon == 'Stop':
            break
        protein += codon

    return f'Sentezlenen protein dizisi: {protein}'

def DNAmotif(sequence, subsequence):
    """

    Girilen DNA alt dizisi DNA dizisi içerisinde bulunuyorsa, indexini döndürür.

    Parameters
    ----------
    sequence : string
        DNA dizisi
    subsequence : string
        DNA alt dizisi

    Returns
    -------
    index : list
        DNA alt dizisinin DNA dizisindeki indexi/indexleri

    """

    index = []

    if subsequence not in sequence:

        return "Motif bulunamadı"

    else:
        for i in range(0, len(sequence)):

            if i+len(subsequence) > len(sequence):
                break
            else:
                if sequence[i:i+len(subsequence)] == subsequence:
                    index.append(i+1)

        return f'Bulunan motiflerin indexleri: {index}'

def consensus(*sequences):
    """
    Girilen DNA dizilerini liste olarak alır. Index bazlı karşılaştırma yapıp indexlerde en çok
    bulunan baz çeşidini ve en yüksek sayıda bulunan bazlardan oluşan consensus dizisini döndürür.

    Parameters
    ----------
    *sequences : list
        DNA dizilerinden oluşan liste

    Returns
    -------
    consensus : string
        consensus stringi
    profile : dictionary
        profile matrisi

    """

    highest = max(len(i) for i in sequences)
    lowest = min(len(i) for i in sequences)

    if highest == lowest:

        A, C, G, T = ([0]*highest for i in range(4))

        for i in range(0, len(sequences)):
            for j in range(0, len(sequences[i])):
                A[j] += sequences[i][j].count('A')
                C[j] += sequences[i][j].count('C')
                G[j] += sequences[i][j].count('G')
                T[j] += sequences[i][j].count('T')

        out = ['A']*highest
        for m in range(0, len(out)):
            if C[m] > A[m] and C[m] > G[m] and C[m] > T[m]:
                out[m] = 'C'
            elif G[m] > A[m] and G[m] > C[m] and C[m] > T[m]:
                out[m] = 'G'
            elif T[m] > A[m] and T[m] > G[m] and T[m] > C[m]:
                out[m] = 'T'

        consensus = ''.join(out)
        profile = {'A':A,
                   'C':C,
                   'G':G,
                   'T':T
                   }

    return f'Consensus dizisi: {consensus}, Profile matrisleri {profile}'


from typing import List, Optional

import time
import asyncio
import ingest_api_data
import pipeline_ml
import json
import copy
import os

import uvicorn
from fastapi import Depends, FastAPI, HTTPException
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from sqlalchemy.orm import Session
from fastapi import FastAPI
from sqlalchemy.orm import Session
from sqlalchemy.orm import sessionmaker
from fastapi_utils.session import FastAPISessionMaker
from fastapi_utils.tasks import repeat_every

import models as models
from db import get_db, engine
from repository import ClassificationRepo, RegressionRepo

regre_model = pipeline_ml.RegressionModel()
class_model = pipeline_ml.ClassificationModel(
    is_mini_batch_mode=os.getenv("MINI_BATCH_MODE", "False") == "True"
)
ingest_api = ingest_api_data.IngestAPI()
app = FastAPI(
    title="REST back-end for dashboard",
    description="Ingest API data and train models and provide endpoints to see the training process",
    version="1.0.0",
)

models.Base.metadata.create_all(bind=engine)

def train_classification_model(data_batch: list) -> None:
    result = class_model.train(mini_batch=data_batch)
    local_session = sessionmaker(autocommit=True, autoflush=True, bind=engine)
    with local_session.begin() as db:
        ClassificationRepo.create(
            db,
            metric_report=class_model.serialize_report(),
            data_batch=result,
            model=copy.deepcopy(class_model),
        )

def train_regression_model(data_batch: list) -> None:
    result = regre_model.train(mini_batch=data_batch)
    local_session = sessionmaker(autocommit=True, autoflush=True, bind=engine)
    with local_session.begin() as db:
        RegressionRepo.create(
            db,
            metric_report=regre_model.serialize_report(),
            data_batch=result,
            model=copy.deepcopy(regre_model),
        )

@app.on_event("startup")
@repeat_every(seconds=2)
def mock_msg_queue() -> None:
    data_batch = ingest_api.get_data()
    train_classification_model(data_batch)
    train_regression_model(data_batch)

@app.exception_handler(Exception)
def validation_exception_handler(request, err):
    base_error_message = f"Failed to execute: {request.method}: {request.url}"
    return JSONResponse(
        status_code=400, content={"message": f"{base_error_message}. Detail: {err}"}
    )

@app.get("/api/v1/classification", tags=["Classification"])
def get_latest_items(db: Session = Depends(get_db)):
    db_item = ClassificationRepo.fetch_lastest(db)
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return db_item.jsonfy()

@app.get("/api/v1/regression", tags=["Regression"])
def get_latest_items(db: Session = Depends(get_db)):
    db_item = RegressionRepo.fetch_lastest(db)
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return db_item.jsonfy()

if __name__ == "__main__":
    uvicorn.run("rest_api:app", port=9000, reload=True, debug=True)