import os
import GPUtil
import shutil
import subprocess
import socket

import json
from omegaconf import DictConfig, open_dict
import torch
from filelock import FileLock

from utils.general import resolve_relative_paths, pid_exists

def take_free_gpus(num_gpus, ignore_used=False):
    taken_file_path = _get_taken_file_path()
    os.makedirs(os.path.dirname(taken_file_path), exist_ok=True)

    """if num_gpus > 0 and "SLURM_PROCID" in os.environ and len(os.environ.get("CUDA_VISIBLE_DEVICES", "")) == 0:
        raise Exception("GPU was not assigned on SLURM")"""
    if "LOCAL_RANK" in os.environ or "SLURM_PROCID" in os.environ:
        # if in DDP we have "LOCAL_RANK"/"SLURM_PROCID" then the right CUDA_VISIBLE_DEVICES was already set
        # cpu_copy_files.sh is a disguise to vscode.sh
        if os.environ.get("SLURM_JOB_NAME") != "cpu_copy_files.sh":
            return

    CUDA_VISIBLE_DEVICES_STR = os.environ.get("CUDA_VISIBLE_DEVICES", "0,1,2,3,4,5,6,7")
    if len(CUDA_VISIBLE_DEVICES_STR.strip()) == 0:
        CUDA_VISIBLE_DEVICES_STR = "0,1,2,3,4,5,6,7"
    CUDA_VISIBLE_DEVICES = list(map(int, CUDA_VISIBLE_DEVICES_STR.split(",")))

    if os.environ.get("CUDA_DEVICES_CHOSEN", "0") == "1":
        # only update taken gpus
        with FileLock(f"{taken_file_path}.lock") as lock:
            taken_gpus, taken_gpus_dict = _get_taken_gpus()
            taken_gpus_dict.update(
                {str(os.getpid()): list(set(taken_gpus_dict.get(str(os.getpid()), []) + CUDA_VISIBLE_DEVICES))}
            )
            with open(taken_file_path, mode="w") as f:
                json.dump(taken_gpus_dict, f)
        return

    with FileLock(f"{taken_file_path}.lock") as lock:
        taken_gpus, taken_gpus_dict = _get_taken_gpus()

        all_gpus = GPUtil.getGPUs()
        available_gpus = [gpu for gpu in all_gpus if gpu.id in CUDA_VISIBLE_DEVICES and gpu.id not in taken_gpus]
        free_gpus_ids = [
            gpu.id
            for gpu, availability in zip(
                available_gpus, GPUtil.getAvailability(available_gpus, maxLoad=0.2, maxMemory=0.01)
            )
            if bool(availability) or ignore_used
        ]
        selected_gpus = free_gpus_ids[:num_gpus]

        if len(all_gpus) > 0 and len(free_gpus_ids) < num_gpus:
            raise GPUException(
                f"Requested {num_gpus} GPUs but only {len(free_gpus_ids)} are available: {free_gpus_ids}"
            )

        os.environ["CUDA_VISIBLE_DEVICES"] = ",".join(map(str, selected_gpus))

        taken_gpus_dict.update(
            {str(os.getpid()): list(set(taken_gpus_dict.get(str(os.getpid()), []) + selected_gpus))}
        )

        with open(taken_file_path, mode="w") as f:
            json.dump(taken_gpus_dict, f)

def _get_taken_file_path():
    taken_file_path = resolve_relative_paths(os.path.join("../taken_gpus", f"{socket.gethostname()}.json"))
    return taken_file_path

def _get_taken_gpus():
    taken_file_path = _get_taken_file_path()
    taken_gpus = set()
    if os.path.isfile(taken_file_path):
        with open(taken_file_path, mode="r") as f:
            taken_gpus_dict = json.load(f)
        pids_to_delete = set()
        for pid_str in taken_gpus_dict.keys():
            pid = int(pid_str)
            if pid_exists(pid):
                taken_gpus.update(taken_gpus_dict[pid_str])
            else:
                pids_to_delete.add(pid_str)
        for pid_to_delete in pids_to_delete:
            del taken_gpus_dict[pid_to_delete]
    else:
        taken_gpus_dict = {}
    return taken_gpus, taken_gpus_dict

def remove_gpus_for_pid(gpus, pid):
    taken_file_path = _get_taken_file_path()
    with FileLock(f"{taken_file_path}.lock") as lock:
        taken_gpus, taken_gpus_dict = _get_taken_gpus()
        if str(pid) in taken_gpus_dict:
            taken_gpus_for_pid = taken_gpus_dict[str(pid)]
            for gpu in gpus:
                if gpu in taken_gpus_for_pid:
                    taken_gpus_for_pid.remove(gpu)
            with open(taken_file_path, mode="w") as f:
                json.dump(taken_gpus_dict, f)

def get_device_memory_info(device):
    queries = ["used", "total"]
    gpu_memory_queries = {}
    for query in queries:
        nvidia_smi_path = shutil.which("nvidia-smi")
        if nvidia_smi_path is None:
            raise FileNotFoundError("nvidia-smi: command not found")
        result = subprocess.run(
            [nvidia_smi_path, f"--query-gpu=memory.{query}", "--format=csv,nounits,noheader"],
            encoding="utf-8",
            capture_output=True,
            check=True,
        )
        # Convert lines into a dictionary
        gpu_memory_queries[query] = [float(x) for x in result.stdout.strip().split(os.linesep)]

    return {query: gpu_memory_queries[query][device] for query in queries}

def config_modifications_for_gpu(cfg: DictConfig):
    if "gpus" not in cfg.trainer:
        with open_dict(cfg):
            cfg.trainer.gpus = 0
    if cfg.trainer.gpus != 0:
        take_free_gpus(cfg.trainer.gpus, ignore_used=cfg["global"].get("ignore_used_gpus", False))
        if not torch.cuda.is_available():
            with open_dict(cfg):
                cfg.trainer.gpus = 0
                cfg.datamodule.pin_memory = False

    if cfg.trainer.get("precision") == 16 and cfg.trainer.gpus == 0:
        # Without this precision will be converted by PyTorch Lightning to bf16 automatically which is extremely slow on CPU
        with open_dict(cfg):
            del cfg.trainer["precision"]

class GPUException(Exception):
    pass


# -*- coding:utf-8 -*-
#filename:atoi.py

class Atoi:
    def __init__(self, inputStr):
        #初始化输入变量
        self.inputStr = inputStr
    def atoi(self):
        #创建digitList用来存储数字
        diglitList = []
        #判断输入的是否为字符串
        if isinstance(self.inputStr, str):
            counter = 0
            #在字符串里循环，判断第一个非空是否是‘-’和数字，如果是，就添加到diglitList里面，如果不是就退出
            while counter < len(self.inputStr):
                if self.inputStr[counter] == '-':
                    digitList.append(self.inputStr[counter])
                    counter += 1
                elif self.inputStr[counter].isdigit():
                    digitList.append(self.inptuStr[counter])
                    counter += 1
                    if not self.inputStr[counter].isdigit():
                        break
                else:
                    counter += 1
        else:
            print("the input str is not correct!")
        #将diglist的数字相连节后，返回int类型的数字
        outStr = "".join(digitList)
        return int(outStr)

if __name__=='__main__':
    inputStr = '   -211 22alkjla  daf'
    atoi = Atoi(inputstr)
    outstr = atoi.atoi()
    print(outstr)


# -*- coding: utf-8 -*-
"""
Created on Mon Mar 28 01:29:23 2016

@author: James
"""

import urllib2
import os

url = "http://www.retrosheet.org/gamelogs/"

for x in range(1871,2016,1):
    f_name = "gl" + str(x) + ".zip"
    url_f = url + f_name
    request = urllib2.urlopen(url_f)

    zip_f = open(os.getcwd() + os.sep + "game_logs" + os.sep + f_name,"w")
    zip_f.write(request.read())
    zip_f.close()


"""Integration tests for the ``forget-me-not`` command."""

import contextlib
import os
from unittest import mock

from check_oldies import forget_me_not

from . import base

@contextlib.contextmanager
def in_working_directory(path):
    current = os.getcwd()
    try:
        os.chdir(path)
        yield
    finally:
        os.chdir(current)

@mock.patch("check_oldies.annotations.get_line_blame", base.fake_get_line_blame)
def test_forget_me_not(capfd):  # capfd is a pytest fixture
    with in_working_directory(base.TEST_DIR_PATH / 'data'):
        forget_me_not.main(argv=[])
    captured = capfd.readouterr()

    stdout = captured.out.rstrip().split(os.linesep)
    expected = [
        "Found annotations or old branches of unknown authors (forwarded to catch-all@example.com):",
        "jane.doe",
        "unknown",
        "catch-all@example.com",
        "    Hello,",
        "",
        "You have 2 old annotation(s) that will block builds in less than 15 days:",
        "",
        "2 days: project5:file1.py:1: # TIMEBOMB: report me (no author => catch-all)",
        "2 days: project5:file1.py:2: # TIMEBOMB (unknown): report me (unknown author => catch-all)",
        "",
        "-- ",
        "Sent by forget-me-not",
        "",
        "--------------------",
        "john.smith@example.com",
        "    Hello,",
        "",
        "You have 3 old annotation(s) that will block builds in less than 15 days:",
        "",
        "2 days: project5:file1.py:3: # TIMEBOMB (jsmith): report me to john.smith@example.com",
        "2 days: project5:file1.py:4: # TIMEBOMB (js): report me to john.smith@example.com (alias)",
        "2 days: project5:file1.py:5: # TIMEBOMB (john.smith@example.com): report me to john.smith@example.com (email)",
        "",
        "-- ",
        "Sent by forget-me-not",
        "",
        "--------------------",
    ]
    assert stdout == expected


#Questão numero 2 30/11/2021
def naorepeticao(v2):
    nv=[0]*20
    x=0
    for h in range(0,20):
        found=False
        for k in range(0,x):
            if v2[h]==0:
                found=True
        if not found:
            nv[x]=v2[h]
            x+=1
    return nv
def cv(v1):
    for h in range(0,20):
        v1[h]=int(input('Coloque os números do vetor : '))
    return v1
v3=[0]*20
cv(v3)
print('O vetor de maneira ordenada é : ', naorepeticao(v3))


'''
    NOTE: we did not include python shebang because this should be run by the venv python

    should be run by cron at intervals (e.g., 2 times per day)
    example:
        0 8,18 * * * /home/andrew/src/python/macdisk/disk-cron.py

    This module will send an SMS to the recipients with the disk utilization
    on the server. Disk utilization is stored in a sqlite3 database (disk.db).
    The database is normally in the folder /home/andrew/src/python/disk
    The database has a table: disk (see disk.py for table structure)

    NOTE: if crontab is not running this file, it may be due to the python path
    best to use the virtual environment, so the crontab should look like:
        0 8,18 * * * /home/andrew/src/python/.venv/bin/python /home/andrew/src/python/macdisk/disk-cron.py
    using that path, all additional modules (like request) will be included.
'''

import sqlite3
from datetime import datetime
import cred
import json
import http.client
import urllib.parse
import cred
from sms import sendSMS

now = datetime.now()

db = sqlite3.connect('/home/andrew/src/python/disk/disk.db')
db.row_factory = sqlite3.Row
cur = db.cursor()
sql = "select * from disk where runid = (select max(runid) from disk) and filesystem like '%root%'"
cur.execute(sql)
data = cur.fetchone()

# 16APR2023@09:46 - if no data returned, do not error out.

# worth mentioning again - cur.fetchone() returns None if there is no data
# but cur.fetchall() returns an empty set [] if there is no data.

if data is None:
    msg = 'No disk utilization records'
else:
    msg = 'Disk Utilization on Mac server:\n'
    msg += 'Timestamp: {}\n'.format(data['runid'])
    msg += 'Filesystem: {}\n'.format(data['filesystem'])
    msg += 'Total Blocks: {}\n'.format(data['blocks'])
    msg += 'Used Blocks: {}\n'.format(data['blocks_used'])
    msg += 'Available Blocks: {}\n'.format(data['blocks_available'])
    msg += 'Percentage used: {}\n'.format(data['used_percent'])
    msg += 'Mount Point: {}'.format(data['mount_point'])

response = sendSMS(msg, cred.recipients)

# 16APR2023@09:32 - logging success/failure of SMS
sql = 'insert into log (logtime, message) values (?, ?)'
cur.execute(sql, [now, response])
db.commit()

# close the database END OF PROGRAM
db.close()

# code below is the old Uwazii Mobile API
# --------------------------------------
#
#jsondata = {
#    "SenderId": cred.SenderId,
#    "Is_Unicode": False,
#    "Is_Flash": False,
#    "SchedTime": "",
#    "GroupId": "",
#    "ServiceId": "",
#    "CoRelator": "",
#    "LinkId": "",
#    "MobileNumbers": cred.MobileNumbers,
#    "Message": msg,
#    "ApiKey": cred.ApiKey,
#    "ClientId": cred.ClientId
#}
#
#jsondata = json.dumps(jsondata)
#
#headers = {
#    "content-type": "application/json",
#    "cache-control": "no-cache"
#}
#
#conn = http.client.HTTPSConnection("api.uwaziimobile.com")
#conn.request("POST", "/api/v2/SendSMS", body=jsondata, headers=headers)
#res = conn.getresponse()
#data = res.read()
#conn.close()
#


import pyo
import numpy as np
import time
from functools import cache
from colorsys import hls_to_rgb
from librosa import note_to_hz as hz
from dissonant import harmonic_tone, dissonance
from antophone import utils
from antophone.phone.config import Config

C = Config.instr

class Instrument:
    def __init__(self):
        layout = C.layout
        xcopies, ycopies = C.copies
        self.layout_width = len(layout[0])
        self.layout_height = len(layout)
        self.width = self.layout_width * xcopies
        self.height = self.layout_height * ycopies
        self.volumes = np.zeros((self.height, self.width))
        self.freq_vols = dict()
        self.audible_freqs = np.array([])
        self.sound_objs = []
        self.dissonance = 0.0
        self.mute = False
        self.audio_server = pyo.Server(buffersize=C.buffer_size).boot()

        for row in layout * ycopies:
            for note in row * xcopies:
                freq = float(hz(note))
                self.freq_vols[freq] = 0.0
                table = pyo.TriangleTable(order=C.partials).normalize()
                sound = pyo.Osc(table=table, freq=freq, mul=0.0)
                self.sound_objs.append(sound)

        self.max_freq = float(max(self.freq_vols.keys()))
        self.running = False

    def run(self):
        self.audio_server.start()
        for sound in self.sound_objs:
            sound.out()

        self.running = True
        while self.running:
            self.update()

        self.audio_server.shutdown()
        for sound in self.sound_objs:
            sound.stop()

    def stop(self):
        self.running = False

    def toggle_mute(self):
        if self.mute:
            self.audio_server.amp = self._last_amp
            self.mute = False
            self._amp = None
        else:
            self._last_amp = self.audio_server.amp
            self.audio_server.amp = 0
            self.mute = True

    def touch(self, x, y, impact):
        assert impact >= 0.0 and impact <= C.per_square_vol_cap

        self.volumes[y][x] += impact

        # apply sympathetic resonances
        for dx, dy in zip(*C.resonances):
            (rdecay_x, rdecay_y) = C.resonance_decay_factor
            dfx = impact / (rdecay_x*abs(dx))
            dfy = impact / (rdecay_y**abs(dy))
            xnext = x + dx
            ynext = y + dy
            if xnext < self.width and xnext >= 0:
                self.volumes[y][xnext] += dfx
            if ynext < self.height and ynext >= 0:
                self.volumes[ynext][x] += dfy

        self.update_sounds()

    def touch_freq(self, freq, impact, tolerance=0):
        '''tolerance: cents range'''

        for y in range(self.height):
            for x in range(self.width):
                f = self.freq_at(x, y)
                if (tolerance == 0 and freq == f) or (abs(utils.diff_cents(f, freq)) < tolerance):
                    self.touch(x, y, impact)

    def update(self):
        ts = utils.ts()

        # decay
        self.volumes *= (1 - C.decay_rate)
        self.update_sounds()

        ts_delta = utils.ts() - ts
        remaining = (C.update_cycle_time - ts_delta) % C.update_cycle_time
        time.sleep(max(remaining, 0))

    def update_sounds(self):
        self.volumes[self.volumes > C.per_square_vol_cap] = C.per_square_vol_cap
        self.volumes[self.volumes < C.per_square_vol_floor] = 0.0

        new_freq_vols = dict()
        for y in range(self.height):
            for x in range(self.width):
                freq = self.freq_at(x, y)
                vol = new_freq_vols.get(freq, 0.0) + self.volumes[y][x]
                new_freq_vols[freq] = vol

        audible_freqs = set()
        for freq, vol in new_freq_vols.items():
            vol = min(vol, C.per_freq_vol_cap)
            new_freq_vols[freq] = vol
            if vol > 0:
                audible_freqs.add(freq)

        # apply volumes
        for sound in self.sound_objs:
            vol = float(new_freq_vols[sound.freq])
            vol = vol if freq <= C.freq_cap else 0.0
            sound.mul = min(max(vol, 0.0), 1.0)

        self.audible_freqs = np.array(list(audible_freqs))
        self.freq_vols = new_freq_vols
        self.last_dissonance = self.dissonance
        self.dissonance = self.get_dissonance()

    def get_dissonance(self):
        if len(self.audible_freqs):
            freqs, amps = harmonic_tone(self.audible_freqs, n_partials=C.partials)
            return dissonance(freqs, amps, model='sethares1993')
        return 0.0

    def get_grid_colors(self):
        colors = []
        for y in range(self.height):
            row = []
            for x in range(self.width):
                vol = self.volumes[y][x]
                freq = self.freq_at(x, y)
                color = self.freq_to_color(freq, vol)
                row.append(color)
            colors.append(row)
        return colors

    @cache
    def freq_to_color(self, freq, vol):
        if vol == 0:
            return C.bg_color
        return [min(255, int(val * 255)) for val in hls_to_rgb(
            freq / self.max_freq,
            vol,
            C.color_saturation,
        )]

    @cache
    def freq_at(self, x, y):
        return float(self.sound_objs[((y * self.width) + x) % len(self.sound_objs)].freq)


# Baekjoon 11725 - 트리의 부모 찾기
# Silver 2
# 그래프 - 트리

#1. recursive function 이용한 dfs
#이 경우 재귀 깊이 제한을 건드려야함
#아이디어는 단순히 dfs를 이용하여 시작노드(1)부터 검색하고 시작노드가 다음 노드의 부모가 되도록 설정
import sys
sys.setrecursionlimit(200000)
input = sys.stdin.readline

def dfs(node):

    visited[node] = True

    for i in graphs[node]:
        if not visited[i]:
            parents[i] = node
            dfs(i)

n = int(input())

graphs = [[] for _ in range(n+1)]
for _ in range(n-1):
    a, b = map(int, input().split())
    graphs[a].append(b)
    graphs[b].append(a)

parents = [0] * (n+1)
visited = [False] * (n+1)

dfs(1)

for i in parents[2:]:
    print(i)

#2. stack 이용한 dfs
# def dfs():

#     stack = [1]
#     visited[1] = True

#     while stack:
#         node = stack.pop()
#         for i in graphs[node]:
#             if not visited[i]:
#                 visited[i] = True
#                 parents[i] = node
#                 stack.append(i)

# n = int(input())

# graphs = [[] for _ in range(n+1)]
# for _ in range(n-1):
#     a, b = map(int, input().split())
#     graphs[a].append(b)
#     graphs[b].append(a)

# parents = [0] * (n+1)
# visited = [False] * (n+1)

# dfs()

# for i in parents[2:]:
#     print(i)


"""
URLConf del modulo de asignaturas
"""

from django.contrib import admin
from django.urls import path

from .views import *

app_name = 'asignaturas'
urlpatterns = [
    path('', Index.as_view(), name='dashboard'),
    path('tabla', AsignaturasAsJson.as_view(), name='all-json'),
    path('detalles/<int:pk>', AsignaturaDetallesView.as_view(), name='detalles'),
    path('eliminar/', EliminarAsignaturaView.as_view(), name='eliminar-asignatura'),
    path('anadir/', AnadirAsignaturaView.as_view(), name='anadir-asignatura'),
]


# thresholding - binarization of the image, pixels are either white or black on the picture
import cv2 as cv
import numpy as np

img = cv.imread('/Users/zhenyabudnyk/PycharmProjects/OpenCV_learning2/images/man.jpg')
cv.imshow("man", img)

blank = np.zeros((400,400), dtype='uint8')

gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
cv.imshow('gray', gray)

# simple thresholding

threshold, thresh = cv.threshold(gray, 150, 255, cv.THRESH_BINARY) #comapres each pixel with threshold value and changes to the 255 or 0
cv.imshow('simple', thresh)

threshold, thresh = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV) #comapres each pixel with threshold value and changes to the 255 or 0
cv.imshow('simple dimple', thresh)

#adaptive threshold - different immages with different threshold
#openCV computes the threshold by itself taking into account the kernel size on the basis of the mean or by gaussian distribution

adaptive_thresh = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 1)
cv.imshow('adaptive', adaptive_thresh)

cv.waitKey(0)


import pygame
from pygame import Surface
import os

# Fonctions, classes et constantes utiles

TITLE = "Le meilleur jeu du monde (et le plus modeste)"
FPS = 60  # Le cap du framerate

ACC = 0.5
FRICTION = -0.12

# Quelques Couleurs
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (255,0,255) #COLORKEY

class Spritesheet:

    def __init__(self, file):

        #self.image = pygame.image.load(file).convert_alpha()
        self.image = file

    def get_region(self, x, y, width, height):

        rimage = pygame.Surface((width, height),pygame.SRCALPHA)
        rimage.blit(source=self.image, dest=(0, 0), area =(x, y, width, height))
        return rimage

class Camera(object):

    def __init__(self, game ,camera_func, width, height):
        self.camera_func = camera_func
        self.state = pygame.rect.Rect(0, 0, width, height)
        self.game = game

    def apply(self, target):
        return target.rect.move((int(self.state.left),int(self.state.top)))

    def update(self, target):
        self.state = self.camera_func(self ,self.state, target.rect)

    def follow_camera(self, camera, target_rect):
        l, _, _, _ = target_rect
        _, _, w, h = camera
        #return pygame.rect.Rect(int(-l + WIDTH / 2),int( -t + HEIGHT / 2),int(w),int(h))
        return pygame.rect.Rect(int(-l + self.game.width / 4),0,int(w),int(h))

class ResourcesManager():

    def __init__(self,resources_path):
        self.path = resources_path

    def load_image(self,name,alpha,scale=None):

        img = pygame.image.load(os.path.join(self.path,name))
        if not scale == None:
            img = pygame.transform.scale(img,scale)
        if alpha :
            return img.convert_alpha()
        else :
            return img.convert()

    def load_sound(self,name):

        return pygame.mixer.Sound(os.path.join(self.path,name))


from math import sqrt
from bisect import *
import sys
input = sys.stdin.readline

prime = [0, 0] + [1 for _ in range(1299708)]
for i in range(2, int(sqrt(1299709))+1):
    j = 2
    if prime[i]:
        while i*j <= 1299709:
            prime[i*j] = 0
            j += 1
prime_number = []
for i in range(2, 1299710):
    if prime[i]: prime_number.append(i)
check_prime = set(prime_number)
for _ in range(int(input())):
    k = int(input())
    if k in check_prime: print(0)
    else:
        x = bisect_right(prime_number, k)
        print(prime_number[x]-prime_number[x-1])


# -*- coding:utf-8 -*-
# pip3 install xlsxwriter
# pip3 install selenium

try:
    import urllib.request as urllib2
except ImportError:
    import urllib2
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
# from fake_useragent import UserAgent
import xlsxwriter
import time
import os, sys

def checkAlert(driver):
    try:
        WebDriverWait(driver, 0).until(EC.alert_is_present(),
                                        'Timed out waiting for PA creation ' +
                                        'confirmation popup to appear.')

        alert = driver.switch_to.alert
        alert.accept()
        # print("alert accepted")
    except TimeoutException:
        pass
        # print("no alert")

def getDetailInfo(driver, js):
    try:
        driver.execute_script(js)
        # time.sleep(2)
        checkAlert(driver)

        html = driver.page_source
        soup = BeautifulSoup(html)
        finds = soup.find("div", {"class": "find_info"})
        details = finds.find_all("li")

        for detail in details:
            title = detail.find('p', {"class": "find01"}).text
            if title == '물품분류':
                category = detail.find('p', {"class": "find02"}).text
                driver.back()
                # time.sleep(2)
                return category
        return "None > None"
    except:
        return "None > None"

def driverInit(driver):
    try:
        if driver is None:
            pass
        else:
            driver.close()
    except:
        pass
    finally:
        dir = os.getcwd() + '/chromedriver'
        driver = webdriver.Chrome(dir)

    driver.set_window_size(100, 100)
    driver.set_window_position(50, 50)
    driver.get('https://www.lost112.go.kr/find/findList.do')

    driver.execute_script("document.getElementById('startYmdInput').value = '20171001';")
    searchBtn = driver.find_element_by_id('searchMain')
    searchBtn.submit()

    return driver

start = 1
finish = 10

# ua = UserAgent()
# dir = os.getcwd() + '/chromedriver'
# print(dir)
# driver = webdriver.Chrome(dir)

# driver = webdriver.Chrome()
# driver.get('https://www.lost112.go.kr/find/findList.do')

# driver.execute_script("document.getElementById('startYmdInput').value = '20171001';")
# searchBtn = driver.find_element_by_id('searchMain')
# searchBtn.submit()

driver = driverInit(None)

# jsList = []
# categories = []

start = int(input("Start Page : "))
finish = int(input("Finish Page : "))

workbook = xlsxwriter.Workbook('findList(%d-%d).xlsx' % (start, finish))
worksheet = workbook.add_worksheet()

row = 0
col = 0
count = 0

try:

    dataList = []
    for page in range(start, finish+1):

        if count >= 30:
            print("Reopen Chrome")
            count = 0
            driver = driverInit(driver)
            # driver.close()
            # driver = webdriver.Chrome(dir)
            # driver.get('https://www.lost112.go.kr/find/findList.do')
        count += 1

        print("Page %d/%d" % (page, finish))

        driver.execute_script('fn_find_link_page(%d);' % page)
        # time.sleep(2)
        checkAlert(driver)

        html = driver.page_source
        soup = BeautifulSoup(html)
        lostList = soup.find_all("td", {"class": "board_title1 "})

        for lost in lostList:
            # print(lost)
            title = lost.find('a').text
            title = title.replace('\n', '').replace('\t', '')
            js = lost.find('a')['href']
            category = getDetailInfo(driver, js)
            js = str(js)
            itemId = js[js.index("(\'")+2:js.index("\',")]
            # dataList.append(data)
            category = str(category)
            categories = category.split('>')
            c1 = categories[0].strip()
            c2 = ""
            if len(categories) > 1:
                c2 = categories[1].strip()
            data = {'id': itemId, 'title': title, 'js': js, 'category1': c1, 'category2': c2}
            print(title)

            worksheet.write(row, 0, data['id'])
            worksheet.write(row, 1, data['title'])
            worksheet.write(row, 2, data['category1'])
            worksheet.write(row, 3, data['category2'])
            worksheet.write(row, 4, data['js'])
            row += 1

finally:
    workbook.close()
    driver.close()

# print()
# for data in dataList:
#     print(data)
#     worksheet.write(row, 0, data['id'])
#     worksheet.write(row, 1, data['title'])
#     worksheet.write(row, 2, data['category'])
#     worksheet.write(row, 3, data['js'])
#     row += 1

# workbook.close()

# driver.execute_script(jsList[0])
# time.sleep(3)
# print(getDetailInfo(driver))
# html = driver.page_source
# soup = BeautifulSoup(html)
# lostList = soup.find_all("p", {"class": "find_info_name"})
#
# print(lostList)

# driver.close()


import os
import logging

LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "default": {
            "format": "%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s",

        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level":  "INFO",
            "formatter": "default",
            "stream": "ext://sys.stdout",
        },
        "file": {
            "class": "logging.FileHandler",
            "level": "WARNING",
            "formatter": "default",
            "filename": "",
        },
    },
}


# ABBA처럼 어느 방향에서 읽어도 같은 문자열을 회문이라 한다. NxN 크기의 글자판에서 길이가 M인 회문을 찾아 출력하는 프로그램을 만드시오.
# 회문은 1개가 존재하는데, 가로 뿐만 아니라 세로로 찾아질 수도 있다.
# 예를 들어 N=10, M=10 일 때, 다음과 같이 회문을 찾을 수 있다.
# [입력]
# 첫 줄에 테스트 케이스 개수 T가 주어진다.  1≤T≤50
# 다음 줄부터 테스트케이스의 첫 줄에 N과 M이 주어진다. 10≤N≤100, 5≤M≤N
# 다음 줄부터 N개의 글자를 가진 N개의 줄이 주어진다.
# [출력]
# 각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다.

test = int(input())
for tc in range(test):
    n,m = map(int,input().split())
    datas = []
    for row in range(n):
        datas.append(list(input()))
    # print(datas)

    garo = []
    sero = []
    result = None
    for line in range(n): #다른줄 확인
        for point in range(n-m+1): #시작 점
            for scale in range(m): #확인 범위
                garo.append(datas[line][point + scale]) #가로로 데이터
                sero.append(datas[point + scale][line]) #세로로 데이터

            #회문 존재 확인
            if garo == garo[::-1]:
                result = garo
                garo = []
                break
            elif sero == sero[::-1]:
                result = sero
                sero = []
                break
            else:
                garo = []
                sero = []

    print('#{} {}'.format(tc+1, ''.join(map(str,result))))


# Randomly fills an array of size 10x10 with 0s and 1s, and outputs the size of
# the largest parallelogram with horizontal sides.
# A parallelogram consists of a line with at least 2 consecutive 1s,
# with below at least one line with the same number of consecutive 1s,
# all those lines being aligned vertically in which case the parallelogram
# is actually a rectangle, e.g.
#      111
#      111
#      111
#      111
# or consecutive lines moved to the left by one position, e.g.
#      111
#     111
#    111
#   111
# or consecutive lines moved to the right by one position, e.g.
#      111
#       111
#        111
#         111
# The size is the number of 1s in the parallelogram. In the above examples, the size is 12.

from random import seed, randrange
import sys

dim = 10

def display_grid():
    for row in grid:
        print('   ', *row)

def size_of_largest_parallelogram():
    # REPLACE PASS ABOVE WITH YOUR CODE
    # row = dim - 1

    computational_stub = [[0 for _ in range(dim)]
                          for _ in range(dim)
                          ]

    computational_left_stub = [[0 for _ in range(dim)]
                               for _ in range(dim)
                               ]
    computational_right_stub = [[0 for _ in range(dim)]
                                for _ in range(dim)
                                ]
    for row in reversed(range(dim)):
        for col in range(dim):
            stub = 0
            rowi = row
            while rowi <= row and rowi >= 0 and grid[rowi][col] != 0:
                stub += 1
                rowi -= 1
            if stub<=1:
                stub=0
            computational_stub[row][col] = stub

            rowl=row
            coll=col
            left=0
            while rowl<=row and rowl>=0 and \
                    coll>=0 and coll<dim and \
                    grid[rowl][coll]!=0:
                left+=1
                rowl-=1
                coll-=1
            if left<=1:
                left=0
            computational_left_stub[row][col] =left

            rowr = row
            colr = col
            right = 0
            while rowr <= row and rowr >= 0 and \
                    colr >= 0 and colr < dim and \
                    grid[rowr][colr] != 0:
                right += 1
                rowr -= 1
                colr += 1
            if right <= 1:
                right = 0
            computational_right_stub[row][col] = right

    # print(("-------mid---------"))
    # for _ in computational_stub:
    #     print('  ', *_)
    #
    # print(("--------left--------"))
    # for _ in computational_left_stub:
    #     print('  ',*_)
    # print(("--------right--------"))
    # for _ in computational_right_stub:
    #     print('  ',*_)
        pass

    max_mid_area = compute(computational_stub)
    max_left_area=compute(computational_left_stub)
    max_right_area=compute(computational_right_stub)
    max_area=max(max_mid_area,max_right_area,max_left_area)
    # print("max_mid_area:",max_mid_area)
    # print("max_left_area:", max_left_area)
    # print("max_right_area:", max_right_area)

    return max_area

# POSSIBLY DEFINE OTHER FUNCTIONS
def compute(stub):
    row = dim - 1
    col = 0

    area_stub = [[0 for _ in range(dim)]
                 for _ in range(dim)
                 ]
    while row >= 0:
        for col in range(dim):
            colj = col
            width = 0
            height = stub[row][col]
            areas=[]
            while colj >= col and colj < dim and stub[row][colj] > 1:
                width += 1
                height = min(height, stub[row][colj])
                if width<=1:
                    areas.append(0)
                else:
                    areas.append(width*height)
                colj += 1
            # if width <= 1:
            #     width = 0
            if len(areas)>0:
                area_stub[row][col] = max(areas)
            else:
                area_stub[row][col]=0
        row -= 1

    max_area = 0
    for row in area_stub:
        new_row = row
        new_row.append(max_area)
        max_area = max(new_row)

    # for _ in area_stub:
    #     print('  ',*_)
    return max_area

try:

    for_seed, density = (int(x) for x in input('Enter two integers, the second '
                                               'one being strictly positive: '
                                               ).split()
                         )
    if density <= 0:
        raise ValueError
except ValueError:
    print('Incorrect input, giving up.')
    sys.exit()

seed(for_seed)
grid = [[int(randrange(density) != 0) for _ in range(dim)]
        for _ in range(dim)
        ]
print('Here is the grid that has been generated:')
display_grid()

size = size_of_largest_parallelogram()
if size:
    print('The largest parallelogram with horizontal sides '
          f'has a size of {size}.'
          )
else:
    print('There is no parallelogram with horizontal sides.')

# while True:
#     try:
#
#         for_seed, density = (int(x) for x in input('Enter two integers, the second '
#                                                    'one being strictly positive: '
#                                                    ).split()
#                              )
#         if density <= 0:
#             raise ValueError
#     except ValueError:
#         print('Incorrect input, giving up.')
#         sys.exit()
#
#     seed(for_seed)
#     grid = [[int(randrange(density) != 0) for _ in range(dim)]
#             for _ in range(dim)
#             ]
#     print('Here is the grid that has been generated:')
#     display_grid()
#     print("*******************************")
#     size = size_of_largest_parallelogram()
#     if size:
#         print('The largest parallelogram with horizontal sides '
#               f'has a size of {size}.'
#               )
#     else:
#         print('There is no parallelogram with horizontal sides.')


import argparse

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

RELEVANT_COLUMNS = ["White", "WhiteElo", "WhiteTitle", "WhiteClocks", "Black", "BlackElo", "BlackTitle",
                    "BlackClocks", "Result"]

def get_result_from_perspective(x, colour):
    if x['Result'] == '1/2-1/2' or x['Result'] == '1/2':
        return 0.5
    elif x['Result'] == '1-0':
        if colour == 'black':
            return 0.0
        else:
            return 1.0
    elif x['Result'] == '0-1':
        if colour == 'black':
            return 1.0
        else:
            return 0.0
    else:
        return np.NaN

def tolerant_mean(arrs):
    """
    :param arrs:
    :return: per move number: average time left, std error, count
    """
    lens = [len(i) for i in arrs]
    arr = np.ma.empty((np.max(lens), len(arrs)))
    arr.mask = True
    for idx, l in enumerate(arrs):
        arr[:len(l), idx] = l
    return np.nanmean(arr, axis=-1), arr.std(axis=-1), arr.count(axis=-1)

parser = argparse.ArgumentParser()
parser.add_argument('csv_file', type=argparse.FileType('r'))
args = parser.parse_args()

game_data = pd.read_csv(args.csv_file, converters={'BlackClocks': pd.eval, 'WhiteClocks': pd.eval})

game_data['WhiteElo'] = pd.cut(game_data['WhiteElo'], bins=np.arange(31) * 100)
game_data['BlackElo'] = pd.cut(game_data['BlackElo'], bins=np.arange(31) * 100)
game_data_white = game_data[RELEVANT_COLUMNS].rename(
    columns={
        "White": "Name",
        "WhiteElo": "Elo",
        "WhiteTitle": "Title",
        "WhiteClocks": "Clocks",
        "Black": "OppName",
        "BlackElo": "OppElo",
        "BlackTitle": "OppTitle",
        "BlackClocks": "OppClocks"
    })
game_data_white["Result"] = game_data_white.apply(get_result_from_perspective, args=("white",), axis=1)

game_data_black = game_data[RELEVANT_COLUMNS].rename(
    columns={
        "White": "OppName",
        "WhiteElo": "OppElo",
        "WhiteTitle": "OppTitle",
        "WhiteClocks": "OppClocks",
        "Black": "Name",
        "BlackElo": "Elo",
        "BlackTitle": "Title",
        "BlackClocks": "Clocks"
    })
game_data_black["Result"] = game_data_black.apply(get_result_from_perspective, args=("black",), axis=1)
player_perspective_data = pd.concat([game_data_white, game_data_black], axis=0)
player_perspective_data = player_perspective_data.dropna(subset=['Result'])

mask = player_perspective_data['Elo'].value_counts() > 100

fig, ax = plt.subplots()
for rating_group in player_perspective_data['Elo'].value_counts()[mask].index.to_list():
    list_of_ys_diff_len = player_perspective_data[player_perspective_data['Elo'] == rating_group]['Clocks'].to_list()
    means, stds, counts = tolerant_mean(list_of_ys_diff_len)
    ax.plot(np.arange(len(means)) + 1, means, label=rating_group)
ax.legend()
plt.savefig("time_usage.png")


# -*- coding:utf-8 -*-
#@Description: 图像预处理完整版样例
#@author xieydd xieydd@gmail.com
#@date 2017-10-17 下午14:09:23
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#给定图像和颜色 color_ordering为可选项 亮度 饱和度 色相 对比度
def distort_color(image,color_ordering=0):
    if color_ordering == 0:
        image = tf.image.random_brightness(image,max_delta=32./255.)
        image = tf.image.random_saturation(image,lower=0.5,upper=1.5)
        image = tf.image.random_hue(image,max_delta=0.2)
        image= tf.image.random_constrast(image,lower=0.5,upper=1.5)
    elif color_ordering == 1:
        image = tf.image.random_saturation(image,lower=0.5,upper=1.5)
        image = tf.image.random_brightness(image,max_delta=32./255.)
        image= tf.image.random_constrast(image,lower=0.5,upper=1.5)
        image = tf.image.random_hue(image,max_delta=0.2)
    #elif color_ordering == 2:其他排列
    return tf.clip_by_value(image,0.0,1.0)

#给定解码后的图片，目标图像尺寸及图像的标注框  输入是图像识别问题中的原始训练数据 输出是神经网络模型输入层
def preprocess_for_train(image,height,width,bbox):
    #如果没有提供标注框就将整个图像作为标注的部分
    if bbox == None:
        bbox = tf.constant([0.0,1.0,0.0,1.0],dtype=tf.float32,shape=[1,1,4])
    #转换图像张量的类型
    if image.dtype != tf.float32:
        image = tf.image.convert_image_dtype(image,dtype=tf.float32)
    #随机截取图像，减小需要关注物体的大小对算法的影响
    bbox_begin,bbox_size,_ = tf.image.sample_distributed_bounding_box(tf.shape(image),bounding_boxes=bbox)
    distorted_image = tf.slice(image,bbox_begin,bbox_size)
    #将随机截取的图像调整成神经网络输入层大小
    distorted_image = tf.image.resize_images(distorted_image,height,width,method=np.random.randint(4))
    #随机左右翻转图像
    distorted_image = tf.image.random_flip_left_right(distorted_image)
    #使用随机的顺序颜色调整图像色彩
    distorted_image = distort_color(distorted_image,color_ordering=np.random.randint(2))
    return distorted_image
image_raw_data = tf.gfile.FastGFile("/path/to/picture",'r').read()
with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(image_raw_data)
    boxes = tf.constant([[[0.05,0.5,0.9,0.7],[0.35,0.47,0.5,0.56]]])
    #运行6次获得不同的图像
    for i in range(6):
        #将图像尺寸调整成299x299
        result = preprocess_for_train(img_data,299,299,boxes)
        plt.imshow(result.eval())
        plt.show()


from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
import impl.utils.config as config
from matplotlib.backends.backend_pdf import PdfPages

def eval_model(model, dataset, folds=20, test_size=0.5):
    X = []
    y = []
    for paper_id, words_one_hot, class_label in dataset.get_content():
        X.append(model[paper_id])
        y.append(class_label)
    clf = LogisticRegression(solver='liblinear', multi_class='ovr')
    scores = []
    accuracies = []
    for i in range(folds):
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=i)
        clf.fit(X_train, y_train)
        y_pred = clf.predict(X_test)
        score = metrics.f1_score(y_test, y_pred, labels=np.unique(y_pred), average='macro')
        accuracy = metrics.accuracy_score(y_test, y_pred)
        scores.append(score)
        accuracies.append(accuracy)
    return [(np.mean(scores), np.std(scores)), (np.mean(accuracies), np.std(accuracies))]

def plot_evals(model, dataset, title, folds=20, test_size=0.5):
    pp = PdfPages(f'./out/figures/{title}.pdf')
    x = [int(val) for val in model.embeddings.keys()]
    y_loss = []
    y_acc = []
    y_macro = []
    config.debug("Evaluating model")
    for epoch in tqdm(model.embeddings.keys(), desc="Evaluating model", disable=(not config.progress)):
        macro, acc = eval_model(model.embeddings[epoch], folds=folds, test_size=test_size, dataset=dataset)
        y_loss.append(model.losses[epoch])
        y_acc.append(acc[0])
        y_macro.append(macro[0])

    # => Accuracy/Loss
    fig1, ax1 = plt.subplots()
    ax1.set_title(title + " (Loss/Accuracy)")
    color = 'tab:blue'
    ax1.set_xlabel('epoch')
    ax1.set_ylabel('average loss (training)', color=color)
    ax1.plot(x, y_loss, color=color, marker='s')
    ax1.tick_params(axis='y', labelcolor=color)

    ax1_2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
    color = 'tab:red'
    ax1_2.set_ylabel('mean accuracy (classification)', color=color)  # we already handled the x-label with ax1
    ax1_2.plot(x, y_acc, color=color, marker='o')
    ax1_2.tick_params(axis='y', labelcolor=color)

    fig1.tight_layout()  # otherwise the right y-label is slightly clipped
    plt.show()
    fig1.savefig(pp, format='pdf')

    # => MacroF1
    fig2, ax2 = plt.subplots()
    ax2.set_title(title + " (Macro F1)")
    ax2.plot(x, y_macro, marker='^')
    plt.show()
    fig2.savefig(pp, format='pdf')

    pp.close()


'''
@author: Faizan-Uni-Stuttgart

Nov 2, 2020

12:43:01 PM

'''
import os
import time
import timeit
from pathlib import Path

import h5py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.ioff()

DEBUG_FLAG = False

def main():

    main_dir = Path(r'P:\Synchronize\IWS\Projects\2016_DFG_SPATE\data\cp_classi_for_partners\ts')
    os.chdir(main_dir)

    in_h5_file = Path(r'test_danube_cosmo2.h5')

    sep = ';'

    float_fmt = '%0.1f'

    out_dir = main_dir

    with h5py.File(in_h5_file, mode='r', driver=None) as h5_hdl:
        keys = [int(key) for key in h5_hdl['x_cen_crds'].keys()]

        for key in keys:
            x_crds = h5_hdl[f'x_cen_crds/{key}'][:]
            y_crds = h5_hdl[f'y_cen_crds/{key}'][:]

            out_df = pd.DataFrame(
                index=np.arange(x_crds.size), columns=['X', 'Y'],
                dtype=float)

            out_df['X'] = x_crds
            out_df['Y'] = y_crds

            out_file_path = (
                out_dir / Path(f'{in_h5_file.stem}__crds_{key}.csv'))

            out_df.to_csv(
                out_file_path,
                sep=sep,
                float_format=float_fmt)

            print('Done with:', out_file_path)

    return

if __name__ == '__main__':

    _save_log_ = False
    if _save_log_:
        from datetime import datetime
        from std_logger import StdFileLoggerCtrl

        # save all console activity to out_log_file
        out_log_file = os.path.join(
            r'P:\Synchronize\python_script_logs\\%s_log_%s.log' % (
            os.path.basename(__file__),
            datetime.now().strftime('%Y%m%d%H%M%S')))

        log_link = StdFileLoggerCtrl(out_log_file)

    print('#### Started on %s ####\n' % time.asctime())
    START = timeit.default_timer()

    #==========================================================================
    # When in post_mortem:
    # 1. "where" to show the stack
    # 2. "up" move the stack up to an older frame
    # 3. "down" move the stack down to a newer frame
    # 4. "interact" start an interactive interpreter
    #==========================================================================

    if DEBUG_FLAG:
        try:
            main()

        except:
            import pdb
            pdb.post_mortem()

    else:
        main()

    STOP = timeit.default_timer()
    print(('\n#### Done with everything on %s.\nTotal run time was'
           ' about %0.4f seconds ####' % (time.asctime(), STOP - START)))

    if _save_log_:
        log_link.stop()


import torch
from torch import nn, optim
import os
import Config
from torch.utils.data import DataLoader
from tqdm import tqdm
from sklearn.metrics import f1_score
from efficientnet_pytorch import EfficientNet
from dataset import DRDataset
from torchvision.utils import save_image
from utils import (
    load_checkpoint,
    save_checkpoint,
    check_accuracy,
    make_prediction,
)

def train_one_epoch(loader, model, optimizer, loss_fn, scaler, device):
    print('Train Begin ')
    losses = []
    loop = tqdm(loader)
    for batch_idx, (data, targets, _) in enumerate(loop):
        # save examples and make sure they look ok with the data augmentation,
        # tip is to first set mean=[0,0,0], std=[1,1,1] so they look "normal"
        #save_image(data, f"hi_{batch_idx}.png")

        data = data.to(device=device)
        targets = targets.to(device=device)

        # forward
        with torch.cuda.amp.autocast():
            scores = model(data)
            loss = loss_fn(scores, targets.unsqueeze(1).float())

        losses.append(loss.item())

        # backward
        optimizer.zero_grad()
        scaler.scale(loss).backward()
        scaler.step(optimizer)
        scaler.update()
        loop.set_postfix(loss=loss.item())

    print(f"Loss average over epoch: {sum(losses)/len(losses)}")

def main():
    # 1 . Preparing DataSets :
    train_ds = DRDataset(
        images_folder="/home/semi/Image_Classification/Full_Preproceed/",
        path_to_csv="/home/semi/Image_Classification/Labels.csv",
        transform=Config.val_transforms,
    )
    test_ds = DRDataset(
        images_folder="/home/semi/Image_Classification/Full_Preproceed/",
        path_to_csv="/home/semi/Image_Classification/Labels.csv",
        transform=Config.val_transforms,
        # train=False,
    )
    # val_ds = DRDataset(
    #     images_folder="/home/semi/Image_Classification/Full_Preproceed/",
    #     path_to_csv="/home/semi/Image_Classification/Labels.csv",
    #     transform=Config.val_transforms,
    # )
    train_loader = DataLoader(
        train_ds,
        batch_size=Config.BATCH_SIZE,
        num_workers=Config.NUM_WORKERS,
        pin_memory=Config.PIN_MEMORY,
        shuffle=False,
    )
    test_loader = DataLoader(
        test_ds, batch_size=Config.BATCH_SIZE, num_workers=6, shuffle=False
    )
    # val_loader = DataLoader(
    #     val_ds,
    #     batch_size=Config.BATCH_SIZE,
    #     num_workers=2,
    #     pin_memory=Config.PIN_MEMORY,
    #     shuffle=False,
    # )
    loss_fn = nn.MSELoss()
    # 2. Building Model :
    model = EfficientNet.from_pretrained("efficientnet-b3")
    model._fc = nn.Linear(1536, 1)
    model = model.to(Config.DEVICE)
    optimizer = optim.Adam(model.parameters(), lr=Config.LEARNING_RATE, weight_decay=Config.WEIGHT_DECAY)
    scaler = torch.cuda.amp.GradScaler()

    if Config.LOAD_MODEL and Config.CHECKPOINT_FILE in os.listdir():
        load_checkpoint(torch.load(Config.CHECKPOINT_FILE), model, optimizer, Config.LEARNING_RATE)

    make_prediction(model, train_loader, "submission_.csv")
    preds, labels = check_accuracy(train_loader, model, Config.DEVICE)
    # print ("The f1 score currently is " , f1_score(preds,labels) )
    print("predictions", preds)
    print("Labels " , labels)
    print ("The f1 score currently is " , f1_score(preds,labels,average = 'weighted')  )

    # for epoch in range(Config.NUM_EPOCHS):
    #     train_one_epoch(train_loader, model, optimizer, loss_fn, scaler, Config.DEVICE)
    #     # get on train
    #     preds, labels = check_accuracy(test_loader, model, Config.DEVICE)
    #     print ("The f1 score currently is " , f1_score(preds,labels,average = 'weighted') )

    #     if Config.SAVE_MODEL:
    #         checkpoint = {
    #             "state_dict": model.state_dict(),
    #             "optimizer": optimizer.state_dict(),
    #         }
    #         save_checkpoint(checkpoint, filename=f"b3_{epoch}.pth.tar")

if __name__ == "__main__":
    main()


# 수업에서 같은 조에 참여하고 싶은 사람끼리 두 사람의 출석 번호를 종이에 적어 제출하였다.
# 한 조의 인원에 제한을 두지 않았기 때문에, 한 사람이 여러 장의 종이를 제출하거나 여러 사람이 한 사람을 지목한 경우 모두 같은 조가 된다.
# 예를 들어 1번-2번, 1번-3번이 같은 조가 되고 싶다고 하면, 1-2-3번이 같은 조가 된다. 번호를 적지도 않고 다른 사람에게 지목되지도 않은 사람은 단독으로 조를 구성하게 된다.
# 1번부터 N번까지의 출석번호가 있고, M 장의 신청서가 제출되었을 때 전체 몇 개의 조가 만들어지는지 출력하는 프로그램을 만드시오.
# [입력]
# 첫 줄에 테스트 케이스의 개수가 주어지고, 다음 줄부터 테스트 케이스 별로 첫 줄에 N과 M, 다음 줄에 M 쌍의 번호가 주어진다. 2<=N<=100, 1<=M<=100
# [출력]
# 각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다.

import sys
sys.stdin = open("input.txt")

def find(x):
    if x != parent[x]: #자신이랑 엄마가 같으면 즉, 자신이 엄마면
        return find(parent[x])
    else:
        return parent[x]

def union(x,y):
    x = find(x) #x엄마 찾기
    y = find(y)
    if x!=y:
        parent[y]=x #y의 엄마가 x가 됨

for tc in range(int(input())):
    num,app = map(int,input().split())

    parent = [0]*(num+1)
    for make in range(1,num+1):
        parent[make] = make
    # print(parent)

    datas = list(map(int,input().split()))
    for check in range(app):
        member1 = datas[2*check]
        member2 = datas[2*check+1]
        union(member1,member2)

    cnt = 0
    result = []
    for target in range(1,num+1):
        result.append(find(target))
        # cnt += 1
    ans = len(list(set(result)))
    print('#{} {}'.format(tc+1,ans))

# for tc in range(int(input())):
#     num,app = map(int,input().split())
#     total = [0]*num
#     for i in range(num):
#         total[i] = i+1
#     # print(total)
#     datas = list(map(int,input().split()))
#     check = 0
#     cnt = 0
#     result = 0
#
#     while check != app and total:
#         member1 = datas[2*check]
#         member2 = datas[2*check+1]
#         if member1 in total and member2 in total:
#             cnt += 1
#             total.remove(member1)
#             total.remove(member2)
#             check += 1
#         elif member1 in total:
#             total.remove(member1)
#             check += 1
#         elif member2 in total:
#             total.remove(member2)
#             check += 1
#     ans = cnt + len(total)
#     print('#{} {}'.format(tc+1,ans))


import sqlite3
import json

# location of SQLite database file
_path_to_db_file = None

# function to set path to database file
def set_path_to_db_file(path_to_db_file):
    global _path_to_db_file
    _path_to_db_file = path_to_db_file

#function to execute an SQL statement
def _execute_sql(sql, read):
    with sqlite3.connect(_path_to_db_file) as conn:
        cursor = conn.cursor()
        cursor.execute(sql)
        if read == 'true':
            output = cursor.fetchall()
            print(output)
            return output
        cursor.close()

# function to create database table
def create_table():
    sql_create_table = """CREATE TABLE users(username PRIMARY KEY, password NOT NULL, lem_id NOT NULL);"""
    _execute_sql(sql_create_table, False)
    # create also table for stores
    sql_create_table = """CREATE TABLE stores(store_id PRIMARY KEY, lem_id NOT NULL, reference NOT NULL);"""
    _execute_sql(sql_create_table, False)
    # create also table for businessLines
    sql_create_table = """CREATE TABLE business(business_line PRIMARY KEY, lem_id NOT NULL, data NOT NULL);"""
    _execute_sql(sql_create_table, False)

# function to insert a user into the database table
def insert_user(user, email, role, description):
    conn = sqlite3.connect(_path_to_db_file)
    cursor = conn.cursor()
    sql_create_table = """CREATE TABLE IF NOT EXISTS usernames(email PRIMARY KEY, user NOT NULL, role NOT NULL, description NOT NULL);"""
    # _execute_sql(sql_create_table, False)
    cursor.execute(sql_create_table)
    sql_insert_user = """INSERT INTO usernames (email, user, role, description) VALUES (?, ?, ?, ?)"""
    cursor.execute(sql_insert_user, (email, user, role, description))
    conn.commit()
    conn.close()
    print("user added")

# function to validate details
def get_data():
    sql_create_table = """CREATE TABLE IF NOT EXISTS usernames(email PRIMARY KEY, user NOT NULL, role NOT NULL, description NOT NULL);"""
    _execute_sql(sql_create_table, False)
    sql_get_user = "SELECT * FROM usernames"
    read = 'true'
    listData = _execute_sql(sql_get_user, read)
    print(listData)
    return listData

def force_delete_table():
    sql_delete_table = "DROP TABLE usernames"
    _execute_sql(sql_delete_table, False)

def delete_user(email):
    try:
        conn = sqlite3.connect(_path_to_db_file)
        cursor = conn.cursor()
        print("Connected to SQLite")
        sql_delete_user = """DELETE FROM usernames WHERE email = ?"""
        cursor.execute(sql_delete_user, (email,))
        conn.commit()
        cursor.close()
    except sqlite3.Error as error:
        print("Failed to read data from sqlite table", error)
    finally:
        if conn:
            conn.close()
            print("The SQLite connection is closed")


import csv
import glob
import os
from collections import namedtuple
from pprint import pprint

import kaldi_io
import numpy as np
import soundfile

from base import util
from base.sound_util import time2sample
from conf import snodgrass_data_dir, processed_data_dir
from dataset_prep.core.cleaning import reject_by_frame_count_snodgrass
from dataset_prep.core.common import fix_scp_encoding
from dataset_prep.core.features import audio2lmfe

SnodgrassWordRating = namedtuple('SnodgrassWordRating',
                                 ['word', 'order', 'p_score', 'p_delay', 'duration', 'synonym', 'comment', 'vp', 'date',
                                  'wav_path'])

def snodgrass_wav2number(path):
    return int(os.path.basename(path).split('-')[0][6:])

def get_snodgrass_segment(word, vp, date, wav_dict, order, p_delay, duration,
                          append_next=False, channel=0, verbose=False):
    wav_path = wav_dict[order]
    wav_next = wav_dict[order + 1] if (order + 1) in wav_dict else None

    segment_name = '{0}_{1}_snodgrass_{2}_{3}'.format(word, os.path.basename(wav_path).split('-')[0][6:], vp, date)

    # TODO: replace with sound_utils call eventually
    data, rate = soundfile.read(wav_path, always_2d=True)
    sample_start = time2sample(p_delay, rate)
    sample_end = time2sample(p_delay + duration, rate)

    # Append next is either specified explicitly, or inferred from the delay and/or duration not fitting into
    # the current file
    if append_next or sample_start > data.shape[0] or sample_end > data.shape[0]:
        if wav_next is None:
            if verbose:
                print('Invalid segment: {0} - needs the next file to complete the audio, but it is not available'
                      .format(segment_name))
            return None, None, None

        data_next, rate_next = soundfile.read(wav_next, always_2d=True)
        if rate != rate_next:
            if verbose:
                print('Invalid segment: {0} - needs the next file, but it has a different format - not handled for now'
                      .format(segment_name))
            return None, None, None
        data = np.vstack((data, data_next))

    segment_data = data[sample_start:sample_end, channel]
    return segment_name, segment_data, rate

def get_word_audio_segment(word, order, p_score, p_delay, duration, synonym, comment, vp, date, wav_dict, word_counts,
                           verbose):
    # TODO: currently skipping synonyms, but need to include them eventually
    if p_delay != 'nan' and duration != 'nan' and synonym == '':
        if float(p_delay) < 50 and float(duration) < 50 and order in wav_dict:
            segment_name, segment_data, rate = \
                get_snodgrass_segment(word, vp, date, wav_dict, order, p_delay,
                                      duration, append_next=('abgeschnitten' in comment), verbose=verbose)
            if segment_data is not None:
                if word not in word_counts:
                    word_counts[word] = 0
                word_counts[word] += 1

                return segment_name, segment_data, rate

def get_complete_audio(word, order, p_score, p_delay, duration, synonym, comment, vp, date, wav_dict, word_counts,
                       verbose):
    if float(p_delay) < 50 and float(duration) < 50 and order in wav_dict:
        wav_path = wav_dict[order]
        segment_name = '{0}_{1}_snodgrass_{2}_{3}'.format(word, os.path.basename(wav_path).split('-')[0][6:], vp, date)
        segment_data, rate = soundfile.read(wav_path, always_2d=True)
        segment_data = segment_data[:, 0]

        return segment_name, segment_data, rate

def _get_wav_paths_for_rating(order, p_delay, duration, comment, wav_dict):
    wav_path = wav_dict[order]
    wav_next = wav_dict[order + 1] if (order + 1) in wav_dict else None

    info = soundfile.info(wav_path)
    if 'abgeschnitten' in comment or p_delay > info.duration or p_delay + duration > info.duration:
        if wav_next is None:
            return None
        else:
            return [wav_path, wav_next]
    else:
        return wav_path

def get_word_rating(word, order, p_score, p_delay, duration, synonym, comment, vp, date,
                    wav_files_dict, word_counts, verbose):
    if order in wav_files_dict:
        if word not in word_counts:
            word_counts[word] = 0
        word_counts[word] += 1
        return SnodgrassWordRating(word, order, p_score, p_delay, duration, synonym, comment, vp, date,
                                   _get_wav_paths_for_rating(order, p_delay, duration, comment, wav_files_dict))
    else:
        return SnodgrassWordRating(word, 'missing', None, None, None, None, None, None, None, None)

def process_data_dir(vp, date, csv_file, data_dir, word_counts, process_recording, verbose=False):
    word_idx = 0
    p_score_idx = 2
    p_delay_idx = 5
    duration_idx = 6
    synonym_idx = 7
    comment_idx = 8

    wav_files = glob.glob(os.path.join(data_dir, '*.wav'))
    wav_dict = {snodgrass_wav2number(path) - 1: path for path in wav_files}

    output = []
    with open(csv_file, 'r', encoding='utf-8') as csv_file:
        csv_reader = csv.reader(csv_file)
        next(csv_reader, None)
        for i, row in enumerate(csv_reader):
            word = row[word_idx]
            p_score = int(row[p_score_idx]) if row[p_score_idx] != '' else None
            p_delay = float(row[p_delay_idx])
            duration = float(row[duration_idx])
            synonym = row[synonym_idx]
            comment = row[comment_idx]

            data = process_recording(word, i, p_score, p_delay, duration, synonym, comment, vp, date, wav_dict,
                                     word_counts, verbose)
            if data is not None:
                output.append(data)

    return output

def snodgrass_iter(snodgrass_dir, process_recording=get_word_audio_segment, verbose=False):
    csv_files = glob.glob(os.path.join(snodgrass_dir, '*.csv'))
    data_dirs = [x for x in os.listdir(snodgrass_dir) if os.path.isdir(os.path.join(snodgrass_dir, x))]
    word_counts = {}

    for file in csv_files:
        parts = os.path.basename(file).split('_')
        vp = parts[0]
        date = parts[1]
        data_dir = [x for x in data_dirs if date in x and x.endswith(vp)][0]

        output = process_data_dir(vp, date, file, os.path.join(snodgrass_dir, data_dir), word_counts, process_recording,
                                  verbose)
        yield data_dir, output, word_counts

def snodgrass2features(input_path, output_path, feature_func, compress=False, verbose=False):
    ark_scp_output = 'ark:| copy-feats --compress={compress} ark:- ark,scp:{0}.ark,{0}.scp' \
        .format(output_path, compress='true' if compress else 'false')

    with kaldi_io.open_or_fd(ark_scp_output, 'wb') as f:
        for data_dir, output, counts in snodgrass_iter(input_path, verbose=verbose):
            for segment_name, segment_data, rate in output:
                features_with_deltas = feature_func(segment_data, rate)

                if reject_by_frame_count_snodgrass(features_with_deltas, segment_name.split('_')[0],
                                                   'snodgrass', segment_name, verbose=True):
                    continue

                kaldi_io.write_mat(f, features_with_deltas, key=segment_name)

    # Fix the encoding of the scp file
    if os.path.exists('{0}.scp'.format(output_path)):
        fix_scp_encoding(output_path)

def print_snodgrass_stats(input_path, verbose=False):
    total_valid = 0
    data_dirs = []
    word_counts = {}

    for data_dir, output, counts in snodgrass_iter(input_path, verbose=verbose):
        data_dirs.append(data_dir)
        total_valid += len(output)
        word_counts = counts

    pprint(word_counts)
    print('Total valid: {0}/{1}'.format(total_valid, len(data_dirs) * 233))

def print_snodgrass_recording_length_stats(input_path, verbose=False):
    lens = []
    for data_dir, output, counts in snodgrass_iter(input_path, process_recording=get_complete_audio, verbose=verbose):
        for key, audio, sample_rate in output:
            lens.append(audio.shape[0] / sample_rate)
    lens = np.array(lens)

    lens = lens[lens > 0.250]  # remove the worst outliers
    print(lens.min(), lens.mean(), lens.max())

if __name__ == '__main__':
    def _process_snodgrass(input_path, sub_dir, feature_func=audio2lmfe):
        sub_dir = os.path.join(processed_data_dir, sub_dir)
        util.ensure_exists(sub_dir)
        output_path = os.path.join(sub_dir, 'snodgrass_data_v3')
        snodgrass2features(input_path, output_path, feature_func, compress=False, verbose=True)

    print_snodgrass_stats(snodgrass_data_dir, verbose=True)
    # print_snodgrass_recording_length_stats(snodgrass_data_dir, verbose=True)
    # _process_snodgrass(snodgrass_data_dir, 'snodgrass_words_cleaned_v3')
    # _process_snodgrass(snodgrass_data_dir, 'snodgrass_words_cleaned_v3_mfcc', feature_func=audio2mfcc)
    # _process_snodgrass(snodgrass_data_dir, 'snodgrass_words_cleaned_v3_reverse', feature_func=audio2lmfe_reverse)
    # _process_snodgrass(snodgrass_data_dir, 'snodgrass_words_cleaned_v3_pncc_mn_off_dct_off',
    #                    feature_func=partial(audio2pncc, mean_norm=False, do_dct=False))

    # print_snodgrass_stats('/home/aleks/data/speech/Naming_Data_Complete/Snodgrass_Recordings_cleaned_denoised',
    #                       verbose=True)
    # _process_snodgrass('/home/aleks/data/speech/Naming_Data_Complete/Snodgrass_Recordings_denoised_19-11-2018',
    #                    'snodgrass_words_cleaned_denoised_19-11-2018')


class Solution: # Time: O(n), Space: O(n)
    def getMaxLen(self, nums: List[int]) -> int:
        pos = [0] * len(nums)
        neg = [0] * len(nums)
        if nums[0] > 0:
            pos[0] = 1
        elif nums[0] < 0:
            neg[0] = 1

        ans = pos[0]
        for i in range(1, len(nums)):
            if nums[i] > 0:
                pos[i] = 1 + pos[i-1]
                neg[i] = 1 + neg[i-1] if neg[i-1] > 0 else 0
            elif nums[i] < 0:
                neg[i] = 1 + pos[i-1]
                pos[i] = 1 + neg[i-1] if neg[i-1] > 0 else 0
            ans = max(ans, pos[i])

        return ans

class Solution: # Time: O(n), Space: O(1). Only keep the previous pos, neg
    def getMaxLen(self, nums: List[int]) -> int:
        pos, neg = 0, 0
        if nums[0] > 0:
            pos = 1
        elif nums[0] < 0:
            neg = 1

        ans = pos
        for i in range(1, len(nums)):
            if nums[i] > 0:
                pos = 1 + pos
                neg = 1 + neg if neg > 0 else 0
            elif nums[i] < 0:
                pos, neg = 1 + neg if neg > 0 else 0, 1 + pos
                # Assignment at the same time, otherwise results would be different because they're relying on each other
            else:
                pos = 0
                neg = 0
            ans = max(ans, pos)

        return ans


from primaires.interpreteur.masque.parametre import Parametre

class PrmEditer(Parametre):

    """Commande 'diligence éditer'.

    """

    def __init__(self):
        """Constructeur du paramètre"""
        Parametre.__init__(self, "éditer", "edit")
        self.schema = "<cle>"
        self.aide_courte = "édite une diligence maudite"
        self.aide_longue = \
                "Cette commande vous permet d'éditer une diligence " \
                "maudite. N'oubliez pas que la plupart de l'édition " \
                "d'une diligence maudite se fait dans la zone-même. " \
                "L'éditeur ne propose que des fonctions assez génériques, " \
                "comme le fait d'indiquer une diligence comme ouverte " \
                "ou fermée."

    def interpreter(self, personnage, dic_masques):
        """Interprétation du paramètre"""
        cle = dic_masques["cle"].cle
        if cle not in importeur.diligence.diligences:
            personnage << "|err|La diligence {} n'existe pas.|ff|".format(cle)
            return

        diligence = importeur.diligence.diligences[cle]
        editeur = type(self).importeur.interpreteur.construire_editeur(
                "diledit", personnage, diligence)
        personnage.contextes.ajouter(editeur)
        editeur.actualiser()


import random

from Organizmy.Ziemia import Ziemia
from Organizmy.Zwierzeta import Zwierzeta

class Antylopa(Zwierzeta):

    def __init__(self, pozycjax, pozycjay, swiat):
        super(Antylopa, self).__init__(4, 4, pozycjax, pozycjay, swiat, 'A', "gray")

    def ZrobDziecko(self, pozycjax, pozycjay):
        dziecko = Antylopa(pozycjax, pozycjay, self.swiat)
        self.swiat.DodMapa(pozycjax, pozycjay, dziecko)

    def Akcja(self):
        super(Antylopa, self).Akcja()
        if (self.swiat.mapa[self.pozycjax][self.pozycjay] == self):
            super(Antylopa, self).Akcja()

    def CzyZwial(self):
        if random.randint(0, 1) == 0:
            tab = self.swiat.GetSasiadow(self)
            if (len(tab) == 0):
                return False
            while len(tab) > 0:
                punkt = random.choice(tab)
                tab.remove(punkt)
                if isinstance(self.swiat.mapa[punkt.x][punkt.y], Ziemia):
                    self.swiat.mapa[self.pozycjax][self.pozycjay] = Ziemia(self.swiat, self.pozycjax, self.pozycjay)
                    self.pozycjax = punkt.x
                    self.pozycjay = punkt.y
                    self.swiat.mapa[self.pozycjax][self.pozycjay] = self
                    return True
            return False


import json

class Config:

	"""The Config class is a template for intializing/importing constants."""
	def __init__(self, file_str, location):

		with open(file_str) as dataFile: # print("config.json: ") # pprint(config)
			config = json.load(dataFile)

		self.serverAddress = config["server"]["address"]
		self.serverPort = config["server"]["port"]
		self.simulationMode = config["simulationMode"]
		self.file_str = file_str
		self.distAO1 = config["distInfo"]["distActuatorToOrigin"]
		self.distAO2 = config["distInfo"]["distPanningActuatorToOrigin"]
		self.secToWait = config["distInfo"]["moveActuatorPerUnitOfSeconds"]
		self.maxActuatorHeight = config["distInfo"]["maxActuatorHeight"]

		self.name = config[location]["name"]
		self.lat = config[location]["latitude"]
		self.lon = config[location]["longitude"]
		self.rate = config[location]["speedUpRate"]

		self.offset = 0 #config[location]["hours_after_UTC"]
		self.tz = config[location]["tz_name"]
		self.speed = config[location]["speedUpRate"]
		self.year = config[location]["year"]
		self.month = config[location]["month"]
		self.day = config[location]["day"]


import numpy as np
import random

# Initialize parameters. epsilon is exploration rate.
epsilon = 0.4

def Bayes_recommendation(data):
    recommendations = []
    for room in data[1]:
        prior_successes = []
        prior_failures = []
        for i in range(len(data[1][room]["feeds"])):
            success_count = data[1][room]["feeds"][i]["count"]
            total_trials = data[1][room]["memberCount"] * data[1][room]["types"][i]["count"]
            failure_count = total_trials - success_count
            prior_successes.append(success_count + 1)
            prior_failures.append(failure_count + 1)
        # Sample from Beta distribution
        arm_values = [np.random.beta(successes, failures) for successes, failures in
                      zip(prior_successes, prior_failures)]
        # Choose an arm to recommend
        if random.random() > epsilon:
            # Exploit the current best arm
            chosen_arm_idx = np.argmax(arm_values)
        else:
            # Explore a random arm
            chosen_arm_idx = random.randrange(len(arm_values))
        # Calculate question ID for tomorrow
        # If daily is selected
        if chosen_arm_idx == 0:
            # if the last questionID is equal to max id, return the min id
            if data[1][room]["current"][0]["currentDaily"] == data[0]["DAILY"]["max"]:
                selected_questionID = data[0]["DAILY"]["min"]
            else:
                selected_questionID = data[1][room]["current"][0]["currentDaily"] + 1
        elif chosen_arm_idx == 1:
            if data[1][room]["current"][0]["currentGame"] == data[0]["GAME"]["max"]:
                selected_questionID = data[0]["GAME"]["min"]
            else:
                selected_questionID = data[1][room]["current"][0]["currentGame"] + 1
        elif chosen_arm_idx == 2:
            if data[1][room]["current"][0]["currentKnow"] == data[0]["KNOW"]["max"]:
                selected_questionID = data[0]["KNOW"]["min"]
            else:
                selected_questionID = data[1][room]["current"][0]["currentKnow"] + 1
        recomm_for_this_room = dict()
        recomm_for_this_room["roomID"] = room
        recomm_for_this_room["questionID"] = selected_questionID
        recommendations.append(recomm_for_this_room)
    return recommendations


def sumEvenAfterQueries(A, queries):
    sunm = []

    if (1 <= len(queries) <= 10000) and (1 <= len(A) <= 10000):
        for i in range(0, len(queries)):
            val = queries[i][0]
            index = queries[i][1]

            if (0 <= index < len(A)):
                num = A[index]

                A[index] = num + val
                result = 0

                for i in A:
                    if i % 2 == 0:
                        result += i
                sunm.append(result)
                result = 0
        return sunm

a = [1,2,3,4]
q = [[1,0],[-3,1],[-4,0],[2,3]]

print('correct: [8,6,2,4]', sumEvenAfterQueries(a,q))


import time
from Arm_Lib import Arm_Device

# Get a robotic arm object
Arm = Arm_Device()
time.sleep(.1)

# Control six servos at the same time, gradually changing the angle.
def ctrl_all_servo(angle, s_time = 500):
    Arm.Arm_serial_servo_write6(angle, 180-angle, angle, angle, angle, angle, s_time)
    time.sleep(s_time/1000)

def main():
    dir_state = 1
    angle = 90

    # Middle servo
    Arm.Arm_serial_servo_write6(90, 90, 90, 90, 90, 90, 500)
    time.sleep(1)

    while True:
        if dir_state == 1:
            angle += 1
            if angle >= 180:
                dir_state = 0
        else:
            angle -= 1
            if angle <= 0:
                dir_state = 1

        ctrl_all_servo(angle, 10)
        time.sleep(10/1000)
#         print(angle)

try :
    main()
except KeyboardInterrupt:
    print(" Program closed! ")
    pass

del Arm  # Release the Arm object


"""
Implementation of Context-Conditional GAN using cifar10 images
From: https://github.com/eriklindernoren/Keras-GAN/blob/master/ccgan/ccgan.py
"""

from __future__ import print_function, division

from keras.datasets import cifar10
from keras_contrib.layers.normalization import InstanceNormalization
from keras.layers import Input, Dense, Reshape, Flatten, Dropout, multiply, GaussianNoise
from keras.layers import BatchNormalization, Activation, Embedding, ZeroPadding2D
from keras.layers import Concatenate,Multiply,Add,Maximum,Average
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import UpSampling2D, Conv2D, Conv2DTranspose, MaxPooling2D
from keras.models import Sequential, Model, model_from_json
from keras.optimizers import Adam
from keras import losses
from keras.utils import to_categorical
import keras.backend as K
import scipy
from sklearn.metrics import mean_squared_error
from skimage.measure import compare_ssim as SSIM

import tensorflow as tf

from tqdm import tqdm
import matplotlib.pyplot as plt
import cv2
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def compute_mse(a,b):
    A = a.flatten()
    B = b.flatten()
    mse = mean_squared_error(A,B)
    return mse

def compute_ssim(a,b):
    ssim = []
    num_imgs = a.shape[0]
    for i in range(num_imgs):
        ssim.append( SSIM(a[i],b[i],
                      data_range=(1-(-1)),
                      multichannel=True))

    # dssim
    return ( 1 - np.array(ssim).mean() ) / 2

class CCGAN():
    def __init__(self):
        self.img_rows = 128
        self.img_cols = 128
        self.mask_height = 64
        self.mask_width = 64
        self.channels = 3
        self.num_classes = 2
        self.img_shape = (self.img_rows, self.img_cols, self.channels)
        self.img_LR_shape = (self.img_rows//4, self.img_cols//4, self.channels)
        self.LR_input = False # SET IF YOU WANT THE LOW RES CONDITION TO BE TRUE

        # Number of filters in first layer of generator and discriminator
        self.gf = 64
        self.df = 64

        lambda_recon = 0.999
        lambda_adv = 0.001
        optimizer_recon = Adam(lr=2e-3, beta_1=0.5,decay=1e-2)
        optimizer_adv =   Adam(lr=2e-3, beta_1=0.5,decay=1e-3)

        # Build and compile the discriminator
        self.discriminator = self.build_discriminator()
        self.discriminator.compile(loss=['binary_crossentropy', 'categorical_crossentropy'],
            loss_weights=[0.5, 0.5],
            optimizer=optimizer_adv,
            metrics=['accuracy'])

        # Build and compile the generator
        self.generator = self.build_generator()

        # The generator takes noise as input and generates imgs
        masked_img = Input(shape=self.img_shape)
        boolean_mask = Input(shape=self.img_shape)
        boolean_mask_reverse = Input(shape=self.img_shape)
        if self.LR_input:
            LR_img = Input(shape=self.img_LR_shape)
            _, gen_img = self.generator([masked_img,boolean_mask,boolean_mask_reverse,LR_img])
        else:
            _, gen_img = self.generator([masked_img,boolean_mask,boolean_mask_reverse])

        # For the combined model we will only train the generator
        self.discriminator.trainable = False
        # The valid takes generated images as input and determines validity
        valid, _ = self.discriminator(gen_img)

        # The combined model  (stacked generator and discriminator) takes
        # masked_img as input => generates images => determines validity
        if self.LR_input:
            self.combined = Model([masked_img,boolean_mask,boolean_mask_reverse,LR_img], [gen_img, valid])
        else:
            self.combined = Model([masked_img,boolean_mask,boolean_mask_reverse], [gen_img, valid])
        self.combined.compile(loss=['mse','binary_crossentropy'],
            loss_weights=[lambda_recon, lambda_adv],
            optimizer=optimizer_recon,
            metrics=['accuracy'])

    def build_generator(self):
        """Create generator model"""
        def conv_bn_relu_pool(input_layer,filters,kernel_size=4,pool=True,pad='same',activation='relu',bn=True):
            if pool:
                y = Conv2D(filters,kernel_size=kernel_size,strides=2,padding=pad)(input_layer)
            else:
                y = Conv2D(filters,kernel_size=kernel_size,strides=1,padding=pad)(input_layer)
            #Activation
            if activation=='relu':
                y = Activation('relu')(y)
            elif activation=='lrelu':
                y = LeakyReLU(alpha=0.2)(y)
            else:
                print("WARNING: no activation layer")
                pass
            #BatchNormalization
            if bn:
                y = BatchNormalization()(y)
                #y = InstanceNormalization()(y)
            else:
                pass
            output = y
            return output

        def deconv_bn_relu(input_layer,filters,kernel_size=4,stride=2,pad='same', activation='relu'):
            y = Conv2DTranspose(filters,kernel_size=kernel_size,
                                strides=stride,padding=pad)(input_layer)
            #Activation
            if activation=='relu':
                y = Activation('relu')(y)
            elif activation=='lrelu':
                y = LeakyReLU(alpha=0.2)(y)
            else:
                input("WARNING: no activation layer <Enter to continue>")
                pass
            #BatchNormalization
            y = BatchNormalization()(y)
            output = y
            return output

        img = Input(shape=self.img_shape)
        mask = Input(shape=self.img_shape,name='boolean_mask')      # boolean tensor
        revmask = Input(shape=self.img_shape,name='boolean_inverted') # 0 at patch
        if self.LR_input:
            img_LR = Input(shape=self.img_LR_shape,name='low_res')

        # Downsampling
        y = conv_bn_relu_pool(img, filters=self.gf,activation='lrelu')
        y = conv_bn_relu_pool(y, filters=self.gf*2,activation='lrelu')
        if self.LR_input:
            y = Concatenate(axis=-1)([y,img_LR])
        y = conv_bn_relu_pool(y, filters=self.gf*4,activation='lrelu')
        y = conv_bn_relu_pool(y, filters=self.gf*8,activation='lrelu')
        y = deconv_bn_relu(y,filters=self.df*4,activation='relu')
        y = deconv_bn_relu(y,filters=self.df*2,activation='relu')
        y = deconv_bn_relu(y,filters=self.df,activation='relu')

        y = Conv2DTranspose(filters=self.channels, kernel_size=4, strides=2, padding='same')(y)
        output_img = Activation('tanh')(y)

        layer_patch =  Multiply()([img,revmask])
        layer_notPatch = Multiply()([output_img,mask])
        patched_img = Add()([layer_patch,layer_notPatch])

        if self.LR_input:
            model = Model([img, mask, revmask, img_LR], [output_img,patched_img])
        else:
            model = Model([img, mask, revmask], [output_img,patched_img])

        print("GENERATOR")
        model.summary()
        return model

    def build_discriminator(self):
        """Create discriminator model"""
        def conv_bn_relu_pool(input_layer,filters,kernel_size=3,stride=2,pool=True,pad='same',activation='relu',bn=True):
            if pool:
                y = Conv2D(filters,kernel_size=kernel_size,strides=2,padding=pad)(input_layer)
            else:
                y = Conv2D(filters,kernel_size=kernel_size,strides=1,padding=pad)(input_layer)
            #Activation
            if activation=='relu':
                y = Activation('relu')(y)
            elif activation=='lrelu':
                y = LeakyReLU(alpha=0.2)(y)
            else:
                print("WARNING: no activation layer")
                pass
            #BatchNormalization
            if bn:
                y = BatchNormalization()(y)
                #y = InstanceNormalization()(y)
            else:
                pass
            output = y
            return output

        """ model """
        img = Input(shape=self.img_shape)
        #"""
        # VGG-A' model
        y = conv_bn_relu_pool(img,self.df,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*2,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*4,pool=False,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*4,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*8,pool=False,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*8,activation='lrelu')
        y = conv_bn_relu_pool(y,self.df*8,pool=False,activation='lrelu')
        features = conv_bn_relu_pool(y,self.df*8,activation='lrelu')
        #"""
        validity = Conv2D(1, kernel_size=4, strides=1, padding='same')(features) # 1 output
        validity = Flatten()(validity)
        validity = Dense(1,activation='sigmoid',name='validity')(validity)

        label = Conv2D(1, kernel_size=4, strides=1, padding='same')(features) # 1 output
        label = Flatten()(label)
        label = Dense(self.num_classes, activation="softmax",name='label')(label)

        model = Model(img, [validity, label])
        print("DISCRIMINATOR")
        model.summary()
        return model

    """ Insert a random mask in the image """
    def mask_randomly(self, imgs, random=True, corner=None):
        if random:
            """create a random mask within the image"""
            y1 = np.random.randint(0, self.img_rows - self.mask_height, imgs.shape[0])
            y2 = y1 + self.mask_height
            x1 = np.random.randint(0, self.img_rows - self.mask_width, imgs.shape[0])
            x2 = x1 + self.mask_width
        else:
            """Creates mask only at the 4 corners of the image"""
            y1 = np.random.randint(0, 2, imgs.shape[0])*(self.img_rows-self.mask_height) # stores 0 and 1
            y2 = y1 + self.mask_height
            x1 = np.random.randint(0, 2, imgs.shape[0])*(self.img_rows-self.mask_width) # stores 0 and 1
            x2 = x1 + self.mask_width

        # overrides the values on top
        if corner:
            y1 = corner[0]
            y2 = corner[0] + self.mask_height
            x1 = corner[1]
            x2 = corner[1] + self.mask_width

        mask_coordinates = np.array([y1,y2,x1,x2])

        #create array with random numbers with same shape as imgs
        masked_imgs = np.empty_like(imgs)
        boolean_masks = np.zeros_like(imgs).astype('bool')
        for i, img in enumerate(imgs):
            masked_img = img.copy()
            boolean_mask_img = np.zeros_like(img).astype('bool')
            _y1, _y2, _x1, _x2 = y1[i], y2[i], x1[i], x2[i],
            masked_img[_y1:_y2, _x1:_x2, :] = 0            # middle, normalized [-1,1]
            boolean_mask_img[_y1:_y2, _x1:_x2, :] = True   # True at patch

            # batch of images and masks
            masked_imgs[i] = masked_img
            boolean_masks[i] = boolean_mask_img

        return masked_imgs, boolean_masks, mask_coordinates

    def train(self, epochs, batch_size=32, sample_interval=50):
        # Load the dataset
        (X_train, y_train), (X_test, y_test) = cifar10.load_data()

        X_train = np.vstack((X_train, X_test))
        y_train = np.vstack((y_train, y_test))

        # Extract dogs and cats
        X_cats = X_train[(y_train == 3).flatten()]
        X_dogs = X_train[(y_train == 5).flatten()]
        X_train = np.vstack((X_cats, X_dogs))
        y_cats = np.zeros(X_cats.shape[0])
        y_dogs = np.ones(X_dogs.shape[0])
        y_train = np.vstack((y_cats, y_dogs))

        # Rescale possible rescale
        X_train = np.array([scipy.misc.imresize(x, [self.img_rows, self.img_cols]) for x in X_train]) # resize to (128,128)

        # Rescale -1 to 1
        X_train = X_train.astype('float32') / 255.0
        X_train = (2 * X_train) - 1
        y_train = y_train.reshape(-1, 1)

        half_batch  = batch_size//2
        batch_count = X_train.shape[0]//batch_size
        print('Epochs:', epochs)
        print('Batch size:', batch_size)
        print('Batch count:', batch_count)
        for epoch in range(epochs):
            # ---------------------
            #  Train Discriminator
            # ---------------------

            # Sample half batch of images
            idx = np.random.randint(0, X_train.shape[0], half_batch)
            imgs = X_train[idx]
            labels = y_train[idx]

            LR_imgs = np.array([scipy.misc.imresize(x, [self.img_rows//4, self.img_cols//4]) for x in imgs])

            masked_imgs, boolean_masks, mask_coordinates = self.mask_randomly(imgs,random=True)
            boolean_inverted = np.invert(boolean_masks)

            # Generate a half batch of new images (try loading generator weights here)
            if self.LR_input:
                _,gen_imgs = self.generator.predict([masked_imgs,boolean_masks,boolean_inverted,LR_imgs])
            else:
                _,gen_imgs = self.generator.predict([masked_imgs,boolean_masks,boolean_inverted])

            valid = np.ones((half_batch,1))
            fake = np.zeros((half_batch,1))

            comb_validity = np.concatenate([valid,fake],axis=0)

            # not yet included in combined
            labels = to_categorical(labels, num_classes=self.num_classes)
            comb_labels = np.concatenate([labels,labels],axis=0)

            # patch cropped part of image
            mask_coordinates = mask_coordinates
            comb_imgs = np.concatenate([imgs,gen_imgs],axis=0)

            # Shuffle data again here
            sh = np.arange(comb_validity.shape[0])
            np.random.shuffle(sh)

            comb_validity = comb_validity[sh]
            comb_labels = comb_labels[sh]
            comb_imgs = comb_imgs[sh]

            d_loss = self.discriminator.train_on_batch(comb_imgs,[comb_validity,comb_labels])

            # ---------------------
            #  Train Generator
            # ---------------------

            # Select a random batch of images
            idx = np.random.randint(0, X_train.shape[0], batch_size)
            imgs = X_train[idx]

            LR_imgs = np.array([scipy.misc.imresize(x, [self.img_rows//4, self.img_cols//4]) for x in imgs])
            masked_imgs, boolean_masks, mask_coordinates = self.mask_randomly(imgs,random=True)
            boolean_inverted = np.invert(boolean_masks)

            # Generator wants the discriminator to label the generated images as valid
            valid = np.ones((batch_size,1))

            # Train the generator
            if self.LR_input:
                g_loss = self.combined.train_on_batch([masked_imgs,boolean_masks,boolean_inverted,LR_imgs], [imgs,valid])
            else:
                g_loss = self.combined.train_on_batch([masked_imgs,boolean_masks,boolean_inverted], [imgs,valid])

            # Plot the progress
            print ("%d [D loss: %f, op_acc: %.2f%%] [gen acc: %.2f%%, mse: %f]" % ( epoch, d_loss[0], 100*d_loss[3], 100*g_loss[4], g_loss[1]))

            # If at save interval => save generated image samples
            if (epoch) % sample_interval == 0:
                # Select a random half batch of images
                idx = np.random.randint(0, X_train.shape[0], 6)
                imgs = X_train[idx]
                self.sample_images(epoch, imgs)
                self.save_model(epoch)

    def test(self, batch_size=10, arch='ccgan.json', weights='ccgan.hdf5'):
        """ Produce same images (patch places) in data """
        pass

    def predict(self,arch='ccgan.json', weights='ccgan.hdf5'):
        pass

    def sample_images(self, epoch, imgs):
        """ saves sample images of the generator """
        r, c = 4, 6

        LR_imgs = np.array([scipy.misc.imresize(x, [self.img_rows//4, self.img_cols//4]) for x in imgs])
        masked_imgs,boolean_masks,mask_coordinates = self.mask_randomly(imgs,random=True)
        boolean_inverted = np.invert(boolean_masks)

        # orig_gen = no patch
        if self.LR_input:
            orig_gen_imgs,gen_imgs = self.generator.predict([masked_imgs,boolean_masks,boolean_inverted,LR_imgs])
        else:
            orig_gen_imgs,gen_imgs = self.generator.predict([masked_imgs,boolean_masks,boolean_inverted])

        imgs = (imgs + 1.0) * 0.5
        masked_imgs = (masked_imgs + 1.0) * 0.5
        orig_gen_imgs = (orig_gen_imgs + 1.0) * 0.5
        gen_imgs = (gen_imgs + 1.0) * 0.5

        orig_gen_imgs = np.clip(orig_gen_imgs,0,1)
        gen_imgs = np.clip(gen_imgs,0,1)

        fig, axs = plt.subplots(r, c)
        for i in range(c):
            axs[0,i].imshow(imgs[i, :, :, :])
            axs[0,i].axis('off')
            axs[1,i].imshow(masked_imgs[i, :, :, :])
            axs[1,i].axis('off')
            axs[2,i].imshow(orig_gen_imgs[i, :, :, :])
            axs[2,i].axis('off')
            axs[3,i].imshow(gen_imgs[i, :, :, :])
            axs[3,i].axis('off')
        fig.savefig("images/%d.png" % epoch)
        plt.close()

    def save_model(self,epoch):
        """ save the weights and architecture """
        def save(model, model_name,epoch):
            model_path = "saved_model/%s.json" % model_name
            weights_path = "saved_model/%s_weights.%s.hdf5" % (model_name,str(epoch))
            options = {"file_arch": model_path,
                        "file_weight": weights_path}
            json_string = model.to_json()
            open(options['file_arch'], 'w').write(json_string)
            model.save_weights(options['file_weight'])

        save(self.generator, "ccgan_generator",epoch=epoch)
        save(self.discriminator, "ccgan_discriminator", epoch=0)

    def load_model(self,arch,weights):
        """ load the weights and architecture of model """
        json_file = open(arch, 'r')
        loaded_model_json = json_file.read()
        json_file.close()
        self.model = model_from_json(loaded_model_json)
        self.model.load_weights(weights)

if __name__ == '__main__':
    ccgan = CCGAN()
    MODE = 'train'
    ARCH = './saved_model/ccgan_generator.json'
    WEIGHTS = './saved_model/ccgan_generator_weights.220.hdf5'
    mode = {'train': 0,
            'test': 1,
            'predict': 2}

    if mode[MODE] == 0:
        ccgan.train(epochs=50000, batch_size=32, sample_interval=50)

    elif mode[MODE] == 1:
        pass

    elif mode[MODE] == 2:
        pass


import estacion

# Test comprobando que da fallo si el campo fecha es nulo
def test_nuevo_dato():
    test_estacion = estacion.Estacion("provincia", "municipio", "estacion", "direccion")
    test_indicador = estacion.Indicador(None, 1, 1, 1, 1, 1)
    assert test_estacion.aniadir_nuevos_indicadores(test_indicador) == 'Dato no valido'

# Test comprobando que se generan correctamente las estadísticas
def test_estadisticas():
    est = estacion.Estacion("Granada", "Granada",
      "Estación Sierra Nevada", "Calle Sierra Nevada")
    indicadores = estacion.Indicador("06/11/2019", 0.5, 256, 25.96, 50.0, 15.89)
    est.aniadir_nuevos_indicadores(indicadores)
    assert est.generar_estadisticas() == 'Estadisticas correctas'