from flask import Flask
from flask import request
import datetime
import telebot
from telebot import types
import os
from database import db, cursor
import threading
from time import sleep

TOKEN = 'This is place for your Token'

APP_URL = f'https://name_your_app_on_heroku.herokuapp.com/{TOKEN}'

bot = telebot.TeleBot(TOKEN)

delay = 50

server = Flask(__name__)

@bot.message_handler(commands=['start'])
def start(message):
    cursor.execute("CREATE TABLE IF NOT EXISTS duty_days (id INT AUTO_INCREMENT PRIMARY KEY, date DATE, date_order SMALLINT)")
    cursor.execute("CREATE TABLE IF NOT EXISTS rescuers (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), name_order SMALLINT)")
    cursor.execute("CREATE TABLE IF NOT EXISTS archive (id INT AUTO_INCREMENT PRIMARY KEY, date DATE, name VARCHAR(255))")
    bot.send_photo(message.chat.id, photo='https://i.postimg.cc/N0htGPMC/channels4-banner.jpg', caption="БУДЬТЕ ВНИМАТЕЛЬНЫ: СЕГОДНЯШНЯЯ ДАТА ДОЛЖНА СОВПАДАТЬ С ВАШЕЙ СМЕНОЙ!!!"
                                      "\nДОЖДИТЕСЬ СВОЕЙ СМЕНЫ и введите 'Начать' для начала работы телеграмм бота:")

# Эта функция нужна чтобы обдурить бесплатный ClearDb, который разрывает соединение с базой данных, если в течении 60 секунд нет запросов))
def send_reminder():
    while True:
        cursor.execute("SELECT COUNT(id) FROM rescuers")
        sleep(delay)

treading = threading.Thread(target=send_reminder)
treading.start()

def main_menu(message):
    global keyboard_main_menu
    keyboard_main_menu = types.InlineKeyboardMarkup()
    button_Add_Duty = types.InlineKeyboardButton(text='Добавить в список дежурных', callback_data='button_Add_Duty')
    keyboard_main_menu.add(button_Add_Duty)
    button_Minus_Duty = types.InlineKeyboardButton(text='Удалить из списка дежурных', callback_data='button_Minus_Duty')
    keyboard_main_menu.add(button_Minus_Duty)
    button_Check_Duty = types.InlineKeyboardButton(text='Узнать когда дежуришь', callback_data='button_Check_Duty')
    keyboard_main_menu.add(button_Check_Duty)
    button_Now_Duty = types.InlineKeyboardButton(text='Сегодня дежурит:', callback_data='button_Now_Duty')
    keyboard_main_menu.add(button_Now_Duty)
    bot.send_message(message.chat.id, 'ВЫБЕРИТЕ ДЕЙСТВИЕ \nИЗ ПРЕДЛОЖЕННЫХ :', reply_markup=keyboard_main_menu)

@bot.message_handler(func=lambda call: True)
def get_first_message(message):
    start_cmd = 'начать'
    if message.text.lower() == start_cmd:
        cursor.execute('SELECT COUNT(*) FROM duty_days')
        result = cursor.fetchone()
        len_duty_days = result[0]
        if len_duty_days >= 1:
            main_menu(message)
        else:
            start = datetime.date.today()
            end = start + datetime.timedelta(days=365)
            interval = datetime.timedelta(days=4)

            while start <= end:
                query = "INSERT INTO duty_days (date) VALUES (%s)"
                value = start
                cursor.execute(query, (value,))
                cursor.execute("SET @num=0")
                cursor.execute("UPDATE duty_days SET date_order =@num:= (@num +1)")
                db.commit()
                start += interval
            main_menu(message)

    else:
        bot.send_message(message.from_user.id, 'СЛЕДУЙТЕ УКАЗАНИЯМ ВЫШЕ')

@bot.callback_query_handler(func=lambda call: True)
def choose_operation(call):
    if call.data == 'button_main_menu':
        main_menu(call.message)

    elif call.data == 'button_Add_Duty':
        bot.send_message(call.message.chat.id, 'Введите имя человека, которого хотите добавить в список дежурных:')
        bot.register_next_step_handler(call.message, add_name_duty)

    elif call.data == 'button_Minus_Duty':
        cursor.execute("SELECT COUNT(name) FROM rescuers")
        result = cursor.fetchone()
        len_rescuers = result[0]
        if len_rescuers >= 1:
            bot.send_message(call.message.chat.id, 'Введите имя человека, которого хотите удалить из списка дежурных:')
            bot.register_next_step_handler(call.message, delete_duty)
        else:
            no_names(call)

    elif call.data == 'button_confirm_delete':
        query = "DELETE FROM rescuers WHERE name = %s"
        value = name_delete
        cursor.execute(query, (value,))
        cursor.execute("SET @num=0")
        cursor.execute("UPDATE rescuers SET name_order =@num:= (@num +1)")
        db.commit()

        keyboard_main_menu2 = types.InlineKeyboardMarkup()
        button_Add_Duty = types.InlineKeyboardButton(text='Добавить в список дежурных',
                                                             callback_data='button_Add_Duty')
        keyboard_main_menu2.add(button_Add_Duty)
        button_Minus_Duty = types.InlineKeyboardButton(text='Удалить из списка дежурных',
                                                               callback_data='button_Minus_Duty')
        keyboard_main_menu2.add(button_Minus_Duty)
        button_Check_Duty = types.InlineKeyboardButton(text='Узнать когда дежуришь',
                                                               callback_data='button_Check_Duty')
        keyboard_main_menu2.add(button_Check_Duty)
        button_Now_Duty = types.InlineKeyboardButton(text='Сегодня дежурит:', callback_data='button_Now_Duty')
        keyboard_main_menu2.add(button_Now_Duty)

        bot.send_message(call.message.chat.id, name_delete + ' удален из списка дежурных!')
        main_menu(call.message)

    elif call.data == 'button_cancel_delete':
        main_menu(call.message)

    elif call.data == 'button_Check_Duty':
        cursor.execute("SELECT COUNT(name) FROM rescuers")
        result = cursor.fetchone()
        len_rescuers = result[0]
        if len_rescuers >= 1:
            bot.send_message(call.message.chat.id, 'Введите имя человека чтобы узнать дату его дежурства: ')
            bot.register_next_step_handler(call.message, check_duty_date)
        else:
            no_names(call)

    elif call.data == 'button_Now_Duty':
        cursor.execute("SELECT COUNT(name) FROM rescuers")
        result = cursor.fetchone()
        len_rescuers = result[0]
        if len_rescuers >= 1:
            cursor.execute("SELECT COUNT(date) FROM duty_days WHERE date=CURDATE()")
            result = cursor.fetchone()
            result_value = result[0]
            if result_value >= 1:
                cursor.execute('CREATE TABLE IF NOT EXISTS counter (id INT AUTO_INCREMENT PRIMARY KEY, num SMALLINT)')
                query = 'INSERT INTO counter (num) VALUES (%s)'
                value = 1
                cursor.execute(query, (value,))
                db.commit()
                confirm_duty(call)

            else:
                not_today_duty_day(call)

        else:
            no_names(call)

    elif call.data == 'button_cancel_today_duty':
        query = 'INSERT INTO counter (num) VALUES (%s)'
        value = 1
        cursor.execute(query, (value,))
        db.commit()
        now_duty(call)

    elif call.data == 'button_confirm_today_duty':
        change_queue()
        delete_duty_day()
        cursor.execute("DELETE FROM counter WHERE id>0")
        db.commit()

        keyboard_go_to_main_menu = types.InlineKeyboardMarkup()
        button_go_to_main_menu = types.InlineKeyboardButton(text='Перейти в главное меню',
                                                            callback_data='button_main_menu')
        keyboard_go_to_main_menu.add(button_go_to_main_menu)

        bot.send_photo(call.message.chat.id, photo='https://i.postimg.cc/N0htGPMC/channels4-banner.jpg',
                        caption=f'{result_duty_name} - умывальников начальник \nи мочалок командир!',
                        reply_markup=keyboard_go_to_main_menu)

def confirm_duty(call):
    global keyboard_confirm_today_duty
    global result_duty_name

    cursor.execute(" SELECT COUNT(id) FROM counter")
    result_counter = cursor.fetchone()
    result_value = result_counter[0]

    query = "SELECT name FROM rescuers WHERE name_order= %s"
    cursor.execute(query, (result_value,))
    result = cursor.fetchone()
    if result is None:
        bot.send_message(call.message.chat.id, 'Еееййй... Очередь тю-тю, закончилась!!!')

    else:
        result_duty_name = result[0]
        bot.send_message(call.message.chat.id, f"Сегодня дежурит: {result_duty_name}")

        keyboard_confirm_today_duty = types.InlineKeyboardMarkup()
        button_confirm_today_duty = types.InlineKeyboardButton(text='Подтвердить',
                                                               callback_data='button_confirm_today_duty')
        button_cancel_today_duty = types.InlineKeyboardButton(text='Не дежурит',
                                                              callback_data='button_cancel_today_duty')
        keyboard_confirm_today_duty.add(button_confirm_today_duty, button_cancel_today_duty)
        bot.send_message(call.message.chat.id, f'Нажмите "Подтвердить", '
                                               f'\nесли {result_duty_name} дежурит сегодня \nИли "Не дежурит" - если нет!'
                                               f'\nБУДЬТЕ ВНИМАТЕЛЬНЫ : \nИзменить дежурного сегодня \nбудет уже НЕЛЬЗЯ!!!',
                         reply_markup=keyboard_confirm_today_duty)

def now_duty(call):
    cursor.execute("SELECT COUNT(name) FROM rescuers")
    result = cursor.fetchone()
    len_rescuers = result[0]
    if len_rescuers >= 1:
        cursor.execute("SELECT COUNT(date) FROM duty_days WHERE date=CURDATE()")
        result = cursor.fetchone()
        result_value = result[0]
        if result_value >= 1:
            confirm_duty(call)

        else:
            not_today_duty_day(call)

    else:
        no_names(call)

def not_today_duty_day(call):
    global keyboard_not_today_duty_day
    keyboard_not_today_duty_day = types.InlineKeyboardMarkup()
    button_go_to_main_menu3 = types.InlineKeyboardButton(text='Перейти в главное меню',
                                                         callback_data='button_main_menu')
    keyboard_not_today_duty_day.add(button_go_to_main_menu3)
    bot.send_message(call.message.chat.id, 'Дождитесь следующей смены!!! '
                                           '\nНазначить нового дежурного можно будет только в день смены!!!', reply_markup=keyboard_not_today_duty_day)

def change_queue():
    query_replica = "INSERT INTO rescuers(name) SELECT name FROM rescuers WHERE name = %s"
    value = result_duty_name
    cursor.execute(query_replica, (value,))

    query_insert = "INSERT INTO archive(name) SELECT name FROM rescuers WHERE name= %s LIMIT 1"
    cursor.execute(query_insert, (value,))

    query_delete = "DELETE FROM rescuers WHERE name= %s LIMIT 1"
    cursor.execute(query_delete, (value,))
    cursor.execute("SET @num=0")
    cursor.execute("UPDATE rescuers SET name_order =@num:= (@num +1)")
    db.commit()

def delete_duty_day():
    cursor.execute("SELECT date FROM duty_days WHERE date_order= 1")
    result = cursor.fetchone()
    value = result[0]
    query = "UPDATE archive SET date= %s WHERE name= %s"
    cursor.execute(query, (value, result_duty_name))

    cursor.execute("DELETE FROM duty_days WHERE date_order= 1")
    cursor.execute("SET @num=0")
    cursor.execute("UPDATE duty_days SET date_order =@num:= (@num +1)")
    db.commit()

def no_names(call):
    global keyboard_no_names
    keyboard_no_names = types.InlineKeyboardMarkup()
    button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
    button_add_duty = types.InlineKeyboardButton(text='Добавить в список', callback_data='button_Add_Duty')
    keyboard_no_names.add(button_main_menu, button_add_duty)
    bot.send_message(call.message.chat.id, 'Список дежурных пока еще пуст!!! \nДобавьте людей в список дежурных!',
                     reply_markup=keyboard_no_names)

def add_name_duty(message):
    global name1
    name1 = message.text
    query = "SELECT COUNT(name) FROM rescuers where name = %s"
    value = (name1)
    cursor.execute(query, (value,))
    result = cursor.fetchone()
    result_value = result[0]

    if result_value >=1:

        keyboard_mistake_add = types.InlineKeyboardMarkup()
        button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
        button_one_more = types.InlineKeyboardButton(text='Попробовать еще', callback_data='button_Add_Duty')
        keyboard_mistake_add.add(button_main_menu, button_one_more)
        bot.send_message(message.chat.id, f"Дежурный {name1} уже есть в базе!!! \nНельзя дважды добавлять одно и то же имя!",
                                reply_markup=keyboard_mistake_add)
    else:
        bot.send_message(message.chat.id, 'Повторно введите имя человека:')
        bot.register_next_step_handler(message, add_finish)

def add_finish(message):
    global name2
    name2 = message.text

    if name1 == name2:
        query = "INSERT INTO rescuers (name) VALUES (%s)"
        value = name2
        cursor.execute(query, (value,))
        cursor.execute("SET @num=0")
        cursor.execute("UPDATE rescuers SET name_order =@num:= (@num +1)")
        db.commit()

        keyboard_correct_add = types.InlineKeyboardMarkup()
        button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
        button_one_more = types.InlineKeyboardButton(text='Добавить еще', callback_data='button_Add_Duty')
        keyboard_correct_add.add(button_main_menu, button_one_more)
        bot.send_message(message.chat.id, name2 + ' добавлен в список дежурных!')
        main_menu(message)

    else:
        keyboard_mistake_add = types.InlineKeyboardMarkup()
        button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
        button_one_more = types.InlineKeyboardButton(text=' Ввести имя ', callback_data='button_Add_Duty')
        keyboard_mistake_add.add(button_main_menu, button_one_more)
        bot.send_message(message.chat.id, 'ИМЕНА НЕ СОВПАДАЮТ!!!', reply_markup=keyboard_mistake_add)

def delete_duty(message):
    global name_delete
    name_delete = message.text
    query = "SELECT COUNT(name) FROM rescuers WHERE name= %s"
    value = name_delete
    cursor.execute(query, (value,))
    result = cursor.fetchone()
    result_value = result[0]

    if result_value >= 1:
        keyboard_confirm_delete = types.InlineKeyboardMarkup()
        button_confirm_delete = types.InlineKeyboardButton(text='Удалить', callback_data='button_confirm_delete')
        button_cancel_delete = types.InlineKeyboardButton(text='Отмена', callback_data='button_cancel_delete')
        keyboard_confirm_delete.add(button_confirm_delete, button_cancel_delete)
        bot.send_message(message.chat.id, 'Вы хотите удалить ' + name_delete + ' из списка дежурных?',
                             reply_markup=keyboard_confirm_delete)

    else:
        keyboard_mistake_delete = types.InlineKeyboardMarkup()
        button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
        button_one_more = types.InlineKeyboardButton(text='Попробовать еще', callback_data='button_Minus_Duty')
        keyboard_mistake_delete.add(button_main_menu, button_one_more)
        bot.send_message(message.chat.id, name_delete + ' нет в списке дежурных! \nПопробуйте ввести имя еще раз!',
                                reply_markup=keyboard_mistake_delete)

def check_duty_date(message):
    global name_check
    name_check = message.text
    query = "SELECT COUNT(name) FROM rescuers WHERE name = %s"
    value = name_check
    cursor.execute(query, (value,))
    result = cursor.fetchone()
    result_value = result[0]

    if result_value >= 1:
        query1 = "SELECT name_order FROM rescuers WHERE name = %s LIMIT 0, 1"
        value1 = name_check
        cursor.execute(query1, (value1,))
        result = cursor.fetchone()
        result_value1 = result[0]

        query2 = "SELECT date FROM duty_days WHERE date_order = %s"
        value2 = result_value1
        cursor.execute(query2, (value2,))
        result = cursor.fetchone()
        result_value2 = result[0]

        bot.send_message(message.chat.id, f"{name_check}  дежурит:  {result_value2}")
        main_menu(message)

    else:
        keyboard_mistake_check_duty_date = types.InlineKeyboardMarkup()
        button_main_menu = types.InlineKeyboardButton(text='В главное меню', callback_data='button_main_menu')
        button_one_more = types.InlineKeyboardButton(text='Попробовать еще', callback_data='button_Check_Duty')
        keyboard_mistake_check_duty_date.add(button_main_menu, button_one_more)
        bot.send_message(message.chat.id, name_check + ' нет в списке дежурных! \nПопробуйте ввести имя еще раз!',
                         reply_markup=keyboard_mistake_check_duty_date)

@server.route('/' + TOKEN, methods=['POST'])
def get_message():
    json_string = request.get_data().decode('utf-8')
    update = telebot.types.Update.de_json(json_string)
    bot.process_new_updates([update])
    return '!', 200

@server.route("/")
def webhook():
    bot.remove_webhook()
    bot.set_webhook(url= APP_URL)
    return "!", 200

if __name__ == '__main__':
    server.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))


import os
import CTtools
from subprocess import call
import sys

ct_scan_path = str(sys.argv[1])

MNI_152_bone = os.path.join(os.getcwd(),'MNI152_T1_1mm_bone.nii.gz')

MNI_152 = os.path.join(os.getcwd(),'MNI152_T1_1mm.nii.gz')

bspline_path = os.path.join(os.getcwd(), 'Par0000bspline.txt')

nameOfAffineMatrix = ct_scan_path[:ct_scan_path.find('.nii.gz')]+'_affine.mat'

#print('The location of MNI152 bone:' , MNI_152_bone)

# if you want to do ct scan removal
#ct_scan_wodevice = CTtools.removeCTscandevice(ct_scan_path)

ct_scan_wodevice = ct_scan_path

try:

	ct_scan_wodevice_bone = CTtools.bone_extracted(ct_scan_wodevice)

	call(['flirt', '-in', ct_scan_wodevice_bone, '-ref', MNI_152_bone, '-omat', nameOfAffineMatrix, '-bins', '256', '-searchrx', '-180', '180', '-searchry', '-180', '180', '-searchrz', '-180', '180', '-dof', '12', '-interp', 'trilinear'])

	call(['flirt', '-in', ct_scan_wodevice, '-ref', MNI_152, '-applyxfm', '-init', nameOfAffineMatrix, '-out', ct_scan_wodevice[:ct_scan_wodevice.find('.nii.gz')]+'_MNI152.nii.gz'])

except:
	print('something did not work in CT2MNI152 for this image.')


# models.py
# Author: Jacob Schreiber <jmschreiber91@gmail.com>

import time
import numpy
import torch

from tqdm import trange

from bpnetlite.losses import MNLLLoss
from bpnetlite.losses import log1pMSELoss

from bpnetlite.performance import pearson_corr
from bpnetlite.performance import calculate_performance_measures

from bpnetlite.logging import Logger

@torch.inference_mode()
def trt_predict(model, X, cell_states, read_depths, batch_size=32):
	"""Makes predictions using fixed batch sizes.

	This function takes in a model and makes predictions for an entire data
	set using fixed batch sizes. This is identical to the `.predict` method
	that comes with the methods except that it constructs a final, fixed-size
	batch for the final elements. For instance, if you are using a batch size
	of 32 and there are 40 elements, the second batch here will have size
	32 but only fill in the first 8 elements and then truncate the remaining
	out. This is necessary when using ahead-of-time compilation, such as
	torch2trt, to speed up model inference, because these methods require
	fixed tensor sizes.

	Parameters
	----------
	X: torch.tensor, shape=(-1, 4, 2114)
		A one-hot encoded sequence tensor.

	cell_states: torch.tensor, shape=(-1, n_inputs)
		A tensor representing the state of each cell that is passed into
		the model, e.g. through PCA or LSI.

	read_depths: torch.tensor, shape=(-1, 1)
		A tensor containing the read depth of each cell or aggregated
		across similar cells.

	batch_size: int, optional
		The number of elements to use in each batch. Default is 64.

	dtype: torch datatype
		The data type to c

	Returns
	-------
	y_hat: torch.tensor, shape=(-1, 1000)
		A tensor containing the predicted profiles.
	"""

	starts = numpy.arange(0, X.shape[0], batch_size)
	ends = starts + batch_size

	y = []

	for start, end in zip(starts, ends):
		if end >= X.shape[0]:
			idx = X.shape[0] - start

			_X = torch.zeros(batch_size, X.shape[1], X.shape[2], dtype=X.dtype,
				device=X.device)
			_X[:idx] = X[start:end]

			_cs = torch.zeros(batch_size, cell_states.shape[1],
				dtype=cell_states.dtype, device=cell_states.device)
			_cs[:idx] = cell_states[start:end]

			_rd = torch.zeros(batch_size, read_depths.shape[1],
				dtype=read_depths.dtype, device=read_depths.device)
			_rd[:idx] = read_depths[start:end]
		else:
			_X = X[start:end]
			_cs = cell_states[start:end]
			_rd = read_depths[start:end]

		_y = model(_X, _cs, _rd)

		if end >= X.shape[0]:
			idx = X.shape[0] - start

			_y = _y[:idx]

		y.append(_y)

	return torch.cat(y)

class DragoNNFruit(torch.nn.Module):
	"""An entire DragoNNFruit model with all components.

	DragoNNFruit is a model for analyzing single cell data sets that include
	an accessibility component. It can be used on scATAC-seq data alone or it
	can be used on multimodal data where one of the components is scATAC-seq.

	Briefly, the model is primarily a ChromBPNet model that uses an external
	factor to modify the parameters of the accessibility model. This external
	factor can be LSI representations from the same scATAC-seq data being
	predicted or it can come from the other modalities, e.g. scRNA-seq, if the
	data is multimodal.

	A DragoNNFruit model is made up of three components: (1) the bias model,
	(2) the dynamic accessibility model, and (3) the dynamic controller. These
	components are defined below, but the first two are based on ChromBPNet.

	Parameters
	----------
	bias: torch.nn.Module
		This model takes in sequence and outputs the shape one would expect in
		ATAC-seq data due to Tn5 bias alone. This is usually a BPNet model
		from the bpnet-lite repo that has been trained on GC-matched non-peak
		regions.

	accessibility: torch.nn.Module
		This model takes in sequence and outputs the accessibility one would
		expect due to the components of the sequence, but also takes in a cell
		representation which modifies the parameters of the model, hence,
		"dynamic." This model is usually a DynamicBPNet model, defined below.

	name: str
		The name to prepend when saving the file.
	"""

	def __init__(self, bias, accessibility, name, alpha=1):
		super(DragoNNFruit, self).__init__()

		for parameter in bias.parameters():
			parameter.requires_grad = False

		self.bias = bias
		self.accessibility = accessibility
		self.name = name
		self.alpha = alpha
		self.logger = Logger(["Epoch", "Iteration", "Training Time",
			"Validation Time", "Training MNLL", "Validation MNLL",
			"Validation Profile Correlation", "Validation Count Correlation",
			"Saved?"], verbose=True)

	def forward(self, X, cell_states, read_depths):
		"""A forward pass through the network.

		This function is usually accessed through calling the model, e.g.
		doing `model(x)`. The method defines how inputs are transformed into
		the outputs through interactions with each of the layers.

		Parameters
		----------
		X: torch.tensor, shape=(-1, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(-1, n_nodes)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		read_depths: torch.tensor, shape=(-1, 1)
			A tensor containing the read depth of each cell or aggregated
			across similar cells.

		Returns
		-------
		y_profile: torch.tensor, shape=(-1, 1000)
			The predicted logit profile for each example. Note that this is not
			a normalized value.
		"""

		return read_depths + self.bias(X)[0][:, 0] + self.accessibility(X,
			cell_states)

	@torch.no_grad()
	def predict(self, X, cell_states, read_depths, batch_size=16,
		reduction=None, verbose=False):
		"""A method for making batched predictions.

		This method will take in a large number of cell states and provide
		predictions in a batched manner without storing the gradients. Useful
		for inference step.

		Parameters
		----------
		X: torch.tensor, shape=(-1, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(-1, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		read_depths: torch.tensor, shape=(-1, 1)
			A tensor containing the read depth of each cell or aggregated
			across similar cells.

		batch_size: int, optional
			The number of elements to use in each batch. Default is 64.

		reduction: None, 'logsumexp', or 'sum', optional
			Whether to reduce the predictions along the final axis. Useful to
			reduce the memory overhead of making large number of predictions.
			If None, perform no reduction. Default is None.

		verbose: bool, optional
			Whether to display a progress bar across batches. Default is False.

		Returns
		-------
		y_hat: torch.tensor, shape=(-1, 1000) or (-1, 1)
			A tensor containing the predicted profiles.
		"""

		y_hat = []
		for start in trange(0, len(X), batch_size, disable=not verbose):
			X_batch = X[start:start+batch_size]
			cs_batch = cell_states[start:start+batch_size]
			rd_batch = read_depths[start:start+batch_size]

			y_hat_ = self(X_batch, cs_batch, rd_batch)
			if reduction == 'sum':
				y_hat_ = torch.sum(y_hat_, dim=-1)
			elif reduction == 'logsumexp':
				y_hat_ = torch.logsumexp(y_hat_, dim=-1)

			y_hat.append(y_hat_)

		y_hat = torch.cat(y_hat)
		return y_hat

	@torch.no_grad()
	def predict_cross(self, X, cell_states, read_depths, batch_size=64,
		reduction=None, verbose=False):
		"""A method for making batched predictions on a locus/cell cross.

		This method makes predictions for a cross between loci and cell states.
		Use this method and not `predict` when you want to make predictions
		for all loci for all cell states. Because the cross is constructed
		in batches the amount of memory required is limited and the size
		of the loci and cell states do not need to match in the first
		dimension.

		Parameters
		----------
		X: torch.tensor, shape=(n_loci, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(n_states, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		read_depths: torch.tensor, shape=(n_states, 1)
			A tensor containing the read depth of each cell or aggregated
			across similar cells.

		batch_size: int, optional
			The number of elements to use in each batch. Default is 64.

		reduction: None, 'logsumexp', or 'sum', optional
			Whether to reduce the predictions along the final axis. Useful to
			reduce the memory overhead of making large number of predictions.
			If None, perform no reduction. Default is None.

		verbose: bool, optional
			Whether to display a progress bar across states. Default is False.

		Returns
		-------
		y_hat: torch.tensor, shape=(n_loci, n_states, 1000)
			A tensor containing the predicted profiles.
		"""

		n_states = cell_states.shape[0]
		y_hat = []

		for i in trange(n_states, disable=not verbose):
			_y_hat = self.predict(X, cell_states[i:i+1].expand(X.shape[0], -1),
				read_depths=read_depths[i:i+1].expand(X.shape[0], -1),
				batch_size=batch_size, reduction=reduction)
			y_hat.append(_y_hat)

		return torch.stack(y_hat)

	def _train_step(self, X, cell_states, read_depths, y, optimizer):
		optimizer.zero_grad()

		with torch.autocast(device_type='cuda', dtype=torch.bfloat16):
			y_hat = self(X, cell_states, read_depths)

		y_hat_ = torch.nn.functional.log_softmax(y_hat.flatten(), dim=-1)
		loss = MNLLLoss(y_hat_, y.flatten())

		loss_ = loss.item()
		loss = loss.backward()

		torch.nn.utils.clip_grad_norm_(self.parameters(), 1)
		optimizer.step()
		return loss_

	def fit(self, training_data, validation_data, optimizer,
		n_validation_samples=5000, max_epochs=100, batch_size=64,
		validation_iter=100, verbose=True):
		"""Fit an entire DragoNNFruit model to the data.
		"""

		X_valid, y_valid, c_valid, r_valid = zip(*[validation_data[i]
			for i in range(n_validation_samples)])
		X_valid = torch.stack(X_valid).cuda().type(torch.float32)
		y_valid = torch.stack(y_valid).cuda().type(torch.float32)
		c_valid = torch.stack(c_valid).cuda()
		r_valid = torch.stack(r_valid).cuda()

		start, best_corr = time.time(), 0
		self.logger.start()
		for epoch in range(max_epochs):
			for i, (X, y, cell_states, read_depths) in enumerate(training_data):
				X = X.cuda().type(torch.float32)
				y = y.cuda()
				cell_states = cell_states.cuda()
				read_depths = read_depths.cuda()

				train_loss = self._train_step(X, cell_states, read_depths, y,
					optimizer)

				if verbose and i % validation_iter == 0:
					train_time = time.time() - start
					tic = time.time()

					# Make predictions
					y_hat = self.predict(X_valid, c_valid, r_valid, batch_size)

					# Calculate MNLL loss
					y_hat_ = torch.nn.functional.log_softmax(y_hat.flatten(),
						dim=-1)
					valid_loss = MNLLLoss(y_hat_, y_valid.flatten()).item()

					# Calculate count correlation
					y_hat_ = torch.logsumexp(y_hat, dim=-1)
					valid_count_corr = pearson_corr(y_hat_, y_valid.sum(dim=-1))
					valid_count_corr = valid_count_corr.mean().item()

					# Calculate profile correlation
					y_hat = torch.nn.functional.log_softmax(y_hat.flatten(),
						dim=-1).reshape(*y_hat.shape)
					y_hat = torch.exp(y_hat)
					valid_profile_corr = pearson_corr(y_hat,
						y_valid).mean().item()

					valid_time = time.time() - tic

					self.logger.add([epoch, i, train_time, valid_time,
						train_loss, valid_loss, valid_profile_corr,
						valid_count_corr, valid_profile_corr > best_corr])

					self.logger.save("{}.log".format(self.name))

					if valid_profile_corr > best_corr:
						best_corr = valid_profile_corr
						torch.save(self, "{}.best.torch".format(self.name))

					start = time.time()
					torch.save(self, "{}.{}.torch".format(self.name, epoch))

class DynamicBPNet(torch.nn.Module):
	"""A BPNet model whose weights are modified by an external factor.

	This model has the same architecture as the original BPNet model except
	that parameters can be controlled by some external factor. Specifically,
	in this model, the bias terms are controlled using the external factor,
	and that external factor is the cell state.

	Because the intended application of this is single cell data, the final
	predictions are modified using the read depth.

	Parameters
	----------
	controller: torch.nn.Module
		This model takes in the cell representation and outputs a
		representation that will be fed into the dynamic accessibility model.
		This model is usually a CellStateController model, as defined below.

	n_filters: int, optional
		The number of filters to use in each convolution layer. Default is 128.

	n_layers: int, optional
		The number of residual dilated convolutions sandwiched between the
		first and the last layer. Does not include the size of the first
		and the last layer. Default is 8.

	trimming: int or None, optional
		The amount of trimming to apply to input sequences to go from the size
		of the input to the size of the output predictions. If none, will
		automatically trim to 2 ** n_layers + 37. Default is None.

	conv_bias: bool, optional
		Whether the convolutions should have learned bias terms in addition
		to those learned from the cell state repressentation. Mostly only
		useful when transferring weights from a pre-trained model.
	"""

	def __init__(self, controller, n_filters=128, n_layers=8, trimming=None,
		conv_bias=False):
		super(DynamicBPNet, self).__init__()

		self.trimming = trimming or 2 ** n_layers + 37
		self.n_filters = n_filters
		self.n_layers = n_layers

		self.iconv = torch.nn.Conv1d(4, n_filters, kernel_size=21, padding=10)
		self.irelu = torch.nn.ReLU()
		self.fconv = torch.nn.Conv1d(n_filters, 1, kernel_size=75, padding=37,
			bias=conv_bias)

		self.biases = torch.nn.ModuleList([
			torch.nn.Linear(controller.n_outputs, n_filters) for i in range(
				n_layers)
		])

		self.convs = torch.nn.ModuleList([
			torch.nn.Conv1d(n_filters, n_filters, kernel_size=3, stride=1,
				dilation=2**i, padding=2**i, bias=conv_bias) for i in range(1,
					n_layers+1)
		])

		self.relus = torch.nn.ModuleList([
			torch.nn.ReLU() for i in range(n_layers)
		])

		self.controller = controller

	def forward(self, X, cell_states):
		"""A forward pass through the network.

		This function is usually accessed through calling the model, e.g.
		doing `model(x)`. The method defines how inputs are transformed into
		the outputs through interactions with each of the layers.

		Parameters
		----------
		X: torch.tensor, shape=(-1, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(-1, n_nodes)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		Returns
		-------
		y_profile: torch.tensor, shape=(-1, 1000)
			The predicted logit profile for each example. Note that this is not
			a normalized value.
		"""

		start, end = self.trimming, X.shape[2] - self.trimming

		cell_states = self.controller(cell_states)
		X = self.irelu(self.iconv(X))

		for i in range(self.n_layers):
			X_conv = self.convs[i](X)
			X_bias = self.biases[i](cell_states).unsqueeze(-1)

			X = X + self.relus[i](X_conv + X_bias)

		y_profile = self.fconv(X)[:, 0, start:end]
		return y_profile

	@torch.no_grad()
	def predict(self, X, cell_states, batch_size=64, reduction=None,
		verbose=False):
		"""A method for making batched predictions.

		This method makes predictions for a paired set of loci and cell states.
		Each locus and cell state are considered individually and so the number
		of loci must match the number of cell states even if many predictions
		are being made for the same cell state or locus. In that case, one
		must pass copies of the locus or cell state to ensure that the shapes
		match.

		Parameters
		----------
		X: torch.tensor, shape=(-1, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(-1, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		batch_size: int, optional
			The number of elements to use in each batch. Default is 64.

		reduction: None, 'logsumexp', or 'sum', optional
			Whether to reduce the predictions along the final axis. Useful to
			reduce the memory overhead of making large number of predictions.
			If None, perform no reduction. Default is None.

		verbose: bool, optional
			Whether to display a progress bar across batches. Default is False.

		Returns
		-------
		y_hat: torch.tensor, shape=(-1, 1000)
			A tensor containing the predicted profiles.
		"""

		y_hat = []
		for start in trange(0, len(X), batch_size, disable=not verbose):
			X_batch = X[start:start+batch_size]
			cs_batch = cell_states[start:start+batch_size]

			y_hat_ = self(X_batch, cs_batch)
			if reduction == 'sum':
				y_hat_ = torch.sum(y_hat_, dim=-1)
			elif reduction == 'logsumexp':
				y_hat_ = torch.logsumexp(y_hat_, dim=-1)

			y_hat.append(y_hat_)

		y_hat = torch.cat(y_hat)
		return y_hat

	@torch.no_grad()
	def predict_cross(self, X, cell_states, batch_size=64, reduction=None,
		verbose=False):
		"""A method for making batched predictions on a locus/cell cross.

		This method makes predictions for a cross between loci and cell states.
		Use this method and not `predict` when you want to make predictions
		for all loci for all cell states. Because the cross is constructed
		in batches the amount of memory required is limited and the size
		of the loci and cell states do not need to match in the first
		dimension.

		Parameters
		----------
		X: torch.tensor, shape=(n_loci, 4, 2114)
			A one-hot encoded sequence tensor.

		cell_states: torch.tensor, shape=(n_states, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		batch_size: int, optional
			The number of elements to use in each batch. Default is 64.

		reduction: None, 'logsumexp', or 'sum', optional
			Whether to reduce the predictions along the final axis. Useful to
			reduce the memory overhead of making large number of predictions.
			If None, perform no reduction. Default is None.

		verbose: bool, optional
			Whether to display a progress bar across states. Default is False.

		Returns
		-------
		y_hat: torch.tensor, shape=(n_loci, n_states, 1000)
			A tensor containing the predicted profiles.
		"""

		n_states = cell_states.shape[0]
		y_hat = []

		for i in trange(n_states, disable=not verbose):
			_y_hat = self.predict(X, cell_states[i:i+1].expand(X.shape[0], -1),
				batch_size=batch_size, reduction=reduction)
			y_hat.append(_y_hat)

		return torch.stack(y_hat)

	def load_conv_weights(self, filename, freeze=False):
		"""Load convolution weights from a pretrained ChromBPNet model.

		This function will load the convolution weights from a pre-trained
		model. Specifically, it will load the convolutions from the
		`accessibility` attribute of the model. Must have the same number
		of layers and filter sizes.

		Parameters
		----------
		filename: str
			The filename of the model to load.

		freeze: bool, optional
			Whether to freeze the layers whose weights are loaded.
		"""

		device = next(self.parameters()).device
		model = torch.load(filename, map_location='cpu').to(device)
		model = model.accessibility

		self.iconv.weight = torch.nn.Parameter(model.iconv.weight)
		self.iconv.weight.requires_grad = not freeze

		self.iconv.bias = torch.nn.Parameter(model.iconv.bias)
		self.iconv.bias.requires_grad = not freeze

		for sconv, mconv in zip(self.convs, model.rconvs):
			sconv.weight = torch.nn.Parameter(mconv.weight)
			sconv.weight.requires_grad = not freeze

			sconv.bias = torch.nn.Parameter(mconv.bias)
			sconv.bias.requires_grad = not freeze

		self.fconv.weight = torch.nn.Parameter(model.fconv.weight)
		self.fconv.weight.requires_grad = not freeze

class CellStateController(torch.nn.Module):
	"""A controller of DynamicBPNet parameters using cell state.

	This component of the DragoNNFruit model concerns taking in cell states
	and transforming them somehow. It is passed into the DynamicBPNet model
	and provides the representations that are used to control the parameters
	of the model.

	Parameters
	----------
	n_inputs: int
		The number of dimensions in the input cell representation.

	n_nodes: int, optional
		The number of nodes in the internal neural network layers. Default
		is 256.

	n_outputs: int, optional
		The number of dimensions in the output cell representation. Default
		is 64.

	n_layers: int, optional
		The total number of internal layers to apply to the representations,
		not including the first layer that transforms the representations from
		input representations to the internal representations or the last
		layer that transforms from the internal representations to the output
		representations. Default is 0.
	"""

	def __init__(self, n_inputs, n_nodes=256, n_outputs=64, n_layers=0):
		super(CellStateController, self).__init__()

		self.n_inputs = n_inputs
		self.n_nodes = n_nodes
		self.n_outputs = n_outputs
		self.n_layers = n_layers

		self.ifc = torch.nn.Linear(n_inputs, n_nodes)
		self.irelu = torch.nn.ReLU()

		self.fcs = torch.nn.ModuleList([
			torch.nn.Linear(n_nodes, n_nodes) for i in range(n_layers)
		])
		self.relus = torch.nn.ModuleList([
			torch.nn.ReLU() for i in range(n_layers)
		])

		self.ffc = torch.nn.Linear(n_nodes, n_outputs)

	def forward(self, cell_states):
		"""A forward pass through the network.

		This function is usually accessed through calling the model, e.g.
		doing `model(x)`. The method defines how inputs are transformed into
		the outputs through interactions with each of the layers.

		Parameters
		----------
		cell_states: torch.tensor, shape=(-1, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		Returns
		-------
		cell_states: torch.tensor, shape=(-1, n_outputs)
			A tensor representing the transformed state of each cell.
		"""

		cell_states = self.irelu(self.ifc(cell_states))
		for i in range(self.n_layers):
			cell_states = self.relus[i](self.fcs[i](cell_states))

		cell_states = self.ffc(cell_states)
		return cell_states

	@torch.no_grad()
	def predict(self, cell_states, batch_size=64):
		"""A method for making batched predictions.

		This method will take in a large number of cell states and provide
		predictions in a batched manner without storing the gradients. Useful
		for inference step.

		Parameters
		----------
		cell_states: torch.tensor, shape=(-1, n_inputs)
			A tensor representing the state of each cell that is passed into
			the model, e.g. through PCA or LSI.

		batch_size: int, optional
			The number of elements to use in each batch. Default is 64.

		Returns
		-------
		cell_states: torch.tensor, shape=(-1, n_outputs)
			A tensor representing the transformed state of each cell.
		"""

		y_hat = []
		for start in range(0, len(cell_states), batch_size):
			cs_batch = cell_states[start:start+batch_size]

			y_hat_ = self(cs_batch)
			y_hat.append(y_hat_)

		y_hat = torch.cat(y_hat)
		return y_hat


from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

ANSIBLE_METADATA = {
    'metadata_version': '1.1',
    'status': ['preview'],
    'supported_by': 'certified'
}

DOCUMENTATION = '''
---
module: aoscx_checkpoint
version_added: "2.8"
short_description: Creates a new checkpoint or copies an existing checkpoint to AOS-CX switch config.
description:
  - This module creates a new checkpoint or copies existing checkpoint
    to the running or startup config of an AOS-CX switch.
author: Aruba Networks (@ArubaNetworks)
options:
  source_config:
    description: Name of the source configuration from which checkpoint needs
      to be created or copied.
    type: str
    required: False
    default: 'running-config'

  destination_config:
    description: Name of the destination configuration or name of checkpoint.
    type: str
    required: False
    default: 'startup-config'
'''

EXAMPLES = '''
- name: Copy running-config to startup-config
  aoscx_checkpoint:
    source_config: 'running-config'
    destination_config: 'startup-config'

- name: Copy startup-config to running-config
  aoscx_checkpoint:
    source_config: 'startup-config'
    destination_config: 'running-config'

- name: Copy running-config to backup checkpoint
  aoscx_checkpoint:
    source_config: 'running-config'
    destination_config: 'checkpoint_20200128'
'''

RETURN = r''' # '''

from ansible.module_utils.aoscx import ArubaAnsibleModule, put

def main():
    module_args = dict(
        source_config=dict(type='str', default='running-config'),
        destination_config=dict(type='str', default='startup-config')
    )

    aruba_ansible_module = ArubaAnsibleModule(module_args=module_args)

    source_config = aruba_ansible_module.module.params['source_config']
    destination_config = \
        aruba_ansible_module.module.params['destination_config']

    url = '/rest/v1/fullconfigs/{dest}?from=/rest/v1/fullconfigs/{src}'.format(
        dest=destination_config, src=source_config)
    put(aruba_ansible_module.module, url)
    result = dict(changed=aruba_ansible_module.changed,
                  warnings=aruba_ansible_module.warnings)
    result["changed"] = True
    aruba_ansible_module.module.exit_json(**result)

if __name__ == '__main__':
    main()


import requests
from bs4 import BeautifulSoup
import re

def getHtmlPage(url):
    html_data = requests.get(url)
    html_data.encoding = html_data.apparent_encoding
    if html_data.status_code == 200:
        return  html_data.text
    else:
        return None

def pasePage(HtmlText):
    soup = BeautifulSoup( HtmlText,'html5lib')
    data = soup.select('div.ranklist-wrapper.clearfix div.bd ul.song-list li')
    pattern1 = re.compile(r'<li.*?
(.*?)
.*?title="(.*?)".*?title="(.*?)".*?
',re.S)
    pattern2 = re.compile(r'(.*?)', re.S)

    dataWant = [];

    for item in data:
        findResult = re.findall(pattern1,str(item))
        if len(findResult) == 1:
            dataWant.append(findResult[0])
        else:
            otherWayData = re.findall(pattern2, str(item))
            dataWant.append(otherWayData[0])
    return dataWant

if __name__ == '__main__':
    url = 'http://music.taihe.com/'
    html = getHtmlPage(url)
    data = pasePage(html)
    for item in data:
        dict = {
            '序号':item[0],
            '歌名':item[1],
            '歌手':item[2]
        }

        print(dict)


from django.shortcuts import render, redirect
from .forms import RecordForm ,PostForm
from .models import *
from django.http import HttpResponse , HttpResponseRedirect
from django.views.generic import TemplateView, FormView, CreateView, ListView, DetailView ,UpdateView, DeleteView
from django.urls import reverse_lazy
from django.contrib import messages
from django.db.models import Q
from .templatetags import tag
from notifications.signals import notify

# Create your views here.
def RecordView(request):
    if request.method=="POST":
        form=RecordForm(request.POST,request.FILES)
        if form.is_valid():
            if not request.user.is_authenticated:
              return HttpResponse("Your Registraion /Login is required")
            object=form.save(commit=False) # commit =False as form still without user data

            object.user=request.user # get logged in user from session data

            # AS WE DEFINED ONE To ONE MODEL RELATION FOR ONE USER  ONLY ONE  ENTRY

            if RecordModel.objects.filter(user=request.user).exists() :
                return HttpResponse(" Your already created your Profile")
            object.save()
            subject=form.cleaned_data['subject'] # get subject objects for iteration of multiple subject entry
            for i in subject:
                object.subject.add(i)
                object.save()
            group=form.cleaned_data['group'] # get group objects for iteration of multiple group entry

            for i in group:
                object.group.add(i)
                object.save()
            messages.success(request,'Record Form has been Successfully Submitted')
            #return HttpResponse("Success")
            return redirect ('/template/')
    else:
        form=RecordForm()
        return render (request, 'education/education.html', {'form':form,'User':request.user})

def RecordDisplay(request):
    record=RecordModel.objects.all()
    record=RecordModel.items.all()
    user=request.user
    if user :
       record_user=RecordModel.objects.filter(user=user.id)

    subject=SubjectModel.objects.all()

    #subject=SubjectModel.objects.filter()

    #user=User.objects.filter(id=5)

   # user=User.objects.filter()

    group=GroupModel.objects.all()
    math=SubjectModel.objects.get(name='Mathematics')
    record_math=math.subject_set.all()
   # record_math_user=math.subject_set.get(user=request.user.id)

    science=GroupModel.objects.get(name='Science')
    record_science=science.group_set.all()
    business=GroupModel.objects.get(name='Business Studies')
    record_business=business.group_set.all()

    Record_user=record.get(id=request.user.id)
    Record_user.views.add(request.user)
    views= Record_user.views.count()

    liked=False
    recorduser=RecordModel.objects.get(id=user.id)
    if recorduser.likes.filter(id=user.id).exists():
        liked=True

    return render (request,'education/record_display.html', {'record':record,'subject':subject,'group':group
         ,'record_math':record_math,'record_science':record_science,'record_business':record_business,'record_user':record_user,
         'user':user,'like':liked,'views':views})

class templateview(TemplateView):
    template_name= 'topic/topics.html'   #'fileupload.html'

    def get_context_data(self, **kwargs):

        context=super().get_context_data(**kwargs)
        context['msg1']="Topic Page => this maeesage from TemplateView"
        context['msg2']="No topic has been added yet => this maeesage from TemplateView"

        return context

class RecordView_by_class(FormView):
      template_name='education/education.html'
      form_class=RecordForm
      success_url='/template'

      def form_valid(self, form):
           #login=self.request.user
           if not self.request.user.is_authenticated:
              return HttpResponse("Log in is required")

           if RecordModel.objects.filter(user=self.request.user).exists() :
                return HttpResponse(" Your have already created your Profile")

           form.save()
           messages.success(self.request,'Record Form Successfully Submitted')
           return super().form_valid(form)
      def form_invalid(form):

        return super().form_invalid(form)
      def get_success_url(self)-> str :
          return super().get_success_url()
          #return reverse_lazy ('')

class PostCreateView(CreateView):
    model=PostModel
    form_class=PostForm
    template_name='education/postcreate.html'
    success_url='/'

    def form_valid(self, form):

         try :
           form.instance.user=self.request.user

           form.save()
           return HttpResponse ("Post has been Successfully Created")
           #return render (self.request, 'education/postcreate.html', {'user': form.instance.user,'msg':'Post has been Successfully Created'} )

          # return super().form_valid(form)
         except :
            #if self.request.user=='':
              #return HttpResponse ("Login is required")
            #else:
                 #return render (self.request, 'education/postcreate.html' )
            return redirect ('../post_create' )     # PostCreateView.as_view()
            #return HttpResponse ("Login is required")
    def form_invalid(form):

          return super().form_invalid(form)
    def get_success_url(self)-> str :
          return super().get_success_url()
         # return reverse_lazy ('topic')

class PostListView(ListView):
    template_name='education/listview.html'
    #queryset=PostModel.objects.filter()
    queryset=RecordModel.objects.filter()

    context_object_name='post'

    def get_context_data(self, **kwargs):

         context= super().get_context_data(**kwargs)
         #context['post'] =context.get('object_list')
         context['msg'] ='This  Total  Post  List'
         context['subjects']=SubjectModel.objects.all()
         context['group']=GroupModel.objects.all()
         return context

class PostDetailView(DetailView):
   template_name='education/postdetails.html'
   model=RecordModel
  # model=PostModel

   def get_context_data(self, **kwargs):
         self.object.views.add(self.request.user)
         liked=False
         if self.object.likes.filter(id=self.request.user.id).exists():
          liked=True
         context= super().get_context_data(**kwargs)
         post=context.get('object')
         #comment=Comment.objects.all()

         comments=Comment.objects.filter(post=self.object.id ,parent_comment= None)
         replies=Comment.objects.filter(post=self.object.id ).exclude(parent_comment=None)
         DictofReply={}
         for reply in replies :
            if reply.parent_comment.id not in DictofReply.keys():
                DictofReply[reply.parent_comment.id]=[reply]
            else :
                DictofReply[reply.parent_comment.id].append(reply)
         context['post'] =context.get('object')  # =>  this line is optional
         context['msg'] ='This is Individual Post Details'

         context['like'] =liked
         context['comments'] =comments
         #context['replies'] =replies
         context['DictofReply'] = DictofReply

         #
         # context['comment'] =comment
         return context

class PostEditView(UpdateView):
    model=RecordModel
    #model=PostModel
    #form_class=PostForm
    form_class=RecordForm
    template_name='education/postcreate.html'
    #success_url='/'

    def get_success_url(self) :
          id=self.object.id
          #return super().get_success_url()
          return reverse_lazy ('PostDetailView',kwargs={'pk':id})

class PostDeleteView(DeleteView):
     model=RecordModel
     template_name='education/postdelete.html'
     success_url=reverse_lazy ('PostListView')

def search (request):
    query=request.POST.get('search',' ')
    if query :
        queryset=(Q(name__icontains=query))|(Q(address__icontains=query))|(Q(medium__icontains=query))|(Q(category__icontains=query))|(Q(subject__name__icontains=query))|(Q(group__name__icontains=query))
        results=RecordModel.objects.filter(queryset).distinct()
    else:
        results=[]
    context={'result':results}
    return render(request, 'education/search.html',context)

def filter (request):

    if request.method=="POST" :
        subject=request.POST['subject']
        group=request.POST['group']
        amount_from=request.POST['amount_from']
        amount_to=request.POST['amount_to']
        available=request.POST['available']

        if subject or group:
           queryset=(Q(subject__name__icontains=subject)) & (Q(group__name__icontains=group)) # & for both instead of | (or)
           results=RecordModel.objects.filter(queryset).distinct()
           if available :
              results=results.filter(available=True)
           if amount_from :
             results=results.filter(amount__gte=amount_from)
           if amount_to:
             results=results.filter(amount__lte=amount_to)
        else:
           results=[]
        context={'result':results}
        return render(request, 'education/search.html',context)
    #return render(request, 'education/listview.html')
def likepost(request, id):
    if request.method=="POST":

        record_user=RecordModel.objects.get(id=id)
        postId=record_user.id
        if record_user.likes.filter(id=request.user.id).exists():
           record_user.likes.remove(request.user)
        else :
           record_user.likes.add(request.user)
           if request.user != record_user.user :
            notify.send(request.user, recipient=record_user.user , verb="has liked your post" + f''' <a href="/education/post_details/{postId}/ " > Go </a>''')
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
    #return redirect(f'../post_details/{postId}/')
def add_comment (request):
    if request.method=="POST":
        comment=request.POST['text'] # New Comment or reply of a comment
        parent_id=request.POST['parent_id'] # id of main comment (if)
        post_id=request.POST['post_id']

        #if (request.POST['parent_id']).strip():
           # ID=True
        #else :
           # ID=False
        post=RecordModel.objects.get(id=post_id)
        if len(comment)==0 :
            return HttpResponseRedirect(request.META.get('HTTP_REFERER')) #  back to comment page/original page
        if parent_id.strip():
            parent_comment=Comment.objects.get(id=parent_id)
            newcomment=Comment(text=comment, user=request.user, post=post, parent_comment=parent_comment) # comment reply
            newcomment.save()
        else :
           newcomment=Comment(text=comment, user=request.user, post=post ) # new comment
           newcomment.save()
    return HttpResponseRedirect(request.META.get('HTTP_REFERER')) #  back to comment page/original page

def notification (request):
    return render (request, 'education/notification.html')


"""Topology for surface tracking (:mod:`fluidimage.topologies.surface_tracking`)
================================================================================

.. autoclass:: TopologySurfaceTracking
   :members:
   :private-members:

.. todo::

   Make this code usable:

   - good unittests
   - tutorial with ipynb
   - example integrated in the documentation

"""
import json

from ..topologies import prepare_path_dir_result
from .base import TopologyBase
from .waiting_queues.base import (
    WaitingQueueMultiprocessing,
    WaitingQueueThreading,
    WaitingQueueLoadImagePath,
    WaitingQueueMakeCouple,
)

from ..data_objects.piv import ArrayCouple
from .. import ParamContainer
from .. import SeriesOfArrays, SerieOfArraysFromFiles
from ..util import logger
from ..works.old.surface_tracking import WorkSurfaceTracking

class TopologySurfaceTracking(TopologyBase):
    """Topology for SurfaceTracking.

    Parameters
    ----------

    params : None

      A ParamContainer containing the parameters for the computation.

    logging_level : str, {'warning', 'info', 'debug', ...}

      Logging level.

    nb_max_workers : None, int

      Maximum numbers of "workers". If None, a number is computed from the
      number of cores detected. If there are memory errors, you can try to
      decrease the number of workers.

    """

    @classmethod
    def create_default_params(cls):
        """Class method returning the default parameters.

        For developers: cf. fluidsim.base.params

        """
        params = ParamContainer(tag="params")

        params._set_child(
            "series",
            attribs={
                "path": "",
                "strcouple": "i:i+2",
                "ind_start": 0,
                "ind_stop": None,
                "ind_step": 1,
            },
        )

        params._set_child(
            "film",
            attribs={
                "fileName": "",
                "path": "",
                "path_ref": "",
                "ind_start": 0,
                "ind_stop": None,
                "ind_step": 1,
            },
        )

        params._set_child(
            "saving",
            attribs={
                "plot": False,
                "how_many": 1000,
                "path": None,
                "how": "hdf5",
                "postfix": "surface_tracking",
            },
        )

        params.saving._set_doc(
            """Saving of the results.

path : None or str

    Path of the directory where the data will be saved. If None, the path is
    obtained from the input path and the parameter `postfix`.

how : str {'ask'}

    'ask', 'new_dir', 'complete' or 'recompute'.

postfix : str

    Postfix from which the output file is computed.
"""
        )

        WorkSurfaceTracking._complete_params_with_default(params)

        params._set_internal_attr(
            "_value_text",
            json.dumps(
                {
                    "program": "fluidimage",
                    "module": "fluidimage.topologies.surface_tracking",
                    "class": "TopologySurfaceTracking",
                }
            ),
        )

        params._set_child("mask", attribs={"strcrop": None})

        params.mask._set_doc(
            """
            Parameters describing how images are masked.

            strcrop : None, str

                Two-dimensional slice (for example '100:600, :'). If None, the
                whole image is used.  """
        )

        return params

    def __init__(self, params=None, logging_level="info", nb_max_workers=None):

        if params is None:
            params = self.__class__.create_default_params()

        self.params = params
        self.path = params.film.path
        self.path_ref = params.film.path_ref
        serie_arrays_ref = SerieOfArraysFromFiles(params.film.path_ref)

        self.surface_tracking_work = WorkSurfaceTracking(params)

        serie_arrays = SerieOfArraysFromFiles(
            params.film.path + "/" + params.film.fileName
        )
        self.series = SeriesOfArrays(
            serie_arrays,
            params.series.strcouple,
            ind_start=params.film.ind_start,
            ind_stop=params.film.ind_stop,
            ind_step=params.film.ind_step,
        )

        path_dir = self.path
        path_dir_result, self.how_saving = prepare_path_dir_result(
            path_dir, params.saving.path, params.saving.postfix, params.saving.how
        )

        self.path_dir_result = params.film.path
        self.results = {}

        def save_surface_tracking_object(o):
            ret = o.save(path_dir_result / o.nameFrame)
            return ret

        self.wq_sf_out = WaitingQueueThreading(
            "save_surface_tracking_object",
            save_surface_tracking_object,
            self.results,
            topology=self,
        )
        self.wq_sf_in = WaitingQueueMultiprocessing(
            "surface_tracking_work",
            self.surface_tracking_work.compute,
            self.wq_sf_out,
            topology=self,
        )

        self.wq_images = WaitingQueueMakeCouple(
            "array image", self.wq_sf_in, topology=self
        )

        self.wq0 = WaitingQueueLoadImagePath(
            destination=self.wq_images, path_dir=path_dir, topology=self
        )

        waiting_queues = [self.wq0, self.wq_images, self.wq_sf_in, self.wq_sf_out]

        super().__init__(
            waiting_queues,
            path_output=path_dir_result,
            logging_level=logging_level,
            nb_max_workers=nb_max_workers,
        )

        self.add_series(self.series)

    def add_series(self, series):
        """
        Fill working queues
        :param series: Series representing a film
        :type SeriesOfArrays
        :return:
        """
        if len(series) == 0:
            logger.warning("add 0 couple. No PIV to compute.")
            return

        if self.how_saving == "complete":
            names = []
            index_series = []
            for i, serie in enumerate(series):
                name_sf = serie.get_name_arrays()
                #                if os.path.exists(os.path.join(self.path_dir_result, name_sf[0])):
                #                    print(os.path.join(self.path_dir_result, name_sf[0]))
                #                    continue

                for name in serie.get_name_arrays():
                    if name not in names:
                        names.append(name)

                index_series.append(i * series.ind_step + series.ind_start)
            if len(index_series) == 0:
                logger.warning(
                    'topology in mode "complete" and work already done.'
                )
                return

            series.set_index_series(index_series)

            logger.debug(repr(names))
            logger.debug(repr([serie.get_name_arrays() for serie in series]))
        else:
            names = series.get_name_all_arrays()

        nb_series = len(series)
        print(f"Add {nb_series} surface fields to compute.")

        for i, serie in enumerate(series):
            if i > 1:
                break

        print("Files of serie {}: {}".format(i, serie.get_name_arrays()))

        self.wq0.add_name_files(names)
        self.wq_images.add_series(series)

        k, o = self.wq0.popitem()
        im = self.wq0.work(o)
        self.wq0.fill_destination(k, im)

        # a little bit strange, to apply mask...
        try:
            params_mask = self.params.mask
        except AttributeError:
            params_mask = None
        couple = ArrayCouple(
            names=("", ""), arrays=(im, im), params_mask=params_mask
        )
        im, _ = couple.get_arrays()

    def print_at_exit(self, time_since_start):
        pass

params = TopologySurfaceTracking.create_default_params()
__doc__ += params._get_formatted_docs()


from bs4 import BeautifulSoup
from urllib.request import Request, urlopen
import re
import csv
#import sys
#import json

if __name__ == '__main__':
    fieldnames = ['name', 'genre', 'actor', 'director', 'duration', 'date_released', 'score']
    with open('metacritic_data.csv', mode='w') as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        writer.writeheader()
        months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
        root = ["https://www.metacritic.com/browse/movies/genre/date/action?view=condensed&page=", "https://www.metacritic.com/browse/movies/genre/date/documentary?view=condensed&page="]
        for rooti in range(2):
            if rooti == 0:
                limitindex = 64
            else:
                limitindex = 36
            for i in range(limitindex):
                print(rooti, i)
                site= root[rooti] + str(i)
                hdr = {'User-Agent': 'Mozilla/5.0'}
                req = Request(site,headers=hdr)
                html = urlopen(req).read().decode('utf-8')
                soup = BeautifulSoup(html, features='lxml')
                all_h3 = soup.find_all("div")
                for one_h3 in all_h3:
                    #try:
                    if one_h3.get('class') is not None and one_h3.findChildren("h3" , recursive=False) == [] and one_h3.get('class')[0] == 'basic_stat' and one_h3.get('class')[1] == 'product_title':
                        links = one_h3.find_all('a')
                        for link in links:
                            info = {}
                            target = 'https://www.metacritic.com'+link.get('href')
                            #print('Go to target: '+target)
                            req = Request(target,headers=hdr)
                            sub_html = urlopen(req).read().decode('utf-8')

                            #print(sub_html)
                            sub_soup = BeautifulSoup(sub_html, features = 'lxml')
                            director = sub_soup.find('div', {'class': "director"})
                            if director is not None:
                                director = director.get_text().split('\n')[2].replace(" and ", "&")
                            else:
                                director = 'null'
                            #print(director)

                            genres = sub_soup.find('div', {'class': "genres"})
                            if genres is not None:
                                genres = ''.join(genres.get_text().split('\n')[3].split(' ')).replace(",", "&")
                            else:
                                genres = 'null'
                            #print(genres)

                            runtime = sub_soup.find('div', {'class': "runtime"})
                            if runtime is not None:
                                runtime = runtime.get_text().split('\n')[2]
                            else:
                                runtime = 'null'
                            #print(runtime)

                            actors = sub_soup.find('div', {'class': "summary_cast details_section"})
                            if actors is not None:
                                actors = ''.join(re.split("  +", actors.get_text().split('\n')[3])).replace(",", "&")
                            else:
                                actors = 'null'
                            #print(actors)

                            date = sub_soup.find('span', {'class': "release_date"})
                            if date is not None:
                                date_letter = date.get_text().split('\n')[2].replace(", ", " ")
                                date_sp = date_letter.split()
                                if date_sp[0] in months:
                                    date_sp[0] = str(months.index(date_sp[0])+1)
                                    date = '/'.join(date_sp)
                                else:
                                    date = 'null'
                            else:
                                date = 'null'
                            #print(date)

#                            userscore = sub_soup.find('div', {'class': re.compile("metascore_w user larger movie *")})
#                            if userscore is not None:
#                                userscore = userscore.get_text().split('\n')[0]
#                            else:
#                                userscore = 'null'
#                            #print(userscore)

                            metascore = sub_soup.find('div', {'class': re.compile("metascore_w larger movie *")})
                            if metascore is not None:
                                metascore = metascore.get_text().split('\n')[0]
                            else:
                                metascore = 'null'
                            #print(metascore)

                            name = sub_soup.find('div', {'class': "product_page_title oswald"})
                            name = name.get_text().split('\n')[1]
                            print(name)
                            #['name', 'genre', 'actor', 'director', 'duration', 'datePublished', 'score']
                            if runtime.lower() == 'tbd' or runtime.lower() == 'tba':
                                runtime = 'null'
                            if name.lower() == 'tbd' or name.lower() == 'tba':
                                name = 'null'
                            if genres.lower() == 'tbd' or genres.lower() == 'tba':
                                genres = 'null'
                            if actors.lower() == 'tbd' or actors.lower() == 'tba':
                                actors = 'null'
                            if date.lower() == 'tbd' or date.lower() == 'tba':
                                date = 'null'
                            if metascore.lower() == 'tbd' or metascore.lower() == 'tba':
                                userscore = 'null'
                            if director.lower() == 'tbd' or director.lower() == 'tba':
                                director = 'null'
        #                    if name == 'Blazing Samurai':
                            info['duration'] = runtime
                            info['name'] = name
                            info['genre'] = genres
                            info['actor'] = actors
                            info['date_released'] = date
                            info['score'] = metascore
                            info['director'] = director
                            writer.writerow(info)

            #except KeyboardInterrupt:
            #    sys.exit()
            #except:
            #    print("An exception occurred while processing ", one_h3)


"""
example:
	python splitH5.py --iname=./pre-trained-rnn.h5 \
					--dataset=/model_weights/dense_1/dense_1/bias:0 \
					--oname=./dense_1_bias.h5 \
					--new_dataset=dense_1/bias:0
"""

import h5py
import argparse

if __name__ == "__main__":

	parser = argparse.ArgumentParser()
	parser.add_argument('--iname', type=str, default="",
		help="the input H5 file")
	parser.add_argument('--dataset', type=str, default="",
		help="the dataset we want to split")
	parser.add_argument('--oname', type=str, default="",
		help="the output H5 file")
	parser.add_argument('--new_dataset', type=str, default="",
		help="the dataset we want to generate in the new H5 file")
	args = parser.parse_args()
	iname = args.iname
	dname = args.dataset
	oname = args.oname
	ndname = args.new_dataset

	f = h5py.File(iname, 'r')
	dataset = f[dname]
	h5f = h5py.File(oname, 'w')
	h5f.create_dataset(ndname, data=dataset)
	h5f.close()

	# f = h5py.File('./pre-trained-rnn.h5', 'r')
	# dataset = f['model_weights/dense_1/dense_1/bias:0']
	# h5f = h5py.File('dense_1_bias.h5', 'w')
	# h5f.create_dataset('dense_1/bias:0', data=dataset)
	# h5f.close()


class GameOfLife():

    _scala = 20

    def __init__(self, size):
        self._scala = int(size / self._scala)
        self.width = self.height = self._scala
        self.width_screen = self.height_screen = size
        self.size_x = self.size_y = size / self.width
        self.board = self.__get_board()

    # return the new state of node(depends of the neighbors alive)
    # 1) Any live cell with fewer than two live neighbors dies,
    #   as if caused under-population
    # 2) Any live cell with two live neighbors lives on to the next
    #   generation
    # 3) Any Live cell with more than three live neighbors dies,
    #   as if by overcrowding
    # 4) Any dead cell with exactly three live neighbors becomes a live cell,
    #   as if by reproduction
    def __change_state(self, current_state, live_cells):
        return live_cells == 3 or (live_cells == 2 and current_state)

    # Every cell interacts with its eight neighbors, which are
    # the cells that are horizontally, vertically, or diagonally
    # adjacent. At each step in time(generation).
    def __get_alive_neighbors(self, x, y):
        alive_neighbors = 0
        size = len(self.board) - 1
        for index_x in (-1, 0, 1):
            for index_y in (-1, 0, 1):
                if (x + index_x) > 0 and (x + index_x) <= size:
                    if (y + index_y) > 0 and (y + index_y) <= size:
                        if index_x == 0 and index_y == 0:
                            continue  # continue if is the current cell
                        if self.board[x + index_x][y + index_y]:
                            alive_neighbors += 1

        return alive_neighbors

    # get a empty board
    def __get_board(self):
        return [[False for col in range(self.width)] for row in range(self.height)]

    # Refresh board
    def update_life(self):
        updated_board = self.__get_board()
        for i, row in enumerate(self.board):
            for j, cell in enumerate(row):
                number_of_neighbors = self.__get_alive_neighbors(i, j)

                updated_board[i][j] = self.__change_state(
                    cell, number_of_neighbors
                )

        self.board = updated_board


def processString(func):
    def wrapper(raw_string):
        return func(''.join(e for e in raw_string if e.isalnum()))
    return wrapper

@processString
def testPalindrome(string: str) -> bool:
    """
    Test if the provided string is a palindrome.
    A string is a palindrome if it is identical forward and backward.
    """
    reverse: list = []

    for char in string:
        reverse.insert(0, char)
    if reverse == list(string):
        return True
    else:
        return False

print(testPalindrome("lev#$e  l"))      # True
print(testPalindrome("io9"))            # False


import math

def printSolution(x):
    print(f"The solution is: {x}")

class Tile:
    def __init__(self):
        self.id = None
        self.data = []
        self.edges = []
        self.connecting = []

    def getEdges(self):
        top, bottom = self.data[0], self.data[-1]
        left, right = [x[0] for x in self.data], [x[-1] for x in self.data]
        for v in [top, bottom, left, right]:
            self.edges.append(self.findValue(v))
            self.edges.append(self.findValue(v[::-1]))
        return self.edges

    def findValue(self, row):
        return int(''.join(row), 2)

    def __repr__(self):
        return repr(f"Tile: {self.id}, {self.data}")

def main():
    file = open("input.txt", "r")

    t = Tile()
    tiles = []
    for line in file:
        line = line.strip()
        if not line:
            t.getEdges()
            tiles.append(t)
            t = Tile()
        elif "Tile" in line:
            t.id = int("".join(filter(str.isdigit, line)))
        else:
            t.data.append(['1' if x == "#" else '0' for x in line])

    t.getEdges()
    tiles.append(t)

    for t in tiles:
        for t_check in tiles:
            if t.id == t_check.id:
                continue
            else:
                c = set(t.edges).intersection(set(t_check.edges))
                if len(c):
                    t.connecting.append(t_check.id)

    corners = [t for t in tiles if len(t.connecting) == 2]

    printSolution(math.prod([t.id for t in corners]))

if __name__ == "__main__":
    main()


'''
Your function will accept a number n and return the nth number of the fibonacci sequence.

Do it recursively, iteratively and Dynamically

Input: fibonacciRecur(10)
Output: 55
'''

# Recursively

def fibonacciRec(n):

	if n == 0 or n == 1:
		return n
	else:
		return fibonacciRec(n - 1) + fibonacciRec(n - 2)

# Iteratively

def fibonacciIter(n):

	 a, b = 0, 1

	 for i in range(n):

	 	a, b = b, a + b

	 return a

# Dynamically

n = 10
cache = [None] * (n + 1)

def fibonacciDyn(n):

    # Base case
	if n == 0 or n == 1:
		return n

	# Check cache
	if cache[n] != None:
		return cache[n]

	# Keep setting cache
	cache[n] = fibonacciDyn(n - 1) + fibonacciDyn(n - 2)

	return cache[n]


import pygame

#kicks off all the modules required for PyGame
pygame.init()

#Launches a window of desired size, return value is a Surface object
screen = pygame.display.set_mode((400, 300))
done = False
is_blue = True
x = 30
y = 30

clock = pygame.time.Clock()

while not done:
    for event in pygame.event.get(): #this empties the event queue, if not used program may become unresponsive
        if event.type == pygame.QUIT: #event triggered when clicking close window button
            done = True
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            is_blue = not is_blue

    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_UP]:
        y-=3
    if pressed[pygame.K_DOWN]:
        y+=3
    if pressed[pygame.K_LEFT]:
        x-=3
    if pressed[pygame.K_RIGHT]:
        x+=3

    screen.fill((0,0,0))

    if is_blue:
        color = (0,128,255)
    else:
        color = (255,100,0)
    #1st arg - the surface object; 2nd arg - color of the rect; 3rd arg - size of the rect drawn
    pygame.draw.rect(screen, color, pygame.Rect(x,y,60,60))
    #swaps the buffers; i.e it is needed so that any updates on the surface object becomes visible
    pygame.display.flip()
    clock.tick(60)


from django.contrib import admin
from django.urls import path, re_path, include
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework.permissions import AllowAny

schema_view = get_schema_view(
    openapi.Info(
        title='CareerHub API',
        default_version='v1',
        description='CareerHub browsable API =)',
        terms_of_service='Thank you',
        contact=openapi.Contact(email='careerhub@careerhub.com'),
        license=openapi.License(name='Лицензий нет =)'),
    ),
    public=True,
    permission_classes=[AllowAny],
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.v1.urls')),
    re_path(
        r'^swagger(?P<format>\.json|\.yaml)$',
        schema_view.without_ui(cache_timeout=0),
        name='schema-json'
    ),
    path(
        'swagger/',
        schema_view.with_ui('swagger', cache_timeout=0),
        name='schema-swagger-ui'
    ),
    path(
        'redoc/',
        schema_view.with_ui('redoc', cache_timeout=0),
        name='schema-redoc'
    ),
]


import pymongo

##### Uncomment this part, if your running on a gnome-terminal ########
##### It launches mongod in a new terminal.                    ########
# import subprocess
# import time
#
# subprocess.call(['gnome-terminal', '--', 'mongod'])
# print("Wait 2 seconds for mongod to start up.....")
# time.sleep(2)
#######################################################################

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["foodDB"]
mycol = mydb["fooditems"]

def deleteOne():
    name = input("Delete product: ")
    myquery = {"name": name}
    if mycol.find_one(myquery):
        mycol.delete_one(myquery)
        emptyLines(1)
        print("Succesfully deleted: " + name)
    else:
        emptyLines(1)
        print(name + " not found.")
    emptyLines()

def findOne():
    name = input("Search product: ")
    food = {"name": name}
    x = mycol.find_one(food)
    if x == None:
        emptyLines(1)
        print(name + " not found")
    else:
        emptyLines(1)
        print(x)
    emptyLines()

def insertOne():
    name = input("Product Name: ")
    while True:
        try:
            kcal = float(input("Kcal :"))
            break
        except ValueError:
            print("Oops! That was not a valid number. Try again...")
            emptyLines(1)
    food = {"name": name, "kcal": kcal}
    x = mycol.insert_one(food)
    emptyLines(1)
    print("Succesfully added :", food)
    emptyLines()

def querySomething():
    myquery = {"kcal": {"$gt": 50}}
    mydoc = mycol.find(myquery)
    for x in mydoc:
        print(x)
    emptyLines()

def showAll(mycol=mycol):
    for x in mycol.find():
        print(x)
    emptyLines()

def showCollections():
    print(mydb.list_collection_names())
    emptyLines()

def sortByName():
    mydoc = mycol.find().sort("name")
    for x in mydoc:
        print(x)
    emptyLines()

def sortByKcal():
    mydoc = mycol.find().sort("kcal", -1)  # , -1  = reverse sort
    for x in mydoc:
        print(x)
    emptyLines()

def updateKcal():
    name = input("Product Name: ")
    myquery = {"name": name}
    if mycol.find_one(myquery):
        while True:
            try:
                kcal = float(input("Update Kcal :"))
                break
            except ValueError:
                print("Oops! That was not a valid number. Try again...")
                emptyLines(1)
        newvalues = {"$set": {"kcal": kcal}}
        mycol.update_one(myquery, newvalues)
        emptyLines(1)
        print("Succefully updated ", name, newvalues["$set"])
    else:
        emptyLines(1)
        print(name + " not found.")
    emptyLines()

def updateName():
    name = input("Product Name: ")
    myquery = {"name": name}
    if mycol.find_one(myquery):
        newName = userChoice = input("New Name: ")
        newvalues = {"$set": {"name": newName}}
        mycol.update_one(myquery, newvalues)
        emptyLines(1)
        print("Succefully updated ", name, newvalues["$set"])
    else:
        emptyLines(1)
        print(name + " not found.")
    emptyLines()

# Non MongoDB

def emptyLines(x=2):
    print('\n' * x)

def printMenu():
    emptyLines()
    print("-" * 22 + "Menu" + "-" * 22)
    print("1. Show all                 5. Update kcal")
    print("2. Add new product          6. Sort by name")
    print("3. Find product             7. Sort by kcal")
    print("4. Update name              8. Delete product")
    print("0. Exit")
    print("-" * 48)
    emptyLines()

# Main Loop

def main():
    userChoice = None
    while True:
        if userChoice in [1, 2, 3, 4, 5, 6, 7, 8, 99]:
            input("Press Enter to continue")

        printMenu()

        while True:
            try:
                userChoice = int(input("Please make a choice: "))
                emptyLines(1)
                break
            except ValueError:
                print("Oops! That was not a valid number. Try again...")
                emptyLines(1)

        if userChoice == 0:
            emptyLines(1)
            print("Goodbye")
            emptyLines(1)
            break

        elif userChoice == 1:
            showAll()
        elif userChoice == 2:
            insertOne()
        elif userChoice == 3:
            findOne()
        elif userChoice == 4:
            updateName()
        elif userChoice == 5:
            updateKcal()
        elif userChoice == 6:
            sortByName()
        elif userChoice == 7:
            sortByKcal()
        elif userChoice == 8:
            deleteOne()
    # test option
        elif userChoice == 99:
            showCollections()
        else:
            print("Please choose a correct number (0-8)")

if __name__ == "__main__":
    main()


# 9.	Countdown Timer: Request a number from the user and use a loop to count down from that number to 1, printing each number.

user_num=int(input("enter the number :"))

if user_num <=0:
    print("enter a positive number:")
else:
    while user_num >=1:
        print(user_num)
        user_num -=1


from flask import Flask, render_template,request
from database.mydatabase import engine,Book,Customer,Loan
from datetime import date, datetime
api = Flask(__name__)

@api.route('/')
def home():
    return render_template("index.html",)

@api.route('/adddata')
def adddata():
    Book.create_books(engine)
    Customer.create_customers(engine)
    return render_template("index.html",)

@api.route('/books')
def books():
    res= Book.get_ordered_data(engine)
    return render_template("books.html",books=res)

@api.route('/books/search',methods=('GET', 'POST'))
def book_search():
    if request.method == 'POST':
        book_name = request.form['book_name']

    res= Book.search_by_name(engine,book_name)

    return render_template("books.html",books=res)

@api.route('/books/newitem',methods=('GET', 'POST'))
def new_book():

    if request.method == 'POST':
        book_name = request.form['book_name']
        author_name = request.form['author_name']
        year_pub = request.form['year_pub']
        book_type = request.form['book_type']
        try:
            Book.create_book(engine,book_name=book_name,author_name=author_name,year_pub=year_pub,book_type=book_type)
        except:pass

    res= Book.get_ordered_data(engine)
    return render_template("books.html",books=res)

@api.route('/books/newloan/<book_id>',methods=('GET', 'POST'))
def new_loan(book_id):

    if request.method == 'POST':
        cust_name = request.form['cust_name']
        loan_date_str = request.form['loan_date_str']

        try:
            loan_date = datetime.strptime(loan_date_str, '%Y-%m-%d')
        except:
            loan_date = datetime.today()
        try:
            cust_id = Customer.get_cust_id(engine,cust_name)
            Loan.create_loan(engine,book_id=int(book_id),cust_id=cust_id,loan_date=loan_date)
        except:pass

    res= Book.get_ordered_data(engine)
    return render_template("books.html",books=res)

@api.route('/books/del/<id>' ,methods=('GET', 'POST'))
def book_del(id):
    Book.delete_book(engine, id)
    res= Book.get_ordered_data(engine)
    return render_template("books.html",books=res)

# ---------------------------
@api.route('/customers')
def customers():
    res= Customer.get_ordered_data(engine)
    return render_template("customers.html",customers=res)

@api.route('/customers/search',methods=('GET', 'POST'))
def cust_search():
    if request.method == 'POST':
        cust_name = request.form['cust_name']

    res= Customer.search_by_name(engine,cust_name)

    return render_template("customers.html",customers=res)
@api.route('/customers/newitem' ,methods=('GET', 'POST'))

def new_customer():

    if request.method == 'POST':
        cust_name = request.form['name']
        city = request.form['city']
        age = request.form['age']
        try:
            Customer.create_customer(engine,cust_name=cust_name,city=city,age=age)
        except:pass

    res= Customer.get_ordered_data(engine)
    return render_template("customers.html",customers=res)

@api.route('/customers/del/<id>' ,methods=('GET', 'POST'))
def cust_del(id):
    Customer.delete_customer(engine, id)
    res= Customer.get_ordered_data(engine)
    return render_template("customers.html",customers=res)

# ---------------------------
@api.route('/loans')
def loans():
    customers= Customer.get_ordered_data(engine)
    books= Book.get_ordered_data(engine)
    loans= Loan.get_ordered_data(engine)
    return render_template("loans.html",loans=loans,books=books,customers=customers)

@api.route('/loans/late')
def late_loans():

    customers= Customer.get_ordered_data(engine)
    books= Book.get_ordered_data(engine)
    loans= Loan.get_late_data(engine)
    return render_template("loans.html",loans=loans,books=books,customers=customers)

@api.route('/loans/return/<id>' ,methods=('GET', 'POST'))
def return_loan(id):
    if request.method == 'POST':
        loan_ret_date_str = request.form['loan_ret_date_str']

        try:
            loan_ret_date = datetime. strptime(loan_ret_date_str, '%Y-%m-%d')
        except:
            loan_ret_date = datetime.today()
        Loan.return_book(engine,id,loan_ret_date)

    customers= Customer.get_ordered_data(engine)
    books= Book.get_ordered_data(engine)
    loans= Loan.get_ordered_data(engine)
    return render_template("loans.html",loans=loans,books=books,customers=customers)

# Program entry point
def main():
    # temporary database filler

    api.run(debug=True)

# run the program
if __name__ == "__main__": main()


import os
import time

current_status = {'user': None, 'login_starus': False}
db_path = r'%s\%s' % (os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'db')
db_emp = 'db.emp'
db_pay = 'db.pay'
db_bill = 'db.bill'
db_bs = 'db.bs'

# logging配置
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'  # 其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

# 定义日志输出格式 结束
logfile_dir = r'%s\logs' % os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # log文件的目录
logfile_name = '%s_ATM.log' % time.strftime("%Y_%m_%d", time.localtime())  # log文件名

# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)

# log配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},
    'handlers': {
        # 打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        # 打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码，再也不用担心中文log乱码了
        },
    },
    'loggers': {
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上，即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上（更高level的logger）传递
        },
    },
}


import sys
from collections import defaultdict

class TrieNode:
    def __init__(self):
        self.children = defaultdict(TrieNode)
        self.end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert_word(self, word: str) -> None:
        node = self.root
        for char in word:
            node = node.children[char]
        node.end = True

    def find_word(self, word: str) -> bool:
        node = self.root
        for char in word:
            if char not in node.children.keys():
                return False
            node = node.children[char]
        return node.end

def main():
    s, m = map(int, sys.stdin.readline().split())

    trie = Trie()

    for _ in range(s):
        trie.insert_word(sys.stdin.readline().strip())

    res = 0
    for _ in range(m):
        if trie.find_word(sys.stdin.readline().strip()):
            res += 1

    print(res)

if __name__ == "__main__":
    main()


import numpy as np
import pandas as pd
import re
from bs4 import BeautifulSoup
import gzip
import os
# import matplotlib.pyplot as plt

def read_abundance(file_path, index_col=0, return_sum=-1, return_mean=-1):
    """
    Abundance table should be tab seprated.
    args:
        file_path: file path of abundance table
        index_col: which column is the indexes (row names), e.g: -1 for last column, 0 for the first column
        return_sum: -1(return df.DataFrame of abundance table), or 1(sums of each row), or 0(sums of each column)
        return_mean: -1(return df.DataFrame of abundance table), or 1(means of each row), or 0(means of each column),
                    if not return_sum==-1, this argument will be disabled.
    """
    df = pd.read_csv(file_path, sep="\t", index_col=index_col)
    df = df.loc[:, df.dtypes != np.object]
    return df.sum(axis=return_sum) if not return_sum == -1 else (df if return_mean == -1 else df.mean(axis=return_mean))

def read_to_html_table(file_path, table_class=False, thead_class=False):
    file_type = re.search(r'[^\.]+$', file_path).group()
    if file_type == 'txt' or file_type == 'csv':
        out_df = pd.read_csv(file_path, sep='\t')
    elif file_type == "html":
        out_df = pd.read_html(file_path)[0]
    # pdb.set_trace()
    table = out_df.to_html(index=False)
    if table_class or thead_class:
        table = BeautifulSoup(table, 'lxml')
        if table_class:
            table.table['class'] = table_class
        if thead_class:
            table.thead['class'] = thead_class
        table = table.prettify()
    return table

def get_kingdom_ratio(species_abundance_table):
    df = read_abundance(species_abundance_table, index_col=-1, return_sum=1)
    kingdom = [re.search('^[^;]+', s).group().replace('k__', '')
               for s in df.index]
    # pdb.set_trace()
    df = df.groupby(kingdom).sum()
    try:
        del df['Environmentalsamples']
    except Exception:
        pass

    def series_to_str(series, value_format=':.2%'):
        return ', '.join([('{}({%s})' % (value_format)).format(k, v) for k, v in series.items()])

    # max_abundance = max(df)
    # explode = [0.1 if i == max_abundance else 0 for i in df]
    # plt.pie(df, explode=explode, labels=df.index, labeldistance=1.1,
    #         autopct='%2.2f%%', shadow=False, startangle=90, pctdistance=0.6)
    # plt.show()
    return "您样本中，检测到的物种有：{}; 物种占比情况：{}。".format(series_to_str(df, value_format=':.0f'), series_to_str(df / df.sum()))

def format_file(in_fp, out_fp, **kwargs):
    with open(in_fp, 'r') as f:
        out = f.read()
        for k, v in kwargs.items():
            out = out.replace("{{%s}}" % (k), v)
    with open(out_fp, 'w') as f:
        f.write(out)

def update_html_properties(html_fp, format_dict, out_fp, filter_function=False, use_selector=False):
    """
    in a format_dict, you should never use '' or "" in a CSS selector
    """
    with open(html_fp, "r", encoding="utf-8") as file:
        fcontent = file.read()
    sp = BeautifulSoup(fcontent, 'lxml')
    for k, v in format_dict.items():
        # pdb.set_trace()
        if use_selector:
            label_list = sp.select(k)
        else:
            tag = re.search(r'^[^\[]+', k).group()
            attrs = re.search(r'\[(.+)\]', k)
            attrs = dict([attr.split('=')
                          for attr in attrs.group(1).split('&')]) if attrs else {}
            label_list = sp.findAll(tag, attrs=attrs)
        for label in label_list:
            for p, n in v.items():
                if label.has_attr(p) and (filter_function(label[p]) if filter_function else True):
                    label[p] = n.format(value=label[p])
    with open(out_fp, "w", encoding="utf-8") as out:
        out.write(sp.prettify())

def read_file_n_lines(file, n):
    """ Read a file n lines at a time """

    line_set = []
    with (gzip.open(file, 'r') if file.endswith('.gz') else open(file, 'r')) as file_handle:
        for line in file_handle:
            if len(line_set) == n:
                yield line_set
                line_set = []
            line_set.append(line)

    # yield the last set
    if len(line_set) == n:
        yield line_set

def iter_fa(fasta, trim_line_break=False):
    with open(fasta, 'r') as file_handle:
        l1 = file_handle.readline()
        header = l1.rstrip('\n') if trim_line_break else l1
        if not header.startswith('>'):
            raise Exception("File is not a standard fasta!")
        seq_set = []
        for line in file_handle:
            li = line.rstrip('\n') if trim_line_break else line
            if line.startswith('>'):
                yield header, "".join(seq_set)
                header = li
                seq_set = []
            else:
                seq_set.append(li)

        # yield the last seq
        yield header, "".join(seq_set)

def trunc_fa(fasta, n, out_dir=False):
    dirname = out_dir or os.path.dirname(fasta)
    basename = os.path.basename(fasta)
    out_files = []
    for i in range(n):
        out_dir = os.path.join(dirname, "{basename}.trunk{i}".format(**locals()))
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        out_files.append(open(os.path.join(out_dir, basename), 'w'))
    ln = 0
    for h, s in iter_fa(fasta, trim_line_break=False):
        out_files[ln % n].write(h + s)
        ln += 1
    for fh in out_files:
        fh.close()