#!/usr/bin/env python3
# 病歷查詢 2014.09.22
#coding: utf-8

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import QSettings, QSize, QPoint

from classes import table_widget
from libs import ui_utils
from libs import system_utils
from libs import string_utils
from libs import db_utils

# 動態輸入主訴
class DialogDiagnosticPicker(QtWidgets.QDialog):
    # 初始化
    def __init__(self, parent=None, *args):
        super(DialogDiagnosticPicker, self).__init__(parent)
        self.parent = parent
        self.database = args[0]
        self.system_settings = args[1]
        self.text_edit = args[2]
        self.clinic_type = args[3]
        self.input_code = args[4]

        self.settings = QSettings('__settings.ini', QSettings.IniFormat)
        self.ui = None
        self.clinic_name = None

        self._set_ui()
        self._set_signal()
        self._read_data()

    # 解構
    def __del__(self):
        self.close_all()

    # 關閉
    def close_all(self):
        pass

    def closeEvent(self, a0: QtGui.QCloseEvent):
        self.settings.setValue("dialog_diagnostic_picker_size", self.size())
        self.settings.setValue("dialog_diagnostic_picker_pos", self.pos())

    # 設定GUI
    def _set_ui(self):
        self.ui = ui_utils.load_ui_file(ui_utils.UI_DIALOG_DIAGNOSTIC_PICKER, self)
        self.setFixedSize(self.size())  # non resizable dialog
        system_utils.set_css(self, self.system_settings)

        self.ui.resize(self.settings.value("dialog_diagnostic_picker_size", QSize(861, 479)))
        self.ui.move(self.settings.value("dialog_diagnostic_picker_pos", QPoint(846, 215)))

        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setText('確定')
        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).setText('取消')
        self.table_widget_diagnostic = table_widget.TableWidget(
            self.ui.tableWidget_diagnostic, self.database)
        self._set_table_width()

    def _set_table_width(self):
        width = [200, 200, 200, 200, 200]
        self.table_widget_diagnostic.set_table_heading_width(width)

    # 設定信號
    def _set_signal(self):
        self.ui.buttonBox.accepted.connect(self.accepted_button_clicked)
        self.ui.tableWidget_diagnostic.clicked.connect(self._table_item_clicked)
        self.ui.tableWidget_diagnostic.doubleClicked.connect(self.accepted_button_clicked)

    def _table_item_clicked(self):
        # database.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).animateClick()
        clinic_name = self._get_clinic_name() + ' '
        self.parent.insert_text(self.text_edit, clinic_name, self.input_code)
        self.input_code = ''

        self._update_diagnosis_hit_rate()

    def accepted_button_clicked(self):
        self.clinic_name = self._get_clinic_name()
        self._update_diagnosis_hit_rate()

        self.close()

    def _update_diagnosis_hit_rate(self):
        clinic_key = self._get_clinic_key()
        if clinic_key is not None:
            db_utils.increment_hit_rate(self.database, 'clinic', 'ClinicKey', clinic_key)

    def _get_clinic_name(self):
        item = self.ui.tableWidget_diagnostic.item(
            self.ui.tableWidget_diagnostic.currentRow(),
            self.ui.tableWidget_diagnostic.currentColumn(),
        )

        if item is not None:
            clinic_name = item.text()
        else:
            clinic_name = ''

        return clinic_name

    def _read_data(self):
        # database.table_widget_diagnostic.set_db_data(database.sql, database._set_wait_data)
        order_type = '''
            ORDER BY LENGTH(ClinicName), CAST(CONVERT(`ClinicName` using big5) AS BINARY)
        '''
        if self.system_settings.field('診察詞庫排序') == '點擊率':
            order_type = 'ORDER BY HitRate DESC'

        sql = '''
            SELECT * FROM clinic
            WHERE
                ClinicType = "{clinic_type}" AND
                InputCode LIKE "{input_code}%"
            GROUP BY ClinicName
            {order_type}
        '''.format(
            clinic_type=self.clinic_type,
            input_code=self.input_code,
            order_type=order_type,
        )
        self.rows = self.database.select_record(sql)
        self.table_widget_diagnostic.set_db_data_without_heading(sql, 'ClinicName')

    def _set_table_data(self, row_no, row):
        diagnostic_row = [
            string_utils.xstr(row['ClinicKey']),
            string_utils.xstr(row['ClinicName']),
        ]

        for column in range(len(diagnostic_row)):
            self.ui.tableWidget_diagnostic.setItem(
                row_no, column,
                QtWidgets.QTableWidgetItem(diagnostic_row[column])
            )

    def _get_clinic_key(self):
        row_no = self.ui.tableWidget_diagnostic.currentRow()
        col_no = self.ui.tableWidget_diagnostic.currentColumn()
        column_count = self.ui.tableWidget_diagnostic.columnCount()

        index = (row_no * column_count) + col_no
        if index >= len(self.rows):
            return None

        return self.rows[index]['ClinicKey']


import numpy as np

"""
A conflict is when two objects are similar but they are in different clusters
or they are dissimilar but they are in the same cluster.
"""
def conflict(relation,partition,i,j):
    return relation[i][j]==1 and partition[i]!=partition[j] or relation[i][j]==-1 and partition[i]==partition[j]

"""
An agreement is when two objects are similar and they are in the same cluster
or they are dissimilar and they are in different clusters.
"""
def agreement(relation,partition,i,j):
    return relation[i][j]==1 and partition[i]==partition[j] or relation[i][j]==-1 and partition[i]!=partition[j]

"""
Converts a tolerance relation into a support matrix
"""
def convert_relation(relation,partition):
    rows, columns = relation.shape
    A = np.zeros((rows, columns))
    for i in range(rows):
        for j in range(columns):
            if conflict(relation,partition,i,j):
                A[i][j]=-1
            if agreement(relation,partition,i,j):
                A[i][j]=1
    return A

def powers(A, eps=1e-8):
    D = A                           # save the matrix
    R = np.ones((len(A),))          # R = 1
    D2 = D@D                        # matrix "squared"
    n = np.linalg.norm(D2@R,np.inf)
    D2 /= n  # normalized square
    steps = 1
    while np.linalg.norm(D@R-D2@R) > eps:
        D, D2 = D2, D2@D2           # swap the values
        D2 /= np.linalg.norm(D2@R,np.inf)          #normalized power
        steps += 1
    return D2, steps

"""
Computes the rank for each object
"""
def rank(relation,partition):
    A = convert_relation(relation,partition)
    B,s = powers(A)             # ranking
    E = np.ones((len(A),))      # unit vector
    R = A@(B@E)                 # ranks
    R /= max(abs(R))
    return R

"""
Assigns a rank value to each point.
"""
def assignRank(points,relation,partition):
    R = rank(relation,partition)
    for i in range(len(points)):
        points[i].rank = R[i]

"""
Returns the representatives for each cluster
"""
def getRepresentatives(clusters):
    representatives = [] #list of representatives
    for i in range(len(clusters)):
        #for each cluster the object with the maximum rank will be its representative
        max = -np.inf
        for j in range(len(clusters[i])):
            if clusters[i][j].rank > max:
                max=clusters[i][j].rank
                max_element = clusters[i][j]
        representatives.append(max_element)

    return representatives

# def closestRepresentative(representatives,element,type):
#     index = 0
#     min = element.distance(representatives[0],type)
#
#     for i in range(1,len(representatives)):
#         if representatives[i] == element:
#             continue
#         d = element.distance(representatives[i],type)
#         if d < min:
#             min = d
#             index = i
#     return index


import copy
import time
from torchvision.utils import make_grid
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torchvision
from torchnet import meter
from torch.autograd import Variable
from tqdm import tqdm
import os

from OXFORD_IIIT.src.data_loader import dset_classes, dset_loaders, dset_sizes, dsets
from OXFORD_IIIT.utils.config import LR, LR_DECAY_EPOCH, NUM_EPOCHS, NUM_IMAGES, MOMENTUM, BATCH_SIZE
from OXFORD_IIIT.utils.logger import Logger
from OXFORD_IIIT.utils.custom_plot import plot_acc_loss
from OXFORD_IIIT.src.densenet_DIY import densenet_DIY
from OXFORD_IIIT.vis_sample import visualize_sample

def record(filepath, mode, results):
    # if not os.path.exists(filepath):
    #     open(filepath,'w')
    with open(filepath, mode) as f:
        f.write(results)

def to_np(x):
    return x.data.cpu().numpy()

def exp_lr_scheduler(optimizer, epoch, init_lr=LR, lr_decay_epoch=LR_DECAY_EPOCH):
    lr = init_lr * (0.1**(epoch // lr_decay_epoch))

    if epoch % lr_decay_epoch == 0:
        print('Learning Rate: {}'.format(lr))

    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

    return optimizer

def train_model(model, criterion, optimizer, lr_scheduler, num_epochs=NUM_EPOCHS):
    since = time.time()

    best_model = model
    best_acc = 0.0
    loss_list, acc_list, val_loss_list, val_acc_list = [], [], [], []

    record_file = 'Results/txt/model_breeds_Epoch_%s_LR_%s_batchSize_%s.txt'% (str(num_epochs),str(LR),str(BATCH_SIZE))

    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch + 1, num_epochs))
        print('-' * 50)
        record(record_file, 'a',  ('Epoch {}/{}\n'.format(epoch + 1, num_epochs)) + ('--' * 50) + '\n')

        for phase in ['train', 'val']:
            if phase == 'train':
                optimizer = lr_scheduler(optimizer, epoch)
                model.train(True)  # Set model to training mode
            else:
                model.train(False)  # Set model to evaluate mode

            running_loss = 0.0
            running_corrects = 0

            for inputs, labels in tqdm(dset_loaders[phase]):
                '''
                # inputs torch.Size([batch_size, 3, 224, 224])
                # labels torch.Size([batch_size])
                '''
                if torch.cuda.is_available():
                    inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
                else:
                    inputs, labels = Variable(inputs), Variable(labels)

                optimizer.zero_grad()

                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    _, preds = torch.max(outputs.data, 1)
                    loss = criterion(outputs, labels)

                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                running_loss += loss.data.item() * inputs.size(0)  # inputs.size(0) 即 batch_size
                running_corrects += (preds == labels).sum().item()

            epoch_loss = running_loss / dset_sizes[phase]
            epoch_acc = running_corrects / dset_sizes[phase]

            print('{} Loss: {:.8f} Acc: {:.8f}'.format(phase, epoch_loss, epoch_acc))
            record(record_file, 'a', ('{} Loss: {:.8f} Acc: {:.8f}\n'.format(phase, epoch_loss, epoch_acc)) + '\n')

            if phase == 'train':
                loss_list.append(epoch_loss)
                acc_list.append(epoch_acc)
            else:
                val_loss_list.append(epoch_loss)
                val_acc_list.append(epoch_acc)

            if phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model = copy.deepcopy(model)

                # time_log = time.strftime('%Y-%m-%d-%H-%M', time.localtime(time.time()))
                save_model_path = 'Results/model/model_breeds_Epoch_%s_LR_%s_batch_size_%s_.pkl ' % (
                str(num_epochs), str(LR), str(BATCH_SIZE))
                torch.save(best_model.state_dict(), save_model_path)
                print("save_model ... ")

            if phase == 'val':
                # ============ TensorBoard logging ============#
                # (1) Log the scalar values
                info = {'loss': epoch_loss, 'accuracy': epoch_acc}
                for tag, value in info.items():
                    logger.scalar_summary(tag, value, epoch + 1)

                # (2) Log values and gradients of the parameters (histogram)
                for tag, value in model.named_parameters():
                    tag = tag.replace('.', '/')
                    logger.histo_summary(tag, to_np(value), epoch + 1)
                    logger.histo_summary(tag + '/grad', to_np(value.grad), epoch + 1)

                # (3) Log the images
                info = {'images': to_np(inputs.view(-1, 3, 224, 224)[:24])}  # view()创建了一个新的对象，与原对象共享相同的数据 #  R G B
                for tag, inputs in info.items():  # inputs
                    logger.image_summary(tag, inputs, epoch + 1)

        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:8f}\n'.format(best_acc))
    results = ('\nTraining complete in {:.0f}m {:.0f}s\n'.format(time_elapsed // 60, time_elapsed % 60)) + ('Best val Acc: {:8f}\n'.format(best_acc))
    record(record_file, 'a', results)

    plot_path = 'Results/plot/'
    plot_acc_loss(loss_list, val_loss_list, acc_list, val_acc_list, plot_path)

    return best_model

def imshow(inp, title=None):
    """Imshow for Tensor."""
    inp = inp.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])  # the same as data_loader config
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    plt.imshow(inp)
    if title is not None:
        plt.title(title)
    # plt.pause(1)

def visualize_model(model, num_images=NUM_IMAGES):
    images_so_far = 0
    plt.figure()

    for _, data in enumerate(dset_loaders['val']):
        inputs, labels = data

        if torch.cuda.is_available():
            inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
        else:
            inputs, labels = Variable(inputs), Variable(labels)

        outputs = model(inputs)
        _, preds = torch.max(outputs.data, 1)

        for j in range(inputs.size()[0]):
            images_so_far += 1
            ax = plt.subplot(num_images//2, 2, images_so_far)
            ax.axis('off')
            ax.set_title('predicted: {}'.format(dset_classes[preds[j]]))
            imshow(inputs.cpu().data[j])

            if images_so_far == num_images:
                plt.savefig(os.path.join(record_path, "val_sampling_preds.png"))
                return

def visualize_prediction(model, env_name, num_images = 1000):

    from visdom import Visdom
    viz = Visdom(env=env_name)
    images_so_far = 0

    for _, data in enumerate(dset_loaders['val']):

        if images_so_far == num_images:
            break

        inputs, labels = data

        if torch.cuda.is_available():
            inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
        else:
            inputs, labels = Variable(inputs), Variable(labels)  # 若内存不够,就用cpu

        outputs = model(inputs)
        _, preds = torch.max(outputs.data, 1)

        for j in range(inputs.size()[0]):

            viz.image(inputs.cpu().data[j],  # Val_dataset with No transforms.Normalize
                      opts=dict(title='predicted: {}'.format(dset_classes[preds[j]])))

            images_so_far += 1

class CNNModel(nn.Module):

    def __init__(self):
        super(CNNModel, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),

            nn.Conv2d(64, 128, kernel_size=5, padding=2),
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 192, kernel_size=5, padding=2),
            nn.BatchNorm2d(192),
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 192, kernel_size=3, padding=1),
            nn.BatchNorm2d(192),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),

            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.BatchNorm2d(384),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(512 * 6 * 6, 2048),
            nn.BatchNorm1d(2048),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            nn.Linear(2048, 2048),
            nn.BatchNorm1d(2048),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            nn.Linear(2048, 37),
            nn.LogSoftmax()
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

if __name__ == '__main__':

    print('\nProcessing Model Breeds...\n')

    logger = Logger('Results/logs')
    record_path = 'Results/txt'
    classes_breeds = dsets['train'].classes

    model = CNNModel()

    # densenet
    model = torchvision.models.densenet161(pretrained=True)
    num_ftrs = model.classifier.in_features
    model.classifier = nn.Linear(num_ftrs, 37)

    # resnet
    model = torchvision.models.resnet50(pretrained=True)
    num_ftrs = model.fc.in_features
    model.classifier = nn.Linear(num_ftrs, 37)

    # densenet-DIY
    model = densenet_DIY()

    # load the pre-saved model
    try:
        saved_model = 'Results/model/DenseNet/densenet161/'
        last_saved_model = sorted(os.listdir(saved_model))[-1]
        load_model_path = saved_model + last_saved_model
        if 'pkl' in last_saved_model:
            model.load_state_dict(torch.load(load_model_path))
            print('load the saved %s successfully ~' % load_model_path)
    except Exception as e:
        print(e)
        pass

    if torch.cuda.is_available():
        model.cuda()

    criterion = nn.CrossEntropyLoss().cuda()

    optimizer = torch.optim.SGD(model.parameters(), lr=LR, momentum=MOMENTUM)

    model = train_model(model, criterion, optimizer, exp_lr_scheduler, num_epochs=NUM_EPOCHS)

    visualize_prediction(model,'visualize-prediction')
    visualize_model(model)

    plt.ioff()
    plt.show()


import cv2
import numpy as np
import video
from serial import Serial
import time

ser = Serial('/dev/ttyUSB0', baudrate=9600, timeout=1) # подключаемся к Arduino

edge = 35 # рамки условного центра изо6ражения
panAngle = 90 # начальное положение сервопривода 1
tiltAngle = 90 # начальное положение сервопривода 2

def ObjectPosition (x, y): # функция вывода в консоль координат центра цели
    print ("[INFO] Object Center coordenates at X0 = {0} and Y0 =  {1}".format(x, y))

def ServoPosition (x, y): # функция управления сервоприводами
    global panAngle
    global tiltAngle
    if (x < width/2 - edge):
        panAngle += 1
        if panAngle > 170:
            panAngle = 170
        ser.write(bytearray([85, panAngle,180 - tiltAngle]))

    if (x > width/2 + edge):
        panAngle -= 1
        if panAngle < 10:
            panAngle = 10
        ser.write(bytearray([85, panAngle,180 - tiltAngle]))

    if (y < height/2 - edge):
        tiltAngle += 1
        if tiltAngle > 170:
            tiltAngle = 170
        ser.write(bytearray([85, panAngle, 180 - tiltAngle]))

    if (y > height/2 + edge):
        tiltAngle -= 1
        if tiltAngle < 10:
            tiltAngle = 10
        ser.write(bytearray([85, panAngle, 180 - tiltAngle]))

cv2.namedWindow( "result" )

cap = video.create_capture(0) # ловим камеру

hsv_min = np.array((59, 49, 56), np.uint8) # нижняя граница зеленого в HSV
hsv_max = np.array((95, 255, 255), np.uint8) # верxняя граница зеленого в HSV

while True:

    flag, img = cap.read() # считываем изо6ражение
    height, width = img.shape[:2] # размеры изо6ражения
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV ) # прео6разуем RGB к HSV
    # накладываем маску и применяем ее
    thresh = cv2.inRange(hsv, hsv_min, hsv_max)
    thresh = cv2.erode(thresh, None, iterations=2)
    thresh = cv2.dilate(thresh, None, iterations=2)
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
		cv2.CHAIN_APPROX_SIMPLE)[-2]
    center = None

    if len(cnts) > 0:
		# поиск наи6ольIIIего контура
        c = max(cnts, key = cv2.contourArea)
        ((x, y), radius) = cv2.minEnclosingCircle(c)
        M = cv2.moments(c)
        center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

        if radius > 50:
			# рисуем окружность в центре фигуры
            cv2.circle(img, (int(x), int(y)), int(radius),
				(0, 255, 255), 2)
            cv2.circle(img, center, 5, (0, 0, 255), -1)

            ObjectPosition(int(x), int(y))
            ServoPosition (int(x), int(y))

    cv2.imshow('result', img)

    ch = cv2.waitKey(5) # выxод через escp
    if ch == 27:
        break
    time.sleep(0.02) # временная задержка, что6ы из6авиться от осцилляции

cap.release()
cv2.destroyAllWindows()


#!/usr/bin/env python3
__author__ = "Christoph Rist"
__copyright__ = "Copyright 2016, Christoph Rist"
__license__ = "MIT"

# read/write own config file
import yaml
# paths
import argparse
from os import path
from os import listdir
# search for monitor string
import re

NITROGEN_CONFIG_FILE = "nitrogen/bg-saved.cfg"
CONFIG_FILE = "nitrogen-rotation.yaml"

DEFAULT_ALL_MONITORS = "all"

def try_parse_config_file(filename):
    try:
        with open(filename, 'r') as stream:
            return yaml.load(stream)
    except yaml.YAMLError:
        return None
    except FileNotFoundError:
        return None

def create_configuration(wallpaper_path):
    # read all files
    files = [f for f in listdir(wallpaper_path) if path.isfile(path.join(wallpaper_path, f))]
    # keep all files ending in .png and .jpg
    files = [f for f in files if f.endswith(".png") or f.endswith(".jpg")]
    # create dict
    conf = dict(wallpaper_path=wallpaper_path,
                wallpapers=files,
                monitor=DEFAULT_ALL_MONITORS)
    return conf

def write_configuration(conf, filename):
    with open(filename, 'w') as outfile:
        outfile.write(yaml.dump(conf, default_flow_style=False))

def is_valid_folder(parser, arg):
    expanded = path.expanduser(arg)
    if not path.isdir(expanded):
        parser.error("The wallpaper path %s is invalid." % expanded)
    else:
        return expanded

def rewrite_nitrogen_configuration(nitrogen_config_file, conf):

    try:
        with open(nitrogen_config_file) as f:
            lines = f.readlines()

        # search for monitor line
        if not conf['monitor'] or conf['monitor'] == DEFAULT_ALL_MONITORS:
            p = re.compile(r'\[.+\]\n')
            monitor_lines = [i for i, x in enumerate(lines) if p.match(x)]

        else:
            search_string = "[" + conf['monitor'] + "]\n"
            monitor_lines = [i for i, x in enumerate(lines) if x == search_string]

        if not monitor_lines:
            print("No matching monitor in nitrogen configuration found!.")
            return None

        wallpaper_not_found = False
        for monitor in monitor_lines:
            # search for 'file=' in monitor description block
            for l_index in range(monitor, monitor + 3):
                if lines[l_index].startswith('file='):
                    break
            else:
                continue

            # separate filename from rest of path
            pos = lines[l_index].rfind('/')
            if pos == -1:
                return None

            current = lines[l_index][pos+1:-1]
            wallpapers = conf['wallpapers']
            full_path = ""

            # search for wallpaper in list, remember index
            current_index = 0
            for index, pic in enumerate(wallpapers):
                if pic == current:
                    current_index = (index + 1) % len(wallpapers)
                    break

            # search for existing wallpaper
            while True:
                # no wallpaper is existing on disk
                if not wallpapers:
                    return False

                # next index (no need for ++ because of del operation at loop end
                current_index %= len(wallpapers)

                # re-write line
                full_path = path.join(conf['wallpaper_path'], wallpapers[current_index])
                if path.isfile(full_path):
                    break

                del wallpapers[current_index]
                wallpaper_not_found = True

            lines[l_index] = "file=" + full_path + '\n'

        # write back into file
        with open(nitrogen_config_file, 'w') as output:
            output.writelines(lines)

        # return False if a wallpaper could not be found
        return not wallpaper_not_found

    except IOError:
        return None

def main():

    config_path = path.join(path.expanduser("~"), ".config")
    config_file = path.join(config_path, CONFIG_FILE)
    configuration = try_parse_config_file(config_file)
    initial_config = configuration
    arg_required = True if not configuration else False
    configuration_changed = False

    if arg_required:
        print("No Configuration found. Parsing arguments.")

    parser = argparse.ArgumentParser(description="Rotate wallpaper (x-window root) using nitrogen.")
    parser.add_argument('--wallpaper-path', dest="path", required=arg_required, metavar="PATH",
                        type=lambda x: is_valid_folder(parser, x), help="Wallpaper location")
    parser.add_argument('--monitor', dest="monitor", required=False, metavar="MONITOR",
                        help="Monitor to set wallpaper, see nitrogen config file.")
    parser.add_argument('--rewrite', action='store_true', dest='rewrite',
                        help='Force re-scanning wallpaper dir and writing a new configuration file')
    args = parser.parse_args()

    # need a new configuration?
    if args.rewrite or args.monitor or args.path:
        if args.path:
            configuration = create_configuration(args.path)
        elif args.rewrite:
            configuration = create_configuration(configuration['wallpaper_path'])
        if args.monitor:
            configuration['monitor'] = args.monitor
        elif initial_config:
            configuration['monitor'] = initial_config['monitor']

        configuration_changed = True

    # write next wallpaper to nitrogen configuration
    ret = rewrite_nitrogen_configuration(path.join(config_path, NITROGEN_CONFIG_FILE), configuration)
    # Only if ret is False: rewrite configuration omitting removed wallpapers
    if ret is not None and not ret:
        configuration_changed = True

    # update own configuration
    if configuration_changed:
        write_configuration(configuration, config_file)

if __name__ == "__main__":
    main()


"""Test for AsyncRainbirdController."""

import datetime
from collections.abc import Awaitable, Callable

import aiohttp
import pytest

from pyrainbird import (
    RAINBIRD_COMMANDS,
    AvailableStations,
    ModelAndVersion,
    WaterBudget,
)
from pyrainbird.async_client import (
    AsyncRainbirdClient,
    AsyncRainbirdController,
    RainbirdApiException,
)
from pyrainbird.encryption import encrypt

from .conftest import LENGTH, PASSWORD, REQUEST, RESPONSE, RESULT_DATA, ResponseResult

async def test_request(
    rainbird_client: Callable[[], Awaitable[AsyncRainbirdClient]],
    response: ResponseResult,
) -> None:
    """Test of basic request/response handling."""
    response(aiohttp.web.Response(body=RESPONSE))
    client = await rainbird_client()
    resp = await client.request(REQUEST, LENGTH)
    assert resp == RESULT_DATA

async def test_request_failure(
    rainbird_client: Callable[[], Awaitable[AsyncRainbirdClient]],
    response: ResponseResult,
) -> None:
    """Test a basic request failure handling."""

    response(aiohttp.web.Response(status=500))
    client = await rainbird_client()
    with pytest.raises(RainbirdApiException):
        await client.request(REQUEST, LENGTH)

@pytest.fixture(name="api_response")
def mock_api_response(response: ResponseResult) -> Callable[[...], Awaitable[None]]:
    """Fixture to construct a fake API response."""

    def _put_result(command: str, **kvargs) -> None:
        resp = RAINBIRD_COMMANDS["ControllerResponses"][command]
        data = command + ("00" * (resp["length"] - 1))
        for k in resp:
            if k in ["type", "length"]:
                continue
            param_template = "%%0%dX" % (resp[k]["length"])
            start_ = resp[k]["position"]
            end_ = start_ + resp[k]["length"]
            data = "%s%s%s" % (
                data[:start_],
                (param_template % kvargs[k]),
                data[end_:],
            )

        body = encrypt(
            ('{"jsonrpc": "2.0", "result": {"data":"%s"}, "id": 1} ' % data),
            PASSWORD,
        )
        response(aiohttp.web.Response(body=body))

    return _put_result

async def test_get_model_and_version(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("82", modelID=16, protocolRevisionMajor=1, protocolRevisionMinor=3)
    assert await controller.get_model_and_version() == ModelAndVersion(16, 1, 3)

async def test_get_available_stations(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("83", pageNumber=1, setStations=0x7F000000)
    assert await controller.get_available_stations() == AvailableStations("7f000000", 1)

async def test_get_serial_number(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("85", serialNumber=0x12635436566)
    assert await controller.get_serial_number() == 0x12635436566

async def test_get_current_time(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    time = datetime.time()
    api_response("90", hour=time.hour, minute=time.minute, second=time.second)
    assert await controller.get_current_time() == time

async def test_get_current_date(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    date = datetime.date.today()
    api_response("92", year=date.year, month=date.month, day=date.day)
    assert await controller.get_current_date() == date

async def test_get_water_budget(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("B0", programCode=1, seasonalAdjust=65)
    assert await controller.water_budget(5) == WaterBudget(1, 65)

@pytest.mark.parametrize(
    "state,expected",
    [(1, True), (0, False)],
)
async def test_get_rain_sensor(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
    state: int,
    expected: bool,
) -> None:
    controller = await rainbird_controller()
    api_response("BE", sensorState=state)
    assert await controller.get_rain_sensor_state() == expected

async def test_get_zone_state(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    for i in range(1, 9):
        for j in range(1, 9):
            mask = (1 << (i - 1)) * 0x1000000
            api_response("BF", pageNumber=0, activeStations=mask)
            assert await controller.get_zone_state(j) == (i == j)

async def test_set_program(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", commandEcho=5)
    await controller.set_program(5)

async def test_irrigate_zone(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", pageNumber=0, commandEcho=6)
    api_response("BF", pageNumber=0, activeStations=0b10000000000000000000000000000)
    await controller.irrigate_zone(5, 30)

async def test_test_zone(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", commandEcho=6)
    await controller.test_zone(6)

async def test_stop_irrigation(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", pageNumber=0, commandEcho=6)
    api_response("BF", pageNumber=0, activeStations=0b0)
    await controller.stop_irrigation()

async def test_get_rain_delay(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("B6", delaySetting=16)
    await controller.get_rain_delay() == 16

async def test_set_rain_delay(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", pageNumber=0, commandEcho=6)
    await controller.set_rain_delay(3)

async def test_advance_zone(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("01", commandEcho=3)
    await controller.advance_zone(3)

@pytest.mark.parametrize(
    "state,expected",
    [
        (1, True),
        (0, False),
    ],
)
async def test_get_current_irrigation(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
    state: int,
    expected: bool,
) -> None:
    controller = await rainbird_controller()
    api_response("C8", irrigationState=state)
    assert await controller.get_current_irrigation() == expected

async def test_not_acknowledge_response(
    rainbird_controller: Callable[[], Awaitable[AsyncRainbirdController]],
    api_response: Callable[[...], Awaitable[None]],
) -> None:
    controller = await rainbird_controller()
    api_response("00", commandEcho=17, NAKCode=28)
    with pytest.raises(RainbirdApiException):
        await controller.irrigate_zone(1, 30)


import pygame
# 将图像当作rect（矩形来处理）
from pygame.sprite import Sprite

class Ship(Sprite):
    """管理飞船的类"""
    def __init__(self, ai_game):    # ai_game就是ai
        """初始化飞船并设置其初始位置"""
        super().__init__()
        self.screen = ai_game.screen    # 获取主程序中的屏幕大小（ai.screen）
        self.settings = ai_game.settings
        # get_rect()是一个处理矩形图像的方法，返回值包含矩形的居中属性，用点表示面location1
        self.screen_rect = ai_game.screen.get_rect() # 获取主程序中屏幕的中心位置即x轴，目的是保证飞船中心和屏幕中心一致

        # 加载飞船图像并获取其外接矩形
        self.image = pygame.image.load('images/ship.bmp')   # 上传飞船图片
        self.rect = self.image.get_rect()   # 获取飞船的中心位置即x,y轴，用点表示面location2
        # location1 要和location2 一致 飞船屏幕中心左右一致
        # 对于每艘新飞船，都将其放在屏幕底部的中央
        self.rect.midbottom = self.screen_rect.midbottom    # 把屏幕底部位置给飞船

        # 在飞船的属性x中存储小数值
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False
    # 实现持续移动
    def update_move(self):
        """根据移动标志持续调整飞船位置向右"""
        # 更新飞船而不是rect对象的x值
        if self.moving_right and self.rect.right < self.screen_rect.right:  # 限定飞船左右移动范围
            self.x += self.settings.ship_speed
        """根据移动标志持续调整飞船位置向左"""
        if self.moving_left and self.rect.left > self.screen_rect.left:
            self.x -= self.settings.ship_speed
        """根据移动标志持续调整飞船位置向上"""
        if self.moving_up and self.rect.top > self.screen_rect.top:
            self.y -= self.settings.ship_speed
        """根据移动标志持续调整飞船位置向下"""
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.y += self.settings.ship_speed
        self.rect.x = self.x
        self.rect.y = self.y

    def blitme(self):
        """在指定位置绘制飞船"""
        # 使用图片，位置来绘制飞船self.rect矩形对象，self.rect.midbottom 矩形位置
        self.screen.blit(self.image, self.rect)

    def center_ship(self):
        """让飞船处于屏幕低端中央"""
        self.rect.midbottom = self.screen_rect.midbottom
        # 更新了飞船的位置 需要重新指定 飞船x轴y轴 为了其可以继续进行 满足小数位 移动
        self.x = float(self.rect.x)
        # 重置用于跟踪飞船确切位置的 x，y
        self.y = float(self.rect.y)


"""converginblockchain URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.conf.urls import url,include

from .views import home,trnxmngrloginaction,trnxviewtransaction,trnxviewpurchase
from .views import patient,patientregister,doctor,doctorregistration,adminlogin,txmanagerlogin,adminloginaction
from .views import viewadminpatientspage,viewadmindoctorspage,viewadmintransactionspage,logout,activatepatients,activatedoctors
from patients.urls import urlpatterns as patients_urlpattern
from patients.views import patientlogincheck,patientsendsymptoms,patientsymtomsanalysis,patientsymptomsview,checkandpay,transactionmanagement,patientpurchaseblkmodel
from doctors.views import doctorlogincheck,doctoranalyzesysmptoms,DoctorsSendPriscription,DoctorPriscription,purchaseviewbydoctor,doctorviewtransaction

urlpatterns = [
    #url(r'^patients/',include((patients_urlpattern,'patients'),namespace='patients'),name='patients'),
    url(r'^admin/', admin.site.urls),
    url(r'^$',home, name="home"),
    url(r'^patient/', patient, name="patient"),
    url(r'^home/',home, name="home"),
    url(r'^patientregister/',patientregister, name="patientregister"),
    url(r'^doctor/',doctor, name="doctor"),
    url(r'^doctorregistration/',doctorregistration, name="doctorregistration"),
    url(r'^adminlogin/',adminlogin, name="adminlogin"),
    url(r'^txmanagerlogin/',txmanagerlogin, name="txmanagerlogin"),
    url(r'^adminloginaction/',adminloginaction,name="adminloginaction"),
    url(r'^viewadminpatientspage/',viewadminpatientspage,name="viewadminpatientspage"),
    url(r'^viewadmindoctorspage/',viewadmindoctorspage,name="viewadmindoctorspage"),
    url(r'^viewadmintransactionspage/',viewadmintransactionspage,name="viewadmintransactionspage"),
    url(r'^logout/',logout,name="logout"),
    #url(r'^activatepatients/',activatepatients,name="activatepatients")
    url(r'^activatepatients/$', activatepatients, name="activatepatients"),
    url(r'^activatedoctors/$', activatedoctors, name="activatedoctors"),
    url(r'^trnxmngrloginaction/',trnxmngrloginaction,name="trnxmngrloginaction"),
    url(r'^trnxviewtransaction/',trnxviewtransaction,name="trnxviewtransaction"),
    url(r'^trnxviewpurchase/',trnxviewpurchase,name="trnxviewpurchase"),

    url(r'^patientlogincheck/', patientlogincheck, name="patientlogincheck"),
    url(r'^patientsendsymptoms/', patientsendsymptoms, name="patientsendsymptoms"),
    url(r'^patientsymtomsanalysis/', patientsymtomsanalysis, name="patientsymtomsanalysis"),
    url(r'^patientsymptomsview/',patientsymptomsview, name="patientsymptomsview"),
    url(r'^checkandpay/',checkandpay, name="checkandpay"),
    url(r'^transactionmanagement/', transactionmanagement, name="transactionmanagement"),
    url(r'patientpurchaseblkmodel/',patientpurchaseblkmodel, name="patientpurchaseblkmodel"),

    url(r'^doctorlogincheck/',doctorlogincheck, name="doctorlogincheck"),
    url(r'^doctoranalyzesysmptoms/',doctoranalyzesysmptoms,name="doctoranalyzesysmptoms"),
    url(r'^DoctorsSendPriscription/',DoctorsSendPriscription, name="DoctorsSendPriscription"),
    url(r'^DoctorPriscription/',DoctorPriscription,name="DoctorPriscription"),
    url(r'^purchaseviewbydoctor/',purchaseviewbydoctor,name="purchaseviewbydoctor"),
    url(r'^doctorviewtransaction/',doctorviewtransaction,name="doctorviewtransaction"),

]


import inspect
import pathlib
from typing import Callable, Tuple

import numpy as np
import pandas as pd
import tensorflow as tf

from models.transfer import build_transfer_model
from utils.logging import logger

def decode_image(
    image_file: pathlib.Path, image_height: int, image_width: int
):
    """
    Read image path and decode as tensor
    :param image_file: image path object
    :param image_height: image height
    :param image_width: image width
    :return: resized image array
    """
    image_data = tf.image.decode_png(image_file, channels=3)
    return tf.image.resize(image_data, [image_height, image_width])

def process_image(
    image_height: int, image_width: int, preprocessing_function: Callable
):
    """
    Function to process image from file path
    :param image_height: image height
    :param image_width: image width
    :param preprocessing_function: preprocessing function
    :return: function thunk to pass to custom data pipeline
    """

    def process_path(file_path: str):
        """
        Thunk function to process image path
        :param file_path: file path in string format
        :return: processed image array
        """
        image_file = tf.io.read_file(file_path)
        image_data = decode_image(
            image_file, image_height=image_height, image_width=image_width
        )
        image_data = preprocessing_function(image_data)
        return tf.expand_dims(image_data, 0)

    return process_path

def generate_test_dataset(
    test_data_dir: pathlib.Path,
    preprocessing_function: Callable = lambda image: image / 255.0,
    image_height: int = 224,
    image_width: int = 224,
):
    """
    Generate testing dataset
    :param test_data_dir: test data directory path object
    :param preprocessing_function: preprocessing function default as rescaling to [0,1]
    :param image_height: image height
    :param image_width: image width
    :return: path and testing dataset object
    """
    image_path = tf.data.Dataset.list_files(
        str(test_data_dir / "*.png"), shuffle=False
    )
    return image_path, image_path.map(
        process_image(
            image_height=image_height,
            image_width=image_width,
            preprocessing_function=preprocessing_function,
        ),
        num_parallel_calls=tf.data.experimental.AUTOTUNE,
    )

def generate_predictions(
    model_path: pathlib.Path,
    base_model: tf.keras.Model,
    image_path: tf.data.Dataset,
    testing_dataset: tf.data.Dataset,
    activation_function: str = "softmax",
):
    base_model.load_weights(model_path)
    activation_layer = dict(inspect.getmembers(tf.nn))[activation_function]
    score = activation_layer(base_model.predict(testing_dataset))
    prediction = np.argmax(score, axis=1)

    series = []
    for path, prediction in zip(
        list(image_path.as_numpy_iterator()), prediction
    ):
        series.append([pathlib.Path(path.decode("utf-8")).stem, prediction])

    predictions = (
        pd.DataFrame(data=series, columns=["ID", "Label"])
        .astype(int)
        .sort_values("ID")
    )
    predictions.to_csv(model_path.parent / "predictions.csv", index=False)
    logger.info(
        f"Predictions saved as {model_path.parent / 'predictions.csv'}"
    )
    return predictions

def load_transfer_model(
    input_shape: Tuple[int, int, int],
    num_classes: int,
    base_model_name: str,
    global_average_pooling: bool,
):
    """
    Helper function to load transfer learning model
    :param input_shape: input shape tuple
    :param num_classes: number of classes
    :param base_model_name: base model name
    :param global_average_pooling: boolean flag of using global average pooling
    :return:
    """
    model_package = None
    base_model = None
    if base_model_name == "vgg16":
        model_package = tf.keras.applications.vgg16
        base_model = model_package.VGG16
    elif base_model_name == "vgg19":
        model_package = tf.keras.applications.vgg19
        base_model = model_package.VGG19
    elif base_model_name == "resnet50":
        model_package = tf.keras.applications.resnet50
        base_model = model_package.ResNet50
    elif base_model_name == "inception":
        model_package = tf.keras.applications.inception_v3
        base_model = model_package.InceptionV3
    else:
        raise ValueError("Model not supported")
    model, base_model = build_transfer_model(
        input_shape, num_classes, base_model, global_average_pooling
    )
    return model, model_package.preprocess_input

if __name__ == "__main__":
    from utils.configuration import (
        MODEL_CHECKPOINT_PATH,
        IMAGE_SHAPE,
        IMAGE_SIZE,
        TEST_DATA_DIR,
    )
    import tensorflow as tf

    activation = "softmax"
    path = (
        MODEL_CHECKPOINT_PATH
        / "transfer_vgg16_o_block4/10311903_cgavg_fc1512_fc2256_fc3128_d30_i512_bn_0.96575/ft-epoch-88-loss-0.0985"
    )
    built_model, preprocessing = load_transfer_model(
        input_shape=IMAGE_SHAPE,
        num_classes=3,
        base_model_name="vgg16",
        global_average_pooling=True,
    )

    test_path, test_dataset = generate_test_dataset(
        test_data_dir=TEST_DATA_DIR,
        preprocessing_function=preprocessing,
        image_height=IMAGE_SIZE[0],
        image_width=IMAGE_SIZE[1],
    )

    generate_predictions(
        model_path=path,
        base_model=built_model,
        image_path=test_path,
        testing_dataset=test_dataset,
        activation_function=activation,
    )


from typing import Sequence

from tacotron2.callbacks.reduce_lr_on_plateau_callback import ReduceLROnPlateauCallback

def test_reduce_on_plateau_callback():
    class Learner:
        class _Optimizer:
            param_groups = [{'lr': 1}]

        def __init__(self, strategy: Sequence[float]):
            self.valid_dl = None
            self.strategy = strategy
            self.optimizer = self._Optimizer()
            self.cur_step = -1

        def eval(self, valid_dl):
            self.cur_step += 1
            return self.strategy[self.cur_step]

    learner = Learner(strategy=[9, 8, 7, 6, 5, 6, 4, 3, 4, 5, 3, 2, 3, 3])
    clb = ReduceLROnPlateauCallback(patience=2, reduce_factor=0.5)

    for _ in learner.strategy:
        clb.on_epoch_end(learner=learner)
        print(learner.optimizer.param_groups)

test_reduce_on_plateau_callback()


from copy import deepcopy
import numpy as np
import logging
import os
import json
import scipy.io.wavfile as wavfile
import librosa
from PIL import Image

DEBUG = False
END = '</s>'
NULL = 'NULL'

if os.path.exists("*.log"):
  os.system("rm *.log")

class XNMTPostprocessor():
  def __init__(self, input_dir, is_phoneme=True):
    self.input_dir = input_dir
    self.is_phoneme = is_phoneme

  # Convert the predicted alignment files to the right format for evaluation
  def convert_alignment_file(self, out_file='pred_alignment.json', feat2wav_file=None):
    all_files = os.listdir(self.input_dir)
    files = []
    for fn in all_files:
      if fn.endswith(".json"):
        files.append(fn)

    files = sorted(files, key=lambda x:int(x.split('.')[-2]))
    alignments = []

    feat2wavs = []
    if feat2wav_file:
      with open(feat2wav_file, 'r') as f:
        feat2wavs = json.load(f)

    for i, f in enumerate(files):
      if f.split('.')[-1] == 'json':
        fp = open(self.input_dir + f, 'r')
        ali = json.load(fp)
        if type(ali) == list:
          ali = ali[0]

        fp.close()

        if END in ali['src_sent']:
          ali['src_sent'].remove(END)
          # XXX: This will make the file format inconsistent with the one generated by the preprocess.py
          # convert_xnmt_text function; fix this later
          ali['trg_sent'].remove(END)
          ali['alignment'] = ali['alignment'][:-1]
          if NULL not in ali['trg_sent']:
            ali['trg_sent'] = [NULL] + ali['trg_sent']
            ali['alignment'] = [a+1 if a<len(ali['trg_sent'])-1 else 0 for a in ali['alignment']]
          else:
            ali['alignment'] = [a if a<len(ali['trg_sent'])-1 else 0 for a in ali['alignment']]

        new_ali = {}
        if not feat2wav_file:
          new_ali = {'index': ali['index'],
                     'is_phoneme': self.is_phoneme,
                     'caption': ali['src_sent'],
                     'image_concepts': ali['trg_sent'],
                     'alignment': ali['alignment'],
                     'attentions': ali['attentions']
                    }
        else:
          feat_len = len(feat2wavs[i])
          ali_len = len(ali['alignment'])
          reduce_factor = ali['reduce_factor']
          new_feat2wav = []
          for i_a in range(ali_len):
            for i_f in range(feat_len):
              st = feat2wavs[i]['feat2wav'][i_f * reduce_factor][0]
              end = feat2wavs[i]['feat2wav'][max(i_f * reduce_factor + 1, feat_len - 1)][1]
              new_feat2wav.append([st, end])

          new_ali = {'index': ali['index'],
                     'is_phoneme': self.is_phoneme,
                     'caption': ali['src_sent'],
                     'image_concepts': ali['trg_sent'],
                     'alignment': ali['alignment'],
                     'attentions': ali['attentions'],
                     'feat2wav': new_feat2wav
                    }

        alignments.append(new_ali)

    with open(out_file, 'w') as fp:
      json.dump(alignments, fp, indent=4, sort_keys=True)

  def convert_retrieval_file(self, in_file, out_file='retrieval_results.txt'):
    fp = open(in_file)
    ret_indices = []
    for line in fp:
      idx_scores = line.strip().split('), (')
      top_indices = []
      for idx_score in idx_scores:
        idx_score = idx_score.replace('[', '')
        idx_score = idx_score.replace('(', '')
        idx_score = idx_score.replace(')', '')
        idx_score = idx_score.replace(']', '')
        idx_score = idx_score.replace(',', '')
        if DEBUG:
          print(idx_score)
        top_indices.append(idx_score.split()[0])
      ret_indices.append(' '.join(top_indices))
    fp.close()
    fp = open(out_file, 'w')
    fp.write('\n'.join(ret_indices))
    fp.close()

def alignment_to_cluster(ali_file, out_file='cluster.json'):
  def _find_distinct_tokens(data):
    tokens = set()
    for datum in data:
      if 'image_concepts' in datum:
        tokens = tokens.union(set(datum['image_concepts']))
      elif 'foreign_sent' in datum:
        tokens = tokens.union(set(datum['foreign_sent']))

    return list(tokens)

  fp = open(ali_file, 'r')
  align_info_all = json.load(fp)
  fp.close()

  classes = _find_distinct_tokens(align_info_all)
  clusters = {c:[] for c in classes}
  for align_info in align_info_all:
    sent = align_info['caption']
    concepts = align_info['image_concepts']
    alignment = align_info['alignment']

    if align_info['is_phoneme']:
      sent, alignment = _findPhraseFromPhoneme(sent, alignment)

    for w_i, a_i in zip(sent, alignment):
      if a_i >= len(concepts):
        if DEBUG:
          print('alignment index: ', align_info['index'])
          print('a_i out of range: ', a_i, concepts)
        a_i = 0
      clusters[concepts[a_i]].append(w_i)
      clusters[concepts[a_i]] = list(set(clusters[concepts[a_i]]))

  with open(out_file, 'w') as fp:
    json.dump(clusters, fp, indent=4, sort_keys=True)

def alignment_to_word_units(alignment_file, phone_corpus,
                                     concept_corpus,
                                     landmark_file = None,
                                     word_unit_file='word_units.wrd',
                                     phone_unit_file='phone_units.phn',
                                     concept2id_file=None,
                                     include_null = False):
  with open(phone_corpus, 'r') as f_p,\
       open(concept_corpus, 'r') as f_c:
    a_corpus, v_corpus = [], []
    for line in f_p:
      a_corpus.append(line.strip().split())

    for line in f_c:
      v_corpus.append(line.strip().split())

  if concept2id_file:
    with open(concept2id_file, 'r') as f:
      concept2id = json.load(f)
  else:
    concept2id = {}

  with open(alignment_file, 'r') as f:
    alignments = json.load(f)

  word_units = []
  phn_units = []
  # XXX
  for align_info, a_sent, v_sent in zip(alignments, a_corpus, v_corpus):
    if len(concept2id) > 0:
      image_concepts = [concept2id[c] for c in v_sent]
      print(image_concepts)
    else:
      image_concepts = align_info['image_concepts']
    alignment = align_info['alignment']
    pair_id = 'pair_' + str(align_info['index'])
    print(pair_id)
    prev_align_idx = -1
    start = 0
    for t, align_idx in enumerate(alignment):
      if t == 0:
        prev_align_idx = align_idx

      phn_units.append('%s %d %d %s\n' % (pair_id, t, t + 1, a_sent[t]))
      if prev_align_idx != align_idx:
        if not include_null and prev_align_idx == 0:
          prev_align_idx = align_idx
          start = t
          continue
        word_units.append('%s %d %d %s\n' % (pair_id, start, t, image_concepts[prev_align_idx]))
        prev_align_idx = align_idx
        start = t
      elif t == len(alignment) - 1:
        if not include_null and prev_align_idx == 0:
          continue
        word_units.append('%s %d %d %s\n' % (pair_id, start, t + 1, image_concepts[prev_align_idx]))

  with open(word_unit_file, 'w') as f:
    f.write(''.join(word_units))

  with open(phone_unit_file, 'w') as f:
    f.write(''.join(phn_units))

def alignment_to_word_classes(alignment_file, phone_corpus,
                                   word_class_file='words.class',
                                   landmark_file=None,
                                   include_null = False):
  f = open(phone_corpus, 'r')
  a_corpus = []
  for line in f:
    a_corpus.append(line.strip().split())
  f.close()
  with open(alignment_file, 'r') as f:
    alignments = json.load(f)

  word_units = {}
  for align_info, a_sent in zip(alignments, a_corpus):
    image_concepts = align_info['image_concepts']
    alignment = align_info['alignment']
    pair_id = 'pair_' + str(align_info['index'])
    print(pair_id)
    # print(image_concepts)
    prev_align_idx = -1
    start = 0
    if len(alignment) != len(a_sent):
      print('Warning: length of the alignment not equal to the length of sentence: %d != %d' % (len(alignment), len(a_sent)))
      gap = len(a_sent) - len(alignment)
      if gap > 0:
        print('Extend the alignment by %d ...' % gap)
        last_align_idx = alignment[-1]
        alignment.extend([last_align_idx]*gap)
        print(len(a_sent), len(alignment))
    for t, (align_idx, phn) in enumerate(zip(alignment, a_sent)):
      if t == 0:
        prev_align_idx = align_idx

      if prev_align_idx != align_idx:
        if not include_null and prev_align_idx == 0:
          prev_align_idx = align_idx
          start = t
          continue
        if image_concepts[prev_align_idx] not in word_units:
          word_units[image_concepts[prev_align_idx]] = ['%s %d %d\n' % (pair_id, start, t)]
        else:
          word_units[image_concepts[prev_align_idx]].append('%s %d %d\n' % (pair_id, start, t))
        prev_align_idx = align_idx
        start = t
      elif t == len(alignment) - 1:
        if not include_null and prev_align_idx == 0:
          continue
        if image_concepts[prev_align_idx] not in word_units:
          word_units[image_concepts[prev_align_idx]] = ['%s %d %d\n' % (pair_id, start, t + 1)]
        else:
          word_units[image_concepts[prev_align_idx]].append('%s %d %d\n' % (pair_id, start, t + 1))

  with open(word_class_file, 'w') as f:
    for i_c, c in enumerate(word_units):
      #print(i_c, c)
      f.write('Class %d:\n' % i_c)
      f.write(''.join(word_units[c]))
      f.write('\n')

def _findPhraseFromPhoneme(sent, alignment):
  if not hasattr(sent, '__len__') or not hasattr(alignment, '__len__'):
    raise TypeError('sent and alignment should be list')
  if DEBUG:
    print(len(sent), len(alignment))
    print(sent, alignment)
  assert len(sent) == len(alignment)
  cur = alignment[0]
  ws = []
  w_align = []
  w = ''
  for i, a_i in enumerate(alignment):
    if cur == a_i:
      w = w + ' ' + sent[i]
    else:
      ws.append(w)
      w_align.append(cur)
      w = sent[i]
      cur = a_i

  ws.append(w)
  w_align.append(cur)

  return ws, w_align

def resample_alignment(alignment_file, src_feat2wavs_file, trg_feat2wavs_file, out_file):
  with open(alignment_file, "r") as f:
    alignments = json.load(f)

  with open(src_feat2wavs_file, "r") as f:
    src_feat2wavs = json.load(f)
  with open(trg_feat2wavs_file, "r") as f:
    trg_feat2wavs = json.load(f)

  src_ids = sorted(src_feat2wavs, key=lambda x:int(x.split("_")[-1]))
  trg_ids = sorted(trg_feat2wavs, key=lambda x:int(x.split("_")[-1]))

  new_alignments = []
  for i_ali, ali in enumerate(alignments):
    # TODO: make this faster by making the feat_id convention more consistent
    trg_feat2wav = trg_feat2wavs[trg_ids[i_ali]]
    src_feat2wav = src_feat2wavs[src_ids[i_ali]]
    wavLen = max(src_feat2wav[-1][1], trg_feat2wav[-1][1])

    # Frames are automatically assigned to the last frame (convenient if the two feat2wavs have different lengths)
    trg_wav2feat = [-1]*wavLen

    alignment = ali["alignment"]

    if DEBUG:
      logging.debug("i_ali: " + str(i_ali))
      logging.debug("src_ids, trg_ids: %s %s" % (src_ids[i_ali], trg_ids[i_ali]))
      logging.debug("# of wav frames in src_feat2wav, # of feat frames: %d %d" % (src_feat2wav[-1][1], len(src_feat2wav)))
      logging.debug("# pf wav frames in trg_feat2wav, # of feat frames: %d %d" % (trg_feat2wav[-1][1], len(trg_feat2wav)))
      logging.debug("# of frames in alignment: " + str(len(alignment)))
      logging.debug("# of frames in trg_feat2wav: " + str(len(trg_feat2wav)))

    for i_seg, seg in enumerate(trg_feat2wav):
      start = seg[0]
      end = seg[1]
      for t in range(start, end):
        trg_wav2feat[t] = i_seg

    new_alignment = [0]*len(trg_feat2wav)
    for i_src in range(len(alignment)):
      for i_wav in range(src_feat2wav[i_src][0], src_feat2wav[i_src][1]):
        if i_wav > len(trg_wav2feat) - 1:
          logging.warning("inconsistent wav lens: %d %d" % (src_feat2wav[-1][1], len(trg_wav2feat)))
          break
        i_trg = trg_wav2feat[i_wav]
        new_alignment[i_trg] = alignment[i_src]

    new_align_info = deepcopy(ali)
    new_align_info["alignment"] = new_alignment
    new_alignments.append(new_align_info)

  with open(out_file, "w") as f:
    json.dump(new_alignments, f, sort_keys=True, indent=4)

def convert_boundary_to_segmentation(binary_boundary_file, frame_boundary_file):
  binary_boundaries = np.load(binary_boundary_file)
  frame_boundaries = []
  for i, b_vec in enumerate(binary_boundaries):
    # print("segmentation %d" % i)
    end_frames = np.nonzero(b_vec)[0]
    frame_boundary = [[0, end_frames[0]]]
    for st, end in zip(end_frames[:-1], end_frames[1:]):
      frame_boundary.append([st, end+1])

    # if i < 5:
    #   print("end_frames: ", end_frames)
    # print("frame_boundary: ", frame_boundary)
    frame_boundaries.append(np.asarray(frame_boundary))

  np.save(frame_boundary_file, frame_boundaries)

def convert_landmark_segment_to_10ms_segmentation(landmark_segment_file, landmarks_file, frame_segment_file):
  lm_segments = np.load(landmark_segment_file)

  lms = np.load(landmarks_file)
  utt_ids = sorted(lms.keys(), key=lambda x:int(x.split('_')[-1]))
  frame_segments = []
  for i, utt_id in enumerate(utt_ids):
    # print(i, utt_id)
    # print('lm_segment: ', lm_segments[i])
    # print('lms: ', lms['arr_'+str(i)])
    # print('len(lm_segment), len(lms): ', len(lm_segments[i]), len(lms['arr_'+str(i)]))
    lm_segment = lm_segments[i]
    lm = np.insert(lms, 0, 0)
    f_seg = []
    for lm_seg in lm_segment:
      lm = np.insert(lms[utt_id], 0, 0)
      f_seg.append(lm[lm_seg])
    frame_segments.append(np.asarray(f_seg))
  np.save(frame_segment_file, frame_segments)

def convert_10ms_segmentation_to_landmark(segmentation_file, ids_to_utterance_label_file, landmarks_file):
  segmentations = np.load(segmentation_file)
  with open(ids_to_utterance_label_file, "r") as f:
    ids_to_utterance_labels = json.load(f)

  landmarks = {}
  assert len(segmentations) == len(ids_to_utterance_labels)
  for (utt, segmentation) in zip(ids_to_utterance_labels, segmentations):
    if int(utt.split('_')[-1]) >= 1 and int(utt.split('_')[-1]) <= 4:
      print(utt, segmentation[-1])
    landmark = [0]
    for seg in segmentation:
      if seg[1] == seg[0]:
        print("Overlapped boundaries: ", seg)
        continue
      landmark.append(int(seg[1]))
    landmarks[utt] = landmark

  np.savez(landmarks_file, **landmarks)

def convert_sec_to_10ms_landmark(real_time_segment_file, feat2wav_file, frame_segment_file, fs=16000, max_feat_len=2000):
  real_time_segments = np.load(real_time_segment_file)
  with open(feat2wav_file, 'r') as f:
    feat2wavs = json.load(f)

  wav2feats = []
  utt_ids = []
  for utt_id, feat2wav in sorted(feat2wavs.items(), key=lambda x:int(x[0].split('_')[-1])):
    feat_len = len(feat2wav)
    wav_len = feat2wav[-1][1]
    print('utt_id, wav_len: ', utt_id, wav_len)
    wav2feat = np.zeros((wav_len,), dtype=int)
    for i in range(feat_len):
      wav2feat[feat2wav[i][0]:feat2wav[i][1]] = i
    wav2feats.append(wav2feat)
    utt_ids.append(utt_id)

  frame_segments = {}
  max_gap = [0, 0.]
  max_gap_segment = []
  for i_seg, r_seg in enumerate(real_time_segments.tolist()):
    feat_len = len(feat2wavs[utt_ids[i_seg]])
    wav2feat = wav2feats[i_seg]
    wav_len = len(wav2feat)

    n_segs = len(r_seg)
    f_seg = [0]
    for i in range(n_segs):
      # XXX: Need thresholding since some syllable segmentation is slightly longer than the actual wavform
      wav_frame_i = min(int(r_seg[i] * fs), wav_len - 1)
      feat_frame_i = wav2feat[wav_frame_i]
      prev_feat_frame = f_seg[-1]

      # XXX: Prevent the segmentation to move backward
      if feat_frame_i <= 0 or feat_frame_i - prev_feat_frame <= 0:
        continue
      else:
        if feat_frame_i - prev_feat_frame > max_gap[1]:
          max_gap = [i_seg, wav2feat[wav_frame_i] - f_seg[-1]]
          max_gap_segment = [f_seg[-1], wav2feat[wav_frame_i]]
        # XXX: Prevent the segmentation to exceends maxlen / length of the actual feature
        if feat_frame_i >= min(feat_len - 1, max_feat_len):
          continue

        f_seg.append(feat_frame_i + 1)
    f_seg.append(min(feat_len, max_feat_len))

    if i_seg >= 1 and i_seg <= 4:
      print('utt_id: ', utt_ids[i_seg])
      print('feat_len, last segmentation frame: ', feat_len)
      print('wav_len from segmentation, wav_len from wav2feats: ', r_seg[-1] * fs, len(wav2feats[i_seg]))
      print("feat_len from segmentation: ", f_seg[-1])

    frame_segments[utt_ids[i_seg]] = f_seg

  print("max_gap: ", max_gap)
  print("max_gap landmark: ", max_gap_segment)
  np.savez(frame_segment_file, **frame_segments)

def convert_txt_to_npy_segment(txt_segment_file, npy_segment_file):
  with open(txt_segment_file, 'r') as f:
    lines = f.read().strip().split('\n\n')
    segmentations = []
    for seg_txt in lines:
      seg = []
      for line in seg_txt.split('\n'):
        t = float(line.split()[1])
        seg.append(t)
      #print(seg)
      segmentations.append(np.asarray(seg))

    np.save(npy_segment_file, segmentations)

def extract_concept_segments(cluster, feat2wav, wav_dir, ids_to_utterance_labels, out_dir=None):
  segments = []
  for seg_info in cluster:
    wav_id = ids_to_utterance[seg_info[0]]
    print(wav_id)
    filename = '_'.join(wav_id.split('_')[:-1]) + ".wav"
    y, sr = wavfile.read(filename)

    t_start, t_end = feat2wav[seg_info[1][0]][0], feat2wav[seg_info[1][1]][1]
    if t_end - t_start <= 1600:
      continue
    segment = y[t_start:t_end]
    segment_melspectrogram = librosa.feature.melspectrogram(segment, sr=sr)

    segments.append(segment)
    segment_features.append(segment_melspectrogram)
    if out_dir:
      segment_file = "%s%s_%d_%d.wav" % (np.out_dir, wav_id, t_start, t_end)
      segment_feat_file = "%s%s_%d_%d.png" % (np.out_dir, wav_id, t_start, t_end)
      wavfile.write(segment_file, sr, y)
      img = Image.fromarray(segment_melspectrogram)
      img.save(segment_feat_file)

  return segments, segment_features

def extract_top_concept_segments(audio_cluster_file, feat2wav_file, wav_dir, ids_to_utterance_label_file, concept_priors_file, n_top=20):
  with open(audio_cluster_file, "r") as f:
    clusters = json.load(f)

  with open(concept_priors_file, "r") as f:
    concept_priors = json.load(f)

  with open(ids_to_utterance_label_file, "r") as f:
    ids_to_utterance_labels = json.load(f)

  with open(feat2wav_file, "r") as f:
    feat2wav = json.load(f)

  top_concepts = sorted(concept_priors, key=lambda x:concept_priors[x], reverse=True)[1:n_top+1]

  for c in top_concepts:
    c_dir = "%s%s/" % (out_dir, c)
    os.mkdir(c_dir)
    _, _ = extract_concept_segments(clusters[c], feat2wav, wav_dir, ids_to_utterance_labels, out_dir=c_dir)

if __name__ == '__main__':
  '''
  postproc = XNMTPostprocessor('../nmt/exp/feb28_phoneme_level_clustering/output/report/')
  postproc.convert_alignment_file('../nmt/exp/feb28_phoneme_level_clustering/output/alignment.json')
  alignment_to_cluster('../nmt/exp/feb28_phoneme_level_clustering/output/alignment.json', '../nmt/exp/feb28_phoneme_level_clustering/output/cluster.json')
  postproc.convert_retrieval_file('../nmt/exp/mar19_phoneme_to_image_norm_over_time/output/phoneme_to_concept.hyp')
  '''
  alignment_file = "../smt/exp/june_24_mfcc_kmeans_mixture=3/flickr30k_pred_alignment.json"
  src_feat2wavs_file = "../data/flickr30k/audio_level/flickr_mfcc_feat2wav.json"
  ref_feat2wavs_file = "../data/flickr30k/audio_level/flickr30k_gold_alignment.json_feat2wav.json"
  out_file = "../smt/exp/june_24_mfcc_kmeans_mixture=3/pred_alignment_resample.json"
  binary_boundary_file = "../comparison_models/exp/july_20_multimodal_kmeans/boundaries_multimodal-kmeans.npy"
  frame_boundary_file = "../data/flickr30k/audio_level/frame_boundaries_semkmeans.npy"
  txt_syl_segment_file = "../data/flickr30k/audio_level/syllable_boundaries.txt"
  npy_syl_segment_file = "../data/flickr30k/audio_level/syllable_segmentations_osc.npy"
  feat_type = "bn"
  if feat_type == "bn":
    landmark_file = "flickr_landmarks_mbn.npz" #"flickr_landmarks_osc_mbn.npz" #"../data/flickr30k/audio_level/flickr_landmarks.npz" #"flickr_landmarks_mbn.npz" #"../data/flickr30k/audio_level/flickr_landmarks.npz"
    feat2wavs_htk_file = "../data/flickr30k/audio_level/flickr30k_gold_alignment.json_feat2wav.json"
  elif feat_type == "mfcc":
    landmark_file = "flickr_landmarks_osc.npz"
    feat2wavs_htk_file = "../data/flickr30k/audio_level/flickr_mfcc_cmvn_htk_feat2wav.json"
  audio_cluster_file = "../comparison_models/exp/aug1_mkmeans/pred_clusters.json"
  ids_to_utterance_file = "../data/flickr30k/audio_level/ids_to_utterance_labels.json"
  wav_dir = "/home/lwang114/data/flickr/flickr_audio/wavs/"
  gold_seg_file = "../data/flickr30k/audio_level/flickr30k_gold_segmentation_mbn.npy"
  #"../data/flickr30k/audio_level/flickr30k_gold_segmentation_mfcc_htk.npy"
  #convert_boundary_to_segmentation(binary_boundary_file, frame_boundary_file)
  #resample_alignment(alignment_file, src_feat2wavs_file, ref_feat2wavs_file, out_file)
  #convert_txt_to_npy_segment(txt_syl_segment_file, npy_syl_segment_file)
  convert_sec_to_10ms_landmark(npy_syl_segment_file, feat2wavs_htk_file, landmark_file)
  #convert_10ms_segmentation_to_landmark(gold_seg_file, ids_to_utterance_file, "flickr30k_gold_landmarks_mbn.npz")


# check if grank or other scripts work correctly
# 运行本程序进行测试 请直接 python check.py 没有太大必要用 shell_plus
from bs4 import BeautifulSoup
import os, re

current_path = os.path.dirname(os.path.realpath(__file__))
raw_html = os.path.join(current_path, 'check.html')
with open(raw_html) as f:
    raw_html = f.read()
soup = BeautifulSoup(raw_html, 'html.parser')

star_review_pattr = re.compile(r'[\n\r]+')
star_pattr = re.compile(r'([\d\.]+).*([\d\.]+)')
review_pattr = re.compile(r'(\d+)')
remove_script_tag = re.compile(r'<script.*?</script>')

def getStarAndReview(soup):
    soup = soup.find(id="averageCustomerReviews")
    while soup.script:
        soup.script.decompose()
    try:
        _star, _review = star_review_pattr.split(soup.text.strip())
    except ValueError: # not enough values to unpack (expected 2, got 1)
        return (0, 0) # 没有评分 或者没有抓到
    _pure_star = star_pattr.findall(_star)[0]
    star = min(_pure_star, key=lambda x:float(x))
    review = review_pattr.findall(_review)[0]
    return (float(star), int(review))

getStarAndReview(soup)


# Crie um programa que vai ler vários números e colocar em uma lista.
# Depois disso, crie duas listas extras que vão conter apenas os valores pares e os valores ímpares digitados, respectivamente.
# Ao final, mostre o conteúdo das três listas geradas.

valores = []
while True:
    valores.append(int(input('Digite um número: ')))
    r = str(input('Deseja continuar? [S/N] ')).upper().strip()
    if r in 'SN' and r == 'N':
        break
    if r not in 'SN':
        r = str(input('Deseja continuar? [S/N] ')).upper().strip()
print(f'Os valores gerados foram {valores}.')
par = [v for v in valores if v % 2 == 0]
print(f'Os valores pares são {par}.')
impar = [v for v in valores if v % 2 != 0]
print(f'Os valores ímpares são {impar}.')


"""Module for creating classification file."""
import numpy as np
import cloudnetpy.output as output
from cloudnetpy.categorize import DataSource
from cloudnetpy.metadata import MetaData
from cloudnetpy.products.product_tools import CategorizeBits

def generate_classification(categorize_file, output_file):
    """Generates Cloudnet classification product.

    Generates categorized bins to 10 types of different targets in atmosphere
    as well as instrument status classification. Classifications are saved to
    NetCDF file with information of classification and measurements.

    Args:
        categorize_file (str): Categorize file name.

        output_file (str): Output file name.

    Examples:
        >>> from cloudnetpy.products.classification import generate_classification
        >>> generate_classification('categorize.nc', 'classification.nc')

    """
    data_handler = DataSource(categorize_file)
    categorize_bits = CategorizeBits(categorize_file)
    classification = get_target_classification(categorize_bits)
    data_handler.append_data(classification, 'target_classification')
    status = get_detection_status(categorize_bits)
    data_handler.append_data(status, 'detection_status')
    output.update_attributes(data_handler.data, CLASSIFICATION_ATTRIBUTES)
    output.save_product_file('classification', data_handler, output_file)

def get_target_classification(categorize_bits):
    """Classifies atmospheric targets by combining active bits."""
    bits = categorize_bits.category_bits
    classification = bits['droplet'] + 2*bits['falling']  # 0, 1, 2, 3
    classification[bits['falling'] & bits['cold']] += 2  # 4, 5
    classification[bits['melting']] = 6
    classification[bits['melting'] & bits['droplet']] = 7
    classification[bits['aerosol']] = 8
    classification[bits['insect']] = 9
    classification[bits['aerosol'] & bits['insect']] = 10
    return classification

def get_detection_status(categorize_bits):
    """Classifies detection status by combining active bits."""
    bits = categorize_bits.quality_bits
    status = np.copy(bits['lidar'].astype(int))
    status[bits['radar']] = 5
    status[bits['lidar'] & bits['radar']] = 3
    status[bits['corrected']] = 6
    status[bits['corrected'] & bits['radar']] = 7
    status[bits['attenuated'] & ~bits['corrected']] = 4
    status[bits['attenuated'] & ~bits['corrected'] & bits['radar']] = 2
    status[bits['clutter']] = 8
    status[bits['molecular'] & ~bits['radar']] = 9
    return status

COMMENTS = {
    'target_classification':
        ('This variable is a simplification of the bitfield "category_bits" in the\n'
         'target categorization and data quality dataset. It provides the 9 main\n'
         'atmospheric target classifications that can be distinguished by radar and\n'
         'lidar. The classes are defined in the definition attributes.'),

    'detection_status':
        ('This variable is a simplification of the bitfield "quality_bits" in the\n'
         'target categorization and data quality dataset. It reports on the\n'
         'reliability of the radar and lidar data used to perform the classification.\n'
         'The classes are defined in the definition attributes.'),
}

DEFINITIONS = {
    'target_classification':
        ('\n'
         'Value 0: Clear sky.\n'
         'Value 1: Cloud liquid droplets only.\n'
         'Value 2: Drizzle or rain.\n'
         'Value 3: Drizzle or rain coexisting with cloud liquid droplets.\n'
         'Value 4: Ice particles.\n'
         'Value 5: Ice coexisting with supercooled liquid droplets.\n'
         'Value 6: Melting ice particles.\n'
         'Value 7: Melting ice particles coexisting with cloud liquid droplets.\n'
         'Value 8: Aerosol particles, no cloud or precipitation.\n'
         'Value 9: Insects, no cloud or precipitation.\n'
         'Value 10: Aerosol coexisting with insects, no cloud or precipitation.'),

    'detection_status':
        ('\n'
         'Value 0: Clear sky.\n'
         'Value 1: Lidar echo only.\n'
         'Value 2: Radar echo but reflectivity may be unreliable as attenuation by\n'
         '         rain, melting ice or liquid cloud has not been corrected.\n'
         'Value 3: Good radar and lidar echos.\n'
         'Value 4: No radar echo but rain or liquid cloud beneath mean that\n'
         '         attenuation that would be experienced is unknown.\n'
         'Value 5: Good radar echo only.\n'
         'Value 6: No radar echo but known attenuation.\n'
         'Value 7: Radar echo corrected for liquid cloud attenuation\n'
         '         using microwave radiometer data.\n'
         'Value 8: Radar ground clutter.\n'
         'Value 9: Lidar clear-air molecular scattering.'),
}

CLASSIFICATION_ATTRIBUTES = {
    'target_classification': MetaData(
        long_name='Target classification',
        comment=COMMENTS['target_classification'],
        definition=DEFINITIONS['target_classification']
    ),
    'detection_status': MetaData(
        long_name='Radar and lidar detection status',
        comment=COMMENTS['detection_status'],
        definition=DEFINITIONS['detection_status']
    )
}


# -*- coding: utf-8 -*-
# 2210104010 浦上太一

def is_prime(n):
    for i in range(2, n + 1):
        if i * i > n:
            break
        if n % i == 0:
            return False
    return n != 1

def greedy_method(S):
    Sa = []
    Sb = []
    for n in S:
        if sum(Sa) <= sum(Sb):
            Sa.append(n)
        else:
            Sb.append(n)
    return [Sa, Sb]

# def sabun_method(S):

def main():
    S = []
    for i in range(1, 101):
        if is_prime(i):
            S.append(i)
    S.reverse()
    Sa, Sb = greedy_method(S)
    print("Sa: {}".format(Sa))
    print("Sb: {}".format(Sb))
    print("要素の総和の差の絶対値の最小値: {}".format(abs(sum(Sa)-sum(Sb))))

if __name__ == '__main__':
    main()


from PyQt4 import QtGui, QtCore
from MyQLine import MyQLine

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8

    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class TabAdv(QtGui.QWidget):
    def __init__(self):
        super(TabAdv, self).__init__()

        self.setObjectName(_fromUtf8("tab_adv"))
        # vertical layout adv tab
        self.vertLO_tab_adv = QtGui.QVBoxLayout(self)
        self.vertLO_tab_adv.setObjectName(_fromUtf8("vertLO_tab_adv"))
        # spacer
        spacerItem4 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem4)
        # line
        self.line_10 = MyQLine(self, "line_10")
        self.vertLO_tab_adv.addWidget(self.line_10)
        # spacer
        spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem5)
        # horizontal layout frame waittime
        self.hoLO_frame_waittime = QtGui.QHBoxLayout()
        self.hoLO_frame_waittime.setObjectName(_fromUtf8("hoLO_frame_waittime"))
        # label frame waittime
        self.lbl_frame_waittime = QtGui.QLabel(self)
        self.lbl_frame_waittime.setObjectName(_fromUtf8("lbl_frame_waittime"))
        self.hoLO_frame_waittime.addWidget(self.lbl_frame_waittime)
        # spin box frame waittime
        self.spinBox_frame_waittime = QtGui.QSpinBox(self)
        self.spinBox_frame_waittime.setMinimum(1)
        self.spinBox_frame_waittime.setMaximum(1000)
        self.spinBox_frame_waittime.setObjectName(_fromUtf8("spinBox_frame_waittime"))
        self.hoLO_frame_waittime.addWidget(self.spinBox_frame_waittime)
        self.vertLO_tab_adv.addLayout(self.hoLO_frame_waittime)
        # spacer
        spacerItem6 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem6)
        # line
        self.line_5 = MyQLine(self, "line_5")
        self.vertLO_tab_adv.addWidget(self.line_5)
        # label start area
        self.lbl_start_area = QtGui.QLabel(self)
        self.lbl_start_area.setObjectName(_fromUtf8("lbl_start_area"))
        self.vertLO_tab_adv.addWidget(self.lbl_start_area)
        # graphics view starting area
         # roi preview output
        self.lbl_starting_area_preview_label = QtGui.QLabel(self)
        self.lbl_starting_area_preview_label.setObjectName(_fromUtf8("lbl_starting_area_preview_label"))
        self.lbl_starting_area_preview_label.setAlignment(QtCore.Qt.AlignCenter)
        self.vertLO_tab_adv.addWidget(self.lbl_starting_area_preview_label)
        # grid layout set starting area
        self.gridLO_start_area = QtGui.QGridLayout()
        self.gridLO_start_area.setObjectName(_fromUtf8("gridLO_start_area"))
        # spinbox starting_x start
        self.spinBox_starting_x1_factor = QtGui.QSpinBox(self)
        self.spinBox_starting_x1_factor.setMaximum(100)
        self.spinBox_starting_x1_factor.setObjectName(_fromUtf8("spinBox_starting_x_start"))
        self.gridLO_start_area.addWidget(self.spinBox_starting_x1_factor, 0, 1, 1, 1)
        # spinbox starting_x end
        self.spinBox_starting_x2_factor = QtGui.QSpinBox(self)
        self.spinBox_starting_x2_factor.setMaximum(100)
        self.spinBox_starting_x2_factor.setObjectName(_fromUtf8("spinBox_starting_x_end"))
        self.gridLO_start_area.addWidget(self.spinBox_starting_x2_factor, 0, 3, 1, 1)
        # spinbox starting_y start
        self.spinBox_starting_y1_factor = QtGui.QSpinBox(self)
        self.spinBox_starting_y1_factor.setMaximum(100)
        self.spinBox_starting_y1_factor.setObjectName(_fromUtf8("spinBox_starting_y_start"))
        self.gridLO_start_area.addWidget(self.spinBox_starting_y1_factor, 1, 1, 1, 1)
        # spinbox starting_y end
        self.spinBox_starting_y2_factor = QtGui.QSpinBox(self)
        self.spinBox_starting_y2_factor.setMaximum(100)
        self.spinBox_starting_y2_factor.setObjectName(_fromUtf8("spinBox_starting_y_end"))
        self.gridLO_start_area.addWidget(self.spinBox_starting_y2_factor, 1, 3, 1, 1)
        # label starting_x start
        self.lbl_start_x_start = QtGui.QLabel(self)
        self.lbl_start_x_start.setObjectName(_fromUtf8("lbl_start_x_start"))
        self.gridLO_start_area.addWidget(self.lbl_start_x_start, 0, 0, 1, 1)
        # label starting_x end
        self.lbl_start_x_end = QtGui.QLabel(self)
        self.lbl_start_x_end.setObjectName(_fromUtf8("lbl_start_x_end"))
        self.gridLO_start_area.addWidget(self.lbl_start_x_end, 0, 2, 1, 1)
        # label starting_y start
        self.lbl_start_y_start = QtGui.QLabel(self)
        self.lbl_start_y_start.setObjectName(_fromUtf8("lbl_start_y_start"))
        self.gridLO_start_area.addWidget(self.lbl_start_y_start, 1, 0, 1, 1)
        # label starting_y end
        self.lbl_start_y_end = QtGui.QLabel(self)
        self.lbl_start_y_end.setObjectName(_fromUtf8("lbl_start_y_end"))
        self.gridLO_start_area.addWidget(self.lbl_start_y_end, 1, 2, 1, 1)
        # add starting are selection grid layout to tab layout
        self.vertLO_tab_adv.addLayout(self.gridLO_start_area)
        # line
        self.line_6 = MyQLine(self, "line_6")
        self.vertLO_tab_adv.addWidget(self.line_6)
        # spacer
        spacerItem7 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem7)
        # horizontal layout set start orientation
        self.hoLO_start_ori = QtGui.QHBoxLayout()
        self.hoLO_start_ori.setObjectName(_fromUtf8("hoLO_start_ori"))
        # label start orientation
        self.lbl_start_orientation = QtGui.QLabel(self)
        self.lbl_start_orientation.setObjectName(_fromUtf8("lbl_start_orientation"))
        self.hoLO_start_ori.addWidget(self.lbl_start_orientation)
        # spinbox set start orientation
        self.spinBox_start_orientation = QtGui.QSpinBox(self)
        self.spinBox_start_orientation.setObjectName(_fromUtf8("spinBox_start_orientation"))
        self.spinBox_start_orientation.setMaximum(359)
        self.hoLO_start_ori.addWidget(self.spinBox_start_orientation)
        # add start orientation layout to tab layout
        self.vertLO_tab_adv.addLayout(self.hoLO_start_ori)
        # spacer
        spacerItem8 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem8)
        # line
        self.line_9 = MyQLine(self, "line_9")
        self.vertLO_tab_adv.addWidget(self.line_9)
        # spacer
        spacerItem9 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem9)
        # grid layout fishsize threshold
        self.gridLO_fishsize_th = QtGui.QGridLayout()
        self.gridLO_fishsize_th.setObjectName(_fromUtf8("gridLO_fishsize_th"))
        # label fishsize threshold
        self.lbl_fishsize_threshold = QtGui.QLabel(self)
        self.lbl_fishsize_threshold.setObjectName(_fromUtf8("lbl_fishsize_threshold"))
        self.gridLO_fishsize_th.addWidget(self.lbl_fishsize_threshold, 0, 0, 1, 1)
        # spinbox fishsize threshold
        self.spinBox_fish_threshold = QtGui.QSpinBox(self)
        self.spinBox_fish_threshold.setMaximum(9999)
        self.spinBox_fish_threshold.setObjectName(_fromUtf8("spinBox_fish_threshold"))
        self.gridLO_fishsize_th.addWidget(self.spinBox_fish_threshold, 0, 1, 1, 1)
        # label maximum fishsize threshold
        self.lbl_max_fishsize_threshold = QtGui.QLabel(self)
        self.lbl_max_fishsize_threshold.setObjectName(_fromUtf8("lbl_max_fishsize_threshold"))
        self.gridLO_fishsize_th.addWidget(self.lbl_max_fishsize_threshold, 1, 0, 1, 1)
        # spinbox maximum fishsize threshold
        self.spinBox_fish_max_threshold = QtGui.QSpinBox(self)
        self.spinBox_fish_max_threshold.setMaximum(9999)
        self.spinBox_fish_max_threshold.setObjectName(_fromUtf8("spinBox_fish_max_threshold"))
        self.gridLO_fishsize_th.addWidget(self.spinBox_fish_max_threshold, 1, 1, 1, 1)
        # add fishsize layout to tab layout
        self.vertLO_tab_adv.addLayout(self.gridLO_fishsize_th)
        # checkbox enable maximum size threshold
        self.cbx_enable_max_size_thresh = QtGui.QCheckBox(self)
        self.cbx_enable_max_size_thresh.setObjectName(_fromUtf8("cbx_enable_max_size_thresh"))
        self.vertLO_tab_adv.addWidget(self.cbx_enable_max_size_thresh)
        # spacer
        spacerItem10 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.vertLO_tab_adv.addItem(spacerItem10)

    def connect_widgets(self, controller):
        self.connect(self.spinBox_starting_x1_factor, QtCore.SIGNAL("valueChanged(int)"), controller.change_starting_area_factors)
        self.connect(self.spinBox_starting_x2_factor, QtCore.SIGNAL("valueChanged(int)"), controller.change_starting_area_factors)
        self.connect(self.spinBox_starting_y1_factor, QtCore.SIGNAL("valueChanged(int)"), controller.change_starting_area_factors)
        self.connect(self.spinBox_starting_y2_factor, QtCore.SIGNAL("valueChanged(int)"), controller.change_starting_area_factors)

        self.connect(self.spinBox_frame_waittime, QtCore.SIGNAL("valueChanged(int)"), controller.change_frame_waittime)

        self.connect(self.spinBox_start_orientation, QtCore.SIGNAL("valueChanged(int)"), controller.change_start_orientation)

        self.connect(self.spinBox_fish_threshold, QtCore.SIGNAL("valueChanged(int)"), controller.change_min_fish_threshold)
        self.connect(self.spinBox_fish_max_threshold, QtCore.SIGNAL("valueChanged(int)"), controller.change_max_fish_threshold)
        self.connect(self.cbx_enable_max_size_thresh, QtCore.SIGNAL("stateChanged(int)"), controller.change_enable_max_size_threshold)
        return

    def retranslate_tab_adv(self):
        self.lbl_frame_waittime.setText(_translate("tracker_main_widget", "Frame Waittime (ms)", None))
        self.lbl_start_area.setText(_translate("tracker_main_widget", "Starting Area (calculated in %)", None))
        self.lbl_start_x_end.setText(_translate("tracker_main_widget", "X End", None))
        self.lbl_start_y_start.setText(_translate("tracker_main_widget", "Y Start", None))
        self.lbl_start_y_end.setText(_translate("tracker_main_widget", "Y End", None))
        self.lbl_start_x_start.setText(_translate("tracker_main_widget", "X Start", None))
        self.lbl_start_orientation.setText(_translate("tracker_main_widget", "Starting Orientation", None))
        self.lbl_fishsize_threshold.setText(_translate("tracker_main_widget", "Fish Detection min Size Threshold", None))
        self.lbl_max_fishsize_threshold.setText(_translate("tracker_main_widget", "Fish Detection max Size Threshold", None))
        self.cbx_enable_max_size_thresh.setText(_translate("tracker_main_widget", "Enable max Size Threshold", None))


# coding: utf-8

import sys
import difflib

def readfile(filename):
    try:
        fileHandler = open(filename, 'rb')
        text = fileHandler.read().splitlines()
        fileHandler.close()

        return text
    except IOError as error:
        print ('Error: ' + str(error))
        sys.exit()

try:
    file1 = sys.argv[1]
    file2 = sys.argv[2]
except Exception as e:
    print ('Error:' + str(e))
    sys.exit()

file1_lines = readfile(file1)
file2_lines = readfile(file2)

diff = difflib.HtmlDiff()
print (diff.make_file(file1_lines, file2_lines))


import sys
sys.stdin = open("input.txt","r")
from collections import deque

def bfs(node):
    q = deque()
    q.append(node)
    check[node] = 0
    while q:
        node = q.popleft()
        for i in range(1, 7):
            n = node + i
            if n > 100:
                continue
            # 다음으로 넘어갈 부분의 인덱스 값
            t = graph[n]
            # 안들린 노드이면 들리고 다시 q에 넣는다.
            if check[t] == -1:
                q.append(t)
                check[t] = check[node] + 1

N, M = map(int, input().split())
graph = [i for i in range(101)]
check = [-1] * 101
for _ in range(N):
    u, v = map(int, input().split())
    graph[u] = v
for _ in range(M):
    u, v = map(int, input().split())
    graph[u] = v

bfs(1)
print(check[100])