import numpy as np
import os
import torch
from tqdm import tqdm
from PIL import Image
import wandb

from .evaluation import eval_llh, eval_translation_error, rotation_model_evaluation, translation_model_evaluation

# Global variables
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def cosine_decay(step, hyper_param):
    warmup_factor = min(step, hyper_param["warmup_steps"]) / hyper_param["warmup_steps"]
    decay_step = max(step - hyper_param["warmup_steps"], 0) / (hyper_param['num_train_iter']- hyper_param["warmup_steps"])
    return hyper_param['learning_rate'] * warmup_factor * (1 + np.cos(decay_step * np.pi)) / 2

def run_single_epoch(model, data_loader, hyper_param, num_iter, mode=0, optimizer=None):
    progress_bar = tqdm(enumerate(data_loader), total=num_iter)
    epoch_losses = []
    #ipdb.set_trace()
    for (i, input_) in progress_bar:
        #load the images from the batch
        img = input_['image']
        img = img.to(DEVICE).float()
        if mode==0:
            ground_truth = input_['obj_pose_in_camera'][:,:3,:3].to(DEVICE).float()
        else:
            ground_truth = input_['obj_pose_in_camera'][:,:3,-1].to(DEVICE).float()

        loss = model.compute_loss(img, ground_truth)

        epoch_losses.append(loss.item())

        #update the learning rate using the cosine decay
        for g in optimizer.param_groups:
            lr = cosine_decay(i+1, hyper_param)
            g['lr'] = lr
        #backward pass through the network
        optimizer.zero_grad()
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.)

        optimizer.step()

        if i == num_iter:
            break
    mean_epoch_loss = np.mean(epoch_losses)
    return mean_epoch_loss

def run_rotation_training(model, train_dataset, val_dataset, optimizer, hyper_param, checkpoint_dir, start_epoch=0):
    """In each epoch the model is trained for num_train_iter iterations defined in the configuration.
    The evaluation step includes calculating the loglikelihood and the spread on a num_eval_step iterations.
    The model is saved in pre-defined intervals, defined in the configuration. If additionally the full evaluation is enabled,
    also all defined evaluation metrics are calculated

    """
    train_losses = []
    loglikelihood = []
    mean_errors = []
    median_errors = []
    num_epochs = hyper_param['num_epochs']

    for epoch in range(start_epoch+1, num_epochs+1):
        # training
        model.train()
        #run a single training epoch
        train_loss = run_single_epoch(model=model,
                                      data_loader=train_dataset,
                                      hyper_param=hyper_param,
                                      num_iter=hyper_param['num_train_iter'],
                                      mode=0,
                                      optimizer=optimizer)
        # validation
        model.eval()
        with torch.no_grad():

            llh = []

            for dataset in val_dataset:
                llh.append(eval_llh(model, dataset=dataset,
                                            num_eval_iter=hyper_param['num_val_iter'],
                                            mode=0,
                                            device=DEVICE))

        if epoch==1:
            rotation_model_evaluation(model=model, dataset=val_dataset, hyper_param_rot=hyper_param)

        train_losses.append(train_loss)
        loglikelihood.append(llh)
        # log the loss values
        wandb.log({
            'TrainLoss': train_loss,
            'Loglikelihood': sum(llh)/len(llh)
        })
        print("Epoch:", epoch, "....", "TrainLoss: ", train_loss, "Loglikelihood: ", llh)
        # save a checkpoint
        if ((epoch % hyper_param['save_freq'] == 0) and epoch>=hyper_param['start_save']) or epoch == num_epochs:
            chkpt_name = f'checkpoint_{epoch}.pth' if epoch != num_epochs else f'checkpoint_final.pth'
            chkpt_path = os.path.join(checkpoint_dir, chkpt_name)
            torch.save({
                            'epoch': epoch,
                            'model_state_dict': model.state_dict(),
                            'optimizer_state_dict': optimizer.state_dict(),
                       },
                       chkpt_path
            )
            # For every saved model run a full evaluation if full_evaluation is set to true
        if hyper_param['full_eval']==True and epoch % hyper_param["eval_freq"]==0:
            rotation_model_evaluation(model=model, dataset=val_dataset, hyper_param_rot=hyper_param)
    print("Training finished.")
    print("The final IPDF model was saved to: ", os.path.join(checkpoint_dir, 'checkpoint_final.pth'))
    print("\nFinal evaluation metrics:\n")
    print("Train Loss:\n", train_losses)
    print("\nLoglikelihood:\n", loglikelihood)
    print("\nMean Error:\n", mean_errors)
    print("\nMedian Error:\n", median_errors)

def run_translation_training(model, train_dataset, val_dataset, optimizer, hyper_param, checkpoint_dir, start_epoch=0):
    """In each epoch the model is trained for num_train_iter iterations defined in the configuration.
    The evaluation step includes calculating the loglikelihood and the spread on a num_eval_step iterations.

    """
    num_epochs = hyper_param['num_epochs']
    for epoch in range(start_epoch+1, num_epochs+1):
        # training
        model.train()
        #run a single training epoch
        train_loss = run_single_epoch(model=model,
                                      data_loader=train_dataset,
                                      hyper_param=hyper_param,
                                      num_iter=hyper_param['num_train_iter'],
                                      mode=1,
                                      optimizer=optimizer)
        # validation

        llh = eval_llh(model, dataset=val_dataset,
                                            num_eval_iter=hyper_param['num_val_iter'],
                                            mode=1,
                                            device=DEVICE)

        model.eval()
        error = 0.0
        if epoch % hyper_param["eval_freq"] == 0 or epoch==1:
            error = eval_translation_error(model, dataset=val_dataset,
                                    batch_size=hyper_param['batch_size_val'],
                                    eval_iter=hyper_param['num_val_iter'],
                                    gradient_ascent=True)
        # log the loss values
            wandb.log({
                'TrainLoss': train_loss,
                'Loglikelihood': llh,
                'EstimateError': error
            })
        else:
            wandb.log({
                'TrainLoss': train_loss,
                'Loglikelihood': llh
            })

        print("Epoch:", epoch, "....", "TrainLoss: ", train_loss, " Loglikelihood: ", llh, " Estimate Error: ", error)
        # save a checkpoint
        if ((epoch % hyper_param['save_freq'] == 0) and epoch>=hyper_param['start_save']) or epoch == num_epochs:
            chkpt_name = f'checkpoint_{epoch}.pth' if epoch != num_epochs else f'checkpoint_final.pth'
            chkpt_path = os.path.join(checkpoint_dir, chkpt_name)
            torch.save({
                            'epoch': epoch,
                            'model_state_dict': model.state_dict(),
                            'optimizer_state_dict': optimizer.state_dict(),
                       },
                       chkpt_path
            )
        # For every saved model run a full evaluation if full_evaluation is set to true
        """if hyper_param['full_eval']==True and epoch % hyper_param["eval_freq"]==0:
            translation_model_evaluation(model=model, dataset=val_dataset)"""
    print("Training finished.")
    print("The final IPDF model was saved to: ", os.path.join(checkpoint_dir, 'checkpoint_final.pth'))


# -*- coding: utf8 -*-
from django.contrib import admin
from models_app.models import Document

@admin.register(Document)
class DocumentAdmin(admin.ModelAdmin):
    list_display = [
        'id',
        'name',
        'file',
        'position',
        'task',
    ]
    list_display_links = (
        'id',
        'name',
    )
    readonly_fields = ['id', 'created_at', 'updated_at']
    ordering = ('id', 'position', 'task')
    list_filter = ('position', 'task')


import sys
from socket import *

def main():
	# checking usage
	if len(sys.argv) != 2:
		print("Usage: python WebServer.py port")
		exit(1)
	# getting the port
	serverPort = int(sys.argv[1])
	# creating the socket and binding to port
	serverSocket = socket(AF_INET, SOCK_STREAM)
	serverSocket.bind(('',serverPort))
	serverSocket.listen(1)
	#print("here we go bois")
	while(1):
		# estabilish connection
		print("Server ready...")
		connectionSocket, addr = serverSocket.accept()
		try:
			# Receive request
			message = connectionSocket.recv(1024)
			# Isolate filename
			filename = message.split()[1]
			print(filename)
			# Open file to get data
			f = open(filename[1:])
			outputdata = f.read()
			# Send data to socket
			connectionSocket.send('\nHTTP/1.1 200 OK\n\n')
			connectionSocket.send(outputdata)
			connectionSocket.close()
		except IOError:
			msg = 'HTTP/1.1 404 Not Found'
			connectionSocket.send(msg.encode())
			connectionSocket.close()
	pass

if __name__ == '__main__':
	main()


from openpyxl.styles import Font, Border, Side, PatternFill, Alignment
from openpyxl import load_workbook
wb = load_workbook("/Users/gunju/Desktop/self study/python/deep/rpa_basic/1_excel/sample.xlsx")
ws = wb.active

a1 = ws["A1"]
b1 = ws["B1"]
c1 = ws["C1"]

ws.column_dimensions["A"].width = 5 # A열 너비 5로 설정
ws.row_dimensions[1].height = 50 # 1행 높이 50으로 설정

a1.font = Font(color = "FF0000", italic = True, bold = True) # 글자 색상 빨강, 이탤릭, 두껍게
b1.font = Font(color = "CC33FF", name = "Arial", strike = True) # 폰트는 Arial, 취소선
c1.font = Font(color = "0000FF", size = 20, underline = "single") # 글자크기 20, 밑줄 1줄(두 줄 하려면 double)

# 테두리 적용
thin_border = Border(left = Side(style = "thin"), right = Side(style = "thin"), top = Side(style = "thin"), bottom = Side(style = "thin"))
a1.border = thin_border
b1.border = thin_border
c1.border = thin_border

# 90점 넘는 셀에 대해서 초록색으로 적용
for row in ws.rows:
    for cell in row:
        # 셀 정렬 / left, right, top, bottom 가능
        cell.alignment = Alignment(horizontal = "center", vertical = "center")

        if cell.column == 1:
            continue

        # 셀이 정수형 데이터이고 90점보다 높으면
        if isinstance(cell.value, int) and cell.value > 90:
            cell.fill = PatternFill(fgColor = "00FF00", fill_type = "solid")
            cell.font = Font(color = "FF0000")

# 틀 고정
ws.freeze_panes = "B2"

wb.save("/Users/gunju/Desktop/self study/python/deep/rpa_basic/1_excel/sample_style.xlsx")


import sys
#sys.path.insert(0, "/home/tomohiro/workspace/web_scraping_venv/lib/python3.6/site-packages")
from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit, send
from flask_pymongo import PyMongo
from bson.objectid import ObjectId
from bs4 import BeautifulSoup
import requests
import re
import sys
import time
import datetime

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.config["MONGO_URI"] = "mongodb://localhost:27017/scrapingdb"
async_mode = None
ping_timeout = 300
socketio = SocketIO(app, async_mode=async_mode, ping_timeout=ping_timeout)

# If the connection gets disconnected in the middle,
# A new session is gonna be created, then
# the server is gonna get not to send back the data to the same session's client
# so that set ping_timeout long not to make the socketio disconnected

mongo = PyMongo(app)
bookmarks = mongo.db.bookmarks

thread = None
bk_list = [s for s in bookmarks.find()]
# @app.route("/", methods=["POST"])
# def test_db():
# 	url = request.form["mongo"]
# 	url = {"subject": url}
# 	urls.insert_one(url)
# 	result = mongo.db.urls.find({"subject": url})
# 	return render_template(("base.html"), urls=result)

@app.route("/", methods=["GET"])
def index_return():
	#デフォルト設定でFlaskはhtmlの所在を、flaskアプリケーションと同じ階層にある
	#templatesディレクトリの中に探しに行くので下記のようなパスでよい
	return render_template("base.html")

@app.route("/itmedia/")
def itmedia():
	return render_template("itmedia/itmain.html")

@app.route("/nikkei/")
def nikkei():
	return render_template("nikkei/nkmain.html")

@app.route("/other/")
def other():
	return render_template("other/otmain.html")

@app.route("/bookmark/")
def bookmark():
	global bk_list
	return render_template("bookmark/bkmain.html", list=bk_list)

@socketio.on('bk_db')
def managebk(bk_dict):
	url = bk_dict["url"]
	head = bk_dict["head"]
	head = head.encode("raw_unicode_escape")
	head = head.decode("utf-8")

	bks = {"url": url, "head": head}
	#To prevent duplicate update from db,
	#need to add upsert=True at the end and use the mongo syntax $setOnInsert
	bookmarks.update(
		{'head': head},
		{'$setOnInsert': bks},
		upsert=True)

@socketio.on("message")
def initial_response(msg):
	send("Hello!")
	print(msg)

@socketio.on("myevent")
def handle_message(array):
	url = array["url"]
	word = array["head"]

	#if re.match(r"(^\\[A-Z].*[a-z].*)?", word):
	# 日本語だと強制的にutf-8？にエンコードされるので、それをutf-8に再度デコード
	word = word.encode("raw_unicode_escape")
	word = word.decode("utf-8")

	#Getting the global variable, thread
	#You can always default the thread value as None by doing this
	global thread

	if thread is None:
		#Starting the function, "sending_results" as background task
		#By doing this, you can devide the threads having the funcion to keep sokcket connection(main thread)
		#and one to send the url and keyword
		socketio.start_background_task(target=sending_results(url, word))

def sending_results(url, word):
	start = time.time()

	print(url)
	print(word)

	if url == "" or word == "":
		print("”URL”　と　”キーワード”　を指定してください")
		send("”URL”　と　”キーワード”　を指定")
		sys.exit()

	if not url.endswith("/"):
		url = url + "/"

	try:
		res = requests.get(url)
	except Exception as e:
		print(e)
		print("URLが正しくありません")
		send("URLが正しくありません")
		send(str(e))
		sys.exit()

	# Starting web scraping
	emit("startcomplete",("Executing scraping"))

	soup = BeautifulSoup(res.content, "html.parser")
	a_tag_list = soup.find_all("a")
	protocol = re.search(".*:", url).group(0)
	url_list = []
	### ループ内で毎回appendを呼び出していると、処理が遅くなるので
	### appendにあらかじめ、url_list.appendという関数を入れておく
	append=url_list.append

	for a in a_tag_list:
		a_link = str(a.get("href"))
		if not re.match(".*/.*", a_link):
			print("This hasn't been added to the list  " + a_link)
		elif a_link.startswith("//"):
			full_url = protocol + a_link
			append(full_url)
		elif a_link.startswith("/") or a_link.startswith("./"):
			#Removing "./" or "/" from a_link and conbining it with url
			full_url = url + re.sub(r".?/", "", a_link, count=1)
			append(full_url)
		#Checking if a_link starts with alphanumeric + "/"
		elif re.match(r"^\w+/", a_link):
			full_url = url + a_link
			append(full_url)
		else:
			append(a_link)

	#appendを初期化
	append=list.append

	perfect_url_list =sorted(set([u for u in url_list if not re.match(".*article.*|.*=.*", u )]))
	tmp_list = []
	append=tmp_list.append
	#global bk_list

	for l in perfect_url_list:
		try:
			res = requests.get(l)
		except Exception as e:
			print(e)
			#print("before for loop of a")

		soup = BeautifulSoup(res.content, "html.parser")
		a_tag_list = soup.find_all("a")
		for a in a_tag_list:
			try:
				a_link = str(a.get("href"))
				a_text = re.sub("・|\u3000|\n|\r|\t", "", a.text)
				if re.match(".*{}.*".format(word), a.text) and not a_text in tmp_list:
					if not re.match(".*/.*", a_link):
						pass
					elif a_link.startswith("//"):
						article = protocol + a_link
					elif a_link.startswith("/") or a_link.startswith("./"):
						article = l + re.sub(r".?/", "", a_link, count=1)
						res = requests.get(article)
						if res.status_code != 200:
							article = url + re.sub(r".?/", "", a_link, count=1)
					elif re.match(r"^\w+/", a_link):
						article = l + a_link
						res = requests.get(article)
						if res.status_code != 200:
							article = url + a_link
					else:
						article = a.get("href")

					append(a_text)
					a_dict_list = {
						"head": a_text,
						"url": article,
						#"sentense": get_p(article)
						}
					emit("myresponse", a_dict_list)
			except Exception as e:
				print(e)

		print("Nothing to be sent to you")

	emit("startcomplete", "DONE")
	print("DONE")
	elapsed = time.time() - start
	print(elapsed)
	append=list.append

if __name__ == "__main__":
	#socketio = SocketIO(app) により、socketio.run(app)でflaskアプリを起動できる
	socketio.run(app)

# @app.route("/next", methods=["POST"])
# def arg_check():
#     if request.method == "POST":
#         url = request.form["url"]
#         keyword = request.form["search"]
#         args = url + keyword
#     return render_template("index.html", result=args)

# @app.route("/", methods=["POST"])
# def start_scraping():
#     if request.method == "POST":
#         url = request.form["url"]
#         word = request.form["search"]

#     return render_template("index.html", result=scraping(url,word))

# @app.route("/", methods=["POST"])
# def start_socketio():

# def ack():
#     print("I got your message")

# @socketio.on("my event")
# def handle_message(json):
#     time.sleep(1)
#     emit("my response", json, callback=ack)
#     print("Replied to the clinet")


import scipy as sp
import numpy as np
import math
import input_checks
import ode_solver

def sparse_A(size, dm, do):
    """
    Creates a sparse matrix used by the scipy spsolve function.
    ----------
    Parameters
    size : int
        The square dimension value of the matrix.
    dm : float OR int
        Value along the main diagonal.
    do : float OR int
        Value along both the offset diagonals.
    ----------
    Returns
        A scipy sparse csr_matrix.
    """

    diagonals = [np.ones(size)*dm, np.ones(size-1)*do, np.ones(size-1)*do]
    return sp.sparse.diags(diagonals, [0, 1, -1], format='csr')

def full_A(size, dm, do):
    """
    Creates a tridiagonal matrix.
    ----------
    Parameters
    size : int
        The square dimension value of the matrix.
    dm : float OR int
        Value along the main diagonal.
    do : float OR int
        Value along both the offset diagonals.
    ----------
    Returns
        A np.ndarray tridiagonal matrix.
    """

    return np.diag(np.ones(size)*dm, 0) + np.diag(np.ones(size-1)*do, 1) + np.diag(np.ones(size-1)*do, -1)

def solve_diffusion(method, l_bound_type, r_bound_type, l_bound_func, r_bound_func, init_func, D, x_min, x_max, nx, t_min, t_max, nt, source_func=None, l_bound_args=None, r_bound_args=None, init_args=None, source_args=None, use_sparse=True):
    """
    Solves the diffusion equation using finite difference methods, based on the specified method and boundary conditions.
    ----------
    Parameters
    method : string
        Either 'lines', 'explicit_euler', 'implicit_euler', 'crank_nicolson', or 'imex'.
    l_bound_type : string
        Either 'dirichlet', 'neumann', or 'robin'.
    r_bound_type : string
        Either 'dirichlet', 'neumann', or 'robin'.
    l_bound_func : function
        Function that takes values (x, u, t) and list (args) as inputs and returns the left boundary value.
    r_bound_func : function
        Function that takes singular values (x, u, t) and list (args) as inputs and returns the right boundary value.
    init_func : function
        Function that takes (x, u, t) and list (args) as inputs and returns intitial solution array.
    D : float OR int
        Diffusion Coefficient.
    x_min : float OR int
        Minimum x value.
    x_max : float OR int
        Maximum x value.
    nx : int
        Number of x values in the grid, affects step size used for x.
    t_min : float OR int
        Minimum t value.
    t_max : float OR int
        Maximum t value.
    nt : int
        Number of t values in the grid, affects step sized used for t.
    source_func : function
        Function that takes singular values (x, t, u) and list (args) as inputs and returns source value.
    l_bound_args : list OR numpy.ndarray
        Additional arguments needed by 'l_bound_func'. If (l_bound_type) is 'robin', must contain two values [delta, gamma], such that r_bound_func returns delta - gamma*u(x).
    r_bound_args : list OR numpy.ndarray
        Additional arguments needed by 'r_bound_func'. If (r_bound_type) is 'robin', must contain two values [delta, gamma], such that r_bound_func returns delta - gamma*u(x).
    init_args : list OR numpy.ndarray
        Additional arguments needed by 'init_func'.
    source_args : list OR numpy.ndarray
        Additional arguments needed by 'source_func'.
    use_sparse : bool
        True indicates that sparse matrices are used for calculations.
    ----------
    Returns
        A numpy.array with a row of values for each solved parameter, and the final row being the x-values solved at.
    """

    # INPUT CHECKS
    input_checks.test_string(method, 'method')
    if method not in ['lines', 'explicit_euler', 'implicit_euler', 'crank_nicolson']:
        raise Exception('Argument (method) must be either \'lines\', \'explicit_euler\', \'implicit_euler\', \'crank_nicolson\'.')
    input_checks.test_string(l_bound_type, 'l_bound_type')
    if l_bound_type not in ['dirichlet', 'neumann', 'robin']:
        raise Exception('Argument (boundary_type) must be either \'dirichlet\', \'neumann\', or \'robin\'.')
    input_checks.test_string(r_bound_type, 'r_bound_type')
    if r_bound_type not in ['dirichlet', 'neumann', 'robin']:
        raise Exception('Argument (boundary_type) must be either \'dirichlet\', \'neumann\', or \'robin\'.')
    input_checks.test_function(l_bound_func, 'l_bound_func')
    input_checks.test_function(r_bound_func, 'r_bound_func')
    input_checks.test_function(init_func, 'init_func')
    input_checks.test_float_int(D, 'D')
    input_checks.test_float_int(x_min, 'x_min')
    input_checks.test_float_int(x_max, 'x_max')
    input_checks.test_int(nx, 'nx')
    input_checks.test_float_int(t_min, 't_min')
    input_checks.test_float_int(t_max, 't_max')
    input_checks.test_int(nt, 'nt')
    if source_func != None:
        input_checks.test_function(source_func, 'source_func')
    if l_bound_args != None:
        input_checks.test_list_nparray(l_bound_args, 'l_bound_args')
    if l_bound_type == 'robin':
        if len(l_bound_args) != 2:
            raise Exception('Argument (l_bound_args) must contain two values.')
    if r_bound_args != None:
        input_checks.test_list_nparray(r_bound_args, 'r_bound_args')
    if r_bound_type == 'robin':
        if len(r_bound_args) != 2:
            raise Exception('Argument (r_bound_args) must contain two values.')
    if init_args != None:
        input_checks.test_list_nparray(init_args, 'init_args')
    if source_args != None:
        input_checks.test_list_nparray(source_args, 'source_args')
    if use_sparse not in [True, False]:
        raise Exception('Argument (use_sparse) must be a boolean True or False.')

    # MEETING STABILITY CONDITION
    dx = (x_max - x_min) / nx
    dt = (t_max - t_min) / nt
    C = (dt * D) / (dx ** 2)
    if method == 'explicit_euler' or method == 'lines':
        dt = 0.49*(dx**2)/D
        nt = math.ceil((t_max - t_min) / dt)
        C = (dt * D) / (dx ** 2)

    # ADJUST SOURCE TERM
    if source_func == None:
        def source_func(x, t, u, args):
            return np.zeros(np.size(x))

    # CONSTRUCT GRIDS
    x_arr = np.linspace(x_min, x_max, nx+1)
    t_arr = np.linspace(t_min, t_max, nt+1)

    # DEFINE x_int AND INITIALISE u_t
    if l_bound_type == 'dirichlet':
        xs = 1
    else:
        xs = 0
    if r_bound_type == 'dirichlet':
        x_int = x_arr[xs:-1]
    else:
        x_int = x_arr[xs:]

    u_t = init_func(x_int, 0, 0, init_args)
    size = len(u_t)

    # CREATE MATRICES
    if use_sparse == True:
        I_mat = sp.sparse.identity(size, format='csr')
        A_mat = sparse_A(size, -2, 1)
    elif use_sparse == False:
        I_mat = np.identity(size)
        A_mat = full_A(size, -2, 1)

    # DEFINE RHS VECTOR AND MODIFY SPARSE MATRICIES ACCORDING TO BOUNDARY CONDITIONS
    if l_bound_type != 'dirichlet':
        A_mat[0, 1] *= 2
    if l_bound_type == 'robin':
        A_mat[0, 0] *= 1 + l_bound_args[1] * dx

    if r_bound_type != 'dirichlet':
        A_mat[-1, -2] *= 2
    if r_bound_type == 'robin':
        A_mat[-1, -1] *= 1 + r_bound_args[1] * dx

    def make_b(t):
        b = np.zeros(size)
        if l_bound_type == 'dirichlet':
            b[0] = l_bound_func(x_min, t, u_t, l_bound_args)
        elif l_bound_type == 'neumann':
            b[0] = l_bound_func(x_min, t, u_t, l_bound_args) * -2 * dx
        elif l_bound_type == 'robin':
            b[0] = l_bound_func(x_min, t, u_t[0], [l_bound_args[0], 0]) * -2 * dx

        if r_bound_type == 'dirichlet':
            b[-1] = r_bound_func(x_max, t, u_t, r_bound_args)
        elif r_bound_type == 'neumann':
            b[-1] = r_bound_func(x_max, t, u_t, r_bound_args) * 2 * dx
        elif r_bound_type == 'robin':
            b[-1] = r_bound_func(x_max, t, u_t[-1], [r_bound_args[0], 0]) * 2 * dx

        return b

    # SOLVE
    if use_sparse == True:
        solver = sp.sparse.linalg.spsolve
    elif use_sparse == False:
        solver = np.linalg.solve

    if method == 'lines':
        def PDE(u, t, args):
            A_mat, b = args
            return (C/dt) * (A_mat@u + b + (dx**2) * (source_func(x_int, t, u, source_args)))
        b = make_b(t_max)
        sol = ode_solver.solve_to(PDE, u_t, t_min, t_max, dt, args=[A_mat, b])
        u_t = sol[:,-1][:-1]

    if method == 'explicit_euler':
        for j in range(0, nt):
            b = make_b(t_arr[j])
            u_t = solver(I_mat, u_t + C*(A_mat@u_t + b + (dx**2) * (source_func(x_int, t_arr[j], u_t, source_args))))

    if method == 'implicit_euler':
        for j in range(0, nt):
            b = make_b(t_arr[j])
            u_t = solver(I_mat - (C*A_mat), u_t + C * (b + (dx**2) * (source_func(x_int, t_arr[j], u_t, source_args))))

    if method == 'crank_nicolson':
        for j in range(0, nt):
            b = make_b(t_arr[j])
            u_t = solver(I_mat - ((C/2)*A_mat), (I_mat + ((C/2)*A_mat))@u_t + C * (b + (dx**2) * (source_func(x_int, t_arr[j], u_t, source_args))))

    # MODIFY u_t ACCORDING TO BOUNDARY CONDITIONS
    if l_bound_type == 'dirichlet':
        u_t = np.concatenate((np.array([l_bound_func(x_min, 0, 0, l_bound_args)]), u_t))
    if r_bound_type == 'dirichlet':
        u_t = np.concatenate((u_t, np.array([r_bound_func(x_max, 0, 0, r_bound_args)])))

    return np.vstack([u_t, x_arr])


#!/usr/bin/python2

from time import gmtime, strftime

serverLogFilename = "server_debug.log"

def writeToLog(fileName, data):
    """
    function to maintain log for debugging
    :param fileName: name of the log file
    :param data: data to be written in string format
    :return: None
    """
    with open(fileName,'a') as logFile:
        logFile.write( "\n" + strftime("%Y-%m-%d %H:%M:%S ", gmtime()) + ":\t" + data)
        return

#No other file to place it
def writeToFile(filename, data):
    """Writes data to file"""

    try:
        with open(filename, "w") as f:
            f.write(data)
    except Exception as err:
        writeToLog(serverLogFilename, "Error writing to " + filename)


# Diseña un programa con una función que pida un número entero entre 1 y 7 y devuelva el día de la semana con letra.

def dia(n):
    d=""
    if n==1:
        d="L"
    elif n==2:
        d="M"
    elif n==3:
        d="M"
    elif n==4:
        d="J"
    elif n==5:
        d="V"
    elif n==6:
        d="S"
    elif n==7:
        d="D"
    else:
        d="Error"
    return d

#Programa principal
n=int(input("Dame el dia de la semana (1-7): "))
print(f"El dia es {dia(n)}")


"""
5.创建技能类(技能名称,攻击比率,消耗法力,持续时间)
  保证数据范         0 - 2  0 - 80  0 - 120
"""

class Profession:
    def __init__(self, name, attack, cost, duration):
        self.name = name
        self.attack = attack
        self.cost = cost
        self.duration = duration

    @property
    def attack(self):
        return self.__attack

    @attack.setter
    def attack(self, value):
        if 0 <= value <= 2:
            self.__attack = value
        else:
            raise Exception("玩完了")

    @property
    def cost(self):
        return self.__cost

    @cost.setter
    def cost(self, value):
        if 0 <= value <= 80:
            self.__cost = value
        else:
            raise Exception("玩完了")

    @property
    def duration(self):
        return self.__duration

    @duration.setter
    def duration(self, value):
        if 0 <= value <= 120:
            self.__duration = value
        else:
            raise Exception("玩完了")

pro01 = Profession("一阳指", 2, 50, 100)
print(pro01.name)


from json import load
from tkinter.font import BOLD
from openpyxl import load_workbook
from openpyxl.styles import PatternFill, Font

def edm(filename):
    wb = load_workbook(filename)
    sheet = wb['Recipients']
    sheet2 = wb['Link Clicks - Detail']

    # Deleting empty rows
    sheet.delete_rows(1,1)
    sheet.delete_rows(2,1)

    # Deleting invalid Group Names
    count = 0

    for row in sheet['C']:
        count += 1
        if row.value == "Reagan_Toh" or row.value == "Seow_Ying":
            sheet.delete_rows(count,2)

    # Insert Status column
    sheet.insert_cols(5)
    sheet['E1'].value = "Status"

    sheet['E1'].font = Font(bold=True)
    sheet['E1'].fill = PatternFill("solid", fgColor="FFFF00")

    # Clicked but unsubbed
    count = 0

    for row in sheet['K']:
        count += 1
        if row.value == "Y":
            sheet[f'E{count}'].value = "1. Clicked (Unsub)"

    # Clicked
    # Getting unique clicked emails
    clicked = []
    count = 0
    for row in sheet2['B']:
        # Exclude header and blank rows
        count += 1
        if count >= 4:
            clicked.append(row.value)

    clicked = set(clicked)

    # Check if specific emails clicked the eDM
    count = 0

    for row in sheet['B']:
        count += 1
        for item in clicked:
            if item == row.value:
                sheet[f'E{count}'].value = "1. Clicked"

    # Opened eDMs
    count = 0
    for row in sheet['H']:
        count += 1
        if row.value and sheet[f'E{count}'].value == None:
            sheet[f'E{count}'].value = "2. Opened"

    # Soft Bounced and Hard Bounced
    count = 0
    for row in sheet['D']:
        count += 1
        if (row.value == 'Remote Server Error' or row.value == 'Error (C)') and sheet[f'E{count}'].value == None:
            sheet[f'E{count}'].value = "4. Soft Bounced"
        elif row.value == 'Bad Address' and sheet[f'E{count}'].value == None:
            sheet[f'E{count}'].value = "5. Hard Bounced"
        elif row.value == 'Sent' and sheet[f'E{count}'].value == None:
            sheet[f'E{count}'].value = "3. Sent"

    # Save workbook
    wb.save(filename=filename)
    wb.close()


from mimetypes import init
from turtle import forward

from torch import conv2d
import torch
import torch.nn as nn
import common
#from model import common
import torch.nn.functional as F
import math
import cv2
import os
import datetime
import scipy.io as io

import numpy as np

def EzConv(in_channel,out_channel,kernel_size):
    return nn.Conv2d(in_channels=in_channel,out_channels=out_channel,kernel_size=kernel_size,stride=1,padding=kernel_size//2,bias=True)

class Upsample(nn.Sequential):
    def __init__(self, scale, n_feats, bn=False, act=False, bias=True, conv=EzConv):
        m = []
        if (scale & (scale - 1)) == 0:    # Is scale = 2^n?
            for _ in range(int(math.log(scale, 2))):
                m.append(conv(n_feats, 4 * n_feats, 3))
                m.append(nn.PixelShuffle(2))
                if bn:
                    m.append(nn.BatchNorm2d(n_feats))
                if act == 'relu':
                    m.append(nn.ReLU(True))
                elif act == 'prelu':
                    m.append(nn.PReLU(n_feats))

        elif scale == 3:
            m.append(conv(n_feats, 9 * n_feats, 3))
            m.append(nn.PixelShuffle(3))
            if bn:
                m.append(nn.BatchNorm2d(n_feats))
            if act == 'relu':
                m.append(nn.ReLU(True))
            elif act == 'prelu':
                m.append(nn.PReLU(n_feats))
        else:
            raise NotImplementedError

        super(Upsample, self).__init__(*m)

class CA(nn.Module):
    '''CA is channel attention'''
    def __init__(self,n_feats,kernel_size=3,bias=True, bn=False, act=nn.ReLU(True),res_scale=1,conv=EzConv,reduction=16):

        super(CA, self).__init__()

        m = []
        for i in range(2):
            m.append(conv(n_feats, n_feats, kernel_size))
            if bn:
                m.append(nn.BatchNorm2d(n_feats))
            if i == 0:
                m.append(act)
        self.body = nn.Sequential(*m)

        # feature channel downscale and upscale --> channel weight
        self.conv_du = nn.Sequential(
                nn.AdaptiveAvgPool2d(1),
                nn.Conv2d(n_feats, n_feats // reduction, 1, padding=0, bias=True),
                nn.ReLU(inplace=True),
                nn.Conv2d(n_feats // reduction, n_feats, 1, padding=0, bias=True),
                nn.Sigmoid()
        )

    def forward(self, x):
        y = self.body(x)
        CA = self.conv_du(y)
        CA = torch.mul(y, CA)
        x = CA + x
        return x

class SCconv(nn.Module):
    def __init__(self,n_feats,kernel_size,pooling_r):
        super(SCconv,self).__init__()
        self.half_feats = n_feats//2
        self.f1 = nn.Sequential(
            nn.Conv2d(n_feats//2,n_feats//2,kernel_size,padding=kernel_size//2),
            nn.ReLU(True)
        )
        self.f2 = nn.Sequential(
            nn.AvgPool2d(kernel_size=pooling_r,stride=pooling_r),
            nn.Conv2d(n_feats//2,n_feats//2,kernel_size,padding=kernel_size//2),
        )
        self.f3 = nn.Conv2d(n_feats//2,n_feats//2,kernel_size,padding=kernel_size//2)
        self.f4 = nn.Sequential(
            nn.Conv2d(n_feats//2,n_feats//2,kernel_size,padding=kernel_size//2),
            nn.ReLU(True)
        )

    def forward(self,x):
        x1 = x[:, 0:self.half_feats, :, :]
        x2 = x[:, self.half_feats:, :, :]
        identity_x1 = x1
        out_x1 = torch.sigmoid(torch.add(identity_x1,F.interpolate(self.f2(x1),identity_x1.size()[2:])))
        out_x1 = torch.mul(self.f3(x1),out_x1)
        out_x1 = self.f4(out_x1)
        out_x2 = self.f1(x2)
        out = torch.cat([out_x1,out_x2],dim=1)
        return out

class SSELB(nn.Module):
    def __init__(self,n_feats,kernel_size,pooling_r):
        super(SSELB,self).__init__()
        self.body = nn.Sequential(
            SCconv(n_feats,kernel_size,pooling_r),
            CA(n_feats),
        )

    def forward(self,x):
        res = self.body(x)
        return res + x

class NGIM(nn.Module):
    def __init__(self,n_feats,scale):
        super(NGIM,self).__init__()

        if scale == 4:
            self.TrunkUp = nn.Sequential(
                nn.ConvTranspose2d(n_feats,n_feats,kernel_size=8,stride=4,padding=2),
                nn.PReLU(n_feats)
            )
            self.MultiUp = nn.Sequential(
                nn.Conv2d(n_feats*3,n_feats//2,kernel_size=3,padding=1),
                nn.Conv2d(n_feats//2,n_feats,kernel_size=3,padding=1),
                nn.ConvTranspose2d(n_feats,n_feats,kernel_size=8,stride=4,padding=2),
                nn.PReLU(n_feats)
            )
        elif scale == 8:
            self.TrunkUp = nn.Sequential(
                nn.ConvTranspose2d(n_feats,n_feats,kernel_size=12,stride=8,padding=2),
                nn.PReLU(n_feats)
            )
            self.MultiUp = nn.Sequential(
                nn.Conv2d(n_feats*3,n_feats//2,kernel_size=3,padding=1),
                nn.Conv2d(n_feats//2,n_feats,kernel_size=3,padding=1),
                nn.ConvTranspose2d(n_feats,n_feats,kernel_size=12,stride=8,padding=2),
                nn.PReLU(n_feats)
            )

        self.error_resblock = nn.Sequential(
            nn.Conv2d(n_feats,n_feats,kernel_size=3,padding=1),
        )
    def forward(self,xl,xi,xn):

        h1 = self.TrunkUp(xi)
        h2 = self.MultiUp(torch.cat([xl,xi,xn],dim=1))
        e = h2 - h1
        e = self.error_resblock(e)
        h1 = h1 + e
        return h1

class SSELM(nn.Module):
    def __init__(self, n_colors, n_feats, n_blocks,pooling_r):
        super(SSELM, self).__init__()
        kernel_size = 3
        self.head = nn.Conv2d(n_colors, n_feats, kernel_size,padding=kernel_size//2)
        body = []
        for i in range(n_blocks):
            body.append(SSELB(n_feats,kernel_size,pooling_r))

        self.body = nn.Sequential(*body)

        #self.recon = nn.Conv2d(n_feats, n_colors, kernel_size=3,padding=kernel_size//2)

    def forward(self, x):
        x = self.head(x)

        y = self.body(x) + x

        return y

class GELIN(nn.Module):
    def __init__(self,n_feats,n_colors,kernel_size,pooling_r,n_subs, n_ovls,blocks,scale):
        super(GELIN,self).__init__()

        # calculate the group number (the number of branch networks)
        # 向上取整计算组的数量 G
        self.n_feats = n_feats
        self.n_subs = n_subs
        self.G = math.ceil((n_colors - n_ovls) / (n_subs - n_ovls))
        # calculate group indices
        self.start_idx = []
        self.end_idx = []
        self.scale = scale
        for g in range(self.G):
            sta_ind = (n_subs - n_ovls) * g
            end_ind = sta_ind + n_subs
            if end_ind > n_colors:
                end_ind = n_colors
                sta_ind = n_colors - n_subs
            # 把每一组的开始 idx 与结束 idx 存入 list
            self.start_idx.append(sta_ind)
            self.end_idx.append(end_ind)

        self.branch = SSELM(n_subs,n_feats,blocks,pooling_r)

        self.branch_up = NGIM(n_feats,scale)
        self.branch_recon = nn.Conv2d(n_feats, n_subs, kernel_size=3,padding=kernel_size//2)

    def forward(self,x,lms):

        b, c, h, w = x.shape
        m = []
        y = torch.zeros(b, c,  h*self.scale,  w*self.scale).cuda()

        channel_counter = torch.zeros(c).cuda()

        for g in range(self.G):

            sta_ind = self.start_idx[g]
            end_ind = self.end_idx[g]

            xi = x[:, sta_ind:end_ind, :, :]
            xi = self.branch(xi)
            m.append(xi)

        for g in range(self.G):

            sta_ind = self.start_idx[g]
            end_ind = self.end_idx[g]

            if g==0:
                xl = m[self.G-1]
                xi = m[g]
                xn = m[g+1]
            elif g==self.G-1:
                xl = m[g-1]
                xi = m[g]
                xn = m[0]
            else:
                xl = m[g-1]
                xi = m[g]
                xn = m[g+1]

            xi = self.branch_up(xl,xi,xn)
            xi = self.branch_recon(xi)
            y[:, sta_ind:end_ind, :, :] += xi
            # 用 channel_counter 记录某一个位置被加了几次，然后再除这个数字取平均
            channel_counter[sta_ind:end_ind] = channel_counter[sta_ind:end_ind] + 1

        # intermediate “result” is averaged according to their spectral indices
        y = y / channel_counter.unsqueeze(1).unsqueeze(2)
        y = y + lms
        return y


"""
https://leetcode.com/problems/sum-of-all-odd-length-subarrays/
Given an array of positive integers arr, calculate the sum of all possible odd-length subarrays.
A subarray is a contiguous subsequence of the array.
Return the sum of all odd-length subarrays of arr.
"""

"""
For array of size x, start with x subarrays
If array.length>2, new array.length-3 subarrays of size 3
If array.length>4, new array.length-4 subarrays of size 5

For all odd n-length subarrays, create m new subarrays
where m is equal to the array length-n.
Add the subarrays.
Add the sums.
"""

from typing import List

class Solution:
    def sumOddLengthSubarrays(self, arr: List[int]) -> int:
        table = arr.copy()

        for n in range(3,len(arr),2):
            for m in range(len(arr)-n):
                table.append(sum(arr[m:m+n]))

        return sum(table)


import time
import json
import os
import requests

class pokemon:
    def __init__(self, number, energy):
        self.number = number
        self.energy = 50
        self.hp = hp_from_id(number)
        self.attack = attack_from_id(number)
        self.defense = defense_from_id(number)
        self.special_attack = special_attack_from_id(number)
        self.special_defense = special_defense_from_id(number)
        self.speed = speed_from_id(number)

class player:
    def __init__(self, name):
        self.beans = 0
        self.name = name
        self.pokemon = []

        self.last_harvest = None

    def harvest(self):
        if self.last_harvest == None:
            harvested_beans = 40
        else:
            seconds_since_last_harvest = time.time() - self.last_harvest
            harvested_beans = int(seconds_since_last_harvest / 180)

        if harvested_beans > 80:
            harvested_beans = 80

        if harvested_beans > 0:
            self.beans += harvested_beans
            self.last_harvest = time.time()

            self.save_to_file()

            print(f"You've harvested {harvested_beans} beans!")
        else:
            print("Oops, the tree hasn't produced any beans yet! Wait a little longer!")

    def print_info(self):
        print(f"You currently have {self.beans} beans!\n \n")

    def print_salutations(self):
        return(f"Hey, {self.name}! What would you like to do? Check your beans, harvest or (add more later)?\n")

    def save_to_file(self):
        # make dict of attributes
        player_data = {
            "name": self.name,
            "beans": self.beans,
            "last_harvest": self.last_harvest
        }

        file_name = f"{self.name}.json"
        file = open(file_name, "w")  # open file
        json.dump(player_data, file)  # write player data to file
        file.close()  # close file

    def load_from_file(self):
        file_name = f"{self.name}.json"
        if os.path.exists(file_name):  #check if player file exists
            player_data = json.load(open(file_name))  # open json file

            # set attributes
            self.name = player_data["name"]
            self.beans = player_data["beans"]
            self.last_harvest = player_data["last_harvest"]
        else:
            print("no player file found")

r = requests.get("https://pokeapi.co/api/v2/pokemon/6")
data = r.json()
stats = {x["stat"]["name"]: x[base_stat]for x in data["stats"]}

p1 = player(input("Hey!Whats your name?\n"))
p1.load_from_file()

x = 1
while x == 1:
    player_choice = input(p1.print_salutations())
    if player_choice == "beans":
        p1.print_info()
        input("Press Enter to go back to the main menu.")
    elif player_choice == "harvest":
        p1.harvest()
        input("Press Enter to go back to the main menu.")


"""Deleted_columns_in_city

Revision ID: 7b8f459a61b0
Revises: e280451841bb
Create Date: 2021-11-11 15:08:06.260280

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '7b8f459a61b0'
down_revision = 'e280451841bb'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('hotel', 'location_link')
    op.drop_column('hotel', 'breakfast_included')
    op.drop_column('hotel', 'transport_from_airport')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('hotel', sa.Column('transport_from_airport', mysql.ENUM('not_included', 'bus', 'car'), nullable=True))
    op.add_column('hotel', sa.Column('breakfast_included', mysql.ENUM('not_included', 'included', 'paid', 'all_inclusive'), nullable=True))
    op.add_column('hotel', sa.Column('location_link', mysql.VARCHAR(length=500), nullable=True))
    # ### end Alembic commands ###


# Write a web scraper that fetches the information from the Wikipedia page
# on Web scraping. Extract all the links on the page and filter them so the
# navigation links are excluded.
# Programmatically follow one of the links that lead to another Wikipedia article,
# extract the text content from that article, and save it to a local text file.
# BONUS TASK: Use RegExp to find all numbers in the text.

URL = "https://en.wikipedia.org/wiki/Web_scraping"

import requests
from bs4 import BeautifulSoup
from pprint import pprint
import json

def extract_links(URL):
    # create a bs object
    page = requests.get(URL)
    soup = BeautifulSoup(page.text,"lxml")

    data = {}
    for para in soup.find_all("p"):
        try:
            links = para.find_all("a")
            for link in links:
                text = link.text
                page_link = link["href"]
                if page_link[0] == "/":
                    full_link = f"https://en.wikipedia.org{page_link}"
                    data[text] = full_link
        except TypeError as e:
            link = None

    with open("wiki_web_scrap.json", "w") as wws:
        json.dump(data,wws)

def extract_texts():

    with open("wiki_web_scrap.json","r") as r:
        data = json.load(r)

    for key,link in data.items():
        page = requests.get(link)

        soup = BeautifulSoup(page.text, "lxml")

        main_content = soup.find("main")
        divs = main_content.find_all("div", class_="mw-parser-output")
        for div in divs:
            with open(f"resources/04_web-scraping/wiki/{key}.txt","a") as f:
                f.write(div.text)

        print("file created successfully \n")

if __name__ == "__main__":
    extract_texts()


from HaierTV import HaierTV
from HisenseTV import HisenseTV

class TVFactory(object):
    @staticmethod
    def produceTV(brand):
        if brand.lower() == 'haier':
            print("正在生产一个Haier电视...")
            return HaierTV()
        elif brand.lower() == 'hisense':
            print("正在生产一个Hisense电视...")
            return HisenseTV()
        else:
            print(brand + "电视无法生产...\n")


import time
import numpy as np
import math
from numba import cuda
from matrix_operations import matmul_packed32_shared, matmul_packed32, TPB
from matrix_convert import to_gpu, from_gpu, to_type, from_type

np.random.seed(1)

def run_uint32(size=10000, times=50, sparsity=0.7):
    A, B = np.random.randint(0, 100, (size,) * 2) > (sparsity * 100)
    C = np.zeros_like(A)

    matrices = {'A': A, 'B': B, 'C': C}
    matrices = to_type(matrices, 'uint32')
    matrices = to_gpu(matrices)

    is_changed = cuda.device_array((1,), dtype=bool)

    blockspergrid = tuple(int(math.ceil(A.shape[i] / TPB[i])) for i in (0, 1))

    print('Begin multuplying without shared memory')
    begin_no_shared = time.time()
    for i in range(times):
        matmul_packed32[blockspergrid, TPB](A, B, C, is_changed)
    end_no_shared = time.time()

    print('Begin multuplying with shared memory')
    begin_shared = time.time()
    for i in range(times):
        matmul_packed32_shared[blockspergrid, TPB](A, B, C, is_changed)
    end_shared = time.time()

    matrices = from_gpu(matrices)
    matrices = from_type(matrices)

    shared_average = (end_shared - begin_shared) / float(times)
    not_shared_average = (end_no_shared - begin_no_shared) / float(times)

    print('For shared memory average is {}'.format(shared_average))
    print('For not shared memory average is {}'.format(not_shared_average))

if __name__ == '__main__':
    print('Testing uint32 multiplication')

    for size in (100, 1000, 100000):
        print('-> Size of matrix {}'.format((size,) * 2))
        run_uint32(size, times=50, sparsity=0.7)


def diff(L1,L2):
    S=[]
    L = []
    l = []
    for i in L1:
        if i not in L:
            L.append(i)
    for j in L2:
        if j not in l:
            l.append(j)

    for i in L:
        if i not in l:
            S.append(i)
    print(S)

L1 = ['Prabhjeet','Singh']
L2 = ['Singh']

diff(L1,L2)


import typer
from typing import Optional
import os
import sys
import json

from alternat.generation import Generator
from alternat.generation.exceptions import InvalidConfigFile, InvalidGeneratorDriver
from alternat.collection import Collector
import subprocess
import shutil

app = typer.Typer()

# This key determines the driver (if present in the json file)
_DRIVER_KEY = "DRIVER"

# This key determines the generator level config (if present in the json file)
_GENERATOR_KEY = "GENERATOR"

@app.command("collect")
def collect(
    url: str = None,
    output_dir_path: str = None,
    download_recursive: bool = False,
    collect_using_apify: bool = True,
):
    """Collects image from URL specified.

    :param url: The URL from where the image needs to be downloaded.
    :type url: str
    :param output_dir_path: Path to directory where the images downloaded should be dumped
    :type output_dir_path: str
    :param download_recursive: Whether to recursively crawl a site, defaults to False
    :type download_recursive: bool, optional
    :param collect_using_apify: Whether to crawl using appify crawler, defaults to True
    :type collect_using_apify: bool, optional
    """
    collector = Collector()

    if url is None:
        typer.echo("ERROR : Specify url from which images needs to be collected using --url argument")
        return None

    if output_dir_path is None:
        typer.echo("ERROR : Specify output directory path where the images needs to be collected using "
                   "--output-dir-path argument")
        return None

    collector.process(url, output_dir_path, download_recursive, collect_using_apify)

@app.command("generate")
def generate(
    output_dir_path: str = typer.Option(...),
    input_dir_path: str = None,
    input_image_file_path: str = None,
    base64_image: str = None,
    driver_config_file_path: str = None

):
    """Analyze the image to generate alt-text

    :param output_dir_path: Output dir path to store the results, defaults to typer.Option(...)
    :type output_dir_path: str, optional
    :param input_dir_path: Directory path to the folder containing images, defaults to None
    :type input_dir_path: str, optional
    :param input_image_file_path: Path to image file to be processed (used only if single image needs to be processed), defaults to None
    :type input_image_file_path: str, optional
    :param base64_image: Base64 image to be processed (used only if single image needs to be processed), defaults to None
    :type base64_image: str, optional
    :param driver_config_file_path: Path to the generator JSON config file (defaults will be used if not provided)
    :return:, defaults to None
    :type driver_config_file_path: str, optional
    :raises InvalidGeneratorDriver: Driver invalid error.
    :raises InvalidConfigFile: Configuration file is invalid.
    :return: collection of JSON representing alt-text data for images
    :rtype: [type]
    """
    generator = Generator()

    if driver_config_file_path is not None:
        file_extension = driver_config_file_path.split(".")[-1]
        if file_extension.lower() == "json":

            #read the json file
            with open(driver_config_file_path) as f:
                data = json.load(f)

                if _DRIVER_KEY in data.keys():
                    generator = Generator(data[_DRIVER_KEY])
                    generator.set_driver_config(data)
                else:
                    raise InvalidGeneratorDriver(Generator.ALLOWED_DRIVERS)

                # check if generator conf is present
                if _GENERATOR_KEY in data.keys():
                    generator_conf = data[_GENERATOR_KEY]
                    generator.set_config(generator_conf)
        else:
            raise InvalidConfigFile()

    results = []
    if input_dir_path is None:
        if input_image_file_path is None:

            if base64_image is not None:
                result_json = generator.generate_alt_text_from_base64(base64_image)
                print(result_json)
                return result_json
            else:
                typer.echo("One of --base64_image or --input-image-file-path is missing")
                return
        else:
            typer.echo("Processing image : %s" % input_image_file_path)

            result_json = generator.generate_alt_text_from_file(input_image_file_path, output_dir_path)
            print(result_json)
            return result_json
    else:
        for path, subdirs, files in os.walk(input_dir_path):
            for filename in files:
                if (
                    filename.endswith(".jpg")
                    or filename.endswith(".png")
                    or filename.endswith(".jpeg")
                ):
                    image_path = os.path.join(path, filename)
                    typer.echo("Processing image : %s" % image_path)
                    result_json = generator.generate_alt_text_from_file(image_path, output_dir_path)
                    print(result_json)
                    results.append(result_json)
                    typer.echo("Result saved at : %s" % output_dir_path)

        return results

if __name__ == "__main__":
    app()


import random

# класс мечник для получения аттрибутов
class Swordman:
    name: str
    strength: int
    agility: int

    def __init__(self):
        self.name = "swordman"
        self.strength = 10000
        self.agility = 5

# класс лучник для получения аттрибутов
class Archer:
    name: str
    strength: int
    agility: int

    def __init__(self):
        self.name = "archer"
        self.strength = 5
        self.agility = 10

# добавление объектов классов в лист
def registration():
    swordman = Swordman()
    archer = Archer()
    classes = list()
    classes.append(swordman)
    classes.append(archer)
    return classes

# класс игрока с его характеристиками и взаимодействия с игроком (взаимодействия с игроком в плане методы взаимодействия? или кто взаимодействует?)
class Player:
    player_id: int
    role: str
    base_strength: int = 0
    base_agility: int = 0
    strength: int
    agility: int
    damage: int
    hp: int
    critical_chance: float
    critical_damage: float
    armor: int
    chance_of_evasion: float
    attack_speed: float
    inventory: list
    lvl: int = 1
    experience: int = 100
    gold: int

    # метод для назначения класса  и начальных аттрибутов пользователю
    def get_role_and_atributes(self, player):
        status = True
        choose = gameplay.choose_class(player)
        classes = registration()
        # try:
        for game_class in classes:
            if choose == game_class.name:
                player.role = game_class.name
                player.base_strength = game_class.strength
                player.base_agility = game_class.agility
                status = True
                break
            else:
                status = False
        if not status:
            print("Ввод не верный, попробуй еще раз")
            self.get_role_and_atributes(player)

    # метод для повышения уровня
    def lvl_up(self, player):
        self.lvl += 1
        self.experience = 0
        self.get_stats()  # он вызовется если он ниже определён?

    # метод для получения и повышения характеристик
    def get_stats(self):
        self.strength = self.base_strength + self.lvl * 5
        self.agility = self.base_agility + self.lvl * 5
        self.strength = self.base_strength + self.lvl * 3
        self.agility = self.base_agility + self.lvl * 2
        self.hp = self.strength * 15
        self.damage = self.strength * 2
        self.critical_chance = self.strength * 0.005
        if self.critical_chance > 0.2:
            self.critical_chance = 0.2
        self.critical_damage = 1 + (self.strength * self.agility * 0.002)
        self.armor = int(self.agility * 0.15)
        self.chance_of_evasion = self.agility * 0.005
        if self.chance_of_evasion > 0.3:
            self.chance_of_evasion = 0.3
        self.attack_speed = 1 + self.agility * 0.005

# Класс для всех предметов
class Item:
    id: int
    cost: int
    rarety: int

# Класс для всех защитных предметов
class Armor(Item):
    armor: int
    hp: int
    chance_of_evasion: float

# класс для создания предмета helmet
class Helmet(Armor):
    def __init__(self):
        self.id = 1
        self.hp = 100
        self.armor = 2

class Location:
    id: int
    needed_lvl: int
    mob_list: list
    drop_list: list

    def generate_enemy(self):
        pass

class Forest(Location):
    def __init__(self):
        self.id = 1
        self.needed_lvl = 1

    def get_mob_list(self):
        self.mob_list = list()
        self.mob_list.append(zombie_enemy)
        return self.mob_list

class mob:
    mob_name: str
    base_strength: int = 1
    base_agility: int = 2
    strength: int
    agility: int
    damage: int
    hp: int
    critical_chance: float
    critical_damage: float
    armor: int
    chance_of_evasion: float
    attack_speed: float
    lvl: int
    gold: int

class Zombie(mob):

    def __init__(self):
        self.mob_name = "zombie"

    def get_lvl(self):
        self.lvl = random.randint(gamer.lvl-2, gamer.lvl+2)
        if self.lvl <= 0:
            self.lvl = 1

    def get_stats(self):
        self.strength = self.base_strength + self.lvl * 3
        self.agility = self.base_agility + self.lvl * 2
        self.hp = self.strength * 15
        self.damage = self.strength * 5
        self.critical_chance = self.strength * 0.005
        if self.critical_chance > 0.2:
            self.critical_chance = 0.2
        self.critical_damage = self.damage * (self.strength * self.agility * 0.002)
        self.armor = int(self.agility * 0.15)
        self.chance_of_evasion = self.agility * 0.005
        if self.chance_of_evasion > 0.3:
            self.chance_of_evasion = 0.3
        self.attack_speed = 1 + self.agility * 0.005

# класс для всех игровых методов
class Gameplay:

    # выбор пользователем класса
    def choose_class(self, player):
        choose = input("Выберите класс: swordman или archer\n")
        return choose

    # Проверка достижения уровня
    def lvl_check(self):
        needed_experience = 100 * gamer.lvl + 100 * (gamer.lvl - 1) ** 2
        if gamer.experience >= needed_experience:
            gamer.lvl_up(gamer)
        else:
            pass

gamer = Player()
gameplay = Gameplay()
helmet = Helmet()
zombie_enemy = Zombie()
forest = Forest()
gamer.get_role_and_atributes(gamer)
gamer.get_stats()
# print(gamer.strength, gamer.agility, gamer.damage, gamer.hp, gamer.critical_damage, gamer.armor)

# zombie_enemy.get_lvl()
# zombie_enemy.get_stats()
# print(zombie_enemy.lvl, zombie_enemy.strength, zombie_enemy.agility)
# forest.get_mob_list()


import unittest
import timeit

# Solution that uses O(n) space to store the result.
def not_in_place(xs):
    xs.sort()
    result = [xs[0]]
    for ca, cb in xs[1:]:
        pa, pb = result[-1]
        if ca <= pb:
            result[-1] = (pa, max(pb, cb))
        else:
            result.append((ca, cb))
    return result

# Solution that uses O(1) space to store the result.
def in_place(xs):
    xs.sort()
    i = 0
    j = i + 1
    while j < len(xs):
        pa, pb = xs[i]
        ca, cb = xs[j]
        if ca <= pb:
            xs[i] = (pa, max(pb, cb))
            del xs[j]
        else:
            i = j
            j += 1
    return xs

def test_nip():
    inputs = [
        [(1, 3), (2, 4)],
        [(5, 6), (6, 8)],
        [(1, 8), (2, 5)],
        [(1, 3), (4, 8)],
        [(1, 4), (2, 5), (5, 8)],
        [(5, 8), (1, 4), (6, 8)],
        [(1, 10), (2, 5), (6, 8), (9, 10), (10, 12)],
        [(0, 1), (3, 5), (4, 8), (10, 12), (9, 10)],
    ]
    for x in inputs:
        not_in_place(x)

def test_ip():
    inputs = [
        [(1, 3), (2, 4)],
        [(5, 6), (6, 8)],
        [(1, 8), (2, 5)],
        [(1, 3), (4, 8)],
        [(1, 4), (2, 5), (5, 8)],
        [(5, 8), (1, 4), (6, 8)],
        [(1, 10), (2, 5), (6, 8), (9, 10), (10, 12)],
        [(0, 1), (3, 5), (4, 8), (10, 12), (9, 10)],
    ]
    for x in inputs:
        in_place(x)

merge_ranges = in_place

setup = 'from __main__ import test_nip, test_ip'
print(timeit.timeit('test_nip()', number=10000, setup=setup))
print(timeit.timeit('test_ip()', number=10000, setup=setup))

# Tests
class Test(unittest.TestCase):
    def test_meetings_overlap(self):
        actual = merge_ranges([(1, 3), (2, 4)])
        expected = [(1, 4)]
        self.assertEqual(actual, expected)

    def test_meetings_touch(self):
        actual = merge_ranges([(5, 6), (6, 8)])
        expected = [(5, 8)]
        self.assertEqual(actual, expected)

    def test_meeting_contains_other_meeting(self):
        actual = merge_ranges([(1, 8), (2, 5)])
        expected = [(1, 8)]
        self.assertEqual(actual, expected)

    def test_meetings_stay_separate(self):
        actual = merge_ranges([(1, 3), (4, 8)])
        expected = [(1, 3), (4, 8)]
        self.assertEqual(actual, expected)

    def test_multiple_merged_meetings(self):
        actual = merge_ranges([(1, 4), (2, 5), (5, 8)])
        expected = [(1, 8)]
        self.assertEqual(actual, expected)

    def test_meetings_not_sorted(self):
        actual = merge_ranges([(5, 8), (1, 4), (6, 8)])
        expected = [(1, 4), (5, 8)]
        self.assertEqual(actual, expected)

    def test_one_long_meeting_contains_smaller_meetings(self):
        actual = merge_ranges([(1, 10), (2, 5), (6, 8), (9, 10), (10, 12)])
        expected = [(1, 12)]
        self.assertEqual(actual, expected)

    def test_sample_input(self):
        actual = merge_ranges([(0, 1), (3, 5), (4, 8), (10, 12), (9, 10)])
        expected = [(0, 1), (3, 8), (9, 12)]
        self.assertEqual(actual, expected)

unittest.main(verbosity=2)


from flask import Flask, render_template, jsonify
import serial
import sys
import threading
import openpyxl
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
import datetime

app = Flask(__name__)

latest_tag = ''
tag_count = 0
tag_data = []

def convert_tag_from_bytes_to_hex(tag_bytes_list):
    tag_hex_value = ""
    for index, bytes_value in enumerate(tag_bytes_list):
        #   First 3 bytes and last byte are placeholders
        if index > 3 and index < 16:
            tag_hex_value += "{0:02X}".format(bytes_value)
    return tag_hex_value

def run_test():
    global latest_tag
    global tag_count
    global tag_data

    tag_bytes_list_for_device_1 = []
    tag_hex_value_list = set([])
    should_read_tag_from_device_1 = False

    try:
        serial_device_1 = serial.Serial('COM4', 57600, timeout=0.5)
    except serial.serialutil.SerialException as err:
        print('There was a problem while opening the ports for the reader')
        raise err

    try:
        serial_device_1.reset_input_buffer()
        # create a new workbook and sheet
        wb = Workbook()
        sheet = wb.active
        sheet.title = "RFID Data"
        sheet['A1'] = "Tag Value"
        sheet['B1'] = "Timestamp"
        row_num = 2
        written_tag_values = set()

        while True:
            tag_hex_value = ""
            read_bytes_from_device_1 = serial_device_1.read()
            int_value_from_device_1 = int.from_bytes(read_bytes_from_device_1, "big")

            if int_value_from_device_1 == 0x11:
                should_read_tag_from_device_1 = True

            if should_read_tag_from_device_1 is True:
                tag_bytes_list_for_device_1.append(int_value_from_device_1)

                if len(tag_bytes_list_for_device_1) == 18:
                    should_read_tag_from_device_1 = False
                    tag_hex_value = convert_tag_from_bytes_to_hex(tag_bytes_list_for_device_1)
                    tag_hex_value_list.add(tag_hex_value)
                    tag_bytes_list_for_device_1.clear()

                    # update latest_tag and tag_count
                    latest_tag = tag_hex_value
                    tag_count = len(tag_hex_value_list)

                    if tag_hex_value not in written_tag_values :
                        # write to excel sheet
                        sheet.cell(row=row_num, column=1).value = tag_hex_value
                        written_tag_values.add(tag_hex_value)
                        sheet.cell(row=row_num, column=2).value = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        row_num += 1
                        wb.save("RFID_Data.xlsx")

            print(f"RFID Tag count: {tag_count}, Latest tag: {latest_tag}")

    except KeyboardInterrupt:
        print("Received keyboard interrupt in the RFID reader test program. Closing the ports and exiting the program")
        serial_device_1.flush()
        serial_device_1.reset_input_buffer()
        serial_device_1.close()

        sys.exit(0)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/stream')
def stream():
    def event_stream():
        while True:
            yield 'data: {{"latest_tag": "{0}", "tag_count": "{1}"}}\n\n'.format(latest_tag, tag_count)
    return app.response_class(event_stream(), mimetype='text/event-stream')

if __name__ == "__main__":
    run_test_thread = threading.Thread(target=run_test)
    run_test_thread.start()

    app.run(debug=True)


from typing import List

def add_value_to_rating(new_value: int, rating: List[int]):
    insert_at = len(rating)
    for i in range(len(rating)):
        if rating[i] < new_value:
            insert_at = i
            break
    rating.insert(insert_at, new_value)

rating = [7, 5, 3, 3, 2]
print('Текущий рейтинг:', rating)

new_value = None
while new_value is None or new_value <= 0:
    s = input('Введите новое значение:')
    if s.isdigit():
        new_value = int(s)

add_value_to_rating(new_value, rating)
print()
print('Новый рейтинг:', rating)


# This is my solution
"""
def solve():
    n, s, x = (int(element) for element in input().split())
    stack = [int(num) for num in input().split()]
    [stack.pop() for i in range(s)]
    if x in stack:
        print("True")
    elif len(stack) >= 1:
        print(min(stack))
    else:
        print(0)

if __name__ == '__main__':
    solve()
"""

# And this is the solution from work in class:
numbers = [int(x) for x in input().split()]
to_push, to_pop, searched_number = numbers

elements = [int(x) for x in input().split()]

[elements.pop() for _ in range(to_pop)]

if searched_number in elements:
    print("True")
else:
    if elements:
        print(min(elements))
    else:
        print(0)

SoftUni Lessons/Python Development/Python Advanced January 2020/Python Advanced/04. EXERCISE LISTS AS STACKS AND QUEUES/01.Basic Stack Operations.py


from odoo import api, models

class CheckReportWizard(models.TransientModel):
    _name = 'check.report.wizard'

    @api.multi
    def print_report(self):
        active_ids = self.env.context.get('active_ids', [])
        payments = self.env['account.payment'].browse(active_ids)
        datas = {
             'ids': active_ids,
             'model': 'account.payment',
             'form': self.read()[0]
        }
        return self.env['report'].get_action(payments, 'mass_payment.report_mass_payment', data=datas)


#!/usr/bin/env python
import subprocess, threading, sys, os, inspect
from threading import Thread

baseDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

class startProcess (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        subprocess.Popen([baseDir+'/musicPlayer.py'])
        subprocess.Popen([baseDir+'/ledServer.py'])

# MAIN LOOP
def main(args):
    print('Starting servers')
    start = startProcess()
    start.daemon = True
    start.start()

if __name__ == "__main__":
    main(sys.argv)


import os

import yaml
from behave import fixture, use_fixture
from selenium import webdriver

browser_type = os.environ.get("BROWSER", "chrome")
platform = os.environ.get("PLATFORM", "desktop")

def get_browser(name):
    if name == "chrome":
        return webdriver.Chrome()
    else:
        return None

def get_vars():
    variables = {}
    dir_path = os.path.dirname(os.path.realpath(__file__))
    print(dir_path)
    for filename in os.listdir(dir_path):
        if filename.endswith("_variables.yaml"):
            file = open(os.path.join(dir_path, filename))
            local_vars = yaml.load(file, yaml.SafeLoader)
            file.close()
            basename = filename.split("_")[0]
            variables[basename] = local_vars
    return variables

def get_lookup(variables):
    def lookup(name):
        parts = name.split("::")
        node = variables
        for p in parts:
            if not isinstance(node, dict):
                return name
            n = node.get(p, None)
            if n is None:
                return name
            node = n
        return node
    return lookup

@fixture
def selenium_browser_chrome(context):
    # -- HINT: @behave.fixture is similar to @contextlib.contextmanager
    context.browser = webdriver.Chrome()
    context.lookup = get_lookup(get_vars())
    yield context.browser
    # -- CLEANUP-FIXTURE PART:
    context.browser.quit()

def before_all(context):
    use_fixture(selenium_browser_chrome, context)
    # -- HINT: CLEANUP-FIXTURE is performed after after_all() hook is called.


import argparse
import conf
from dfwrapper import HeinzWrapper, ResistanceWrapper
from plotting import Plotter

def main(args):
    conf.configure_from_args(args)
    curr_wrapper = HeinzWrapper(conf.curr_file_names, 'curr')
    volt_wrapper = HeinzWrapper(conf.volt_file_names, 'volt')
    comb_wrapper = ResistanceWrapper(curr_wrapper, volt_wrapper)
    my_plotter = Plotter(comb_wrapper)
    my_plotter.plot()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--datelist", nargs="+", default=None, help="dates to consider")
    parser.add_argument("--loglvl", type=int, default=0, help="0: warning, 1: info, 2: debug")
    parser.add_argument("--outputfolder", type=str, default="data/output/",
                        help="name of output file")
    args = parser.parse_args()
    main(args)


#!d:/python/python.exe
# *********************************************************************
# Program to submit the interim and full export publishing job.
# ---------------------------------------------------------------------
# Created:          2007-04-03        Volker Englisch
# *********************************************************************
import sys
import cdr
import os
import time
from argparse import ArgumentParser
from cdrapi import db

# Setting the host variable to submit the link for the error report
# -----------------------------------------------------------------
host = cdr.APPC
url = 'https://%s' % host

# Setting directory and file names
# --------------------------------
PUBPATH = os.path.join('d:\\cdr', 'publishing')
# PUBPATH = os.path.join('d:\\home', 'venglisch', 'cdr', 'publishing')

TIER = cdr.Tier().name
MAX_RETRIES = 10
RETRY_MULTIPLIER = 5.0
wait = 60    # number of seconds to wait between status checks

# The performance of the publishing job has greatly improved allowing
# us to cancel a running job much sooner if it fails to finish.
# Optionally overriden below once we know the publishing subset.
# --------------------------------------------------------------------
if cdr.isProdHost():
    waitTotal = 10800  # 3.0 hours
elif cdr.isDevHost():
    waitTotal = 10800  # 3.0 hours
else:
    waitTotal = 14400  # 4.0 hours

testMode = None
fullMode = None

session = cdr.login("cdroperator", cdr.getpw("cdroperator"))
pubSystem = 'Primary'

pubEmail = cdr.getEmailList('Operator Publishing Notification')

# ------------------------------------------------------------
# Custom argument parser (so we can log errors).
# ------------------------------------------------------------
class Parser(ArgumentParser):
    JOBMODES = (
        ("interim", "run in interim (nightly) production mode"),
        ("export", "run in export (weekly) production mode"),
    )
    RUNMODES = (
        ("testmode", "run in TEST mode"),
        ("livemode", "run in LIVE mode"),
    )
    MODES = JOBMODES, RUNMODES

    def __init__(self):
        ArgumentParser.__init__(self)
        for modes in self.MODES:
            group = self.add_mutually_exclusive_group(required=True)
            for option, help in modes:
                args = f"--{option}", f"--{option[0]}"
                opts = dict(action="store_true", help=help)
                group.add_argument(*args, **opts)

    def error(self, message):
        LOGGER.error(message)
        self.print_help(sys.stderr)
        sys.stderr.write(f"\n{message}\n")
        sys.exit(1)

# ---------------------------------------------------------------
# Function to check the job status of the submitted publishing
# job.
# ---------------------------------------------------------------
def checkJobStatus(jobId):
    # Defensive programming.
    tries = MAX_RETRIES

    while tries:
        try:
            conn = db.connect(timeout=300)
            cursor = conn.cursor()
            cursor.execute("""\
                SELECT id, status, started, completed, messages
                  FROM pub_proc
                 WHERE id = %d""" % int(jobId))
            row = cursor.fetchone()

            # We can stop trying now, we got it.
            tries = 0

        except Exception:
            LOGGER.exception("*** Failure connecting to DB ***")
            LOGGER.info("*** Unable to check status for PubJob%s", jobId)
            waitSecs = (MAX_RETRIES + 1 - tries) * RETRY_MULTIPLIER
            LOGGER.info("    RETRY: %d retries left; waiting %f seconds",
                        tries, waitSecs)
            time.sleep(waitSecs)
            tries -= 1

    if not row:
        raise Exception("*** (3) Tried to connect %d times. No Pub Job-ID." %
                        MAX_RETRIES)

    return row

# ---------------------------------------------------------------
# Function to set the job status to failure
# On occasion, the publishing job fails to finish (network
# connectivity issues?) and will get cancelled once the max time
# allowed is reached.
# This function sets the job status to 'Failure' so that the job
# status isn't preventing new jobs from being processed because
# only one single job (per job type) is allowed to run at a time.
#
# If testing this function for a job that *not* actually failed be
# prepared that the status gets set to 'Failure' but will be
# updated again - possibly to 'Success' - at the end of the
# "not-really-failed" publishing job.
# ---------------------------------------------------------------
def statusPubJobFailure(jobId):
    # Defensive programming.
    tries = MAX_RETRIES
    row = cursor = None

    while tries:
        try:
            conn = db.connect(timeout=300)
            cursor = conn.cursor()
            cursor.execute("""\
                SELECT id, status, started, completed, messages
                  FROM pub_proc
                 WHERE id = %d""" % int(jobId))
            row = cursor.fetchone()
            LOGGER.info("Job%d status: %s", row[0], row[1])

            # We can stop trying now, we got it.
            tries = 0

        except Exception:
            LOGGER.exception("*** Failure connecting to DB ***")
            LOGGER.warning("*** Unable to set job status to 'Failure'.")
            LOGGER.info("*** PubJob%d", jobId)
            waitSecs = (MAX_RETRIES + 1 - tries) * RETRY_MULTIPLIER
            LOGGER.info("    RETRY: %d retries left; waiting %f seconds",
                        tries, waitSecs)
            time.sleep(waitSecs)
            tries -= 1

    if cursor is None:
        raise Exception("Unable to connect to the database")

    # Setting the job status to 'Failure' rather than leaving it as
    # 'In process'.  That way a new job won't fail until the job
    # status has been manually updated.
    # -------------------------------------------------------------
    try:
        cursor.execute("""\
            UPDATE pub_proc
               SET status = 'Failure'
            WHERE id = %d
               AND status = 'In process'""" % int(jobId))

        conn.commit()
    except Exception:
        LOGGER.exception("*** Failure updating job status ***")
        LOGGER.info("*** Manually set the job status to 'Failure'.")
        LOGGER.info("*** PubJob%s", jobId)

    if not row:
        raise Exception("*** (3) Tried to connect %d times. No Pub Job-ID." %
                        MAX_RETRIES)

    return row

# --------------------------------------------------------------
# Function to find the job ID of the push job.
# --------------------------------------------------------------
def getPushJobId(jobId):
    # Defensive programming.
    tries = MAX_RETRIES
    time.sleep(15)

    while tries:
        try:
            conn = db.connect()
            cursor = conn.cursor()
            cursor.execute("""\
                SELECT id, status, started, completed
                  FROM pub_proc
                 WHERE id > %d
                   AND pub_system = 178
                   AND (pub_subset LIKE '%%_Interim-Export'
                        OR
                        pub_subset LIKE '%%_Export')
                   """ % int(jobId))
            row = cursor.fetchone()

            # If the SELECT returns nothing a push job was not submitted
            # because another job is still pending.
            # Otherwise the push job may already have completed.
            # -----------------------------------------------------------
            if row is None:
                LOGGER.error("*** Error - No push job waiting. "
                             "Check for pending job")
                cursor.execute("""\
                   SELECT id, messages
                     FROM pub_proc
                    WHERE id = %d""" % int(jobId))
                row = cursor.fetchone()
                LOGGER.info("%s", row[1])
                raise Exception("No push job waiting")

            # We can stop trying now, we got it.
            tries = 0

        except Exception:
            LOGGER.exception("*** Failure connecting to DB ***")
            LOGGER.info("*** Unable to find status for PushJob%s", jobId)
            waitSecs = (MAX_RETRIES + 1 - tries) * RETRY_MULTIPLIER
            LOGGER.info("    RETRY: %d retries left; waiting %f seconds",
                        tries, waitSecs)
            time.sleep(waitSecs)
            tries -= 1

    if not row:
        raise Exception("*** (1) Tried to connect %d times. No Push Job-ID." %
                        MAX_RETRIES)

    return row[0]

# ---------------------------------------------------------------------
# Function to send an email when the job fails instead of silently
# exiting.
# ---------------------------------------------------------------------
def sendFailureMessage(header="*** Error ***", body=""):
    emailDL = cdr.getEmailList('Test Publishing Notification')
    subject = header
    if not body:
        body = """
The publishing job failed.  Please check the log files.
"""
    opts = dict(subject=subject, body=body)
    cdr.EmailMessage(cdr.OPERATOR, emailDL, **opts).send()

    return

# ---------------------------------------------------------------------
# Function to check if an Interim job is already underway (maybe it runs
# longer then 24 hours or it has been started manually).
# Note:
# We may want to change the SQL query to make sure a weekly export can
# not be started if a nightly job hasn't finished yet.
# ---------------------------------------------------------------------
def checkPubJob():
    # Defensive programming.
    tries = MAX_RETRIES

    while tries:
        try:
            conn = db.connect()
            cursor = conn.cursor()
            cursor.execute("""\
                SELECT id, pub_subset, status, started, completed
                  FROM pub_proc
                 WHERE status not in ('Failure', 'Success')
                   AND pub_system = 178
                   AND pub_subset LIKE '%%Export' """)
            row = cursor.fetchone()
            return row or 0

        except Exception:
            LOGGER.exception("*** Failure checking for running jobs ***")
            waitSecs = (MAX_RETRIES + 1 - tries) * RETRY_MULTIPLIER
            LOGGER.info("    RETRY: %d retries left; waiting %f seconds",
                        tries, waitSecs)
            time.sleep(waitSecs)
            tries -= 1

    raise Exception(f"*** (2) Giving up after {MAX_RETRIES:d} times.")

# ---------------------------------------------------------------------
# Instantiate the Log class
# ---------------------------------------------------------------------
LOGGER = cdr.Logging.get_logger("PubJob", console=True)
LOGGER.info("SubmitPubJob - Started")
LOGGER.info('Arguments: %s', sys.argv)

opts = Parser().parse_args()
testMode = opts.testmode
fullMode = opts.export

# Based on the command line parameter passed we are submitting a
# interim publishing job or a full export
# ---------------------------------------------------------------
if fullMode:
    pubSubset = 'Export'
else:
    pubSubset = 'Interim-Export'
override = cdr.getControlValue("Publishing", f"{pubSubset}-wait-seconds")
try:
    override = int(override)
    waitTotal = override
except Exception:
    pass

try:
    # Before we start we need to check if a publishing job is already
    # underway.  It could be in the process of publishing or pushing.
    # We do not allow two jobs of the same job type to run simultanously.
    # Also, if a publishing job ran but the push job failed the
    # initiated push job would fail with a message 'Push job pending'.
    # ---------------------------------------------------------------
    LOGGER.info("Checking job queue ...")

    # checkPubJob will exit if another job is already running
    # -------------------------------------------------------
    currentJobs = checkPubJob()
    if currentJobs:
        LOGGER.error("\n%s job is still running.", pubSubset)
        LOGGER.error("Job%s status: %s", currentJobs[0], currentJobs[2])
        LOGGER.error("Job%s type  : %s", currentJobs[0], currentJobs[1])
        raise Exception("Job%s still in process (%s: %s)" %
                        (currentJobs[0], pubSubset, currentJobs[2]))

    LOGGER.info("   OK to submit")

    # Submitting publishing job.  If an integer job ID is returned
    # we continue.  Otherwise, submitting the job failed and we exit.
    # ---------------------------------------------------------------
    LOGGER.info("Submitting publishing job ...")
    submit = cdr.publish(session, pubSystem, pubSubset, email=pubEmail)

    if submit[0] is None:
        LOGGER.error("*** Failure starting publishing job ***")
        LOGGER.error("%s", submit[1])
        sys.exit(1)
    else:
        LOGGER.info("Pub job started as Job%s", submit[0])
        LOGGER.info("Waiting for publishing job to complete ...")

    # We started the publishing job.  Now we need to wait until
    # publishing (and pushing) is complete before we exit the
    # program.  Otherwise the following SQL Server Agent steps
    # would start without the data being ready.
    # Checking the status every minute
    # ---------------------------------------------------------
    done = 0
    counter = 0
    while not done:
        time.sleep(wait)
        counter += 1
        jobInfo = checkJobStatus(submit[0])
        status = jobInfo[1]
        messages = jobInfo[4]

        # Don't print every time we're checking (every 15 minutes)
        # ---------------------------------------------------------
        if counter % 15 == 0:
            LOGGER.info("    Status: %s (%d sec)", status, counter*wait)

            if counter * wait > waitTotal:
                hours = waitTotal / (60 * 60)
                LOGGER.error("*** Publishing job failed to finish!!!")
                LOGGER.error("*** Completion exceeded maximum time allowed")
                LOGGER.error("*** Cancelled after %s hours", hours)
                subject = "Publishing Failure: Max time exceeded"
                msgBody = """
The publishing job failed.  It did not finish within the maximum time
allowed.
"""
                sendFailureMessage(subject, msgBody)
                statusPubJobFailure(submit[0])
                sys.exit(1)

        # Once the publishing job completed with status Success
        # we need to find the push job and wait for it to finish
        # We will continue after both jobs completed with Success.
        # --------------------------------------------------------
        if status in ('Verifying', 'Success'):
            LOGGER.info("Publishing job started at %s", jobInfo[2])
            LOGGER.info("         and completed at %s", jobInfo[3])
            try:
                pushId = getPushJobId(submit[0])
                LOGGER.info("Push job started as Job%s", pushId)
            except Exception:
                LOGGER.exception("*** Failed to submit Push job for Job%s",
                                 submit[0])
                sys.exit(1)

            pdone = 0
            pcounter = 0

            # Waiting for the push job to finish
            # -----------------------------------
            while not pdone:
                time.sleep(wait)
                pcounter += 1
                jobInfo = checkJobStatus(pushId)
                pstatus = jobInfo[1]
                if pcounter % 15 == 0:
                    args = pstatus, pcounter * wait
                    LOGGER.info("    Status: %s (%d sec)", *args)
                if pstatus in ('Verifying', 'Success'):
                    pdone = 1
                    LOGGER.info("   Pushing job started at %s", jobInfo[2])
                    LOGGER.info("         and completed at %s", jobInfo[3])
                elif pstatus == 'Failure':
                    LOGGER.error("*** Push job failed at %s", jobInfo[3])
                    LOGGER.info("         Status:  %s", pstatus)
                    LOGGER.info("%s", jobInfo[4])
                    sys.exit(1)
                else:
                    pdone = 0

            done = 1
        elif status == 'Failure':
            LOGGER.error("*** Error - Publication job failed")
            LOGGER.error("... %s", messages[-500:])
            subj = "*** Publishing Failure: The current job did not succeed!"
            msgBody = """
The publishing job started but did not complete successfully.
See logs below:
---------------
%s
""" % messages[-500:]
            sendFailureMessage(subj, msgBody)
            sys.exit(1)
        else:
            done = 0

    try:
        # Submitting the email notification including the error report
        # The mail is send two different groups depending if it's a
        # nightly or a weekly publishing job
        # ------------------------------------------------------------
        if fullMode:
            emailDL = cdr.getEmailList('Weekly Publishing Notification')
            addSubj = 'Weekly'
        else:
            emailDL = cdr.getEmailList('Nightly Publishing Notification')
            addSubj = 'Nightly'

        # If we're not running in production we want to avoid sending
        # these email messages to the users.  Overwriting the emailDL
        # group to a developers/testers list or recipients
        # -----------------------------------------------------------
        if not TIER == 'PROD':
            emailDL = cdr.getEmailList('Test Publishing Notification')

        args = TIER, addSubj
        subject = '[%s] Status and Error Report for %s Publishing' % args

        emailDL.sort()
        if not len(emailDL):
            emailDL = cdr.getEmailList("Developers Notification")
            subject = '*** DL Missing *** %s' % subject
            LOGGER.warning('*** Warning: No Email DL found')

        message = """\

Status and Error reports for the latest %s publishing/push jobs:

Publishing Job Report:
   %s/cgi-bin/cdr/PubStatus.py?id=%s

Push Job Report:
   %s/cgi-bin/cdr/PubStatus.py?id=%s

""" % (addSubj.lower(), url, submit[0], url, pushId)

        opts = dict(subject=subject, body=message)
        cdr.EmailMessage(cdr.OPERATOR, emailDL, **opts).send()
        LOGGER.info("Submitting Email: OK")
    except Exception:
        LOGGER.exception("*** Error sending email ***")
        raise

except Exception as arg:
    LOGGER.exception("*** Standard Failure")
    subject = '[%s] *** SubmitPubJob.py - Standard Failure' % TIER
    msgBody = "The publishing job failed:  %s" % arg
    sendFailureMessage(subject, msgBody)

sys.exit(0)


from typing import Any, Mapping, Optional, Union, Tuple
from flax.core import scope as flax_scope
import jax
import jax.numpy as jnp
import t5x.models as t5x_models
from models import gp_models  # local file import from baselines.t5
from models import models as ub_models  # local file import from baselines.t5

Array = t5x_models.Array

class EncoderDecoderBEClassifierModel(ub_models.EncoderDecoderClassifierModel):
  """A wrapper of EncoderDecoderClassifierModel to support BatchEnsemble loss."""

  def loss_fn(
      self,
      params,
      batch,
      dropout_rng,
  ):
    target_tokens = batch['decoder_target_tokens']
    # Tile the labels for batch ensembles.
    ens_size = self.module.ens_size
    batch['decoder_target_tokens'] = jnp.tile(target_tokens, [ens_size] + [1] *
                                              (target_tokens.ndim - 1))
    loss_weights = batch['decoder_loss_weights']
    if loss_weights is not None:
      batch['decoder_loss_weights'] = jnp.tile(loss_weights, [ens_size] + [1] *
                                               (loss_weights.ndim - 1))
    return super().loss_fn(params, batch, dropout_rng)

  def _compute_argmax_score(
      self,
      params: t5x_models.PyTreeDef,
      batch: Mapping[str, jnp.ndarray],
      return_intermediates: bool = False,
      dropout_rng: Optional[jnp.ndarray] = None,
      ensemble_probs: bool = True,
  ) -> Union[jnp.ndarray, Tuple[jnp.ndarray, Mapping[str, Any]]]:
    """Compute class logits on a batch."""
    ens_size = self.module.ens_size
    sequence_scores = super()._compute_argmax_score(params, batch,
                                                    return_intermediates,
                                                    dropout_rng, ensemble_probs)
    if return_intermediates:
      sequence_scores, intermediates = sequence_scores
    if ens_size > 1:
      sequence_scores = jnp.reshape(sequence_scores,
                                    (ens_size, -1) + sequence_scores.shape[1:])  # pytype: disable=attribute-error  # jax-ndarray
      if ensemble_probs:
        # Computes log(mean(exp(logits))) along the first dimension.
        sequence_scores = (
            jax.nn.logsumexp(sequence_scores, axis=0) - jnp.log(ens_size))
      else:
        sequence_scores = jnp.mean(sequence_scores, axis=0)
    if return_intermediates:
      return sequence_scores, intermediates
    return sequence_scores

  def _compute_logits_from_slice(self,
                                 decoding_state,
                                 params,
                                 encoded_inputs,
                                 raw_inputs,
                                 max_decode_length,
                                 rngs=None,
                                 ensemble_probs=True):
    """Token slice to logits from decoder model."""
    ens_size = self.module.ens_size
    k = jax.tree_util.tree_flatten(params)[0][0].shape[0]
    flat_logits, new_cache = super()._compute_logits_from_slice(
        decoding_state, params, encoded_inputs, raw_inputs, max_decode_length,
        rngs, ensemble_probs)
    if ens_size > 1:
      flat_logits = jnp.reshape(flat_logits,
                                (k, ens_size, -1) + flat_logits.shape[1:])
      if ensemble_probs:
        flat_logits = (
            jax.nn.logsumexp(flat_logits, axis=1) - jnp.log(ens_size))
      else:
        flat_logits = jnp.mean(flat_logits, axis=1)
      flat_logits = jnp.reshape(flat_logits, (-1,) + flat_logits.shape[2:])
    return flat_logits, new_cache

class EncoderDecoderBEGpClassifierModel(EncoderDecoderBEClassifierModel,
                                        gp_models.EncoderDecoderGPModel):
  """A wrapper of EncoderDecoderClassifierModel for BatchEnsemble and GP."""

  def loss_fn(
      self,
      params,
      batch,
      dropout_rng,
  ):
    target_tokens = batch['decoder_target_tokens']
    # Tile the labels for batch ensembles.
    ens_size = self.module.ens_size
    batch['decoder_target_tokens'] = jnp.tile(target_tokens, [ens_size] + [1] *
                                              (target_tokens.ndim - 1))
    loss_weights = batch['decoder_loss_weights']
    if loss_weights is not None:
      batch['decoder_loss_weights'] = jnp.tile(loss_weights, [ens_size] + [1] *
                                               (loss_weights.ndim - 1))
    return gp_models.EncoderDecoderGPModel.loss_fn(self, params, batch,
                                                   dropout_rng)

  def get_initial_variables(
      self,
      rng: jnp.ndarray,
      input_shapes: Mapping[str, Array],
      input_types: Optional[Mapping[str, jnp.dtype]] = None
  ) -> flax_scope.FrozenVariableDict:
    initial_variables = gp_models.EncoderDecoderGPModel.get_initial_variables(
        self, rng=rng, input_shapes=input_shapes, input_types=input_types)
    return initial_variables

class EncoderDecoderBEBeamScoreModel(ub_models.EncoderDecoderBeamScoreModel,  # pytype: disable=signature-mismatch  # overriding-parameter-count-checks
                                     EncoderDecoderBEClassifierModel):
  """A wrapper of EncoderDecoderClassifierModel to support BatchEnsemble loss."""

  def loss_fn(self, params, batch, dropout_rng):
    return EncoderDecoderBEClassifierModel.loss_fn(self, params, batch,
                                                   dropout_rng)

  def _compute_argmax_score(
      self,
      params: t5x_models.PyTreeDef,
      batch: Mapping[str, jnp.ndarray],
      return_intermediates: bool = False,
      dropout_rng: Optional[jnp.ndarray] = None,
      ensemble_probs: bool = True,
  ) -> Union[jnp.ndarray, Tuple[jnp.ndarray, Mapping[str, Any]]]:
    """Compute class logits on a batch."""
    return EncoderDecoderBEClassifierModel._compute_argmax_score(
        self,
        params,
        batch,
        return_intermediates=return_intermediates,
        dropout_rng=dropout_rng,
        ensemble_probs=ensemble_probs)

  def _compute_logits_from_slice(self,
                                 decoding_state,
                                 params,
                                 encoded_inputs,
                                 raw_inputs,
                                 max_decode_length,
                                 rngs=None,
                                 ensemble_probs=True):
    """Token slice to logits from decoder model."""
    return EncoderDecoderBEClassifierModel._compute_logits_from_slice(
        self,
        decoding_state,
        params,
        encoded_inputs,
        raw_inputs,
        max_decode_length,
        rngs=rngs,
        ensemble_probs=ensemble_probs)

class EncoderDecoderBEGpBeamScoreModel(EncoderDecoderBEBeamScoreModel,  # pytype: disable=signature-mismatch  # overriding-parameter-count-checks
                                       EncoderDecoderBEGpClassifierModel):
  """A wrapper of EncoderDecoderBeamScoreModel for BatchEnsemble and GP."""

  def loss_fn(self, params, batch, dropout_rng):
    return EncoderDecoderBEGpClassifierModel.loss_fn(self, params, batch,
                                                     dropout_rng)

  def get_initial_variables(
      self,
      rng: jnp.ndarray,
      input_shapes: Mapping[str, Array],
      input_types: Optional[Mapping[str, jnp.dtype]] = None
  ) -> flax_scope.FrozenVariableDict:
    initial_variables = EncoderDecoderBEGpClassifierModel.get_initial_variables(
        self, rng=rng, input_shapes=input_shapes, input_types=input_types)
    return initial_variables


import tkinter as tk
import random
plocha=tk.Canvas(width=1000,height=500)
n=int(input("Zadaj počet napísov (min. 15):"+"\n"))
plocha.pack()
if n<15:
    print("Chyba!!! Zadané číslo musí byť min.15!")
else:
    for i in range(n):
        x=random.randint(50,950)
        y=random.randint(50,450)
        veľkosť=random.randint(10,30)
        veľkosť_písma=f'Arial {veľkosť} bold'
        plocha.create_text(x,y,text="STREDA",fill="green",angle="-30",font=veľkosť_písma)

print()
input()
quit()


"""
File: class_reviews.py
Name:黃稚程 mike
-------------------------------
At the beginning of this program, the user is asked to input
the class name (either SC001 or SC101).
Attention: your program should be case-insensitive.
If the user input -1 for class name, your program would output
the maximum, minimum, and average among all the inputs.
"""
EXIT = '-1'

def main():
    """
    This function will individually calculate max, min, average of score of the two class, SC001 and SC101.
    """
    a = input("Which class? ")
    a = a.upper()
    Max001 = 0
    Min001 = 101
    Total001 = 0
    number001 = 0
    Max101 = 0
    Min101 = 101
    Total101 = 0
    number101 = 0
    while a != EXIT:
        b = int(input("Score: "))
        if a == "SC001":
            number001 += 1
            Total001 += b
            if b >= Max001:
                Max001 = b
            if b < Min001:
                Min001 = b
        if a == "SC101":
            number101 += 1
            Total101 += b
            if b >= Max101:
                Max101 = b
            if b < Min101:
                Min101 = b
        a = input("Which class? ")
        a = a.upper()
    if number001 == 0 and number101 == 0:
        print("No class scores were entered")
    else:
        if number001 != 0:
            print("==========================SC001==========================")
            print("Max (001): "+str(Max001))
            print("Min (001): "+str(Min001))
            avg001 = Total001 / number001
            print("Avg (001): "+str(avg001))
        else:
            print("==========================SC001==========================")
            print("No score for SC001")
        if number101 != 0:
            print("==========================SC101==========================")
            print("Max (101): " + str(Max101))
            print("Min (101): "+str(Min101))
            avg101 = Total101 / number101
            print("Avg (101): " + str(avg101))
        else:
            print("==========================SC101==========================")
            print("No score for SC101")

#####  DO NOT EDIT THE CODE BELOW THIS LINE  #####
if __name__ == '__main__':
    main()