#!/usr/bin/env python

import fileinput

def compute_row(line):
    """Compute the row of the seat."""
    low: int = 0
    high: int = 127
    for char in line[:7]:
        diff: int = high - low
        if char == 'F':
            # lower half
            high -= int(diff / 2 + 0.5)

        elif char == 'B':
            # upper half
            low += int(diff / 2 + 0.5)
    return high

def compute_col(line):
    """Compute the column of the seat."""
    low: int = 0
    high: int = 7
    for char in line[7:]:
        diff: int = high - low
        if char == 'L':
            # lower half
            high -= int(diff / 2 + 0.5)
        elif char == 'R':
            # upper half
            low += int(diff / 2 + 0.5)
    return high

def main():
    IDs = []
    for line in fileinput.input():
        line = line.strip()
        # invalid input if the line isn't 7+3 characters long
        if len(line) != 10:
            continue
        row = compute_row(line)
        col = compute_col(line)
        seatID = row * 8 + col
        IDs.append(seatID)

    IDs.sort()  # sort the list so the accurate first ID can be asserted
    search = IDs[0]
    my_seat = 0
    for i, ID in enumerate(IDs):
        if ID != search + i:
            my_seat = search + i
            break

    print(my_seat)

if __name__ == '__main__':
    main()


from typing import Dict, List, Tuple, Union

from sqllineage.core.holders import SubQueryLineageHolder
from sqllineage.core.models import Column, Path, SubQuery, Table
from sqllineage.exceptions import SQLLineageException
from sqllineage.utils.constant import EdgeType

class SourceHandlerMixin:
    tables: List[Union[Path, SubQuery, Table]]
    columns: List[Column]
    union_barriers: List[Tuple[int, int]]

    def end_of_query_cleanup(self, holder: SubQueryLineageHolder) -> None:
        for i, tbl in enumerate(self.tables):
            holder.add_read(tbl)
        self.union_barriers.append((len(self.columns), len(self.tables)))
        for i, (col_barrier, tbl_barrier) in enumerate(self.union_barriers):
            prev_col_barrier, prev_tbl_barrier = (
                (0, 0) if i == 0 else self.union_barriers[i - 1]
            )
            col_grp = self.columns[prev_col_barrier:col_barrier]
            tbl_grp = self.tables[prev_tbl_barrier:tbl_barrier]
            tgt_tbl = None
            if holder.write:
                if len(holder.write) > 1:
                    raise SQLLineageException
                tgt_tbl = list(holder.write)[0]
            if tgt_tbl:
                for tgt_col in col_grp:
                    tgt_col.parent = tgt_tbl
                    for src_col in tgt_col.to_source_columns(
                        self.get_alias_mapping_from_table_group(tbl_grp, holder)
                    ):
                        holder.add_column_lineage(src_col, tgt_col)

    @classmethod
    def get_alias_mapping_from_table_group(
        cls,
        table_group: List[Union[Path, Table, SubQuery]],
        holder: SubQueryLineageHolder,
    ) -> Dict[str, Union[Path, Table, SubQuery]]:
        """
        A table can be referred to as alias, table name, or database_name.table_name, create the mapping here.
        For SubQuery, it's only alias then.
        """
        return {
            **{
                tgt: src
                for src, tgt, attr in holder.graph.edges(data=True)
                if attr.get("type") == EdgeType.HAS_ALIAS and src in table_group
            },
            **{
                table.raw_name: table
                for table in table_group
                if isinstance(table, Table)
            },
            **{str(table): table for table in table_group if isinstance(table, Table)},
        }


import csv
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
import datetime
import openpyxl

wb = openpyxl.Workbook()    # 建立空白的 Excel 活页簿物件
wb.save('empty.xlsx')
wb = openpyxl.load_workbook('empty.xlsx', data_only=True) #读取excel

#防止excel资料表被洗掉
#dt = datetime.datetime.now()
#excelNameTime = str(dt.year) +'年'+str(dt.month)+'月'+str(dt.day)+'日'+str(dt.hour)+'点'+str(dt.minute)+'分'
#wb = openpyxl.Workbook()    # 建立空白的 Excel 活页簿物件
#wb.save('empty.xlsx'+excelNameTime)
#wb = openpyxl.load_workbook('empty.xlsx'+excelNameTime, data_only=True) #读取excel

class PrintExcel:
    #印标题
    def title(driver):
        data = [["测试内容","测试结果","备注","测试时间"]]
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                # 逐笔添加到最后一列
        wb.save('empty.xlsx')

    #检测测试时间
    def testTime(driver):
        dt = datetime.datetime.now()
        time = str(dt.year) +'年'+str(dt.month)+'月'+str(dt.day)+'日'+str(dt.hour)+'点'+str(dt.minute)+'分'
        return time

    #测试公司
    def testCompany(driver,testName ,result):
        data = [[testName ,result ,"" ,PrintExcel.testTime(driver)]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')

    #印出零股测试结果
    def testOddLot(driver,companyName,result):
        data = [[companyName + " 零股名称测试结果" ,result , "" ,PrintExcel.testTime(driver)]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')

    #印出K线测试结果
    def testKLine(driver,companyName,result):
        data = [[companyName + " K线名称测试结果" ,result , "" ,PrintExcel.testTime(driver)]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')

    #印出外资、投信...等测试资料
    def testNumber(driver,testNum,result,company,compareName):
        data = [[ company + " " + compareName + " " + testNum ,result , "" ,PrintExcel.testTime(driver) ]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')

    #印出买入、卖出测试结果
    def clickBuyAndSell(driver,companyName,testName,result):

        data = [[ companyName + testName ,result , "" ,PrintExcel.testTime(driver) ]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')

    def error(driver):
        data = [[ "无法找到资料或发生错误" ,PrintExcel.testTime(driver) ]]
        #要写入的资料表
        sheet=wb['Sheet']
        for i in data:
            sheet.append(i)                   # 逐笔添加到最后一列

        wb.save('empty.xlsx')


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

from django.shortcuts import render
from django.core.urlresolvers import reverse
from django.http import HttpResponse, JsonResponse
from ..models.journal import Student_visiting
from ..models.monthjournal import MonthJournal
from ..models.students import Student
from ..models.groups import Group
from django.views.generic.base import TemplateView
from datetime import datetime, date
from dateutil.relativedelta import relativedelta
from calendar import monthrange, weekday, day_abbr
from ..views.paginator import page_scroll
import pdb
from ..util import get_current_group

class JournalView(TemplateView):
	template_name = 'students/journal.html'

	def get_context_data(self, **kwargs):
		context = super(JournalView, self).get_context_data(**kwargs)

		if self.request.GET.get('month'):
			month = datetime.strptime(self.request.GET['month'], '%Y-%m-%d').date()
		else:
			today = datetime.today()
			month = date(today.year, today.month, 1)

		next_month = month + relativedelta(months=1)
		prev_month = month - relativedelta(months=1)
		context['prev_month'] = prev_month.strftime('%Y-%m-%d')
		context['next_month'] = next_month.strftime('%Y-%m-%d')
		context['year'] = month.year
		context['cur_month'] = month.strftime('%Y-%m-%d')
		context['month_verbose'] = month.strftime('%B')

		myear, mmonth = month.year, month.month
		number_of_days = monthrange(myear,mmonth)[1]
		context['month_header'] = [
			{'day': d, 'verbose': day_abbr[weekday(myear,mmonth,d)][:2]}
				for d in range(1, number_of_days+1)]

		if kwargs.get('pk'):
			queryset = [Student.objects.get(pk=kwargs['pk'])]
		else:
			current_group = get_current_group(self.request)
			if current_group:
				queryset = Student.objects.filter(student_group=current_group)
			else:
				queryset = Student.objects.all()

		order_by = self.request.GET.get('order_by', '')
		if order_by:
			queryset = queryset.order_by(order_by)
			if self.request.GET.get('reverse', '') == '1':
				queryset = queryset.reverse()

		update_url = reverse('journal')

		students = []

		for student in queryset:
			try:
				journal = MonthJournal.objects.get(student=student, date=month)
			except:
				journal = None
			days = []
			for day in range(1,number_of_days+1):
				days.append({
					'day': day,
					'present': journal and getattr(journal, 'present_day%d'
						% day, False) or False,
					'date': date(myear, mmonth, day).strftime('%Y-%m-%d'),
					'verbose_date': date(myear, mmonth, day).strftime('%w'),
					})
			students.append({
				'full_name': u'%s %s' % (student.first_name, student.last_name),
				'days': days,
				'id': student.id,
				'update_url': update_url,
				})

		context['pages'] = page_scroll(students, 10)

		page = int(self.request.GET.get('page', '1'))
		context['page'] = (page - 1) * 10
		if len(context['pages']) <= 1:
			context['students'] = students
		else:
			context['students'] = students[(page - 1)*10:page*10]

		return context

	def post(self, request, *args, **kwargs):
		data = request.POST
		current_date = datetime.strptime(data['date'], '%Y-%m-%d').date()
		month = date(current_date.year, current_date.month, 1)
		present = data['present'] and True or False
		student = Student.objects.get(pk=data['pk'])
		journal = MonthJournal.objects.get_or_create(student=student, date=month)[0]

		setattr(journal, 'present_day%d' % current_date.day, present)
		journal.save()

		return JsonResponse({'status': 'success'})

def journal_list(request):
	students = Student_visiting.objects.all()

	order_by = request.GET.get('order_by', '')
	if order_by in ('id', 'student_name__first_name'):
		students = students.order_by(order_by)
		if request.GET.get('reverse', '') == '1':
			students = students.reverse()
	else:
		students = students.order_by('id')

	pages = []
	k = 0
	if not students.count() % 3 == 0:
		k = 1
	for i in range(students.count() / 5 + k):
		pages.append(str(i+1))

	number_page = int(request.GET.get('page', '1'))
	if number_page > len(pages):
		number_page = len(pages) - 3
		number_page = len(pages)
	students = students[number_page * 3 - 3: number_page * 3]

	days = '111111111111111111111111111111'

	groups = Group.objects.all()
	return render(request, 'students/journal_list.html', {'students': students, 'groups': groups, 'pages': pages, 'days': days})


from django.db import models

class Etiqueta(models.Model):
    nombre = models.CharField(max_length=200, default="", help_text="")

    class Meta:
        ordering = ['-id']
        db_table = 'etiquetas'
        verbose_name_plural = "etiquetas"

    class JSONAPIMeta:
        resource_name = 'etiquetas'

    def __str__(self):
        return self.nombre


#!/usr/bin/env python

import sys
import math
from random import *
from math import *

from pyx import canvas, path, deco, trafo, style, text, color, unit, epsfile, deformer

rgb = color.rgb
rgbfromhexstring = color.rgbfromhexstring

red, green, blue, yellow = (rgb.red,
    rgbfromhexstring("#008000"),
    rgb.blue, rgb(0.75, 0.75, 0))

blue = rgb(0., 0., 0.8)
lred = rgb(1., 0.4, 0.4)
lgreen = rgb(0.4, 0.8, 0.2)

text.set(mode="latex")
#text.set(docopt="10pt")
text.preamble(r'\usepackage{amsfonts}')
#text.preamble(r"\def\I{\mathbb{I}}")

c = canvas.canvas()

l = 4
my = 1.2
mx = 0.9

coords = {}
for i in range(-1, l):
  for j in range(-1, l):
   for k in range(2):
    x = 2*j + i
    y = 1.7*i + k
    y *= my
    x *= mx
    coords[i, j, k] = (x, y)
    #for di in (-l, 0, l):
    #  for dj in (-l, 0, l):
    #    coords[i+di, j+dj, k] = (x, y)

radius = 0.45
roff = 0.25
ta = [text.halign.boxcenter, text.valign.middle]

for i in range(l-1):

    x0, y0 = coords[i, 0, 0]
    x1, _ = coords[i, l-2, 0]

    c.stroke(path.line(x0-3*radius, y0, x1+0*radius, y0), [style.linestyle.dashed])
    c.text(x0-3*radius, y0+0.1, "$i=%s$"%(i+1))

    c.text(x1+2*radius, y0+0.1, "$k=1$", [text.valign.top])

    _, y0 = coords[i, 0, 1]
    #c.stroke(path.line(x0, y0, x1+3*radius, y0), [style.linestyle.dashed])
    c.text(x1+2*radius, y0+0.1, "$k=2$", [text.valign.top])

for j in range(l-1):
    x0, y0 = coords[0, j, 0]
    x1, y1 = coords[l-1, j, 0]

    c.stroke(path.line(x0, y0, x1, y1), [style.linestyle.dotted])
    c.text(x1-1.0, y1-0.1, "$j=%s$"%(j+1))

for i in range(l-1):
  for j in range(l-1):

    k = 0
    x, y = coords[i, j, k]
    c.fill(path.circle(x, y, 1.2*radius), [color.rgb.white])

    k = 1
    x, y = coords[i, j, k]
    c.fill(path.circle(x, y, 1.2*radius), [color.rgb.white])

xcoords = {}
ycoords = {}
zcoords = {}
for i in range(l):
  for j in range(l-1):

    k = 0
    x, y = coords[i, j, k]
    xcoords[i, j, k] = xc, yc = (x, y+roff)
    ycoords[i, j, k] = xc, yc = (x+0.75**0.5*roff, y-0.5*roff)
    zcoords[i, j, k] = xc, yc = (x-0.75**0.5*roff, y-0.5*roff)

    k = 1
    x, y = coords[i, j, k]
    xcoords[i, j, k] = xc, yc = (x, y-roff)
    ycoords[i, j, k] = xc, yc = (x-0.75**0.5*roff, y+0.5*roff)
    zcoords[i, j, k] = xc, yc = (x+0.75**0.5*roff, y+0.5*roff)

la = [style.linewidth(0.3), style.linecap.round]
for i in range(l-1):
  for j in range(l-1):

    x0, y0 = xcoords[i, j, 0]
    x1, y1 = xcoords[i, j, 1]
    c.stroke(path.line(x0, y0, x1, y1), la+[lgreen])

    x0, y0 = ycoords[i, j, 0]
    if (i-1, j+1, 1) in ycoords:
        x1, y1 = ycoords[i-1, j+1, 1]
        c.stroke(path.line(x0, y0, x1, y1), la+[lgreen])

    x0, y0 = zcoords[i, j, 0]
    if (i-1, j, 1) in zcoords:
        x1, y1 = zcoords[i-1, j, 1]
        c.stroke(path.line(x0, y0, x1, y1), la+[lgreen])

for i in range(l-1):
  for j in range(l-1):

    k = 0
    x, y = coords[i, j, k]
    c.stroke(path.circle(x, y, radius))

    xc, yc = xcoords[i, j, k]
    c.text(xc, yc, "$X$", ta)
    xc, yc = ycoords[i, j, k]
    c.text(xc, yc, "$Y$", ta)
    xc, yc = zcoords[i, j, k]
    c.text(xc, yc, "$Z$", ta)

    k = 1
    x, y = coords[i, j, k]
    c.stroke(path.circle(x, y, radius))

    xc, yc = xcoords[i, j, k]
    c.text(xc, yc, "$X$", ta)
    xc, yc = ycoords[i, j, k]
    c.text(xc, yc, "$Y$", ta)
    xc, yc = zcoords[i, j, k]
    c.text(xc, yc, "$Z$", ta)

c.writePDFfile("fig_00")

c = canvas.canvas()

X, Y, Z = "$X$ $Y$ $Z$".split()

xoff = 0.25
yoff = 0.05

op0 = [
    (0, 0, 0, X),
    (0, 0, 1, Y),
    (1, 0, 0, Y),
    (1, 0, 1, Y),
    (2, 0, 0, Y),
    (2, 0, 1, Y),
    (3, 0, 0, X),
    (2, 1, 1, X),
    (3, 1, 0, X),
    (2, 2, 1, X),
    (3, 2, 0, X),
    (2, 3, 1, Y),
]

for idx in range(len(op0)-1):
    x0, y0 = coords[op0[idx][:3]]
    x1, y1 = coords[op0[idx+1][:3]]
    c.stroke(path.line(x0-xoff, y0+yoff, x1-xoff, y1+yoff), la+[lgreen])

for idx in range(len(op0)):
    i, j, k, opc = op0[idx]
    x, y = coords[i, j, k]
    c.text(x-xoff, y+yoff, opc, ta)

op1 = [
    (0, 0, 0, X),
    (0, 0, 1, Y),
    (1, 0, 0, Y),
    (1, 0, 1, Y),
    (2, 0, 0, X),
    (1, 1, 1, X),
    (2, 1, 0, X),
    (1, 2, 1, X),
    (2, 2, 0, X),
    (1, 3, 1, X),
    (2, 3, 0, Z),
]

for idx in range(len(op1)-1):
    x0, y0 = coords[op1[idx][:3]]
    x1, y1 = coords[op1[idx+1][:3]]
    c.stroke(path.line(x0+xoff, y0-yoff, x1+xoff, y1-yoff), la+[lgreen])

for idx in range(len(op1)):
    i, j, k, opc = op1[idx]
    x, y = coords[i, j, k]
    c.text(x+xoff, y-yoff, opc, ta)

for i in range(l):
  for j in range(l):

    if (i,j)==(l-1,l-1):
        continue

    k = 0
    x, y = coords[i, j, k]
    c.stroke(path.circle(x, y, radius))

    if i==l-1:
        continue

    k = 1
    x, y = coords[i, j, k]
    c.stroke(path.circle(x, y, radius))

x, y = coords[l-2,l-1,0]
c.text(x+1.2*radius, y-2.*radius, "$g_{341}$", ta)
x, y = coords[l-2,l-1,1]
c.text(x+1.0*radius, y+2.*radius, "$g_{342}$", ta)

c.writePDFfile("fig_01")


import streamlit as st
import tensorflow.keras
from PIL import Image, ImageOps
import numpy as np
from pycaret.classification import load_model, predict_model
import pandas as pd
import cv2
import os

threshold = 0.95
width = 700

# Disable scientific notation for clarity
np.set_printoptions(suppress=True)

# Load the model
model_teachable = tensorflow.keras.models.load_model('keras_model1.h5')
model_ml = load_model('pycaret_model')

# Create the array of the right shape to feed into the keras model
# The 'length' or number of images you can put into the array is
# determined by the first position in the shape tuple, in this case 1.
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)

@st.cache(allow_output_mutation=True)
def clasify(image):
    # resize the image to a 224x224 with the same strategy as in TM2:
    # resizing the image to be at least 224x224 and then cropping from the center
    size = (224, 224)
    image = ImageOps.fit(image, size, Image.ANTIALIAS)

    # turn the image into a numpy array
    image_array = np.asarray(image)
    if image_array.shape == (224, 224, 3):
        # display the resized image
        # image.show()

        # Normalize the image
        normalized_image_array = (image_array.astype(np.float32) / 127.0) - 1

        # Load the image into the array
        data[0] = normalized_image_array

        # run the inference
        prediction = model_teachable.predict(data)
        return prediction
    else:
        pass

def normalize_histograms(im):  # normalizes the histogram of images
    im1 = im.copy()
    for i in range(3):
        imi = im[:, :, i]
        # print(imi.shape)
        minval = np.min(imi)
        maxval = np.max(imi)
        # print(minval,maxval)
        imrange = maxval - minval
        im1[:, :, i] = (255 / (imrange + 0.0001) * (
                imi - minval))  # imi-minval will turn the color range between 0-imrange, and the scaleing will stretch the range between 0-255
    return im1

######################################################################
# This following function reads the images from file,
# auto crops the image to its relevant content, then normalizes
# the histograms of the cropped images
######################################################################

def read_and_process_image(filename):
    path = "analizer.png"
    im_array = np.array(filename)
    cv2.imwrite(path, cv2.cvtColor(im_array, cv2.COLOR_RGB2BGR))
    im = cv2.imread(path)

    # The following steps re needed for auto cropping the black paddings in the images

    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)  # convert 2 grayscale
    _, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)  # turn it into a binary image
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # find contours
    if len(contours) != 0:
        # find the biggest area
        cnt = max(contours, key=cv2.contourArea)

        # find the bounding rect
        x, y, w, h = cv2.boundingRect(cnt)

        crop = im[y:y + h, x:x + w]  # crop image
        # crop1=cv2.resize(crop,(im_size,im_size)) # resize to im_size X im_size size
        crop = normalize_histograms(crop)
        return crop
    else:
        return (normalize_histograms(im))

##################################################################################
#### The following functions are for extracting features from the images #########
##################################################################################

# histogram statistics (mean, standard deviations, energy, entropy, log-kurtosis)

def histogram_statistics(hist):
    # hist= cv2.calcHist([gr],[0],None,[256],[0,256])
    hist = hist / np.sum(hist)  # probabilities
    hist = hist.reshape(-1)
    hist[hist == 0] = 10 ** -20  # replace zeros with a small number
    mn = np.sum([i * hist[i] for i in range(len(hist))])  # mean
    std_dev = np.sqrt(np.sum([((i - mn) ** 2) * hist[i] for i in range(len(hist))]))  # standard deviation
    energy = np.sum([hist[i] ** 2 for i in range(len(hist))])  # energy
    entropy = np.sum([hist[i] * np.log(hist[i]) for i in range(len(hist))])  # entropy
    kurtosis = np.log(np.sum([(std_dev ** -4) * ((i - mn) ** -4) * hist[i] for i in range(len(hist))]))  # kurtosis
    return [mn, std_dev, energy, entropy, kurtosis]

#################################################################
# create thresholding based features, the idea is to hand engineer some features based on adaptive thresholding.
# After looking at the images it appeared  that adaptive thresholding may
# leave different artifacts in the processed images, we can extract several features from these artifacts
##################################################################

def thresholding_based_features(im, imsize, quartiles):
    im = cv2.resize(im, (imsize, imsize))
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    w = 11  # window
    t = 5  # threshold
    counts = []
    th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, w,
                               t)  # adaptive gaussian threshold the image
    th = cv2.bitwise_not(
        th)  # invert the image (the black pixels will turn white and the white pixels will turn black)
    contours, hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL,
                                           cv2.CHAIN_APPROX_SIMPLE)  # find cntours in the image
    # print(len(contours))

    q = np.zeros(len(quartiles))  # quartiles of contours will be stored here

    for cnt in contours:
        area = cv2.contourArea(cnt)  # calculate the area of the contours
        if area < 40000:  # Exclude contours that are too big, generally these are the image outlines
            counts.append(area)
    if len(counts) > 1:
        q = np.quantile(np.array(counts), quartiles)  # contour quartiles

    return (q, len(counts), np.sum(th) / (255 * th.shape[0] * th.shape[
        1]))  # return the contour quartiles, number of contours, proportion of white pixels in the thresholded images
    # counts.append(np.sum(th)/(normalizing_factor*(th.shape[0]*th.shape[1])))

##########################################################################
############ The following code creates the various features #############
##########################################################################

# color averages
@st.cache(allow_output_mutation=True)
def various_features(image_ml):
    B = []
    G = []
    R = []

    # mini 16 bin histograms
    hist_B = []
    hist_G = []
    hist_R = []

    # statistics fom full 256 bin shitogram
    hist_feat_B = []
    hist_feat_G = []
    hist_feat_R = []
    hist_feat_GS = []

    # thresholding based features
    mean_pixels = []  # proportion of white pixels
    contour_quartiles = []  # contour area quartiles
    no_of_contours = []  # total number of contours

    quartiles = np.arange(0.1, 1, 0.1)  # contour area quartiles
    bins = 16  # mini histogram bins

    im = read_and_process_image(image_ml)
    # im_yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV)

    # equalize the histogram of the Y channel
    # im_yuv[:,:,0] = cv2.equalizeHist(im_yuv[:,:,0])

    # convert the YUV image back to RGB format
    # im = cv2.cvtColor(im_yuv, cv2.COLOR_YUV2BGR)

    # median color
    B.append(np.median(im[:, :, 0]))
    G.append(np.median(im[:, :, 1]))
    R.append(np.median(im[:, :, 2]))

    # histograms
    hist_B.append(cv2.calcHist([im], [0], None, [bins], [0, 256]) / (im.size / 3))
    hist_G.append(cv2.calcHist([im], [1], None, [bins], [0, 256]) / (im.size / 3))
    hist_R.append(cv2.calcHist([im], [2], None, [bins], [0, 256]) / (im.size / 3))

    # more histogram features

    hist_feat_B.append(histogram_statistics(cv2.calcHist([im], [0], None, [256], [0, 256])))
    hist_feat_G.append(histogram_statistics(cv2.calcHist([im], [1], None, [256], [0, 256])))
    hist_feat_R.append(histogram_statistics(cv2.calcHist([im], [2], None, [256], [0, 256])))

    gr = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    gr = cv2.equalizeHist(gr)
    hist_feat_GS.append(histogram_statistics(cv2.calcHist([gr], [0], None, [256], [0, 256])))

    # threshold featues
    q, nc, m = thresholding_based_features(im, 256, quartiles)
    mean_pixels.append(m)
    contour_quartiles.append(q)
    no_of_contours.append(nc)

    # create feature vectors
    width_of_features = 3 * bins + len(quartiles) + 2 + 20  # 20 features are histogram statistics

    X = np.zeros((1, width_of_features))   # this is where all features will be stored

    X[0, 0:bins] = hist_B[0].reshape(-1)
    X[0, bins:2 * bins] = hist_G[0].reshape(-1)
    X[0, 2 * bins:3 * bins] = hist_R[0].reshape(-1)
    X[0, 3 * bins:3 * bins + len(quartiles)] = contour_quartiles[0].reshape(-1)
    X[0, 3 * bins + len(quartiles)] = mean_pixels[0]
    X[0, 3 * bins + len(quartiles) + 1] = no_of_contours[0]
    start = 3 * bins + len(quartiles) + 2
    X[0, start:start + 5] = hist_feat_B[0]
    X[0, start + 5:start + 10] = hist_feat_G[0]
    X[0, start + 10:start + 15] = hist_feat_R[0]
    X[0, start + 15:start + 20] = hist_feat_B[0]

    return X

#######################################################################
########### Divide the dataset into 70%train and 30% test data########
######################################################################

# Parameters to pycaret
# index = int(len(labels1) * 0.7)
#
# X_train = X[:index, :]
# Y_train1 = labels1[:index]
#
# X_test = X[index:, :]
# Y_test1 = labels1[index:]

def teachable_machine_model():
    st.subheader("Validación con modelo generado con Teachable Machine")
    # Upload image
    uploaded_file = st.file_uploader("Ingrese una imagen para analizar", type='png')

    if uploaded_file is not None:
        image = Image.open(uploaded_file)
        st.image(image, caption="El archivo ha sido cargado exitosamente...", width=width)
        pred = clasify(image)

        if pred is not None:
            # Cataract
            if pred[0][0] >= threshold:
                st.success("Catarata with probability: {}".format(str(pred[0][0])))
            # Normal
            elif pred[0][1] >= threshold:
                st.success("Normal with probability: {}".format(str(pred[0][1])))
            else:
                st.warning(
                    "La probabilidad no es confiable en la validacion de la imagen con las siguientes "
                    "valoraciones: \n "
                    "Catarata: {0} \n"
                    "Normal: {1}".format(pred[0][0], pred[0][1]))
        else:
            st.warning("ERROR image shape is not support")

        image.close()

def machine_learning_model():
    st.subheader("Clasificación mediante el modelo de aprendizaje de máquina")
    uploaded_file = st.file_uploader("Ingrese una imagen para analizar", type=None)

    if uploaded_file is not None:
        image_ml = Image.open(uploaded_file)
        st.image(image_ml, caption="El archivo ha sido cargado exitosamente...",
                 width=width)

        # Send to extract image caracters in dataset
        image_processing = various_features(image_ml)
        df_image_processing = pd.DataFrame(image_processing)
        predictions = predict_model(model_ml, df_image_processing)
        os.remove("/mnt/napster_disk/saturdays_ai/segunda_edicion/Proyecto/saturdays_second_edition/analizer.png")
        result = int(predictions['Label'])
        score = float(predictions['Score'])

        if result == 0:
            st.success("Es glaucoma con {0} de probabilidad".format(score))
        elif result == 1:
            st.success("Es normal con {0} de probabilidad".format(score))
        elif result == 2:
            st.success("Problemas con la retina con {0} de probabilidad".format(score))
        elif result == 3:
            st.success("Es catarata con {0} de probabilidad".format(score))

def main():
    # Desabilita el FileUploaderEncodingWarning This change will go in effect after August 15, 2020.
    st.set_option('deprecation.showfileUploaderEncoding', False)
    st.title("Detector de Cataratas ")

    # agrega la barra de al lado para seleccionar el modelo que deseamos utilizar
    activities = ["Modelo Teachable Machine", "Modelo ML"]
    choice = st.sidebar.selectbox("Seleccione el modelo a utilizar:", activities)

    if choice == "Modelo Teachable Machine":
        teachable_machine_model()
    elif choice == "Modelo ML":
        machine_learning_model()

if __name__ == "__main__":
    main()


#Reference https://github.com/sooftware/attentions
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import Tensor
import numpy as np
import math
from math import sqrt
from typing import Optional, Tuple

class ScaledDotProductAttention(nn.Module):
    """
    Scaled Dot-Product Attention proposed in "Attention Is All You Need"
    Compute the dot products of the query with all keys, divide each by sqrt(dim),
    and apply a softmax function to obtain the weights on the values
    Args: dim, mask
        dim (int): dimention of attention
        mask (torch.Tensor): tensor containing indices to be masked
    Inputs: query, key, value, mask
        - **query** (batch, q_len, d_model): tensor containing projection vector for decoder.
        - **key** (batch, k_len, d_model): tensor containing projection vector for encoder.
        - **value** (batch, v_len, d_model): tensor containing features of the encoded input sequence.
        - **mask** (-): tensor containing indices to be masked
    Returns: context, attn
        - **context**: tensor containing the context vector from attention mechanism.
        - **attn**: tensor containing the attention (alignment) from the encoder outputs.
    """
    def __init__(self, dim: int):
        super(ScaledDotProductAttention, self).__init__()
        self.sqrt_dim = np.sqrt(dim)

    def forward(self, query: Tensor,
                        key: Tensor,
                        value: Tensor,
                        mask: Optional[Tensor] = None) -> Tuple[Tensor, Tensor]:
        score = torch.bmm(query, key.transpose(1, 2)) / self.sqrt_dim

        if mask is not None:
            score.masked_fill_(mask.view(score.size()), -float('Inf'))

        attn = F.softmax(score, -1)
        context = torch.bmm(attn, value)
        return context, attn

class DotProductAttention(nn.Module):
    """
    Compute the dot products of the query with all values and apply a softmax function to obtain the weights on the values
    """
    def __init__(self, hidden_dim):
        super(DotProductAttention, self).__init__()

    def forward(self, query: Tensor, value: Tensor) -> Tuple[Tensor, Tensor]:
        batch_size, hidden_dim, input_size = query.size(0), query.size(2), value.size(1)

        score = torch.bmm(query, value.transpose(1, 2))
        attn = F.softmax(score.view(-1, input_size), dim=1).view(batch_size, -1, input_size)
        context = torch.bmm(attn, value)

        return context, attn

class AdditiveAttention(nn.Module):
    """
     Applies a additive attention (bahdanau) mechanism on the output features from the decoder.
     Additive attention proposed in "Neural Machine Translation by Jointly Learning to Align and Translate" paper.
     Args:
         hidden_dim (int): dimesion of hidden state vector
     Inputs: query, value
         - **query** (batch_size, q_len, hidden_dim): tensor containing the output features from the decoder.
         - **value** (batch_size, v_len, hidden_dim): tensor containing features of the encoded input sequence.
     Returns: context, attn
         - **context**: tensor containing the context vector from attention mechanism.
         - **attn**: tensor containing the alignment from the encoder outputs.
     Reference:
         - **Neural Machine Translation by Jointly Learning to Align and Translate**: https://arxiv.org/abs/1409.0473
    """
    def __init__(self, hidden_dim: int) -> None:
        super(AdditiveAttention, self).__init__()
        self.query_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
        self.key_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
        self.bias = nn.Parameter(torch.rand(hidden_dim).uniform_(-0.1, 0.1))
        self.score_proj = nn.Linear(hidden_dim, 1)

    def forward(self, query: Tensor, key: Tensor, value: Tensor) -> Tuple[Tensor, Tensor]:
        score = self.score_proj(torch.tanh(self.key_proj(key) + self.query_proj(query) + self.bias)).squeeze(-1)
        attn = F.softmax(score, dim=-1)
        context = torch.bmm(attn.unsqueeze(1), value)
        return context, attn

class LocationAwareAttention(nn.Module):
    """
    Applies a location-aware attention mechanism on the output features from the decoder.
    Location-aware attention proposed in "Attention-Based Models for Speech Recognition" paper.
    The location-aware attention mechanism is performing well in speech recognition tasks.
    We refer to implementation of ClovaCall Attention style.
    Args:
        hidden_dim (int): dimesion of hidden state vector
        smoothing (bool): flag indication whether to use smoothing or not.
    Inputs: query, value, last_attn, smoothing
        - **query** (batch, q_len, hidden_dim): tensor containing the output features from the decoder.
        - **value** (batch, v_len, hidden_dim): tensor containing features of the encoded input sequence.
        - **last_attn** (batch_size * num_heads, v_len): tensor containing previous timestep`s attention (alignment)
    Returns: output, attn
        - **output** (batch, output_len, dimensions): tensor containing the feature from encoder outputs
        - **attn** (batch * num_heads, v_len): tensor containing the attention (alignment) from the encoder outputs.
    Reference:
        - **Attention-Based Models for Speech Recognition**: https://arxiv.org/abs/1506.07503
        - **ClovaCall**: https://github.com/clovaai/ClovaCall/blob/master/las.pytorch/models/attention.py
    """
    def __init__(self, hidden_dim: int, smoothing: bool = True) -> None:
        super(LocationAwareAttention, self).__init__()
        self.hidden_dim = hidden_dim
        self.conv1d = nn.Conv1d(in_channels=1, out_channels=hidden_dim, kernel_size=3, padding=1)
        self.query_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
        self.value_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
        self.score_proj = nn.Linear(hidden_dim, 1, bias=True)
        self.bias = nn.Parameter(torch.rand(hidden_dim).uniform_(-0.1, 0.1))
        self.smoothing = smoothing

    def forward(self, query: Tensor, value: Tensor, last_attn: Tensor) -> Tuple[Tensor, Tensor]:
        batch_size, hidden_dim, seq_len = query.size(0), query.size(2), value.size(1)

        # Initialize previous attention (alignment) to zeros
        if last_attn is None:
            last_attn = value.new_zeros(batch_size, seq_len)

        conv_attn = torch.transpose(self.conv1d(last_attn.unsqueeze(1)), 1, 2)
        score = self.score_proj(torch.tanh(
                self.query_proj(query.reshape(-1, hidden_dim)).view(batch_size, -1, hidden_dim)
                + self.value_proj(value.reshape(-1, hidden_dim)).view(batch_size, -1, hidden_dim)
                + conv_attn
                + self.bias
        )).squeeze(dim=-1)

        if self.smoothing:
            score = torch.sigmoid(score)
            attn = torch.div(score, score.sum(dim=-1).unsqueeze(dim=-1))
        else:
            attn = F.softmax(score, dim=-1)

        context = torch.bmm(attn.unsqueeze(dim=1), value).squeeze(dim=1)  # Bx1xT X BxTxD => Bx1xD => BxD

        return context, attn

class MultiHeadLocationAwareAttention(nn.Module):
    """
    Applies a multi-headed location-aware attention mechanism on the output features from the decoder.
    Location-aware attention proposed in "Attention-Based Models for Speech Recognition" paper.
    The location-aware attention mechanism is performing well in speech recognition tasks.
    In the above paper applied a signle head, but we applied multi head concept.
    Args:
        hidden_dim (int): The number of expected features in the output
        num_heads (int): The number of heads. (default: )
        conv_out_channel (int): The number of out channel in convolution
    Inputs: query, value, prev_attn
        - **query** (batch, q_len, hidden_dim): tensor containing the output features from the decoder.
        - **value** (batch, v_len, hidden_dim): tensor containing features of the encoded input sequence.
        - **prev_attn** (batch_size * num_heads, v_len): tensor containing previous timestep`s attention (alignment)
    Returns: output, attn
        - **output** (batch, output_len, dimensions): tensor containing the feature from encoder outputs
        - **attn** (batch * num_heads, v_len): tensor containing the attention (alignment) from the encoder outputs.
    Reference:
        - **Attention Is All You Need**: https://arxiv.org/abs/1706.03762
        - **Attention-Based Models for Speech Recognition**: https://arxiv.org/abs/1506.07503
    """
    def __init__(self, hidden_dim: int, num_heads: int = 8, conv_out_channel: int = 10) -> None:
        super(MultiHeadLocationAwareAttention, self).__init__()
        self.hidden_dim = hidden_dim
        self.num_heads = num_heads
        self.dim = int(hidden_dim / num_heads)
        self.conv1d = nn.Conv1d(num_heads, conv_out_channel, kernel_size=3, padding=1)
        self.loc_proj = nn.Linear(conv_out_channel, self.dim, bias=False)
        self.query_proj = nn.Linear(hidden_dim, self.dim * num_heads, bias=False)
        self.value_proj = nn.Linear(hidden_dim, self.dim * num_heads, bias=False)
        self.score_proj = nn.Linear(self.dim, 1, bias=True)
        self.bias = nn.Parameter(torch.rand(self.dim).uniform_(-0.1, 0.1))

    def forward(self, query: Tensor, value: Tensor, last_attn: Tensor) -> Tuple[Tensor, Tensor]:
        batch_size, seq_len = value.size(0), value.size(1)

        if last_attn is None:
            last_attn = value.new_zeros(batch_size, self.num_heads, seq_len)

        loc_energy = torch.tanh(self.loc_proj(self.conv1d(last_attn).transpose(1, 2)))
        loc_energy = loc_energy.unsqueeze(1).repeat(1, self.num_heads, 1, 1).view(-1, seq_len, self.dim)

        query = self.query_proj(query).view(batch_size, -1, self.num_heads, self.dim).permute(0, 2, 1, 3)
        value = self.value_proj(value).view(batch_size, -1, self.num_heads, self.dim).permute(0, 2, 1, 3)
        query = query.contiguous().view(-1, 1, self.dim)
        value = value.contiguous().view(-1, seq_len, self.dim)

        score = self.score_proj(torch.tanh(value + query + loc_energy + self.bias)).squeeze(2)
        attn = F.softmax(score, dim=1)

        value = value.view(batch_size, seq_len, self.num_heads, self.dim).permute(0, 2, 1, 3)
        value = value.contiguous().view(-1, seq_len, self.dim)

        context = torch.bmm(attn.unsqueeze(1), value).view(batch_size, -1, self.num_heads * self.dim)
        attn = attn.view(batch_size, self.num_heads, -1)

        return context, attn

class MultiHeadAttention(nn.Module):
    """
    Multi-Head Attention proposed in "Attention Is All You Need"
    Instead of performing a single attention function with d_model-dimensional keys, values, and queries,
    project the queries, keys and values h times with different, learned linear projections to d_head dimensions.
    These are concatenated and once again projected, resulting in the final values.
    Multi-head attention allows the model to jointly attend to information from different representation
    subspaces at different positions.
    MultiHead(Q, K, V) = Concat(head_1, ..., head_h) · W_o
        where head_i = Attention(Q · W_q, K · W_k, V · W_v)
    Args:
        d_model (int): The dimension of keys / values / quries (default: 512)
        num_heads (int): The number of attention heads. (default: 8)
    Inputs: query, key, value, mask
        - **query** (batch, q_len, d_model): In transformer, three different ways:
            Case 1: come from previoys decoder layer
            Case 2: come from the input embedding
            Case 3: come from the output embedding (masked)
        - **key** (batch, k_len, d_model): In transformer, three different ways:
            Case 1: come from the output of the encoder
            Case 2: come from the input embeddings
            Case 3: come from the output embedding (masked)
        - **value** (batch, v_len, d_model): In transformer, three different ways:
            Case 1: come from the output of the encoder
            Case 2: come from the input embeddings
            Case 3: come from the output embedding (masked)
        - **mask** (-): tensor containing indices to be masked
    Returns: output, attn
        - **output** (batch, output_len, dimensions): tensor containing the attended output features.
        - **attn** (batch * num_heads, v_len): tensor containing the attention (alignment) from the encoder outputs.
    """
    def __init__(self, d_model: int = 512, num_heads: int = 8):
        super(MultiHeadAttention, self).__init__()

        assert d_model % num_heads == 0, "d_model % num_heads should be zero."

        self.d_head = int(d_model / num_heads)
        self.num_heads = num_heads
        self.scaled_dot_attn = ScaledDotProductAttention(self.d_head)
        self.query_proj = nn.Linear(d_model, self.d_head * num_heads)
        self.key_proj = nn.Linear(d_model, self.d_head * num_heads)
        self.value_proj = nn.Linear(d_model, self.d_head * num_heads)

    def forward(
            self,
            query: Tensor,
            key: Tensor,
            value: Tensor,
            mask: Optional[Tensor] = None
    ) -> Tuple[Tensor, Tensor]:
        batch_size = value.size(0)

        query = self.query_proj(query).view(batch_size, -1, self.num_heads, self.d_head)  # BxQ_LENxNxD
        key = self.key_proj(key).view(batch_size, -1, self.num_heads, self.d_head)      # BxK_LENxNxD
        value = self.value_proj(value).view(batch_size, -1, self.num_heads, self.d_head)  # BxV_LENxNxD

        query = query.permute(2, 0, 1, 3).contiguous().view(batch_size * self.num_heads, -1, self.d_head)  # BNxQ_LENxD
        key = key.permute(2, 0, 1, 3).contiguous().view(batch_size * self.num_heads, -1, self.d_head)      # BNxK_LENxD
        value = value.permute(2, 0, 1, 3).contiguous().view(batch_size * self.num_heads, -1, self.d_head)  # BNxV_LENxD

        if mask is not None:
            mask = mask.unsqueeze(1).repeat(1, self.num_heads, 1, 1)  # BxNxQ_LENxK_LEN

        context, attn = self.scaled_dot_attn(query, key, value, mask)

        context = context.view(self.num_heads, batch_size, -1, self.d_head)
        context = context.permute(1, 2, 0, 3).contiguous().view(batch_size, -1, self.num_heads * self.d_head)  # BxTxND

        return context, attn

class RelativeMultiHeadAttention(nn.Module):
    """
    Multi-head attention with relative positional encoding.
    This concept was proposed in the "Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context"
    Args:
        d_model (int): The dimension of model
        num_heads (int): The number of attention heads.
        dropout_p (float): probability of dropout
    Inputs: query, key, value, pos_embedding, mask
        - **query** (batch, time, dim): Tensor containing query vector
        - **key** (batch, time, dim): Tensor containing key vector
        - **value** (batch, time, dim): Tensor containing value vector
        - **pos_embedding** (batch, time, dim): Positional embedding tensor
        - **mask** (batch, 1, time2) or (batch, time1, time2): Tensor containing indices to be masked
    Returns:
        - **outputs**: Tensor produces by relative multi head attention module.
    """
    def __init__(
            self,
            d_model: int = 512,
            num_heads: int = 16,
            dropout_p: float = 0.1,
    ):
        super(RelativeMultiHeadAttention, self).__init__()
        assert d_model % num_heads == 0, "d_model % num_heads should be zero."
        self.d_model = d_model
        self.d_head = int(d_model / num_heads)
        self.num_heads = num_heads
        self.sqrt_dim = math.sqrt(d_model)

        self.query_proj = nn.Linear(d_model, d_model)
        self.key_proj = nn.Linear(d_model, d_model)
        self.value_proj = nn.Linear(d_model, d_model)
        self.pos_proj = nn.Linear(d_model, d_model, bias=False)

        self.dropout = nn.Dropout(p=dropout_p)
        self.u_bias = nn.Parameter(torch.Tensor(self.num_heads, self.d_head))
        self.v_bias = nn.Parameter(torch.Tensor(self.num_heads, self.d_head))
        torch.nn.init.xavier_uniform_(self.u_bias)
        torch.nn.init.xavier_uniform_(self.v_bias)

        self.out_proj = nn.Linear(d_model, d_model)

    def forward(
            self,
            query: Tensor,
            key: Tensor,
            value: Tensor,
            pos_embedding: Tensor,
            mask: Optional[Tensor] = None,
    ) -> Tensor:
        batch_size = value.size(0)

        query = self.query_proj(query).view(batch_size, -1, self.num_heads, self.d_head)
        key = self.key_proj(key).view(batch_size, -1, self.num_heads, self.d_head).permute(0, 2, 1, 3)
        value = self.value_proj(value).view(batch_size, -1, self.num_heads, self.d_head).permute(0, 2, 1, 3)
        pos_embedding = self.pos_proj(pos_embedding).view(batch_size, -1, self.num_heads, self.d_head)

        content_score = torch.matmul((query + self.u_bias).transpose(1, 2), key.transpose(2, 3))
        pos_score = torch.matmul((query + self.v_bias).transpose(1, 2), pos_embedding.permute(0, 2, 3, 1))
        pos_score = self._compute_relative_positional_encoding(pos_score)

        score = (content_score + pos_score) / self.sqrt_dim

        if mask is not None:
            mask = mask.unsqueeze(1)
            score.masked_fill_(mask, -1e9)

        attn = F.softmax(score, -1)
        attn = self.dropout(attn)

        context = torch.matmul(attn, value).transpose(1, 2)
        context = context.contiguous().view(batch_size, -1, self.d_model)

        return self.out_proj(context)

    def _compute_relative_positional_encoding(self, pos_score: Tensor) -> Tensor:
        batch_size, num_heads, seq_length1, seq_length2 = pos_score.size()
        zeros = pos_score.new_zeros(batch_size, num_heads, seq_length1, 1)
        padded_pos_score = torch.cat([zeros, pos_score], dim=-1)

        padded_pos_score = padded_pos_score.view(batch_size, num_heads, seq_length2 + 1, seq_length1)
        pos_score = padded_pos_score[:, :, 1:].view_as(pos_score)

        return pos_score

class CustomizingAttention(nn.Module):
    r"""
    Customizing Attention
    Applies a multi-head + location-aware attention mechanism on the output features from the decoder.
    Multi-head attention proposed in "Attention Is All You Need" paper.
    Location-aware attention proposed in "Attention-Based Models for Speech Recognition" paper.
    I combined these two attention mechanisms as custom.
    Args:
        hidden_dim (int): The number of expected features in the output
        num_heads (int): The number of heads. (default: )
        conv_out_channel (int): The dimension of convolution
    Inputs: query, value, last_attn
        - **query** (batch, q_len, hidden_dim): tensor containing the output features from the decoder.
        - **value** (batch, v_len, hidden_dim): tensor containing features of the encoded input sequence.
        - **last_attn** (batch_size * num_heads, v_len): tensor containing previous timestep`s alignment
    Returns: output, attn
        - **output** (batch, output_len, dimensions): tensor containing the attended output features from the decoder.
        - **attn** (batch * num_heads, v_len): tensor containing the alignment from the encoder outputs.
    Reference:
        - **Attention Is All You Need**: https://arxiv.org/abs/1706.03762
        - **Attention-Based Models for Speech Recognition**: https://arxiv.org/abs/1506.07503
    """

    def __init__(self, hidden_dim: int, num_heads: int = 4, conv_out_channel: int = 10) -> None:
        super(CustomizingAttention, self).__init__()
        self.hidden_dim = hidden_dim
        self.num_heads = num_heads
        self.dim = int(hidden_dim / num_heads)
        self.scaled_dot_attn = ScaledDotProductAttention(self.dim)
        self.conv1d = nn.Conv1d(1, conv_out_channel, kernel_size=3, padding=1)
        self.query_proj = nn.Linear(hidden_dim, self.dim * num_heads, bias=True)
        self.value_proj = nn.Linear(hidden_dim, self.dim * num_heads, bias=False)
        self.loc_proj = nn.Linear(conv_out_channel, self.dim, bias=False)
        self.bias = nn.Parameter(torch.rand(self.dim * num_heads).uniform_(-0.1, 0.1))

    def forward(self, query: Tensor, value: Tensor, last_attn: Tensor) -> Tuple[Tensor, Tensor]:
        batch_size, q_len, v_len = value.size(0), query.size(1), value.size(1)

        if last_attn is None:
            last_attn = value.new_zeros(batch_size * self.num_heads, v_len)

        loc_energy = self.get_loc_energy(last_attn, batch_size, v_len)  # get location energy

        query = self.query_proj(query).view(batch_size, q_len, self.num_heads * self.dim)
        value = self.value_proj(value).view(batch_size, v_len, self.num_heads * self.dim) + loc_energy + self.bias

        query = query.view(batch_size, q_len, self.num_heads, self.dim).permute(2, 0, 1, 3)
        value = value.view(batch_size, v_len, self.num_heads, self.dim).permute(2, 0, 1, 3)
        query = query.contiguous().view(-1, q_len, self.dim)
        value = value.contiguous().view(-1, v_len, self.dim)

        context, attn = self.scaled_dot_attn(query, value)
        attn = attn.squeeze()

        context = context.view(self.num_heads, batch_size, q_len, self.dim).permute(1, 2, 0, 3)
        context = context.contiguous().view(batch_size, q_len, -1)

        return context, attn

    def get_loc_energy(self, last_attn: Tensor, batch_size: int, v_len: int) -> Tensor:
        conv_feat = self.conv1d(last_attn.unsqueeze(1))
        conv_feat = conv_feat.view(batch_size, self.num_heads, -1, v_len).permute(0, 1, 3, 2)

        loc_energy = self.loc_proj(conv_feat).view(batch_size, self.num_heads, v_len, self.dim)
        loc_energy = loc_energy.permute(0, 2, 1, 3).reshape(batch_size, v_len, self.num_heads * self.dim)

        return loc_energy

class FullAttention(nn.Module):
    def __init__(self, mask_flag=True, factor=5, scale=None, attention_dropout=0.1, output_attention=False):
        super(FullAttention, self).__init__()
        self.scale = scale
        self.mask_flag = mask_flag
        self.output_attention = output_attention
        self.dropout = nn.Dropout(attention_dropout)

    def forward(self, queries, keys, values, attn_mask):
        B, L, H, E = queries.shape
        _, S, _, D = values.shape
        scale = self.scale or 1. / sqrt(E)

        scores = torch.einsum("blhe,bshe->bhls", queries, keys)

        if self.mask_flag:
            if attn_mask is None:
                attn_mask = TriangularCausalMask(B, L, device=queries.device)

            scores.masked_fill_(attn_mask.mask, -np.inf)

        A = self.dropout(torch.softmax(scale * scores, dim=-1))
        V = torch.einsum("bhls,bshd->blhd", A, values)

        if self.output_attention:
            return (V.contiguous(), A)
        else:
            return (V.contiguous(), None)

class ProbAttention(nn.Module):
    def __init__(self, mask_flag=True, factor=5, scale=None, attention_dropout=0.1, output_attention=False):
        super(ProbAttention, self).__init__()
        self.factor = factor
        self.scale = scale
        self.mask_flag = mask_flag
        self.output_attention = output_attention
        self.dropout = nn.Dropout(attention_dropout)

    def _prob_QK(self, Q, K, sample_k, n_top):  # n_top: c*ln(L_q)
        # Q [B, H, L, D]
        B, H, L_K, E = K.shape
        _, _, L_Q, _ = Q.shape

        # calculate the sampled Q_K
        K_expand = K.unsqueeze(-3).expand(B, H, L_Q, L_K, E)
        index_sample = torch.randint(L_K, (L_Q, sample_k))  # real U = U_part(factor*ln(L_k))*L_q
        K_sample = K_expand[:, :, torch.arange(L_Q).unsqueeze(1), index_sample, :]
        Q_K_sample = torch.matmul(Q.unsqueeze(-2), K_sample.transpose(-2, -1)).squeeze()

        # find the Top_k query with sparisty measurement
        M = Q_K_sample.max(-1)[0] - torch.div(Q_K_sample.sum(-1), L_K)
        M_top = M.topk(n_top, sorted=False)[1]

        # use the reduced Q to calculate Q_K
        Q_reduce = Q[torch.arange(B)[:, None, None],
                   torch.arange(H)[None, :, None],
                   M_top, :]  # factor*ln(L_q)
        Q_K = torch.matmul(Q_reduce, K.transpose(-2, -1))  # factor*ln(L_q)*L_k

        return Q_K, M_top

    def _get_initial_context(self, V, L_Q):
        B, H, L_V, D = V.shape
        if not self.mask_flag:
            # V_sum = V.sum(dim=-2)
            V_sum = V.mean(dim=-2)
            contex = V_sum.unsqueeze(-2).expand(B, H, L_Q, V_sum.shape[-1]).clone()
        else:  # use mask
            assert (L_Q == L_V)  # requires that L_Q == L_V, i.e. for self-attention only
            contex = V.cumsum(dim=-2)
        return contex

    def _update_context(self, context_in, V, scores, index, L_Q, attn_mask):
        B, H, L_V, D = V.shape

        if self.mask_flag:
            attn_mask = ProbMask(B, H, L_Q, index, scores, device=V.device)
            scores.masked_fill_(attn_mask.mask, -np.inf)

        attn = torch.softmax(scores, dim=-1)  # nn.Softmax(dim=-1)(scores)

        context_in[torch.arange(B)[:, None, None],
        torch.arange(H)[None, :, None],
        index, :] = torch.matmul(attn, V).type_as(context_in)
        if self.output_attention:
            attns = (torch.ones([B, H, L_V, L_V]) / L_V).type_as(attn).to(attn.device)
            attns[torch.arange(B)[:, None, None], torch.arange(H)[None, :, None], index, :] = attn
            return (context_in, attns)
        else:
            return (context_in, None)

    def forward(self, queries, keys, values, attn_mask):
        B, L_Q, H, D = queries.shape
        _, L_K, _, _ = keys.shape

        queries = queries.transpose(2, 1)
        keys = keys.transpose(2, 1)
        values = values.transpose(2, 1)

        U_part = self.factor * np.ceil(np.log(L_K)).astype('int').item()  # c*ln(L_k)
        u = self.factor * np.ceil(np.log(L_Q)).astype('int').item()  # c*ln(L_q)

        U_part = U_part if U_part < L_K else L_K
        u = u if u < L_Q else L_Q

        scores_top, index = self._prob_QK(queries, keys, sample_k=U_part, n_top=u)

        # add scale factor
        scale = self.scale or 1. / sqrt(D)
        if scale is not None:
            scores_top = scores_top * scale
        # get the context
        context = self._get_initial_context(values, L_Q)
        # update the context with selected top_k queries
        context, attn = self._update_context(context, values, scores_top, index, L_Q, attn_mask)

        return context.contiguous(), attn

class AttentionLayer(nn.Module):
    def __init__(self, attention, d_model, n_heads, d_keys=None,
                 d_values=None):
        super(AttentionLayer, self).__init__()

        d_values = d_values or (d_model // n_heads)
        d_keys = d_keys or (d_model // n_heads)

        self.inner_attention = attention
        self.query_projection = nn.Linear(d_model, d_keys * n_heads)
        self.key_projection = nn.Linear(d_model, d_keys * n_heads)
        self.value_projection = nn.Linear(d_model, d_values * n_heads)
        self.out_projection = nn.Linear(d_values * n_heads, d_model)
        self.n_heads = n_heads

    def forward(self, queries, keys, values, attn_mask):
        B, L, _ = queries.shape
        _, S, _ = keys.shape
        H = self.n_heads

        queries = self.query_projection(queries).view(B, L, H, -1)
        keys = self.key_projection(keys).view(B, S, H, -1)
        values = self.value_projection(values).view(B, S, H, -1)

        out, attn = self.inner_attention(
            queries,
            keys,
            values,
            attn_mask
        )
        out = out.view(B, L, -1)

        return self.out_projection(out), attn

class AttentionBlock(nn.Module):
    def __init__(self, embed_dim:int= None,
                    key_dim:int= None,
                    value_dim:int= None,
                    dropout:int = 0.1):
        """An attention mechanism Scale Dot Product Attention et al (2017)
            Reference: https://github.com/flrngel/TCN-with-attention
            Time Series Batch-Size, Uni(Multi)-Variate TS, Windows

            The input of the AttentionBlock is `BxDxT` where
            `B` is the input 'Batch size', -> 0th
            `D` is the `dimensions of each Feature`. 1th
            `T` is the length of the `Time Sequence` 2th

                'Attention = softmax( (Q*K.T)/sqrt.dK )*V'

            The output of the AttentionLayer is `BxTx(D+"V")` where `V` is the size of the
            attention values.

        Args:
            embed_dim (int, optional): the number of dimensions (or channels) of each element in
                                    the length of the input and output sequences.
            key_dim (int, optional): the size of the attention keys. Defaults to None.
            value_dim (int, optional): the size of the attention values. Defaults to None.
            dropout (int, optional): drop-out rate. Defaults to 0.1.
        """
        super(AttentionBlock, self).__init__()

        assert embed_dim is not None, "Provide either embed_dim"

        value_dim = value_dim or embed_dim
        self.key_dim = value_dim or embed_dim

        self.key_W = nn.Linear(embed_dim, key_dim)
        self.query_W = nn.Linear(embed_dim, key_dim)
        self.value_W = nn.Linear(embed_dim, value_dim)

        self.d_k = 1/math.sqrt(key_dim)

        self.dropout = nn.Dropout(p=dropout)

        self.init_parameters()

    def init_parameters(self):
        for param in self.parameters():
            stdv = 1. / math.sqrt(param.size(-1))
            param.data.uniform_(-stdv, stdv)

    def forward(self, query):
        B, L, E = query.size() #B=batch_size, L=Length, E= Feature Len

        K = self.key_W(query)
        Q = self.query_W(query)
        V = self.value_W(query)

        #Q shape is (B, L, E), K shape is (B, E, L)
        #BMM to Q*K = (B, L, L)
        Q = Q.permute(0, 2, 1)
        scores = torch.einsum("bij,bjk->bik", Q, K) * self.d_k

        attn_mask = TriangularCausalMask(B, E, device=V.device)

        scores.masked_fill_(attn_mask.mask, -np.inf)

        V = V.permute(0, 2, 1)
        A = self.dropout(F.softmax(scores, dim=1))

        V = torch.einsum("bij,bjk->bik", A, V)
        V = V.permute(0, 2, 1).contiguous()

        return V + query

class TriangularCausalMask():
    def __init__(self, B, L, device="cpu"):
        #mask_shape = [B, 1, L, L]
        mask_shape = [B, L, L]
        with torch.no_grad():
            self._mask = torch.triu(torch.ones(mask_shape, dtype=torch.bool), diagonal=1).to(device)

    @property
    def mask(self):
        return self._mask

class ProbMask():
    def __init__(self, B, H, L, index, scores, device="cpu"):
        _mask = torch.ones(L, scores.shape[-1], dtype=torch.bool).to(device).triu(1)
        _mask_ex = _mask[None, None, :].expand(B, H, L, scores.shape[-1])
        indicator = _mask_ex[torch.arange(B)[:, None, None],
                    torch.arange(H)[None, :, None],
                    index, :].to(device)
        self._mask = indicator.view(scores.shape).to(device)

    @property
    def mask(self):
        return self._mask


import torch
from torch import nn
from torch.nn import functional as F
from torch.autograd import Variable

class BoxFilter(nn.Module):
    def __init__(self, r):
        super(BoxFilter, self).__init__()
        self.r = r

    def forward(self, x):
        assert x.dim() == 4
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

        in_channels = x.shape[1]
        out_channels = in_channels
        weights = 1 / ((2 * self.r + 1) ** 2)
        box_kernel = weights * torch.ones((out_channels, 1, 2 * self.r + 1, 2 * self.r + 1))
        box_kernel = box_kernel.to(device)
        output = F.conv2d(x, box_kernel, groups=in_channels, padding='same')
        return output

class GuidedFilter(nn.Module):
    def __init__(self, r, eps=0.1):
        super(GuidedFilter, self).__init__()

        self.r = r
        self.eps = eps
        self.boxfilter = BoxFilter(r)

    def forward(self, x, y):
        n_x, c_x, h_x, w_x = x.size()
        n_y, c_y, h_y, w_y = y.size()

        assert n_x == n_y
        assert c_x == 1 or c_x == c_y
        assert h_x == h_y and w_x == w_y
        assert h_x > 2 * self.r + 1 and w_x > 2 * self.r + 1

        # N
        N = self.boxfilter(
            Variable(x.data.new().resize_((1, 1, h_x, w_x)).fill_(1.0)))

        # mean_x
        mean_x = self.boxfilter(x) / N
        # mean_y
        mean_y = self.boxfilter(y) / N
        # cov_xy
        cov_xy = self.boxfilter(x * y) / N - mean_x * mean_y
        # var_x
        var_x = self.boxfilter(x * x) / N - mean_x * mean_x

        # A
        A = cov_xy / (var_x + self.eps)
        # b
        b = mean_y - A * mean_x

        # mean_A; mean_b
        mean_A = self.boxfilter(A) / N
        mean_b = self.boxfilter(b) / N

        return mean_A * x + mean_b

if __name__ == '__main__':
    pass


# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os

import tensorflow as tf

def create_keras_model():

    model = tf.keras.Sequential(
        [
            tf.keras.layers.Conv2D(32, 3, activation="relu", input_shape=(28, 28, 1)),
            tf.keras.layers.MaxPooling2D(),
            tf.keras.layers.Flatten(),
            tf.keras.layers.Dense(64, activation="relu"),
            tf.keras.layers.Dense(10, activation="softmax"),
        ]
    )

    model.compile(
        loss="sparse_categorical_crossentropy",
        optimizer=tf.keras.optimizers.Adam(),
        metrics=["sparse_categorical_accuracy"],
    )

    return model


import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, Update
from telegram.ext import CallbackContext, CallbackQueryHandler, CommandHandler, Dispatcher, Filters, MessageHandler

from app.models import Command, TelegramUser
from app.report import generate_report

logger = logging.getLogger(__name__)

reply_keyboard = ReplyKeyboardMarkup([['ℹ О сервисе']], resize_keyboard=True)
select_report_markup = InlineKeyboardMarkup([
    [InlineKeyboardButton('Отчет по товару 1', callback_data='keyboard_report_1')],
    [InlineKeyboardButton('Отчет по товару 2', callback_data='keyboard_report_2')],
])

def process_event(event, user):
    logger.info(event)

def user_get_by_update(update: Update):
    if update.message:
        message = update.message
    else:
        message = update.callback_query.message

    full_name = ''
    if message.chat.first_name:
        full_name += message.chat.first_name
    if message.from_user.last_name:
        full_name += ' ' + message.chat.last_name

    instance, created = TelegramUser.objects.update_or_create(
        chat_id=message.chat.id,
        defaults={
            'chat_id': message.chat.id,
            'user_name': message.chat.username,
            'full_name': full_name,
        },
    )

    return instance

def process_command(name, user, text=''):
    slug_list = {
        'Started bot': 'help_start',
        'Sent command "Help analyse category"': 'help_analyse_category',
        'Sent command "Help catalog link"': 'help_catalog_link',
        'Sent command "Info"': 'help_info',
        'Sent command "Feedback"': 'help_feedback',
        'Sent command "No limits"': 'help_no_limits',
        'Sent unknown command': 'help_command_not_found',
        'Sent command "WB analyse item"': 'wb_analyse_item',
        'Sent not supported marketplace command': 'help_marketplace_not_supported',
        'Sent command on maintenance mode': 'help_maintenance_mode',
    }

    if name in slug_list.keys():
        log_item = Command.objects.create(
            user=user,
            command=slug_list[name],
            message=text,
        )
    else:
        logger.error('Command %s not in slug list, it must me updated', name)

        return None

    process_event(name, user)

    return log_item

def help_start(update: Update, context: CallbackContext):
    user = user_get_by_update(update)

    process_command(name='Started bot', user=user)

    context.bot.send_message(
        chat_id=user.chat_id,
        text=f'Приветствую, {user.full_name}!\n\nЗадача бота – помочь тебе разобраться в своих товарах и отзывах на них. Выберите один из демо-отчетов чтобы оченить работу бота:',
        reply_markup=select_report_markup,
    )

def help_info(update: Update, context: CallbackContext):
    user = user_get_by_update(update)

    process_command(name='Sent command "Info"', user=user)

    context.bot.send_message(
        chat_id=user.chat_id,
        text='📊 Этот телеграм бот поможет собирать данные отзывов на товары на Wildberries и анализировать их. Выберите один из демо-отчетов чтобы оченить работу бота:',
        reply_markup=InlineKeyboardMarkup([
            [InlineKeyboardButton('Отчет по товару 1', callback_data='keyboard_report_1')],
            [InlineKeyboardButton('Отчет по товару 2', callback_data='keyboard_report_2')],
            [InlineKeyboardButton('Отчет по товару 3', callback_data='keyboard_report_3')],
            [InlineKeyboardButton('Отчет по товару 4', callback_data='keyboard_report_4')],
        ]),
    )

def help_command_not_found(update: Update, context: CallbackContext):
    user = user_get_by_update(update)
    process_command(name='Sent unknown command', user=user, text=update.message.text)

    context.bot.send_message(
        chat_id=user.chat_id,
        text='⚠🤷 Непонятная команда.\nСкорее всего, вы указали неправильную команду. Сейчас бот может анализировать только ссылки на демонстрационные товары.',
        reply_markup=InlineKeyboardMarkup([
            [InlineKeyboardButton('💁 Как правильно указать категорию?', callback_data='keyboard_help_catalog_link')],
        ]),
    )

def help_maintenance_mode(update: Update, context: CallbackContext):
    user = user_get_by_update(update)
    process_command(name='Sent command on maintenance mode', user=user, text=update.message.text)

    context.bot.send_message(
        chat_id=user.chat_id,
        text='🧩 Наш сервис обновляется. Мы обновляем сервис и не можем обработать ваш запрос. Как только обновление будет готово мы сразу же оповестим вас.',
    )

def report_1(update: Update, context: CallbackContext):
    user = user_get_by_update(update)

    report_file = generate_report(username=user.full_name)

    context.bot.send_document(
        chat_id=user.chat_id,
        document=report_file,
        caption='Отчет по товару 1',
        filename='report_1.pdf',
    )

def report_2(update: Update, context: CallbackContext):
    user = user_get_by_update(update)

    report_file = generate_report(username=user.full_name)

    context.bot.send_document(
        chat_id=user.chat_id,
        document=report_file,
        caption='Отчет по товару 2',
        filename='report_2.pdf',
    )

def reset_webhook(bot, url, token):
    bot.delete_webhook()
    bot.set_webhook(url=url + token)

def start_bot(bot):
    dp = Dispatcher(bot, None, workers=0, use_context=True)

    dp.add_handler(CommandHandler('start', help_start))
    dp.add_handler(CommandHandler('help', help_start))

    dp.add_handler(MessageHandler(Filters.text & Filters.regex('ℹ О сервисе'), help_info))

    dp.add_handler(CallbackQueryHandler(report_1, pattern='keyboard_report_1'))
    dp.add_handler(CallbackQueryHandler(report_2, pattern='keyboard_report_2'))

    dp.add_handler(MessageHandler(Filters.all, help_info))

    return dp


from pathlib import Path, os
myfiles = ['games','pictures','videos']
for file in myfiles:
    print(f" C:// This pc// {file}")

print(
    Path.home()
)

#Making directory from os function, it can make several directories at once
# os.makedirs("C:/Users/Asus/Desktop/The folder created by Python")

#Making directory with path function
# Path("C:/Users/Asus/Desktop/Folder created from path function").mkdir()

#Knowing whether the path is absolute or relative
print(
    Path().cwd()
)
print(
Path().cwd().is_absolute()
)
print(
    Path("Desktop/The folder created by Python").is_absolute()
)
#Getting the parts of the file
path1 = "C:/Users\Asus/Desktop/Python practice/Automate the Boring stuff with python"
print(
    Path().cwd().parents[4]
)
realpath = path1 + "/" +"File_handling(FirstHalf).py"
  #Getting path base name
print(
    os.path.basename(realpath)
)
  #Getting both basename and directory name of the file
print(
    os.path.split(realpath)
)
#Getting the file size
print(
os.path.getsize(realpath)
)
#Getting the list of each file in particular directory
print(
    os.listdir(path1)
)
#Getting the total size of directory
totalsize = 0
for filesize in os.listdir(path1):
    totalsize =totalsize + os.path.getsize(filesize)
print(totalsize)

#Glob Method
p = Path(path1)
   #listing path of all files of directory
print (list(p.glob("*")))
   #listing all only text files of directory
print(list(p.glob("*.txt")))
   #listing all python files of directory
print(list(p.glob("*.py")))

Some stuffs with python/python part  1/File_handling(FirstHalf).py


import json
import bsddb3
from DashboardService.GenericClient import GenericClient

class ServiceError(Exception):
    def __init__(self, name=None, code=None, message=None, data=None, error=None):
        super(ServiceError, self).__init__(message)
        self.name = name
        self.code = code
        self.message = '' if message is None else message
        self.data = data or error or ''
        # data = JSON RPC 2.0, error = 1.1

    def __str__(self):
        return self.name + ': ' + str(self.code) + '. ' + self.message + \
            '\n' + self.data

class AppCache:
    def __init__(self, path=None, narrative_method_store_url=None):
        if path is None:
            raise ValueError('The "path" argument is required')
        if not isinstance(path, str):
            raise ValueError('The "path" argument must be a string')
        self.path = path

        if narrative_method_store_url is None:
            raise ValueError('The "narrative_method_store_url" argument is required')
        if not isinstance(narrative_method_store_url, str):
            raise ValueError('The "narrative_method_store_url" argument must be a string')
        self.narrative_method_store_url = narrative_method_store_url

        # self.make()

    def make(self):
        self.db = bsddb3.db.DB()

    def close(self):
        self.db.close()

    def start(self):
        print('+OPEN1')
        self.db.open(self.path, None, bsddb3.db.DB_HASH, bsddb3.db.DB_RDONLY)
        print('-OPEN1')

    def stop(self):
        self.db.close()

    def initialize(self):
        self.db.open(self.path, None, bsddb3.db.DB_HASH, bsddb3.db.DB_CREATE)
        self.populate_cache()
        self.db.close()

    def create(self):
        print('+OPEN3')
        self.db.open(self.path, None, bsddb3.db.DB_HASH, bsddb3.db.DB_CREATE)
        # self.db.close()
        print('-OPEN3')

    def remove(self):
        try:
            self.db.remove(self.path)
        except bsddb3.db.DBNoSuchFileError as err:
            pass

    def load_for_tag(self, tag):
        rpc = GenericClient(
            module='NarrativeMethodStore',
            url=self.narrative_method_store_url,
            token=None
        )
        result, error = rpc.call_func('list_methods', [{
            'tag': tag
        }])
        if error:
            raise ServiceError(**error)

        for app in result[0]:
            key = app['id']
            if not self.db.exists(key.encode('utf8')):
                self.db.put(key.encode('utf8'), json.dumps(app).encode('utf8'))

    def populate_cache(self):
        self.load_for_tag('release')
        self.load_for_tag('beta')
        self.load_for_tag('dev')

    # public interface

    def get(self, app_id):
        value = self.db.get(app_id.encode('utf8'))

        if value is not None:
            return (None, json.loads(value.decode('utf8')))
        else:
            return (None, None)


#!/usr/bin/env python

import numpy as np
import h5py
import glob
import sys
import os
import multiprocessing as mp
import ctypes
import argparse

parser = argparse.ArgumentParser(description='Lit pixel hit finder')
parser.add_argument('run', help='Run number', type=int)
parser.add_argument('-d', '--dark', help='Dark run if not latest', type=int, default=None)
args = parser.parse_args()

folder = '/gpfs/exfel/exp/SPB/201701/p002013/raw/r%.4d/'%args.run
if args.dark is None:
    calib_file = '/gpfs/exfel/exp/SPB/201701/p002013/usr/Shared/calib/latest/Cheetah-AGIPD15-calib.h5'
else:
    calib_file = '/gpfs/exfel/exp/SPB/201701/p002013/scratch/calib/r%.4d/Cheetah-AGIPD15-calib.h5'%args.dark

# Constants
dset_name = '/INSTRUMENT/SPB_DET_AGIPD1M-1/DET/15CH0:xtdf/image/data'
cellid_name = '/INSTRUMENT/SPB_DET_AGIPD1M-1/DET/15CH0:xtdf/image/cellId'
trainid_name = '/INSTRUMENT/SPB_DET_AGIPD1M-1/DET/15CH0:xtdf/image/trainId'
good_cells = range(2,62,2)
num_h5cells = 64
adu_threshold = 40
num_threads = 80

# Calibration file for module 15
bool_cells = np.zeros(num_h5cells, dtype=np.bool)
bool_cells[good_cells] = True
with h5py.File(calib_file, 'r') as f:
    offset = f['AnalogOffset'][:, bool_cells]
    gain = f['RelativeGain'][:, bool_cells]
    gain_threshold = f['DigitalGainLevel'][:, bool_cells]
    badpix = f['Badpixel'][:, bool_cells]

def threshold(digital, cell):
    thresh = gain_threshold[:,cell]
    high_gain = digital < thresh[1]
    low_gain = digital > thresh[2]
    medium_gain = (~high_gain) * (~low_gain)
    return low_gain*2 + medium_gain

def calibrate(data, digital, cell):
    gain_mode = threshold(digital, cell)
    o = np.empty(gain_mode.shape)
    g = np.empty(gain_mode.shape)
    b = np.empty(gain_mode.shape)
    for i in range(3):
        o[gain_mode==i] = offset[i,cell][gain_mode==i]
        g[gain_mode==i] = gain[i,cell][gain_mode==i]
        b[gain_mode==i] = badpix[i,cell][gain_mode==i]

    data = (np.float32(data) - o)*g
    data[b != 0] = 0
    return data

def litpix_worker(rank, fname, num_trains, litpix, trainids, cellids):
    np_litpix = np.frombuffer(litpix.get_obj(), 'i4')
    np_trainids = np.frombuffer(trainids.get_obj(), 'u8')
    np_cellids = np.frombuffer(cellids.get_obj(), 'u8')
    fp = h5py.File(fname, 'r')
    for i in range(rank, num_trains, num_threads):
        start = i*len(good_cells)
        end = (i+1)*len(good_cells)
        h5start = i*num_h5cells
        h5end = (i+1)*num_h5cells

        analog = fp[dset_name][h5start:h5end, 0][good_cells]
        digital = fp[dset_name][h5start:h5end, 1][good_cells]
        for j in range(len(good_cells)):
            data = calibrate(analog[j], digital[j], j)
            np_litpix[start+j] = (data[384:]>adu_threshold).sum()
        np_trainids[start:end] = fp[trainid_name][h5start:h5end][good_cells].flatten()
        np_cellids[start:end] = fp[cellid_name][h5start:h5end][good_cells].flatten()
        if rank == 0:
            sys.stderr.write('\r%s %d/%d' % (fname, i+1, num_trains))
    fp.close()

litpix = np.empty((0,), dtype='i4')
trainids = np.empty((0,), dtype='u8')
cellids = np.empty((0,), dtype='u8')

# For all module 15 files
flist = sorted(glob.glob('%s/*AGIPD15*h5'%folder))
for fname in flist:
    with h5py.File(fname, 'r') as f:
        num_trains = f[dset_name].shape[0] // num_h5cells
    litpix_array = mp.Array(ctypes.c_int, len(good_cells)*num_trains)
    trainids_array = mp.Array(ctypes.c_ulong, len(good_cells)*num_trains)
    cellids_array = mp.Array(ctypes.c_ulong, len(good_cells)*num_trains)
    jobs = []
    for i in range(num_threads):
        p = mp.Process(target=litpix_worker, args=(i, fname, num_trains, litpix_array, trainids_array, cellids_array))
        jobs.append(p)
        p.start()
    for j in jobs:
        j.join()
    sys.stderr.write('\n')

    litpix = np.concatenate((litpix, np.frombuffer(litpix_array.get_obj(), 'i4')))
    trainids = np.concatenate((trainids, np.frombuffer(trainids_array.get_obj(), 'u8')))
    cellids = np.concatenate((cellids, np.frombuffer(cellids_array.get_obj(), 'u8')))

os.makedirs('data', exist_ok=True)
with h5py.File('data/hits_r%.4d.h5'%args.run, 'w') as f:
    f['hitFinding/litPixels'] = litpix
    f['hitFinding/trainId'] = trainids
    f['hitFinding/cellId'] = cellids
    f['hitFinding/ADUThreshold'] = adu_threshold
    f['hitFinding/goodCells'] = good_cells


"""
투자 귀재 규식이 2
divide and conquer 방식을 사용하여 풀어보자!
**분할과 정복**이라는 뜻으로 문제를 단번에 알아내기 어려울 경우 부분 부분으로 나누어 푸는 방법론이다.
이는 총 3단계로 나뉘는데 `Divide(분할)`, `Conquer(정복)`, `Combine(결합)`으로 나뉜다.
1. `Divide(분할)`는 하나의 복잡한 문제를 부분적으로 분할한다는  의미이다.
2. `Conquer(정복)`은 부분적으로 분할된 문제들의 답을 도출한다는 의미이다.
3. `Combine(결합)`은 도출된 답들을 모두 결합하여 기존 문제를 해결 한다는 의미이다.
"""

def sublist_max(profits, start, end):
    # 코드를 작성하세요.
    if start == end:
        return profits[start]

    mid = (start + end)//2

    return

# 테스트
list1 = [-2, -3, 4, -1, -2, 1, 5, -3]
print(sublist_max(list1, 0, len(list1) - 1))

list2 = [4, 7, -6, 9, 2, 6, -5, 7, 3, 1, -1, -7, 2]
print(sublist_max(list2, 0, len(list2) - 1))

list3 = [9, -8, 0, -7, 8, -6, -3, -8, 9, 2, 8, 3, -5, 1, -7, -1, 10, -1, -9, -5]
print(sublist_max(list3, 0, len(list3) - 1))

list4 = [-9, -8, -8, 6, -4, 6, -2, -3, -10, -8, -9, -9, 6, 2, 8, -1, -1]
print(sublist_max(list4, 0, len(list4) - 1))


# encoding:utf-8

# @Author: Rilzob
# @Time: 2019/3/31 下午7:23

import re
from bs4 import BeautifulSoup, Tag
from selenium import webdriver
import time

from Spider.HtmlDownloader import HtmlDownloader

class HtmlParser(object):
    def __init__(self):
        super(HtmlParser, self).__init__()
        self.browser = webdriver.Chrome(
            executable_path='/Users/rilzob/PycharmProjects/SubjectKG/chromedriver'
        )
        self.dropdown_num = 1  # 自动下滚次数

    @staticmethod
    def parser(url):
        if url is None:
            return None
        content = HtmlDownloader().download(url)
        soup = BeautifulSoup(content, 'html.parser')
        # school_name = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1').get_text()  # 学校名称
        # en_school_name = soup.find('dd', class_='lemmaWgt-lemmaTitle-subTitle').find('h3').get_text()  # 学校英文名
        # school_tag = soup.find('dd', class_="lemmaWgt-lemmaTitle-keyInfo lemmaWgt-lemmaTitle-keyInfo-with-link").get_text().strip()  # 学校标签
        old_school_introduce = soup.find('div', class_='lemma-summary').get_text().strip('\n')  # 学校简介
        pattern = re.compile(r'\[[0-9-]*\]')
        new_school_introduce = re.sub(pattern, '', old_school_introduce)
        # for i in r
        # # base_info1 = soup.find_all('div', class_='dl-baseinfo')[0]
        # # base_info2 = soup.find_all('div', class_='dl-baseinfo')[1]
        # # infoset1 = []
        # # for info in base_info1.select('dd'):
        # #     if isinstance(info, Tag):
        # #         infoset1.append(info.get_text())
        # #     else:
        # #         continue
        # # creation_time = infoset1[0]  # 创办时间
        # # property = infoset1[1]  # 属性
        # # Administration = infoset1[2]  # 主管部门
        #
        # # infoset2 = []
        # # for info in base_info2.select('dd'):
        # #     if isinstance(info, Tag):
        # #         infoset1.append(info.get_text())
        # #     else:
        # #         continue
        # # category = infoset2[0]  # 类别
        # # famous_alumni = infoset2[1]  # 知名校友
        # # official_website = infoset2[2]  # 官网
        #
        # # property_test = soup.select('body > div.body-wrapper.feature.feature_small.collegeSmall > div.feature_poster > div > div.poster-left > div.poster-bottom > div > div:nth-child(1) > dl:nth-child(2) > dd')
        #
        # # html = etree.HTML(content)
        # # property = html.xpath("//html/body/div[4]/div[3]/div/div[1]/div[3]/div/div[1]/dl[2]/text()")  # 属性
        # # print("属性：", property)
        # # Administration = html.xpath('//html/body/div[4]/div[3]/div/div[1]/div[3]/div/div[1]/dl[3]/dd/a/text()')  # 主管部门
        #
        # # property = soup.find('div', class_)

        basic_info_dict = {}  # 所有信息所存放的dict

        dict_school_url = {}
        dict_school_url['baike_url'] = url
        basic_info_dict.update(dict_school_url)
        # dict_school_tag = {}
        # dict_school_tag['school_tag'] = school_tag
        # basic_info_dict.update(dict_school_tag)
        dict_school_introduce = {}
        dict_school_introduce['school_introduce'] = new_school_introduce
        basic_info_dict.update(dict_school_introduce)

        basic_info = soup.find('div', class_='basic-info cmn-clearfix')
        dt_list = []
        for dt in basic_info.find_all('dt'):
            if isinstance(dt, Tag):
                dt_list.append(dt.get_text().strip('\n').replace('\xa0', '').replace('\n', '|'))
            else:
                continue
        dd_list = []
        for dd in basic_info.find_all('dd'):
            if isinstance(dd, Tag):
                dd_list.append(dd.get_text().strip('\n').replace('\xa0', '').replace('\n', '|'))
            else:
                continue

        for i in range(len(dt_list)):
            dict = {}
            dict[dt_list[i]] = dd_list[i]
            basic_info_dict.update(dict)

        return basic_info_dict

    def main_parse(self):
        # 985工程url
        url = 'https://baike.baidu.com/item/985%E5%B7%A5%E7%A8%8B/1077915?fromtitle=985&fromid=7809859&fr=aladdin'

        # url = 'https://baike.baidu.com/item/%E6%9C%AC%E7%A7%91%E9%99%A2%E6%A0%A1/17606093'
        if url is None:
            return None
        # self.browser.get(url)
        # for i in range(self.dropdown_num):  # 下滚次数
        #     self.browser.execute_script("window.scrollTo(0, document.body.scrollHeight);"
        #                                   "var lenOfPage=document.body.scrollHeight;"
        #                                   "return lenOfPage")  # 执行下拉操作刷新页面
        content = HtmlDownloader().download(url)
        # print(content)
        # content1 = self.browser.page_source
        # print(content1)
        # self.browser.quit()
        soup = BeautifulSoup(content, 'html.parser')
        school_set = soup.find_all('td', align='center')
        school_url_list = []
        school_name_list = []
        for school in school_set:
            # school.find('a')['href'])
            # print(str(school.find('a')['href']))
            # school_url = 'https://baike.baidu.com' + str(school.find_all('a')['href'])
            if school.find('a') is not None:
                school_url_list.append('https://baike.baidu.com' + school.find('a')['href'])
                school_name_list.append(school.find('a').get_text())
            else:
                continue
            # print("school_url", school_url)

        whole_info = {}
        for i in range(len(school_url_list)):
            school_dict = {}
            school_dict[school_name_list[i]] = HtmlParser().parser(school_url_list[i])
            whole_info.update(school_dict)
            time.sleep(1)
        return whole_info

    def new_main_parse(self):
        url = 'https://baike.baidu.com/wikitag/taglist?tagId=37678&fromLemma=true'
        if url is None:
            return None
        content = ''
        self.browser.get(url)
        for i in range(1, 38):  # 下滚次数
            self.browser.execute_script("window.scrollTo(0, document.body.scrollHeight);"
                                          "var lenOfPage=document.body.scrollHeight;"
                                          "return lenOfPage")  # 执行下拉操作刷新页面
            time.sleep(3)
            content = content + self.browser.page_source
            self.browser.find_element_by_css_selector('#waterfall-horPagerBox > div > a.pTag.next').click()
            print('i: ', i)
            # time.sleep(3)
        soup = BeautifulSoup(content, 'html.parser')
        school_set = soup.find_all('div', class_='waterFall_item fromLemma')
        school_url_list = []
        school_name_list = []
        for school in school_set:
            if school.find('a') is not None:
                school_url_list.append(school.find('a')['href'])
                school_name_list.append(school.find('div', class_='waterFall_content_title').get_text())
            else:
                continue
            # print("school_url", school_url)

        whole_info = {}
        for i in range(len(school_url_list)):
            school_dict = {}
            school_dict[school_name_list[i]] = self.parser(school_url_list[i])
            whole_info.update(school_dict)
            time.sleep(1)
        return whole_info


#
# @lc app=leetcode.cn id=1046 lang=python3
#
# [1046] 最后一块石头的重量

from typing import List
# @lc code=start
class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        n = len(stones)
        if n == 1:
            return stones[0]
        elif n == 2:
            return abs(stones[1] - stones[0])
        else:
            stones.sort()
            if stones[n - 3] == 0:
                return stones[n - 1] - stones[n - 2]
            stones[n - 1] = stones[n - 1] - stones[n - 2]
            stones[n - 2] = 0
            return self.lastStoneWeight(stones)
# @lc code=end

每日一题/1046.最后一块石头的重量.py

1046.最后一块石头的重量.py


# -*- coding: utf-8 -*-
from datas import Store

# 色のフォーマット用Enum
class color:
    OK = '\033[92m'
    WARN = '\033[93m'
    NG = '\033[91m'
    END_CODE = '\033[0m'

# テストを実施するメソッド
# name='テストケースの識別名'
def expect(name, check):
    success = '{s}OK{e}'.format(s=color.OK, e=color.END_CODE)
    ng = '{s}NG{e}'.format(s=color.NG, e=color.END_CODE)
    tmp = None
    if check:
        tmp = '{name} : [ {command} ]'.format(name=name, command=success)
    else:
        tmp = '{name} : [ {command} ]'.format(name=name, command=ng)
    print(tmp)

testCase = 10
dumpStore = Store(name='test2', test=testCase)
dumpStore.dump()

# ストアが存在していた場合のテストケース
loadStore = Store.load(name='test2')
expect('Store load Test', loadStore.test == testCase)

# ストアのファイルが存在していない場合のテストケース
notStore = Store.load(name='test3')
expect('Not Exists Test', notStore == None)


# -*- coding: utf-8 -*-
"""
Created on Wed Jul 28 21:11:33 2021

@author: Kevin Chang

Project: Codeforces Problem 1541A

"""

for _ in range(int(input())):
    n = int(input())
    res = list(range(1, n+1))
    res = [i+1 if i%2 == 1 else i-1 for i in res]
    if len(res)%2== 1:
        res[-2] += 2
        res[-1] -= 3
    print(*res)


""" Menu module """

class Menu:
    """ Create a menu object """

    def __init__(self, menu: dict) -> None:
        """
        Initialize the menu object

        >>> MAIN = {
        ...     "header": "Welcome to Game Picker!",
        ...     1: "Games",
        ...     2: "Budget",
        ...     3: "Schedule",
        ... }
        >>> main_menu = Menu(MAIN)
        >>> main_menu
        <__main__.Menu object at 0x...>
        >>> main_menu.header
        'Welcome to Game Picker!'
        >>> main_menu.selections
        {1: 'Games', 2: 'Budget', 3: 'Schedule', 0: 'Exit'}
        >>> main_menu.messages
        {'exit': 'Goodbye!', 'invalid': 'Selection is invalid... Goodbye!'}

        """
        # Add exit to end of menu
        menu[0] = "Exit"

        self.header: str = menu.pop("header")
        self.selections: dict = menu
        self.messages: dict = {
            "exit": "Goodbye!",
            "invalid": "Selection is invalid... Goodbye!",
        }

    def __str__(self) -> str:
        """
        Return a string representation of the menu object which includes the
        header and selections by overriding the __str__ method.

        >>> MAIN = {
        ...     "header": "Welcome to Game Picker!",
        ...     1: "Games",
        ...     2: "Budget",
        ...     3: "Schedule",
        ... }
        >>> main_menu = Menu(MAIN)
        >>> print(main_menu)
        Welcome to Game Picker!
        <BLANKLINE>
        [1] Games
        [2] Budget
        [3] Schedule
        [0] Exit
        <BLANKLINE>

        """
        # Create string for header
        header = self.header + "\n\n"

        # Create string for selections
        selections = ""
        for key, value in self.selections.items():
            selections = selections + f"[{key}] {value}\n"

        return header + selections

    def get_selection(self) -> int:
        """
        Print menu and return selection

        >>> MAIN = {
        ...     "header": "Welcome to Game Picker!",
        ...     1: "Games",
        ...     2: "Budget",
        ...     3: "Schedule",
        ... }
        >>> main_menu = Menu(MAIN)
        >>> selection = main_menu.get_selection()  # doctest: +SKIP
        Welcome to Game Picker!

        [1] Games
        [2] Budget
        [3] Schedule
        [0] Exit

        > 3

        >>> selection  # doctest: +SKIP
        3

        """
        print(self)
        selection = input("> ")
        print()

        return int(selection)

    def print_message(self, message: str) -> None:
        """
        Print message from dict of self.messages

        >>> MAIN = {
        ...     "header": "Welcome to Game Picker!",
        ...     1: "Games",
        ...     2: "Budget",
        ...     3: "Schedule",
        ... }
        >>> main_menu = Menu(MAIN)
        >>> main_menu.messages
        {'exit': 'Goodbye!', 'invalid': 'Selection is invalid... Goodbye!'}
        >>> main_menu.print_message("invalid")
        Selection is invalid... Goodbye!

        """
        message = self.messages[message]
        print(message)

def test():
    """ Test docstrings using doctest """

    import doctest

    flags = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE
    doctest.testmod(verbose=True, optionflags=flags)

if __name__ == "__main__":
    test()