import os
import numpy as np
import cv2
import pickle
import random
import imutils
import time
import matplotlib.pyplot as plt
#from sklearn.metrics import plot_confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from skimage.feature import hog
from skimage import measure, color, io
from skimage.segmentation import clear_border

# output_file = open('Central Pallor.csv', 'x')

# def create_data_WS(trdir):
# 	global dataFile
#
# 	data = []
#
# 	for category in categories:
# 		path = os.path.join(trdir, category)
# 		label = categories.index(category)
#
# 		for img in os.listdir(path):
# 			imgpath = os.path.join(path, img)
# 			blood_img = cv2.imread(imgpath)
# 			blood_img_gray = cv2.cvtColor(blood_img, cv2.COLOR_BGR2GRAY)
# 			ret, blood_img_otsu = cv2.threshold(blood_img_gray, 0, 255, cv2.THRESH_OTSU)
# 			blood_imgf = cv2.resize(blood_img_otsu, (48, 48))

if __name__ == "__main__":

	propList = ['Area',
				'equivalent_diameter',
				'orientation',
				'MajorAxisLength',
				'MinorAxisLength',
				'Perimeter',
				'MinIntensity',
				'MeanIntensity',
				'MaxIntensity']

	output_file = open('Central Pallor.csv', 'w')
	output_file.write('Cell #' + "," + "," + ",".join(propList) + '\n')
	output_file.close()

	global dataFile

	# location directory of training images
	train_dir = 'trainingbed_\\trbed_main'

	# location directory of test image/s
	# test_dir = 'test_image\\Im083_02.jpg'

	dataFile = 'dataset_dir\\OTSU\\Data_DiscoEchinoStomatoWS0.pickle'
	modelFile = 'model_dir\\OTSU\\ModelSVM_DiscoEchinoStomatoWS0.sav'
	# set dataset and model file

	categories = ['Negative', 'Pos_Disco', 'Pos_Echino', 'Pos_Stomato']  # 0, 1, 2
	# displayLabels = ["Others", "Echinocytes", "Stomatocytes"]
	# categories = ['Neg_Stomatocyte', 'Pos_Stomatocyte']
	# categories = ['Discocyte', 'Echinocyte', 'Negative', 'Others', 'Stomatocyte']

	global total_Discocyte
	global total_Echinocyte
	global total_Stomatocyte
	global total_Others
	global prediction

	# # load model
	# pick = open(modelFile, 'rb')  # change model depending on SVC parameter
	# model = pickle.load(pick)
	# pick.close()

	data = []

	for category in categories:
		path = os.path.join(train_dir, category)
		label = categories.index(category)

		for img in os.listdir(path):
			imgpath = os.path.join(path, img)
			blood_img = cv2.imread(imgpath)
			blood_img_gray = cv2.cvtColor(blood_img, cv2.COLOR_BGR2GRAY)
			ret, blood_img_otsu = cv2.threshold(blood_img_gray, 0, 255, cv2.THRESH_OTSU)
			blood_imgf = cv2.resize(blood_img_otsu, (48, 48))

			# noise removal
			kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
			opening = cv2.morphologyEx(blood_img_otsu, cv2.MORPH_OPEN, kernel1, iterations=1)
			cv2.imshow("erode-dilate", opening)

			cv2.waitKey(0)

			# sure background area
			sure_bg = cv2.dilate(opening, kernel1, iterations=3)
			cv2.imshow("bg", sure_bg)

			cv2.waitKey(0)

			# Finding sure foreground area
			dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 3)
			cv2.normalize(dist_transform, dist_transform, 0, 1.0, cv2.NORM_MINMAX)
			cv2.imshow("normalized", dist_transform)

			cv2.waitKey(0)

			ret, sure_fg = cv2.threshold(dist_transform, 0.0001 * dist_transform.max(), 255, 0)
			cv2.imshow("fg", sure_fg)

			# sure_fg = cv2.dilate(sure_fg, kernel1)
			# cv2.imshow("peaks", sure_fg)

			# Finding unknown region
			sure_fg = np.uint8(sure_fg)
			unknown = cv2.subtract(sure_bg, sure_fg)

			cv2.waitKey(0)

			# Marker labelling
			ret, markers = cv2.connectedComponents(sure_fg)

			# Add one to all labels so that sure background is not 0, but 1
			markers = markers + 1

			# Now, mark the region of unknown with zero
			markers[unknown == 255] = 0

			markers = cv2.watershed(blood_img, markers)
			blood_img[markers == -1] = [0, 255, 255]

			ws = color.label2rgb(markers, bg_label=0)
			cv2.imshow("overlay on original image", blood_img)
			cv2.imshow("watershed", ws)

			cv2.waitKey(0)

			regions = measure.regionprops(markers, intensity_image=blood_img)

			propList = ['Area',
						'equivalent_diameter',
						'orientation',
						'MajorAxisLength',
						'MinorAxisLength',
						'Perimeter',
						'MinIntensity',
						'MeanIntensity',
						'MaxIntensity']

			output_file = open('Central Pallor.csv', 'w')
			output_file.write('Cell #' + "," + "," + ",".join(propList) + '\n')
			output_file.close()
	#
	# # image pipeline
	# # img1 = glob.glob("test_image/*.jpg")
	# # for images in img1:
	# #     # load image
	# #     bld_img = cv2.imread(images)
	# #     bld_img = cv2.resize(bld_img, dsize)
	# #     scan_image(bld_img, winW, winH, model)
	#
	# # load single image
	# # blood_img = cv2.imread(test_dir)
	#
	# # sharpen
	# # kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]], dtype = np.float32)
	# # laplacian = cv2.filter2D(blood_img, cv2.CV_32F, kernel)
	# # sharp = np.float32(blood_img)
	# # blood_img = sharp - laplacian
	# # blood_img = np.clip(blood_img, 0, 255)
	# # blood_img = blood_img.astype('uint8')
	# # laplacian = np.clip(laplacian, 0, 255)
	# # laplacian = np.uint8(laplacian)
	#
	# #cv2.imshow("sharpened", blood_img)
	#
	# cv2.waitKey(0)
	#
	# # nagcreate lang ako ng copy sa line na to
	# #blood_img2 = blood_img
	#
	# # load image as grayscale
	# blood_img_gray = cv2.cvtColor(blood_img, cv2.COLOR_BGR2GRAY)
	#
	# # perform OTSU's binarization method
	# ret, blood_img_otsu = cv2.threshold(blood_img_gray, 0, 255, cv2.THRESH_OTSU)
	# # cv2.imshow("otsu", blood_img_otsu)
	#
	# # inverse otsu (black bg, white foreground)
	# invblood_otsu = cv2.bitwise_not(blood_img_otsu)
	# # cv2.imshow("inverse otsu", invblood_otsu)
	#
	# # noise removal
	# kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
	# opening = cv2.morphologyEx(blood_img_otsu, cv2.MORPH_OPEN, kernel1, iterations=1)
	# cv2.imshow("erode-dilate", opening)
	#
	# cv2.waitKey(0)
	#
	# # sure background area
	# sure_bg = cv2.dilate(opening, kernel1, iterations=3)
	# cv2.imshow("bg", sure_bg)
	#
	# cv2.waitKey(0)
	#
	# # Finding sure foreground area
	# dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 3)
	# cv2.normalize(dist_transform, dist_transform, 0, 1.0, cv2.NORM_MINMAX)
	# cv2.imshow("normalized", dist_transform)
	#
	# cv2.waitKey(0)
	#
	# ret, sure_fg = cv2.threshold(dist_transform, 0.01 * dist_transform.max(), 255, 0)
	# cv2.imshow("fg", sure_fg)
	#
	# # sure_fg = cv2.dilate(sure_fg, kernel1)
	# # cv2.imshow("peaks", sure_fg)
	#
	# # Finding unknown region
	# sure_fg = np.uint8(sure_fg)
	# unknown = cv2.subtract(sure_bg, sure_fg)
	#
	# cv2.waitKey(0)
	#
	# # Marker labelling
	# ret, markers = cv2.connectedComponents(sure_fg)
	#
	# # Add one to all labels so that sure background is not 0, but 1
	# markers = markers + 1
	#
	# # Now, mark the region of unknown with zero
	# markers[unknown == 255] = 0
	#
	# markers = cv2.watershed(blood_img, markers)
	# blood_img[markers == -1] = [0, 255, 255]
	#
	# ws = color.label2rgb(markers, bg_label=0)
	# cv2.imshow("overlay on original image", blood_img)
	# cv2.imshow("watershed", ws)
	#
	# cv2.waitKey(0)
	#
	# regions = measure.regionprops(markers, intensity_image=blood_img)
	#
	# propList = ['Area',
	# 			'equivalent_diameter',
	# 			'orientation',
	# 			'MajorAxisLength',
	# 			'MinorAxisLength',
	# 			'Perimeter',
	# 			'MinIntensity',
	# 			'MeanIntensity',
	# 			'MaxIntensity']
	#
	# output_file = open('Central Pallor.csv', 'w')
	# output_file.write('Cell #' + "," + "," + ",".join(propList) + '\n')
	# output_file.close()
	# #
	# # # # inverse otsu (black bg, white foreground)
	# # # invblood_otsu = cv2.bitwise_not(blood_img_otsu)
	# # #
	# # # cv2.imshow("inverse otsu", invblood_otsu)
	# #
	# # sure_fg_8u = sure_fg.astype('uint8')
	# #
	# # contours, hierarchy = cv2.findContours(sure_fg_8u, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
	# #
	# # markers = np.zeros(sure_fg.shape, dtype=np.int32)
	# #
	# # for i in range(len(contours)):
	# #     cv2.drawContours((markers, contours, i, (i+1), -1))
	# #
	# # cv2.circle(markers, (5,5), 3, (255,255,255), -1)
	# # cv2.imshow('Markers', markers * 10000)
	# #
	# # cv2.waitKey(0)
	#
	# # contours, hierarchy = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
	# # for cnt in contours:
	# #     cv2.drawContours(opening, [cnt], 0, 255, -1)
	# #
	# # cv2.imshow("filled", opening)
	# #
	# # img = opening
	# #
	# # # # fill holes found on Inverse Otsu
	# # # contours, hierarchy = cv2.findContours(invblood_otsu, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
	# # # for cnt in contours:
	# # #     cv2.drawContours(invblood_otsu, [cnt], 0, 255, -1)
	# # #
	# # # cv2.imshow("filled", invblood_otsu)
	# # #
	# # # # Clean cell edges
	# # # kernel = np.ones((2, 2), np.uint8)
	# # # img = cv2.morphologyEx(invblood_otsu, cv2.MORPH_OPEN, kernel, iterations=3)
	# # # #cv2.imshow('Morphological', img)
	# #
	# # # BlobDetector Parameters
	# # params = cv2.SimpleBlobDetector_Params()
	# # params.minThreshold = 0
	# # params.maxThreshold = 256
	# # params.filterByArea = True
	# # params.maxArea = 13000
	# # params.minArea = 2000
	# # params.filterByColor = True
	# # params.blobColor = 255
	# # params.filterByCircularity = False
	# # params.maxCircularity = 1.00
	# # params.minCircularity = 0.75
	# # params.filterByConvexity = True
	# # params.maxConvexity = 1.00
	# # params.minConvexity = 0.00
	# # params.filterByInertia = True
	# # params.maxInertiaRatio = 1.00
	# # params.minInertiaRatio = 0.00
	# #
	# # # BlobDetector
	# # detector = cv2.SimpleBlobDetector_create(params)
	# # keypoints = detector.detect(img)
	# #
	# # draw = cv2.drawKeypoints(img, keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
	# # # for keypoints in keypoints:
	# # #     print(keypoints.size)
	# #
	# # cv2.imshow("Keypoints", draw)
	# #
	# # cv2.waitKey(0)


from django.urls import path
from . import views
# 正在部署的应用的名称
app_name = 'question'

urlpatterns = [
    path('question-list/', views.question_list, name='question_list'),
    path('question-detail/<id>/', views.question_detail, name='question_detail'),
    # 删除文章
    path('question-delete/<id>/', views.question_delete, name='question_delete'),
    # 更新文章
    path('question-update/<id>/', views.question_update, name='question_update'),
]


# utils
from .utils.webdriver import start_webdriver
from .utils.html_element import HTML
html = HTML()

# webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

# scrapper
from bs4 import BeautifulSoup

def profile_tweets(username: str, limit: int = 100) -> list:
    """scrapper for profile's tweets

    Args:
        username (str): twitter username
        limit (int, optional): max tweets to scrape. Defaults to 100.

    Returns:
        list[str]: scrapped tweet's => [
            "time",
            "tweets"
        ]
    """

    driver = start_webdriver() # Webdriver
    driver.get('https://nitter.net/' + username) # Redirect to user's profile page
    print("=== redirect to tweets profile ===")

    tweets_corpus = [] # Containing scrapped tweets
    try:
        while True:
            # Try to find the "show more" button and click it
            load_more_button = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, html.load_more_button)))

            # Parser HTML page
            soup = BeautifulSoup(driver.page_source, 'html.parser')

            tweets = soup.find_all('div', class_=html.tweet_container)
            for tweet in tweets:
                try:
                    tweet_text = tweet.find('div', class_=html.tweet_text).get_text() # Scrapped tweet text

                    tweet_time = tweet.find('span', class_=html.tweet_time).find('a')['title'] # Scrapped time

                    tweets_corpus.append(
                        {
                            'time':tweet_time,
                            'tweet':tweet_text
                        }
                    ) # Append data to tweets_corpus: list

                # Skip first tweet component after n+1 pages, beacuse its not containing scrapped element
                except AttributeError:
                    continue

            # click show more / next page
            load_more_button.click()
            print(f"Tweets scraped: {len(tweets_corpus)}")

            # Limit n scrapped tweets
            if len(tweets_corpus) >= limit:
                print("=== done! ===")

                print(f"success scrapping {len(tweets_corpus)} tweets")
                break

    # If there's no element left to scrape then error -> scrapped finish
    except Exception as _:
        print("Finished loading all content or an error occurred:", str(_))

    return tweets_corpus


'''
707.

Design your implementation of the linked list. You can choose to use a singly or doubly linked list.

A node in a singly linked list should have two attributes: val and next. val is the value of the current node,

and next is a pointer/reference to the next node.

If you want to use the doubly linked list, you will need one more attribute prev to indicate the previous node in the linked list.

Assume all nodes in the linked list are 0-indexed.

Implement the MyLinkedList class:

MyLinkedList() Initializes the MyLinkedList object.

int get(int index) Get the value of the indexth node in the linked list. If the index is invalid, return -1.

void addAtHead(int val) Add a node of value val before the first element of the linked list. After the insertion,

the new node will be the first node of the linked list.

void addAtTail(int val) Append a node of value val as the last element of the linked list.

void addAtIndex(int index, int val) Add a node of value val before the indexth node in the linked list.

If index equals the length of the linked list, the node will be appended to the end of the linked list.

If index is greater than the length, the node will not be inserted.

void deleteAtIndex(int index) Delete the indexth node in the linked list, if the index is valid.

Example:

Input
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
[[], [1], [3], [1, 2], [1], [1], [1]]
Output
[null, null, null, null, 2, null, 3]

Explanation
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2);    // linked list becomes 1->2->3
myLinkedList.get(1);              // return 2
myLinkedList.deleteAtIndex(1);    // now the linked list is 1->3
myLinkedList.get(1);              // return 3

'''

##Date: 5.20, still some bugs, some cases can not pass

##Singlelist node

class SingleListNode():
    def __init__(self, val = None, next = None):
        self.val = val
        self.next = next

class MyLinkedList(object):

    def __init__(self):
        self.head = SingleListNode()
        self.size = 0

    def get(self, index):
        """
        :type index: int
        :rtype: int
        """
        if index < 0 or index >= self.size:
            return -1

        current_node = self.head.next
        while index:
            current_node = current_node.next
            index -= 1
        return current_node.val

    def addAtHead(self, val):
        """
        :type val: int
        :rtype: None
        """
        node = SingleListNode(val = val)
        node.next = self.head.next
        self.head.next = node
        self.size += 1

    def addAtTail(self, val):
        """
        :type val: int
        :rtype: None
        """
        node = SingleListNode(val = val)

        current_node = self.head
        while current_node.next is not None:
            current_node = current_node.next
        current_node.next = node
        self.size += 1

    def addAtIndex(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        if index < 0:
            self.addAtHead(val = val)
        elif index == self.size:
            self.addAtTail(val = val)
        elif index > self.size:
            pass
        else:
            current_node = self.head
            while index:
                current_node = current_node.next
                index -= 1
            node = SingleListNode(val = val, next = current_node.next)
            current_node.next = node
            self.size += 1
        return

    def deleteAtIndex(self, index):
        """
        :type index: int
        :rtype: None
        """
        if index >= self.size or index < 0:
            pass
        else:
            current_node = self.head
            while index:
                current_node = current_node.next
                index -= 1
            current_node.next = current_node.next.next
            self.size -= 1

##Double linked list

class DoubleListNode:

    def __init__(self, val = None, prev = None, next = None):
        self.val = val
        self.prev = prev
        self.next = next

class MyLinkedList(object):

    def __init__(self):
        self.head = DoubleListNode()
        self.tail = DoubleListNode()
        self.head.next = self.tail
        self.tail.prev = self.head
        self.size = 0

    def get_node(self, index):
        if index < self.size // 2:
            current_node = self.head.next
            while index:
                current_node = current_node.next
                index -= 1
        else:
            current_node = self.tail.prev
            index = self.size - index - 1
            while index:
                current_node = current_node.prev
                index -= 1
        return current_node

    def get(self, index):
        """
        :type index: int
        :rtype: int
        """
        if index < 0 or index >= self.size:
            return -1
        else:
            node = self.get_node(index)
            return node.val

    def addAtHead(self, val):
        """
        :type val: int
        :rtype: None
        """
        node = DoubleListNode(val = val, next = self.head.next, prev = self.head)
        self.head.next.prev = node
        self.head.next = node
        self.size += 1

    def addAtTail(self, val):
        """
        :type val: int
        :rtype: None
        """
        node = DoubleListNode(val = val, prev = self.tail.prev, next = self.tail)
        self.tail.prev.next = node
        self.tail.prev = node
        self.size += 1

    def addAtIndex(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        if index < 0:
            self.addAtHead(val)
        elif index == self.size:
            self.addAtTail(val)
        elif index > self.size:
            pass
        else:
            node = self.get_node(index)
            added_node = DoubleListNode(val = val, prev = node.prev, next = node)
            node.prev.next = added_node
            node.prev = added_node
            self.size += 1

    def deleteAtIndex(self, index):
        """
        :type index: int
        :rtype: None
        """
        if index < 0 or index >= self.size:
            pass
        else:
            node = self.get_node(index)
            print(node.val)
            prev = node.prev
            print(prev.val)
            next = node.next
            print(next.val)
            prev.next, next.prev = next, prev
            self.size -= 1


from optparse import make_option
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from teleforma.models import *

class Command(BaseCommand):
    help = "Unpublish all contents for a given period"
    args = "period_name"
    admin_email = 'webmaster@parisson.com'

    def add_arguments(self, parser):
        parser.add_argument('args', nargs='*')

    def handle(self, *args, **options):
        period_name = args[0]
        period = Period.objects.get(name=period_name)
        conferences = Conference.objects.filter(period=period)
        for conference in conferences:
            conference.status = 0
            conference.save()
            for media in conference.media.all():
                media.is_published = False
                media.save()
        # <HACK
        for document in Document.objects.all():
            if document.file:
                document.is_published = True
                document.save()
        # HACK>

        for document in period.document.all():
            document.is_published = False
            document.save()


#!/usr/bin/python3

import sys
import textwrap

tw = textwrap.TextWrapper(width=72, break_long_words=False)
wrap_style = "left"

def add_para(para, out):
    if wrap_style == "off":
        out.extend(para)
        out[-1] += "\n"
    else:
        #if wrap_style is not "off", then we don't want to
        #add a blank line for an empty paragraph
        if len(para) == 0: return
        unwrapped = "-"
        for l in para:
            if len(l) == 0: continue
            if unwrapped[-1] != "-" and l[0] != "-":
                unwrapped += " "
            unwrapped += l
        out.extend(tw.wrap(unwrapped[1:]))
        out[-1] += "\n"

def process_instruction(instruction, para, out):
    global wrap_style
    global tw
    fields = instruction.split()
    if fields[0] == "dowrap":
        add_para(para, out)
        del para[:]
    elif fields[0] == "blank":
        if para:
            add_para(para, out)
            del para[:]
        out[-1] += ("\n" * (int(fields[1]) - 1))
    elif fields[0] == "wrap":
        if para:
            add_para(para, out)
            del para[:]
        wrap_style = fields[1]
    elif fields[0] == "indent":
        if para:
            add_para(para, out)
            del para[:]
        tw.initial_indent = tw.subsequent_indent = " " * int(fields[1])

in_text = sys.stdin.read()
out = [""]
para = []
for l in in_text.splitlines():
    if l[:2] == "::" and l[-2:] == "::":
        process_instruction(l[2:-2], para, out)
    elif len(l) == 0:
        process_instruction("dowrap", para, out)
    else:
        para.append(l)
process_instruction("dowrap", para, out)
if out[0] == "": del out[0]
sys.stdout.write("\n".join(out).replace("\n", "\r\n"))


import os
from pathlib import Path

from hybrid_md.decision_making import SimpleDecisionMaker
from hybrid_md.state_objects import HybridMD, StepKinds

dummy_input_content = """
can_update: true
check_interval: 5
num_initial_steps: 3
tolerances:
  ediff: 0.01  # eV
refit:
  e0_method: "average"
"""

def test_simple_decision_maker(tmp_path):
    # go to a temp dir
    os.chdir(tmp_path)

    # create a dummy input file
    input_yaml = Path("dummy.hybrid-md-input.yaml")
    with input_yaml.open(mode="w") as file:
        file.write(dummy_input_content)

    # state object - reads the above
    state = HybridMD("dummy")

    for md_iteration, result in [
        # nb. 0 is the initial step and calls to this are from 1
        (1, StepKinds.INITIAL),
        (2, StepKinds.INITIAL),
        (3, StepKinds.LAST_INITIAL),
        (4, StepKinds.GENERIC),
        (8, StepKinds.CHECK),
        (14376, StepKinds.GENERIC),
        (6343, StepKinds.CHECK),
    ]:
        # print("num:", md_iteration, result)
        assert SimpleDecisionMaker(state).get_step_kind(md_iteration) == result


import argparse
import os

# https://github.com/RobertBoganKang/file_processing
from file_processing import FileProcessing
# https://github.com/RobertBoganKang/midi_translate
from syntheize import Synthesize

class BatchSynthesize(FileProcessing):
    """
    batch apply synthesize performance
    """

    def __init__(self, ops):
        super().__init__(ops)
        self.sample_rate = ops.sample_rate
        self.reverb = ops.reverb_off
        self.synth = Synthesize(prepare_sound=False)

        self.change_part_synth_param()

    def change_part_synth_param(self):
        self.synth.sample_rate = self.sample_rate
        self.synth.reverb_add = self.reverb
        self.synth.prepare_sound_library()

    def do(self, in_path, out_path):
        if os.path.exists(out_path):
            return
        self.synth.synthesize(in_path, out_path)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='batch apply synthesize performance')
    fp_group = parser.add_argument_group('file processing arguments')
    fp_group.add_argument('--input', '-i', type=str, help='the input folder/file, or a text file for paths',
                          default='in')
    fp_group.add_argument('--in_format', '-if', type=str, help='the input format', default='mid')
    fp_group.add_argument('--output', '-o', type=str, help='the output folder/file', default='out')
    fp_group.add_argument('--out_format', '-of', type=str, help='the output format', default='wav')
    fp_group.add_argument('--cpu_number', '-j', type=int, help='cpu number of processing', default=0)

    synth_group = parser.add_argument_group('synthesize arguments')
    synth_group.add_argument('--sample_rate', '-sr', type=int, help='sample rate to process', default=48000)
    synth_group.add_argument('--reverb_off', '-ro', action='store_false', help='do not add reverb')

    args = parser.parse_args()

    # do batch synthesize
    BatchSynthesize(args)()


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

# Swagger
from django.urls import re_path
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

apiversion = 'api/v1/'

schema_view = get_schema_view(
   openapi.Info(
      title="Event Anywhere",
      default_version='v1',
      description="Esta aplicación te permite registrar eventos y administrarlos.",
      terms_of_service="",
      contact=openapi.Contact(email="narvaezsebas8@gmail.com"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
)

urlpatterns = [
    # Swagger
    path('docs/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

    # Paths app
    path('admin/', admin.site.urls),
    path(f'{apiversion}event/', include('apps.event.api.urls')),
    path(f'{apiversion}status/', include('apps.status.api.urls')),
    path(f'{apiversion}type/', include('apps.type.api.urls')),
]


__author__ = 'Kelvin Wu'

import config

# ====================================================
def sesh_getter():
    """takes a list of infosessions and prints the
    elements"""
    from uwaterlooapi import UWaterlooAPI

    uw = UWaterlooAPI(api_key=config.super_secret_key)
    infosesh = uw.infosessions()

    text = ''
    for infosession in infosesh:
        text += ("Employer: {}\n"
                 "Date: {}\n"
                 "Starts: {}\n"
                 "Ends: {}\n"
                 "Location: {}\n"
                 "Website: {}\n"
                 "Audience: {}\n"
                 "Programs: {}\n"
                 "Description: {}\n"
                 "--------------------\n") \
            .format(infosession['employer'], infosession['date'],
                    infosession['start_time'], infosession['end_time'],
                    infosession['location'], infosession['website'],
                    infosession['audience'], infosession['programs'],
                    infosession['description'])
    return text
# ====================================================

# Sending a GET request and parsing the JSON response
# manually since the relevant function doesn't exist in
# the UWaterlooAPI module
# ====================================================
def goosewatch():
    """prints the goosewatch information"""
    import dateutil.parser
    import requests

    resp = requests.get("https://api.uwaterloo.ca/v2/resources/goosewatch.json",
                        params={'key':config.super_secret_key})
    gw = resp.json()['data']

    text = ''
    for goose_location in gw:
        parsed_date = dateutil.parser.parse(goose_location['updated'])
        text += ("Location: {}\n"
                 "Latitude: {}\n"
                 "Longitude: {}\n"
                 "Last Update: {}\n"
                 "--------------------\n") \
            .format(goose_location['location'],
                    goose_location['latitude'],
                    goose_location['longitude'],
                    parsed_date.strftime('%B %d, %Y'))
    return text
# ====================================================


import base64
import json
import os
import subprocess
import time

import tkinter as tk
import cv2 as cv
import numpy as np
from PIL import ImageTk, Image
from tkinter import scrolledtext, font, W, CENTER
from  tkinter import ttk

import paho.mqtt.client as mqtt
from djitellopy import Tello

import math
from tkinter import Menu
import tensorflow as tf
import os
# importar libreria para ver el funcionamiento de la red
from tensorflow.keras.callbacks import TensorBoard
# importar libreria para poder modificar las imagenes
from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array

def calc_pixels(tupla_1, tupla_2):
    pixels = math.sqrt(math.pow((tupla_1[0]-tupla_2[0]), 2) + math.pow((tupla_1[1]-tupla_2[1]), 2))
    return pixels

master = tk.Tk()
client = mqtt.Client('Dashboard')
global_broker_address ="127.0.0.1"
global_broker_port = 1884

# treatment of messages received from gate through the global broker

def on_message(client, userdata, message):
    global panel
    global lbl
    global table

    splited = message.topic.split('/')
    origin = splited[0]
    destination = splited[1]
    command = splited[2]

    if origin == "cameraService":

        if command == "videoFrame":
            img = base64.b64decode(message.payload)
            # converting into numpy array from buffer
            npimg = np.frombuffer(img, dtype=np.uint8)
            # Decode to Original Frame
            img = cv.imdecode(npimg, 1)
            # show stream in a separate opencv window
            cv.imshow("Stream", img)
            cv.waitKey(1)
        if command == 'picture':
            print('show picture')
            img = base64.b64decode(message.payload)
            # converting into numpy array from buffer
            npimg = np.frombuffer(img, dtype=np.uint8)
            # Decode to Original Frame
            cv2image = cv.imdecode(npimg, 1)
            gray = cv.cvtColor(cv2image, cv.COLOR_BGR2GRAY)
            print(detector_ball)
            if detector_ball:
                ball = detector_ball.detectMultiScale(gray, 1.35, 20)
                for (x, y, w, h) in ball:
                    cv.rectangle(cv2image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            elif detector_face and detector_body:
                print('detect face')
                face = detector_face.detectMultiScale(gray, 1.2, 5)
                body = detector_body.detectMultiScale(gray, 1.2, 5)
                for (x, y, w, h) in face:
                    cv.rectangle(cv2image, (x, y), (x + w, y + h), (0, 255, 0), 2)
                for (x, y, w, h) in body:
                    cv.rectangle(cv2image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            elif detector_2:
                gray = cv.resize(gray, (200, 200), interpolation=cv.INTER_CUBIC)
                gray = np.array(gray).astype(float) / 255
                img = img_to_array(gray)
                img = np.expand_dims(img, axis=0)
                predict = detector_2.predict(img)
                predict = predict[0][0]
                if predict > 0.98:
                    cv.putText(cv2image, "Cat or dog detected", (200, 70), cv.FONT_HERSHEY_PLAIN, 3, (0, 0, 255))
            dim = (300, 300)
            # resize image
            cv2image = cv.resize(cv2image, dim, interpolation=cv.INTER_AREA)
            img = Image.fromarray(cv2image)
            imgtk = ImageTk.PhotoImage(image=img)
            panel.imgtk = imgtk
            panel.configure(image=imgtk)
    if origin == "autopilotService":
        if (command == "droneAltitude"):
            answer = str(message.payload.decode("utf-8"))
            lbl['text'] = answer[:5]
        if (command == "droneHeading"):
            answer = str(message.payload.decode("utf-8"))
            lbl['text'] = answer[:5]
        if (command == "droneGroundSpeed"):
            answer = str(message.payload.decode("utf-8"))
            lbl['text'] = answer[:5]

        if (command  == "dronePosition"):
            positionStr = str(message.payload.decode("utf-8"))
            position = positionStr.split('*')
            latLbl['text'] = position[0]
            lonLbl['text'] = position[1]

        if (command  == "droneBattery"):
            answer = str(message.payload.decode("utf-8"))
            lbl['text'] = answer[:5]

    if origin == "dataService":
        if  (command == "storedPositions"):
            # receive the positions stored by the data service
            data = message.payload.decode("utf-8")
            # converts received string to json
            dataJson = json.loads(data)
            cont = 0
            for dataItem in dataJson:
                table.insert(parent='', index='end', iid=cont, text='',
                        values=(dataItem['time'], dataItem['lat'], dataItem['lon']))
                cont = cont + 1

            table.pack()

    if origin == "radiationService":
        if (command == "Radiation"):
            answer = str(message.payload.decode("utf-8"))
            lbl['text'] = answer[:5] + ' mSv'

client.on_message = on_message

# |--DASHBOARD master frame ----------------------------------------------------------------------------------|
# |                                                                                |
# |  |---connection frame--------------------------------------------------------------------------------|    |
# |  |---------------------------------------------------------------------------------------------------|    |
# |                                                                                |
# |  |---top frame---------------------------------------------------------------------------------------|    |
# |  |                                                                                |    |
# |  |   |--Autopilot control label frame ----------------------------|  |--LEDs control label frame--|  |    |
# |  |   |                                                            |  |                            |  |    |
# |  |   |  |--Arm/disarm frame -----------------------------------|  |  |----------------------------|  |    |
# |  |   |  |------------------------------------------------------|  |                                  |    |
# |  |   |                                                            |                                  |    |
# |  |   |  |--bottom frame ---------------------------------------|  |                                  |    |
# |  |   |  |                                                      |  |                                  |    |
# |  |   |  |  |-Autopilot get frame--|  |-Autopilot set frame -|  |  |                                  |    |
# |  |   |  |  |----------------------|  |----------------------|  |  |                                  |    |
# |  |   |  |                                                      |  |                                  |    |
# |  |   |  |------------------------------------------------------|  |                                  |    |
# |  |   |                                                            |                                  |    |
# |  |   |------------------------------------------------------------|                                  |    |
# |  |---------------------------------------------------------------------------------------------------|    |
# |                                                                                |
# |  |---camera control label frame----------------------------------------------------------------------|    |
# |  |                                                                                |    |
# |  |   |--- Take picture frame -----------|            |--- Video stream frame -----------|            |    |
# |  |   |                                  |            |                                  |            |    |
# |  |   |----------------------------------|            |----------------------------------|            |    |
# |  |---------------------------------------------------------------------------------------------------|    |
# |                                                                                |
# |-----------------------------------------------------------------------------------------------------------|

# Connection frame ----------------------
connected = False
connectionFrame = tk.Frame (master)
connectionFrame.pack(fill = tk.X)

def connectionButtonClicked():
    global connected
    global client
    global detector_ball
    detector_ball = False
    global detector_2
    detector_2 = False
    global detector_body
    detector_body = False
    global detector_face
    detector_face = False

    if not connected:
        connectionButton['text'] = "Disconnect"
        connectionButton['bg'] = "green"
        connected = True
        client.connect(global_broker_address,  global_broker_port)
        client.publish("dashBoard/gate/connectPlatform")
        client.loop_start()
        client.subscribe("+/dashBoard/#")
        print('Connected with drone platform')

        topFrame.pack(fill=tk.X)
        cameraControlFrame.pack(padx=20, pady=20);

    else:
        print('Disconnect')
        connectionButton['text'] = "Connect with drone platform"
        connectionButton['bg'] = "red"
        connected = False
        topFrame.pack_forget()
        ledsControlFrame.pack_forget()
        cameraControlFrame.pack_forget()

connectionButton = tk.Button(connectionFrame, text="Connect with drone platform", width = 50, bg='red', fg="white", command=connectionButtonClicked)
connectionButton.grid(row = 0, column = 0, padx=60, pady=20)
# top frame -------------------------------------------
topFrame = tk.Frame (master)

# Autopilot control label frame ----------------------
autopilotControlFrame = tk.LabelFrame(topFrame, text="Autopilot control", padx=5, pady=5)
autopilotControlFrame.pack(padx=20, side = tk.LEFT);

# Arm/disarm frame ----------------------
armDisarmFrame = tk.Frame (autopilotControlFrame)
armDisarmFrame.pack(padx=20)

armed = False
def armDisarmButtonClicked():
    global armed

    if not armed:
            armDisarmButton['text'] = "Disarm drone"
            armDisarmButton['bg'] = "green"
            armed = True
            client.publish("dashBoard/autopilotService/armDrone")

    else:
            armDisarmButton['text'] = "Arm drone"
            armDisarmButton['bg'] = "red"
            armed = False
            client.publish("dashBoard/autopilotService/disarmDrone")

armDisarmButton = tk.Button(armDisarmFrame, text="Arm drone", bg='red', fg="white",  width = 90, command=armDisarmButtonClicked)
armDisarmButton.grid(column=0, row=0,  pady = 5)

# bottomFrame frame ----------------------
bottomFrame = tk.Frame (autopilotControlFrame)
bottomFrame.pack(padx=20)

# Autopilot get frame ----------------------
autopilotGet = tk.Frame (bottomFrame)
autopilotGet.pack(side = tk.LEFT, padx=20)

v1 = tk.StringVar()
s1r1= tk.Radiobutton(autopilotGet,text="Altitude", variable=v1, value=1).grid(column=0, row=0, columnspan = 5, sticky=tk.W)
s1r2= tk.Radiobutton(autopilotGet,text="Heading", variable=v1, value=2).grid(column=0, row=1, columnspan = 5, sticky=tk.W)
s1r3= tk.Radiobutton(autopilotGet,text="Ground Speed", variable=v1, value=3).grid(column=0, row=2, columnspan = 5, sticky=tk.W)
s1r4= tk.Radiobutton(autopilotGet,text="Battery level", variable=v1, value=4).grid(column=0, row=3, columnspan = 5, sticky=tk.W)
v1.set(1)

def autopilotGetButtonClicked():
    if v1.get() == "1":
        client.publish("dashBoard/autopilotService/getDroneAltitude")
    elif v1.get() == "2":
        client.publish("dashBoard/autopilotService/getDroneHeading")
    elif v1.get() == "3":
        client.publish("dashBoard/autopilotService/getDroneGroundSpeed")
    else:
        client.publish("dashBoard/autopilotService/getDroneBattery")

autopilotGetButton = tk.Button(autopilotGet, text="Get", bg='red', fg="white", width = 10, height=5, command=autopilotGetButtonClicked)
autopilotGetButton.grid(column=5, row=0, columnspan=2, rowspan = 3, padx=10)

lbl = tk.Label(autopilotGet, text=" ", width = 10, borderwidth=2, relief="sunken")
lbl.grid(column=7, row=1,  columnspan=2 )

# Autopilot set frame ----------------------
autopilotSet = tk.Frame (bottomFrame)
autopilotSet.pack( padx=20)

def takeOffButtonClicked():
    client.publish("dashBoard/autopilotService/takeOff", metersEntry.get() )

takeOffButton = tk.Button(autopilotSet, text="Take Off", bg='red', fg="white",  width = 10, command=takeOffButtonClicked)
takeOffButton.grid(column=0, row=1, columnspan=2, sticky=tk.W)

to = tk.Label(autopilotSet, text="to")
to.grid(column=2, row=1)
metersEntry = tk.Entry(autopilotSet, width = 10)
metersEntry.grid(column=3, row=1,  columnspan=2 )
meters = tk.Label(autopilotSet, text="meters")
meters.grid(column=5, row=1)

lat = tk.Label(autopilotSet, text="lat")
lat.grid(column=2, row=2,  columnspan=2,padx = 5 )

lon = tk.Label(autopilotSet, text="lon")
lon.grid(column=4, row=2,  columnspan=2,padx = 5 )

def getPositionButtonClicked():
    client.publish("dashBoard/autopilotService/getDronePosition" )

getPositionButton = tk.Button(autopilotSet, text="Get Position", bg='red', fg="white",  width = 10,  command=getPositionButtonClicked)
getPositionButton.grid(column=0, row=3, pady = 5, sticky=tk.W)

latLbl = tk.Label(autopilotSet, text=" ", width = 10, borderwidth=2, relief="sunken")
latLbl.grid(column=2, row=3,  columnspan=2,padx = 5 )

lonLbl = tk.Label(autopilotSet, text=" ", width = 10, borderwidth=2, relief="sunken")
lonLbl.grid(column=4, row=3,  columnspan=2,padx = 5 )

def goToButtonClicked():
    position = str (goTolatEntry.get()) + '*' + str(goTolonEntry.get())
    client.publish("dashBoard/autopilotService/goToPosition", position)

goToButton = tk.Button(autopilotSet, text="Go To", bg='red', fg="white",  width = 10,  command=goToButtonClicked)
goToButton.grid(column=0, row=4, pady = 5, sticky=tk.W)

goTolatEntry = tk.Entry(autopilotSet, width = 10)
goTolatEntry.grid(column=2, row=4,  columnspan=2,padx = 5 )

goTolonEntry = tk.Entry(autopilotSet, width = 10)
goTolonEntry.grid(column=4, row=4,  columnspan=2,padx = 5 )

def returnToLaunchButtonClicked():
    client.publish("dashBoard/autopilotService/returnToLaunch")

returnToLaunchButton = tk.Button(autopilotSet, text="Return To Launch", bg='red', fg="white",  width = 40, command=returnToLaunchButtonClicked)
returnToLaunchButton.grid(column=0, row=5,  pady = 5, columnspan=6, sticky=tk.W)

def openWindowToShowRecordedPositions():
    # Open a new small window to show the positions timestamp to be received from the data service
    global newWindow
    global table
    newWindow = tk.Toplevel(master)

    newWindow.title("Recorded positions")

    newWindow.geometry("400x400")
    table = ttk.Treeview(newWindow)

    table['columns'] = ('time', 'latitude', 'longitude')

    table.column("#0", width=0, stretch=tk.NO)
    table.column("time", anchor=tk.CENTER, width=150)
    table.column("latitude", anchor=tk.CENTER, width=80)
    table.column("longitude", anchor=tk.CENTER, width=80)

    table.heading("#0", text="", anchor=tk.CENTER)
    table.heading("time", text="Time", anchor=tk.CENTER)
    table.heading("latitude", text="Latitude", anchor=tk.CENTER)
    table.heading("longitude", text="Longitude", anchor=tk.CENTER)

    # requiere the stored positions from the data service
    client.publish("dashBoard/dataService/getStoredPositions")

    closeButton = tk.Button(newWindow, text="Close", bg='red', fg="white", command=closeWindowToShowRecordedPositions).pack()

def closeWindowToShowRecordedPositions ():
    global newWindow
    newWindow.destroy()

showRecordedPositionsButton = tk.Button(autopilotSet, text="Show recorded positions", bg='red', fg="white",  width = 40, command=openWindowToShowRecordedPositions)
showRecordedPositionsButton.grid(column=0, row=6,  pady = 5, columnspan=6, sticky=tk.W)

# LEDs control frame ----------------------
ledsControlFrame = tk.LabelFrame(topFrame, text="LEDs control", padx=5, pady=5)
ledsControlFrame.pack(padx=20, pady=20);

v3 = tk.StringVar()
s1r7= tk.Radiobutton(ledsControlFrame,text="LED sequence START/STOP", variable=v3, value=1).grid(column=2, row=2, columnspan = 3)
s1r8= tk.Radiobutton(ledsControlFrame,text="LED sequence for N seconds", variable=v3, value=2).grid(column=2, row=3, columnspan = 3)

seconds = tk.Entry(ledsControlFrame, width = 5)
seconds.grid(column=5, row=3, columnspan = 3)
v3.set(1)

lEDSequence = False;

def LEDControlButtonClicked():
    global E1
    global lEDSequence
    if v3.get() == "1":
        if not lEDSequence:
            ledControlButton['text'] = "Stop"
            ledControlButton['bg'] = "green"
            lEDSequence = True
            print ('Start LEDs sequence')
            client.publish("dashBoard/LEDsService/startLEDsSequence")

        else:
            ledControlButton['text'] = "Start"
            ledControlButton['bg'] = "red"
            lEDSequence = False
            print('Stop LEDs sequence')
            client.publish("dashBoard/LEDsService/stopLEDsSequence")

    if v3.get() == "2":
            print('LEDs sequence for N seconds')
            client.publish("dashBoard/LEDsService/LEDsSequenceForNSeconds", seconds.get())

ledControlButton = tk.Button(ledsControlFrame, text="Start", bg='red', fg="white",  width = 10, height = 3, command=LEDControlButtonClicked)
ledControlButton.grid(column=8, row=1,  padx = 5, columnspan=4, rowspan = 3)

# Radiation control frame ----------------------
radiationControlFrame = tk.LabelFrame(topFrame, text="Radiation control", padx=5, pady=5)
radiationControlFrame.pack(padx=20, pady=20)

v4 = tk.StringVar()
s1r9= tk.Radiobutton(radiationControlFrame,text="Radiation value", variable=v4, value=4).grid(column=0, row=1, columnspan = 5, sticky=tk.W)
v4.set(1)

def radiationGetButtonClicked():
    if v4.get() == "1":
        client.publish("dashBoard/radiationService/getRadiation")

radiationGetButton = tk.Button(radiationControlFrame, text="Get", bg='red', fg="white", width = 10, height=3, command=radiationGetButtonClicked)
radiationGetButton.grid(column=5, row=0, columnspan=2, rowspan = 3, padx=10)

lbl = tk.Label(radiationControlFrame, text=" ", width = 10, borderwidth=2, relief="sunken")
lbl.grid(column=7, row=1,  columnspan=2 )

# flightplan open map frame ----------------------
flightplanControlFrame = tk.LabelFrame(topFrame, text="Flightplan Map", padx=5, pady=5)
flightplanControlFrame.pack(padx=20, pady=20)

def openFlightplanButtonClicked():
    print('Opening Flightplan map')
    client.publish("dashBoard/flightplanService/openFlightplan")
    client.subscribe("flightplanService/#")

flightplanOpenButton = tk.Button(flightplanControlFrame, text="OPEN", bg='red', fg="white", width = 10, height=3, command=openFlightplanButtonClicked)
flightplanOpenButton.grid(column=5, row=0, columnspan=2, rowspan = 3, padx=10)

# Camera control label frame ----------------------
cameraControlFrame = tk.LabelFrame(master, text="Camera control", padx=5, pady=5)

takePictureFrame = tk.Frame (cameraControlFrame)
takePictureFrame.pack(side = tk.LEFT)

def train():
    text_1 = input_1_text.get()
    text_2 = input_2_text.get()
    epoch = input_3_text.get()
    print(text_1, text_2, epoch)
    ## Almacenamiento de imagnes
    train_path = text_1
    vali_path = text_2
    train_list = os.listdir(train_path)
    vali_list = os.listdir(vali_path)

    ## Parametros para el almacenamiento de las imagenes
    width = 200
    heigth = 200
    # Entrenamiento
    labels_train = []
    imag_train = []
    data_train = []
    cont_train = 0
    # Validacion
    labels_val = []
    imag_val = []
    data_val = []
    cont_val = 0

    ## Extraer fotos y etiquetarlas

    for folder_name in train_list:
        name_path = train_path + '/' + folder_name
        folder = os.listdir(name_path)
        for file in folder:
            labels_train.append(cont_train)
            img = cv.imread(name_path + '/' + file, 0)
            img = cv.resize(img, (width, heigth), interpolation=cv.INTER_CUBIC)
            img = img.reshape(width, heigth, 1)
            data_train.append([img, cont_train])
            imag_train.append(img)
        cont_train += 1

    for folder_name in vali_list:
        name_path = vali_path + '/' + folder_name
        folder = os.listdir(name_path)
        for file in folder:
            labels_val.append(cont_val)
            img = cv.imread(name_path + '/' + file, 0)
            img = cv.resize(img, (width, heigth), interpolation=cv.INTER_CUBIC)
            img = img.reshape(width, heigth, 1)
            data_val.append([img, cont_val])
            imag_val.append(img)
        cont_val += 1

    ## Normalizar imagenes
    imag_train = np.array(imag_train).astype(float) / 255
    print(imag_train.shape)
    imag_val = np.array(imag_val).astype(float) / 255
    print(imag_val.shape)
    # Pasar las listas a arrays
    labels_train = np.array(labels_train)
    labels_val = np.array(labels_val)

    ## Dar realismo a las imagenes
    # Modificar las imagenes aleatoriamente

    image_random_gen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=10,
        zoom_range=[0.2, 1],
        horizontal_flip=True,
        vertical_flip=True,
    )

    image_train_gen = image_random_gen.flow(imag_train, labels_train, batch_size=32)

    ## Creamos el modelo de la red convolucional con Drop Out
    cnn_model = tf.keras.models.Sequential([
        tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(200, 200, 1)),
        # capa convolucional con 32 Kernel
        tf.keras.layers.MaxPool2D(2, 2),
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),  # capa convolucional con 64 Kernel
        tf.keras.layers.MaxPool2D(2, 2),
        tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),  # capa convolucional con 128 Kernel
        tf.keras.layers.MaxPool2D(2, 2),

        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(256, activation='relu'),
        tf.keras.layers.Dense(1, activation='sigmoid')
    ])

    ## Compilamos el modelo y añadimos una funcion de perdida y el optimizador
    cnn_model.compile(
        optimizer='adam',
        loss='binary_crossentropy',
        metrics=['accuracy']
    )

    ## Entrenar la red neuronal
    # tensorboard --logdir="C:/RedNeuronal/board"

    board = TensorBoard(log_dir='C:/RedNeuronal/board')
    cnn_model.fit(
        image_train_gen,
        batch_size=32,
        validation_data=(imag_val, labels_val),
        epochs=epoch,
        callbacks=[board],
        steps_per_epoch=int(np.ceil(len(imag_train) / float(32))),
        validation_steps=int(np.ceil(len(imag_val) / float(32)))
    )

    cnn_model.save('clasificador1.h5')
    print('Red Nueronal Terminada')

def ball_command():
    global detector_ball
    # detect, use 1,7 and 20
    path_ball = os.path.dirname(__file__) + '/cascade_balls.xml'
    detector_ball = cv.CascadeClassifier(path_ball)
    print(detector_ball)
    pass

def animals_command():
    ## path de nuestro modelo
    cnn_model = os.path.dirname(__file__) + '/CatsDogs.h5'

    ## Leer la red neuronal
    detector_2 = tf.keras.models.load_model(cnn_model)
    print(detector_2)

def human_command():
    path_face = os.path.dirname(__file__) + '/haarcascade_frontalface_default.xml'
    path_body = os.path.dirname(__file__) + '/haarcascade_fullbody.xml'
    detector_face = cv.CascadeClassifier(path_face)
    detector_body = cv.CascadeClassifier(path_body)
    detector_2 = False
    detector_ball = False
    print(detector_body, detector_face)

def use():
    path = object_path_text.get()
    print(path)
    cnn_model = path
    detector_2 = tf.keras.models.load_model(cnn_model)
    print(detector_2)

def useObjectWindow():
    # Toplevel object which will
    newWindow = tk.Toplevel(master)
    # sets the title of the
    newWindow.title("New Window")
    # sets the geometry of toplevel
    newWindow.geometry("400x400")

    input_1_label = tk.Label(newWindow,text="Object detection path").place(x=45, y=60)
    submit_button = tk.Button(newWindow,text="Submit", command=use).place(x=45,y=110)
    text_1 = tk.StringVar()
    global object_path_text
    input_1 = tk.Entry(newWindow, textvariable=text_1, width=50).place(x=45,y=85)
    object_path_text =text_1
    newWindow.destroy()

def trainObjectWindow():
    # Toplevel object which will
    newWindow = tk.Toplevel(master)
    # sets the title of the
    newWindow.title("New Window")
    # sets the geometry of toplevel
    newWindow.geometry("400x400")

    input_1_label = tk.Label(newWindow,text="Train path").place(x=45, y=60)
    input_2_label = tk.Label(newWindow,text="Validation path").place(x=40,y=100)
    input_3_label = tk.Label(newWindow, text="Epocas").place(x=40, y=140)
    submit_button = tk.Button(newWindow,text="Submit", command=train).place(x=40,y=180)
    text_1 = tk.StringVar()
    text_2 = tk.StringVar()
    text_3 = tk.StringVar()
    global input_1_text
    input_1 = tk.Entry(newWindow, textvariable=text_1, width=30).place(x=130,y=60)
    input_1_text =text_1
    global input_2_text
    input_2 = tk.Entry(newWindow, textvariable=text_2, width=30).place(x=130,y=100)
    input_2_text = text_2
    global input_3_text
    input_3 = tk.Entry(newWindow, textvariable=text_3, width=30).place(x=130,y=140)
    input_3_text = text_3
    newWindow.destroy()

my_menu = Menu(master)
master.config(menu=my_menu)
red_menu = Menu(my_menu)
my_menu.add_cascade(menu=red_menu, label='Redes Neuronales')
red_menu.add_command(label='Human detection', command=human_command)
red_menu.add_separator()
red_menu.add_command(label="Ball detection", command=ball_command)
red_menu.add_separator()
red_menu.add_command(label="Cats & dogs detection", command=animals_command)
red_menu.add_separator()
red_menu.add_command(label="Train a new object recognition", command=trainObjectWindow)
red_menu.add_separator()
red_menu.add_command(label="Use the new object recognition", command=useObjectWindow)

def takePictureButtonClicked():
    print ("Take picture")
    client.publish("dashBoard/cameraService/takePicture")

takePictureButton = tk.Button(takePictureFrame, text="Take Picture", width=50, bg='red', fg="white", command=takePictureButtonClicked)
takePictureButton.grid(column=0, row=0, pady = 20, padx = 20)

img = Image.open("image1.jpg")
img = img.resize((350, 350), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
panel = tk.Label(takePictureFrame, image=img, borderwidth=2, relief="raised")
panel.image = img
panel.grid(column=0, row=1, columnspan=3, rowspan = 3)

videoStreamFrame = tk.Frame(cameraControlFrame)
videoStreamFrame.pack()

videoStream = False;

def videoStreamButtonClicked():
    global videoStream
    global client
    if not videoStream:
        videoStreamButton['text'] = "Stop video stream"
        videoStreamButton['bg'] = "green"
        videoStream = True
        print ('Start video stream')
        client.publish("dashBoard/cameraService/startVideoStream")

    else:
        videoStreamButton['text'] = "Start video stream on a separaded window"
        videoStreamButton['bg'] = "red"
        videoStream = False
        print ('Stop video stream')
        client.publish("dashBoard/cameraService/stopVideoStream")

        cv.destroyWindow("Stream")

videoStreamButton = tk.Button(videoStreamFrame, text="Start video stream \n on a separaded window", width=50, height = 25, bg='red', fg="white",
                              command=videoStreamButtonClicked)
myFont = font.Font(size=12)
videoStreamButton['font'] = myFont
videoStreamButton.grid(column=0, row=0, pady=20, padx=20, )

master.mainloop()


#!/usr/bin/env python3

import collections
import sys

# Constants

BLUE = 0
RED  = 1

# Read Graph

def read_graph(n, m):
    ''' Construct adjacency set '''
    g = {v: set() for v in range(n)}

    for _ in range(m):
        s, t = map(int, sys.stdin.readline().split())
        g[s].add(t)
        g[t].add(s)

    return g

# Determine if Bicolorable

def is_bicolorable(g):
    ''' Determines if graphis bicolorable by walking it recursively. '''
    return walk(g, list(g.keys())[0], BLUE, {})

def walk(g, n, color, visited):
    ''' Recursively walk graph and verifying that the node has the appropriate
    color. '''

    # We have already visited this node, so verify we still have the same
    # color.
    if n in visited:
        return visited[n] == color

    # We have not visited this node yet, so store its color.
    visited[n] = color

    # Visit each neighbor recursively with the alternate color and check that
    # they are colorable.
    for v in g[n]:
        if not walk(g, v, (color + 1) % 2, visited):
            return False

    return True

def walk(g, n, color, visited):
    ''' Iteratively walk graph and verifying that the node has the appropriate
    color. '''
    # Establish frontier with initial node and color
    frontier = [(n, color)]

    # While there are still nodes in the frontier...
    while frontier:
        # Pop one node from frontier
        v, c = frontier.pop()

        # Check if it has been visited
        if v in visited:
            if c != visited[v]:
                return False
            else:
                continue

        # Mark that it has been visited
        visited[v] = c

        # Add neighbors to frontier
        for u in g[v]:
            frontier.append((u, (c + 1) % 2))

    return True

# Main execution

def main():
    n, m = map(int, sys.stdin.readline().split())
    while n and m:
        g = read_graph(n, m)
        if is_bicolorable(g):
            print('BICOLORABLE')
        else:
            print('NOT BICOLORABLE')

        n, m = map(int, sys.stdin.readline().split())

if __name__ == '__main__':
    main()


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:

        if not head:
            return None

        if not head.next:
            return TreeNode(head.val)

        # print(head)

        # recursively split list in half, return to caller
        fast = head.next.next
        mid = head

        while fast and fast.next:
            fast = fast.next.next
            mid = mid.next

        tmp = mid.next
        mid.next = None
        node = TreeNode(tmp.val)
        node.left = self.sortedListToBST(head)
        node.right = self.sortedListToBST(tmp.next)

        return node


# Configuration

DEBUG = False

# training
EPOCHS = 10
MOMENTUM = 0.9
LEARNING_RATE = 0.01
BATCH_SIZE = 256
THREADS = 8

USE_CUDA = True

# file paths
IMAGES_PATH = "input"
TRAINING_PATH = "train_file.csv"
VALIDATION_PATH = "test_file.csv"
TEST_PATH = "test_file.csv"

RESULTS_PATH = "results"


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

from osv import osv, fields
from datetime import datetime

from ..giscedata_polissa import PERMISSION_SELECTION, ERROR_CODES
AVAILABLE_STATES = [
    ('init','Init'),
    ('admin_specified', 'Nova administradora OV especificada'),
    ('done', 'Done')
]

class WizardModifyOVAdmin(osv.osv_memory):

    _name = 'wizard.modify.ov.admin'

    def onchange_administradora(self, cursor, uid, ids, administradora_id):
            res = {'value': {"state": "init"}}
            if administradora_id:
                res = {'value': {"state": "admin_specified"}}
            return res

    def default_get(self, cr, uid, fields, context={}):
        active_id = context.get('active_id', False)

        res = {}
        if not active_id:
            return res

        if isinstance(active_id, (list, tuple)):
            active_id = active_id[0]

        pol_obj = self.pool.get("giscedata.polissa")
        titular = pol_obj.read(cr, uid, active_id, ['titular'])['titular'][0]

        res['claimant'] = titular
        res['state'] = 'init'

        return res

    def annotate_legal_representative(self, cursor, uid, titular_id, repersentative_id):
        res_partner_obj = self.pool.get('res.partner')
        admin_comment = res_partner_obj.read(cursor, uid, titular_id,
            ['comment']).get("comment", "")
        representative_vals = res_partner_obj.read(cursor, uid, repersentative_id,
            ['name', 'vat'])
        data = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        message = u"Durant el procés d'assignació d'Administradora OV, aquest " +\
            u"partner va declarar en {} que el partner ".format(data) +\
            u"{} amb VAT {} és el representant legal d'aquest.".format(
                representative_vals['name'], representative_vals['vat']
            )
        if admin_comment:
            message = admin_comment + "\n\n" + message
        res_partner_obj.write(cursor, uid, titular_id,
            {"comment": message})

    def create_admin_notification_modification(self, cursor, uid, partner_id,
            ov_admin_modification, notification_receptor, semantic_id):
        if partner_id is None:
            return

        mdata_obj = self.pool.get('ir.model.data')
        template_id = mdata_obj.get_object_reference(
            cursor, uid, 'som_polissa_administradora', semantic_id
        )[1]

        admin_noti_obj = self.pool.get('som.admin.notification')
        if partner_id not in notification_receptor.keys():
            notification_receptor[partner_id] = admin_noti_obj.create(cursor, uid, {
                "receptor": partner_id, "pending_notification": True,
                "template_id": template_id
            })

        admin_noti_obj.write(cursor, uid, notification_receptor[partner_id],
            {'modification': [(4, ov_admin_modification)]})

    def action_assignar_administradora(self, cursor, uid, ids, context=None):
        active_ids = context.get('active_ids', [])

        if not active_ids:
            return {}

        pol_obj = self.pool.get('giscedata.polissa')
        partner_obj = self.pool.get('res.partner')
        admin_noti_obj = self.pool.get("som.admin.notification")
        admin_mod_obj = self.pool.get("som.admin.modification")

        wiz_vals = self.read(cursor, uid, ids)[0]
        new_administradora_id = wiz_vals.get("new_administradora", False)
        administradora_permissions = wiz_vals.get("administradora_permissions", False)
        is_legal_representative = wiz_vals.get("is_legal_representative", False)
        not_notify_changes = wiz_vals.get("not_notify_changes", False)

        # validate fields
        if not (new_administradora_id and administradora_permissions):
            raise osv.except_osv('Error!', u"Falten camps per emplenar")

        new_administradora_name = partner_obj.read(
            cursor, uid, new_administradora_id, ['name'])['name']

        notification_receptor = {}
        titulars_anotats = []
        polisses = pol_obj.browse(cursor, uid, active_ids)
        info = ""
        for pol in polisses:
            # keep old administrator if there is
            old_administradora_id = None
            if pol.administradora:
                old_administradora_id = pol.administradora.id

            titular_id = pol.titular.id

            # perform assignment
            result = pol.add_contract_administrator(new_administradora_id,
                    administradora_permissions, is_legal_representative=is_legal_representative)

            error = result.get('error', None) is not None

            ov_admin_modification = None
            if error:
                error_msg = u"- S'ha produït un error al assignar l'administradora " + \
                    u"per la pòlissa {}: \"{}\"\n"
                error_msg = error_msg.format(pol.name, result['error_msg'])
                info += error_msg

                skip_error = ERROR_CODES.get(result['error'], {}).get('skip_error', False)
                if not skip_error:
                    vals = {
                        "old_administradora": old_administradora_id,
                        "new_administradora": new_administradora_id,
                        "permissions": administradora_permissions,
                        "is_legal_representative": is_legal_representative,
                        "error": True,
                        "info": error_msg
                    }
                    ov_admin_modification = pol_obj.register_ov_admin_modification(
                        cursor, uid, pol.id, vals)
                else:
                    continue
            else:
                ov_admin_modification = result['modification']
                # update info if there's no error
                msg = ''
                if old_administradora_id is not None:
                    old_administradora_name = partner_obj.read(
                        cursor, uid, old_administradora_id, ['name'])['name']
                    msg = u"- S'ha sustituit el partner '{}' (ID {}) pel partner " + \
                        u"'{}' (ID {}) com a administradora OV a la pòlissa {}\n"
                    msg = msg.format(
                        old_administradora_name, old_administradora_id,
                        new_administradora_name, new_administradora_id, pol.name)
                else:
                    msg = u"- S'ha assignat el partner '{}' (ID {}) " + \
                        u"com a administradora OV a la pòlissa {}\n"
                    msg = msg.format(
                        new_administradora_name, new_administradora_id, pol.name)

                admin_mod_obj.write(cursor, uid, ov_admin_modification, {"info": msg})

                info += msg

            # create notifications and associate with modification
            self.create_admin_notification_modification(cursor, uid, titular_id,
                ov_admin_modification, notification_receptor, 'email_assignacio_a_titular')
            self.create_admin_notification_modification(cursor, uid, old_administradora_id,
                ov_admin_modification, notification_receptor, 'email_desassignacio_a_administradora')
            self.create_admin_notification_modification(cursor, uid, new_administradora_id,
                ov_admin_modification, notification_receptor, 'email_assignacio_a_administradora')

            if is_legal_representative and titular_id not in titulars_anotats:
                self.annotate_legal_representative(cursor, uid, titular_id, new_administradora_id)
                titulars_anotats.append(titular_id)

        self.write(cursor, uid, ids, {
            "state": "done",
            "info": info
        })

        cursor.commit()

        if not not_notify_changes:
            # notify assignation
            for noti_id in notification_receptor.values():
                admin_noti_obj.send_email(cursor, uid, noti_id)

        return

    def action_desassignar_administradora(self, cursor, uid, ids, context=None):
        active_ids = context.get('active_ids', [])

        if not active_ids:
            return {}

        pol_obj = self.pool.get('giscedata.polissa')
        partner_obj = self.pool.get('res.partner')
        admin_noti_obj = self.pool.get("som.admin.notification")
        admin_mod_obj = self.pool.get("som.admin.modification")

        wiz_vals = self.read(cursor, uid, ids)[0]
        not_notify_changes = wiz_vals.get("not_notify_changes", False)

        notification_receptor = {}
        polisses = pol_obj.browse(cursor, uid, active_ids)
        info = ""
        for pol in polisses:
            # keep old administrator if there is
            old_administradora_id = None
            if pol.administradora:
                old_administradora_id = pol.administradora.id

            titular_id = pol.titular.id

            # perform unassignment
            result = pol.remove_contract_administrator()

            error = result.get('error', None) is not None

            ov_admin_modification = None
            if error:
                error_msg = u"- S'ha produït un error al assignar l'administradora " + \
                    u"per la pòlissa {}: \"{}\"\n"
                error_msg = error_msg.format(pol.name, result['error_msg'])
                info += error_msg

                skip_error = ERROR_CODES.get(result['error'], {}).get('skip_error', False)
                if not skip_error:
                    vals = {
                        "old_administradora": old_administradora_id,
                        "new_administradora": None,
                        "permissions": None,
                        "is_legal_representative": False,
                        "error": True,
                        "info": error_msg
                    }
                    ov_admin_modification = pol_obj.register_ov_admin_modification(
                        cursor, uid, pol.id, vals)
                else:
                    continue
            else:
                ov_admin_modification = result['modification']
                # update info if there's no error
                old_administradora_name = partner_obj.read(
                    cursor, uid, old_administradora_id, ['name'])['name']
                msg = u"- S'ha desassignat el partner '{}' (ID {}) de la pòlissa {}\n".format(
                    old_administradora_name, old_administradora_id, pol.name)

                admin_mod_obj.write(cursor, uid, ov_admin_modification, {"info": msg})

                info += msg

            # create notifications and associate with modification
            self.create_admin_notification_modification(cursor, uid, titular_id,
                ov_admin_modification, notification_receptor, 'email_desassignacio_a_titular')
            self.create_admin_notification_modification(cursor, uid, old_administradora_id,
                ov_admin_modification, notification_receptor, 'email_desassignacio_a_administradora')

        self.write(cursor, uid, ids, {
            "state": "done",
            "info": info
        })

        cursor.commit()

        if not not_notify_changes:
            # notify assignation
            for noti_id in notification_receptor.values():
                admin_noti_obj.send_email(cursor, uid, noti_id)

        return

    _columns = {
        'new_administradora': fields.many2one(
            'res.partner', 'Nova Administradora OV'
        ),
        'claimant': fields.many2one(
            'res.partner', 'Sol·licitant'
        ),
        'is_legal_representative': fields.boolean(
            'Representant legal',
            help=u"Si s'activa, es deixarà una nota a la fitxa del titular amb el nom i VAT " +\
                u"de l'Administradora OV, especificant que aquesta última és la representant " +\
                u"legal del titular."
        ),
        'administradora_permissions': fields.selection(
            PERMISSION_SELECTION,
            string='Permisos Administradora OV',
            help=u"Permisos de l'Administradora OV sobre la pòlissa"
        ),
        'state': fields.selection(
            selection=AVAILABLE_STATES,
            string='Estat'
        ),
        'not_notify_changes': fields.boolean(
            'No notificar canvis',
            help=u"Si s'activa, els canvis d'Administradora no es notificaràn a ningú"
        ),
        'info': fields.text('Info'),
    }

WizardModifyOVAdmin()


"""
 Color Math Module (colormath)
 Copyright (C) 2009 Gregory Taylor

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

"""
Formulas for density calculation.
"""
from math import log10, log
from colormath_fast.density_standards import *

def ansi_density(color, std_array):
    """
    Calculates density for the given SpectralColor using the spectral weighting
    function provided. For example, ANSI_STATUS_T_RED. These may be found in
    density_standards.py.

    color: (SpectralColor) The SpectralColor object to calculate density for.
    std_array: (ndarray) NumPy array of filter of choice from density_standards.py.
    """
    # Load the spec_XXXnm attributes into a Numpy array.
    sample = color.get_numpy_array()
    # Matrix multiplication
    intermediate = sample * std_array

    # Sum the products.
    numerator = intermediate.sum()
    # This is the denominator in the density equation.
    sum_of_standard_wavelengths = std_array.sum()

    # This is the top level of the density formula.
    return -1.0 * log10(numerator / sum_of_standard_wavelengths)

def auto_density(color):
    """
    Given a SpectralColor, automatically choose the correct ANSIT filter. Returns
    a tuple with a string representation of the filter the calculated density.
    """
    color_array = color.get_numpy_array()
    blue_density = ansi_density(color, ANSI_STATUS_T_BLUE)
    green_density = ansi_density(color, ANSI_STATUS_T_GREEN)
    red_density = ansi_density(color, ANSI_STATUS_T_RED)

    densities = [blue_density, green_density, red_density]
    min_density = min(densities)
    max_density = max(densities)
    density_range = max_density - min_density
    #print "DIFF", density_range

    # See comments in density_standards.py for VISUAL_DENSITY_THRESH to
    # understand what this is doing.
    if density_range <= VISUAL_DENSITY_THRESH:
        #print "visual"
        return ansi_density(color, ISO_VISUAL)
    elif blue_density > green_density and blue_density > red_density:
        #print "blue"
        return blue_density
    elif green_density > blue_density and green_density > red_density:
        #print "green"
        return green_density
    else:
        #print "red"
        return red_density


import os
from dotenv import load_dotenv
from chromadb import PersistentClient
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction

load_dotenv(".env")

openai_embeddings = OpenAIEmbeddingFunction(
    api_key=os.getenv("OPENAI_API_KEY"),
    model_name="text-embedding-ada-002"
)

client = PersistentClient("db/embeddings")

def get_context(user_id: int, query: str) -> str:
    collection = client.get_or_create_collection(
        f"{user_id}", embedding_function=openai_embeddings)
    embeddings = openai_embeddings([query])
    context = collection.query(query_embeddings=embeddings, n_results=3)

    collection.add(
        ids=["10"],
        metadatas=[{"sourse": "balls"}],
        documents=[
            "IQ baby palace это детский сад и детский развивающий центр в городе Гатчина. Сюда можно отправить детей, чтобы они стали гениями."
        ]
    )

    print("collection_name ", collection.name)
    print("context", context["documents"])

    return "\n".join(context["documents"][0])

def get_collection_size(user_id: int) -> bool:
    collection = client.get_collection(
        str(user_id), embedding_function=openai_embeddings)

    print("collection", collection.count())
    return collection.count()


'''
Parsing - Exercise 6

The script reads a multiple sequence regord FASTA file and
writes the sequences to a new file separated by a blank line.

'''

fasta = open('sprot_prot.fasta')
seqs = open('seqs.txt', 'w')

for line in fasta:
	if line[0] == '>':
		seqs.write('\n')
	elif line[0] != '>':
		seqs.write(line.strip() + '\n')

seqs.close()


import math
import random

def evaluate(state):
    lines = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],
        [0, 3, 6], [1, 4, 7], [2, 5, 8],
        [0, 4, 8], [2, 4, 6]
    ]

    for line in lines:
        a, b, c = line
        if state[a] == state[b] == state[c]:
            if state[a] == 'X':
                return 1
            elif state[a] == 'O':
                return -1

    if ' ' not in state:
        return 0

    return None

def print_board(state):
    print("---------")
    print("|", state[0], state[1], state[2], "|")
    print("|", state[3], state[4], state[5], "|")
    print("|", state[6], state[7], state[8], "|")
    print("---------")

def player_move(player):
    row = int(input(f"Player {player}'s turn. Enter the row (0-2): "))
    col = int(input("Enter the column (0-2): "))

    index = row * 3 + col
    if initial_state[index] == ' ':
        initial_state[index] = player
        print(f"Player {player}'s Move:")
        print_board(initial_state)
        return True
    else:
        print("Invalid move! Try again.")
        return False

def computer_move(player):
    print(f"Player {player}'s turn.")

    moves = []
    for i in range(9):
        if initial_state[i] == ' ':
            moves.append(i)

    if moves:
        index = random.choice(moves)
        initial_state[index] = player
        print(f"Player {player}'s Move:")
        print_board(initial_state)
    else:
        print("No valid moves left!")

initial_state = [" "] * 9
print("Initial State:")
print_board(initial_state)

mode = input("Select game mode (1 for Player vs. Player, 2 for Player vs. Computer): ")
while mode != "1" and mode != "2":
    mode = input("Invalid input. Select game mode (1 for Player vs. Player, 2 for Player vs. Computer): ")

game_status = None
current_player = 'X'

while game_status is None:
    if mode == "1" or current_player == 'X':
        while not player_move(current_player):
            pass
    else:
        computer_move(current_player)

    game_status = evaluate(initial_state)

    if game_status is not None:
        break

    current_player = 'O' if current_player == 'X' else 'X'

if game_status == 1:
    print(f"Player X wins!")
elif game_status == -1:
    print(f"Player O wins!")
else:
    print("It's a draw!")


"""Task 0.8"""

""" This function will convert time in minutes, to a more detailed layout with hours and minutes"""
def time(t):
    hours = (t // 60)
    minutes = (t % 60)
    print((str(hours) + " hour") + " " + ( str(minutes) + " minutes") )

time(71)

print(("*" * 14) + "end")


'''nome = 'David Mateus'
idade = 25
peso = 65.8
print(nome, "|", idade ,"|", peso)'''
#Receber dados
#Print: Escreva, Input: Leia,

'''nome = input("Qual é seu nome ")
idade = input("Qual sua idade? ")
peso = input("Qual seu peso? ")
print(nome,"|", idade,"|", peso)'''

#Desafio

'''nome = input('Qual é o seu nome? ')
print("Olá,", nome, "! Prazer em te conhecer")'''
'''
print("========Desafio========")
dia = input("que dia vc nasceu? ")
mes = input("que mês vc nasceu? ")
ano = input("Ano que vc nasceu? ")
print("você nasceu no dia",dia,"de",mes,"de",ano,". Correto?")
'''
A = int(input("Digite um numero: "))
B = int(input("Digite outro numero: "))
total = A+B
print("Valor da soma:",total)


'''
Created on Nov 4, 2012

@author: Chris
'''
import image, text
from gui.modal import ModalDialog
from gui.button import Button
from gui.label import Label
import gui.component as component
import mob.hero as hero
import mob.trait as trait
from util.tools import Rect
import core.event_manager as event_manager
from core.event_manager import Event
import hexcrawl.misc_commands as misc_commands

PACK_SLOT = 0
EQUIP_SLOT = 1

class ItemLabel(Label):

    def __init__(self, position_rect, base_icon, index):
        super(ItemLabel, self).__init__(position_rect, base_icon, image_label=True)
        self.curr_item = None
        self.index = index
        self.selected = False

    def set_item(self, new_item):
        self.curr_item = new_item
        self.draggable = self.curr_item != None

    def render(self, surface, images):
        super(ItemLabel, self).render(surface, images)

        if self.curr_item != None:
            surface.blit(images.item_icons[self.curr_item.get_icon()], (self.rect.x, self.rect.y))

        if self.selected:
            surface.blit(images.selected_item, (self.rect.x, self.rect.y))

    def mark_selected(self, selected):
        self.selected = selected

    def event_handler(self, event):
        if event.type == component.MOUSE_CLICK:
            self.mark_selected(True)
            self.parent.mark_selected(self.index) # return unit_index # self.curr_group.get_unit(unit_index)
            return True
        if event.type == component.KEY_DOWN:
            return self.parent.handle_key(event)
        if event.type == component.MOUSE_DROP:
           return self.parent.handle_child_drop(event, self.index)
        return super(ItemLabel, self).event_handler(event)

class ItemDialog(ModalDialog):

    def __init__(self, width, height, head_text, item_unit, can_sell_items, images):
        super(ItemDialog, self).__init__(width, height, head_text)
        self.unit = item_unit
        self.selected_item = None
        self.trait_labels = []

        # backpack slots
        self.item_icons = []
        y = self.rect.y + 32
        x = self.rect.x + 32
        for i in range(hero.BACKPACK_SIZE):
            item_icon = ItemLabel(Rect(x,y,image.ITEM_ICON_WIDTH, image.ITEM_ICON_HEIGHT),
                                  images.backpack_slot, (PACK_SLOT, i))
            self.add_child(item_icon)
            self.item_icons.append(item_icon)
            y += image.ITEM_ICON_HEIGHT + 4
        x += image.ITEM_ICON_WIDTH + 16

        # equip slots
        y = self.rect.y + 32
        for i in range(len(hero.EQUIP_SLOTS)):
            item_icon = ItemLabel(Rect(x,y,image.ITEM_ICON_WIDTH, image.ITEM_ICON_HEIGHT),
                                      images.equip_slots[hero.EQUIP_SLOTS[i]], (EQUIP_SLOT, i))
            self.add_child(item_icon)
            self.item_icons.append(item_icon)
            y += image.ITEM_ICON_HEIGHT + 4
        x += image.ITEM_ICON_WIDTH + 4

        # buttons
        x = self.rect.x + 44
        def transfer_callback():
            component.post_ui_event(component.KEY_DOWN, unicode = 't', key = 't')
        self.transfer_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT), images.transfer,
                                      transfer_callback,  image_label = True,  tool_tip_text = "transfer (t)")
        x += image.SM_BUTTON_WIDTH + 4

        def disband_callback():
            component.post_ui_event(component.KEY_DOWN, unicode = 'x', key = 'x')
        self.disband_button = Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT), images.disband,
                                     disband_callback, image_label = True,  tool_tip_text = "discard (x)")
        self.add_child(self.transfer_button)
        self.add_child(self.disband_button)
        x += image.SM_BUTTON_WIDTH + 4

        if can_sell_items:
            def sell_callback():
                self.sell_selected()

            self.add_child(Button(Rect(x, y, image.SM_BUTTON_WIDTH, image.SM_BUTTON_HEIGHT),
                                  images.gold_small, sell_callback, image_label = True,
                                  tool_tip_text = "sell (s)"))
        x += image.SM_BUTTON_WIDTH + 4

        self.refresh_items()
        event_manager.add_listener(self.handle_game_events, event_manager.ITEM_ADDED)
        event_manager.add_listener(self.handle_game_events, event_manager.ITEM_SHIFTED)
        event_manager.add_listener(self.handle_game_events, event_manager.ITEM_REMOVED)

    def handle_game_events(self, event):
        self.refresh_items()
        self.mark_selected(None)

    def refresh_items(self):
        for i in range(hero.BACKPACK_SIZE):
            self.item_icons[i].set_item(self.unit.get_backpack_item(i))

        for i in range(len(hero.EQUIP_SLOTS)):
            self.item_icons[hero.BACKPACK_SIZE + i].set_item(self.unit.get_equipped_item(i))

    def sell_selected(self):
        if self.selected_item == None:
            return
        command =  misc_commands.ItemSellCommand(self.unit, self.selected_item[0] == PACK_SLOT, self.selected_item[1])
        event_manager.queue_event(Event(event_manager.COMMAND_ISSUED, [command]))

    def event_handler(self, event):
        if event.type == component.KEY_DOWN:
            key_val = event.unicode
            # equip/unequip/destroy selected item
            if key_val == 't' and self.selected_item != None:
                # equip/unequip selected item
                command =  misc_commands.ItemTransferCommand(self.unit, self.selected_item[0] == PACK_SLOT, self.selected_item[1])
                event_manager.queue_event(Event(event_manager.COMMAND_ISSUED, [command]))
                return True
            if key_val == 'x' and self.selected_item != None:
                # throw away selected item
                command =  misc_commands.ItemDiscardCommand(self.unit, self.selected_item[0] == PACK_SLOT, self.selected_item[1])
                event_manager.queue_event(Event(event_manager.COMMAND_ISSUED, [command]))
                return True
            if key_val == 's' and self.selected_item != None:
                # sell selected item
                self.sell_selected()
                return True

        return super(ItemDialog, self).event_handler(event)

    def handle_child_drop(self, event, new_index):
        dropped_icon = event.dropped
        if dropped_icon.index[0] != new_index[0]:
            command =  misc_commands.ItemTransferCommand(self.unit, dropped_icon.index[0] == PACK_SLOT, dropped_icon.index[1])
            event_manager.queue_event(Event(event_manager.COMMAND_ISSUED, [command]))
            return True

        return False

    def mark_selected(self, index):
        if self.selected_item != None and self.selected_item != index:
            # deselect previous selection
            self.item_icons[self.selected_item[0] * hero.BACKPACK_SIZE + self.selected_item[1]].mark_selected(False)
        self.selected_item  = index

        # clear old trait labels
        for trait_label in self.trait_labels:
            self.remove_child(trait_label)
        self.trait_labels = []

        if index == None:
            return

        column, row = self.selected_item
        selected_item = self.unit.get_equipped_item(row) if column == EQUIP_SLOT else self.unit.get_backpack_item(row)
        if selected_item == None:
            return

        x = self.rect.x + 32 + image.ITEM_ICON_WIDTH * 2 + 20
        y = self.rect.y + 32
        name_label = Label(Rect(x, y, self.rect.width/2, 20), selected_item.get_name()) #,font = text.lg_font)
        self.trait_labels.append(name_label)
        self.add_child(name_label)

        traits = selected_item.get_traits()
        #x_index = 0
        y += 18
        value_label = Label(Rect(x, y, self.rect.width/2, 12), "Value: " + str(selected_item.get_gold_value()))
        self.trait_labels.append(value_label)
        self.add_child(value_label)
        y += 18

        for curr_trait in traits:
            trait_text = trait.trait_str(curr_trait, traits[curr_trait])
            trait_label = Label(Rect(x, y, self.rect.width/2, 12), trait_text, tool_tip_text = trait.tool_tip_table[curr_trait])
            self.add_child(trait_label)
            self.trait_labels.append(trait_label)
            y += 14

        self.show()

    def render(self, surface, images):
        super(ItemDialog, self).render(surface, images)


import sys, unittest
from functools import reduce
from faker import Faker
sys.path.insert(0, './src')
from classes import MealBox
from resources import *

faker = Faker()

class MealBoxTest(unittest.TestCase):

   def test_mealBox_passing_argument(self):
      argument = faker.name()

      with self.assertRaises(TypeError):
         meal_box = MealBox(argument)

   def test_mealBox_instancing(self):
      meal_box = MealBox()
      self.assertTrue(isinstance(meal_box, MealBox))

   def test_mealValidate_with_random_value(self):
      argument_1 = faker.name()
      argument_2 = faker.random_int()

      with self.assertRaises(Exception):
         MealBox._meal_validate(argument_1)

      with self.assertRaises(Exception):
         MealBox._meal_validate(argument_2)

      with self.assertRaises(Exception):
         MealBox._meal_validate(None)

   def test_mealValidate_with_spy_without_name(self):
      spy = AbstractMealWithOutNameSpy()

      with self.assertRaises(Exception):
         MealBox._meal_validate(spy)

   def test_mealValidate_with_spy_without_price(self):
      spy = AbstractMealWithOutPriceSpy()

      with self.assertRaises(Exception):
         MealBox._meal_validate(spy)

   def test_mealValidate_with_spy_without_get_price(self):
      spy = AbstractMealWithOutGetPriceSpy()

      with self.assertRaises(Exception):
         MealBox._meal_validate(spy)

   def test_add_with_empty_list(self):
      meal_box = MealBox()
      meal_box.add(list())

      self.assertFalse(bool(meal_box._children))

   def test_add_with_single_spy(self):
      spy = AbstractMealSpy()
      meal_box = MealBox()
      meal_box.add(spy)

      SPY_INDEX = 0

      self.assertTrue(bool(meal_box._children)) # is not empty
      self.assertEqual(meal_box._children[SPY_INDEX], spy)

   def test_add_with_multiple_spies(self):
      spies_number = faker.random_int(min=2,max=30)
      spies = [AbstractMealSpy() for i in range(spies_number)]
      meal_box = MealBox()
      meal_box.add(spies)

      self.assertTrue(bool(meal_box._children)) # is not empty
      self.assertEqual(len(meal_box._children), len(spies))

      for value, spy in zip(meal_box._children, spies):
         self.assertEqual(value, spy)

   def test_get_price_with_no_values_add(self):
      meal_box = MealBox()
      EMPTY_PRICE = 0

      self.assertEqual(meal_box.get_price(), EMPTY_PRICE)

   def test_get_price_with_single_spy(self):
      spy = AbstractMealSpy()
      meal_box = MealBox()
      meal_box.add(spy)

      self.assertEqual(meal_box.get_price(), int(spy.price))

   def test_get_price_with_multiple_spies(self):
      spies_number = faker.random_int(min=2,max=30)
      spies = [AbstractMealSpy() for _ in range(spies_number)]
      total_price = reduce(lambda sum, spy: sum + spy.get_price(), spies, 0)
      meal_box = MealBox()
      meal_box.add(spies)

      self.assertEqual(meal_box.get_price(), total_price)

if __name__ == '__main__':
   unittest.main()


"""Main module for BlackJack Python Game."""

from game import Game
from exceptions import GameOverCroupierException, GameOverUserException

if __name__ == '__main__':
    try:
        game = Game()
        game.play()
    except GameOverCroupierException:
        print('The player has won.')
    except GameOverUserException:
        print('The croupier has won.')


from sys import path
from PathPlanning import PathPlanning
from MoveCalculation import MoveCalculation
from MoveSimulation import Simulation
import serial
import time

class Toolbox(PathPlanning, MoveCalculation, Simulation):
    pass

a = Toolbox()
a.setState("A")
# a.simulation(a.pathPlanningStep("D"))
run = a.pathPlanningStep("D", status=False)
counterA = 0
#print(run)

def rencana () :
    for i in range(len(run)):
        if i<1:
            path = str((run[counterA][0]))
            jarak = str((run[counterA][1]))
            derajat = str((run[counterA][2]))
            tujuan = str((run[counterA][3]))

    total = path + ',' + jarak + ',' + derajat + ',' + tujuan + '$'
    return total

# #cam = 'krai' + '#' + ','
if __name__ == '__main__':
    ser = serial.Serial('COM13',115200, timeout=1)
    ser.flush()
    while True:
        if ser.in_waiting > 0:
            line = ser.readline().decode('utf-8').rstrip()
            if counterA > len(run) :
                counterA=0
            if line == "Path Selesai":
                counterA +=1
            ser.write(b"" + rencana().encode())
            print(rencana())
            print(line)