# -*- coding: utf-8 -*-
from json import dumps
import requests

BASE = "http://localhost:8080/"
HEADER = {'content-type': 'application/json'}

def alta_habitacion():
    print("Introduce el número de plazas de la habitación:")
    while True:
        try:
            plazas = int(input("> "))
            if plazas >= 1:
                break
            else:
                print("El numero de plazas tiene que ser mayor que 0")
        except ValueError:
            print("Debe introducir números.")
    equipamiento = []
    print("Introduce el quipamiento de la habitación ('Salir' para seguir con el procedimiento):")
    while True:
        nuevo_equipamiento = input("> ")
        if nuevo_equipamiento == "Salir":
            break;
        else:
            equipamiento.append(nuevo_equipamiento)
    print("Introduce el precio por noche de la habitacion:")
    while True:
        try:
            precio = int(input("> "))
            if precio >= 0:
                break
            else:
                print("El precio no puede ser negativo.")
        except ValueError:
            print("Debe introducir números.")
    payload = {'plazas': plazas, 'equipamiento': equipamiento, 'precio': precio}
    r = requests.post(BASE, data=dumps(payload), headers=HEADER)
    if r.status_code == 400:
        print(r.json()['error_description'])
    else:
        print("Habitación creada correctamente.")
    iniciar_seleccion()

def borrar_habitacion():
    print("Introduce la ID de la habitación que desea borrar:")
    while True:
        try:
            id_habitacion = int(input("> "))
            if id_habitacion >= 1:
                break
            else:
                print("La ID tiene que ser mayor que 0")
        except ValueError:
            print("Debe introducir números.")
    r = requests.delete(BASE + id_habitacion.__str__(), headers=HEADER)
    if r.status_code == 409 or r.status_code == 404:
        print(r.json()['error_description'])
    else:
        print("Habitación eliminada correctamente.")
    iniciar_seleccion()

def modificar_habitacion():
    print("Introduce la ID de la habitación que desea modificar:")
    while True:
        try:
            id_habitacion = int(input("> "))
            if id_habitacion >= 1:
                break
            else:
                print("La ID tiene que ser mayor que 0")
        except ValueError:
            print("Debe introducir números.")
    r = requests.get(BASE + id_habitacion.__str__(), headers=HEADER)
    if r.status_code == 404:
        print(r.json()['error_description'])
    else:
        print("Elige que opción deseas realizar: ")
        print("     1. Modificar plazas.")
        print("     2. Modificar equipamiento.")
        print("     3. Modificar precio.")
        print("     4. Modificar disponibilidad.")
        print("     5. Salir.")
        while True:
            try:
                opcionseleccionada = int(input("> "))
                if opcionseleccionada >= 1 and opcionseleccionada <= 5:
                    if opcionseleccionada == 1:
                        print("Introduce el nuevo número de plazas de la habitación:")
                        while True:
                            try:
                                plazas = int(input("> "))
                                if plazas >= 1:
                                    break
                                else:
                                    print("El numero de plazas tiene que ser mayor que 0")
                            except ValueError:
                                print("Debe introducir números.")
                        y = requests.put(BASE + id_habitacion.__str__() + '/plazas', params={'plazas': plazas}, headers=HEADER)
                        if y.status_code == 409:
                            print(y.json()['error_description'])
                        else:
                            print("El valor plazas se cambio correctamente.")
                    if opcionseleccionada == 2:
                        print("Elige que opción deseas realizar: ")
                        print("     1. Reemplazar listado completo de equipamiento.")
                        print("     2. Añadir equipamiento.")
                        print("     3. Eliminar equipamiento.")
                        print("     4. Salir.")
                        while True:
                            try:
                                opcionmodificar = int(input("> "))
                                if opcionmodificar >= 1 and opcionmodificar <= 3:
                                    equipamiento = []
                                    print("Introduce el quipamiento de la habitación ('Salir' para seguir con el procedimiento):")
                                    while True:
                                        nuevo_equipamiento = input("> ")
                                        if nuevo_equipamiento == "Salir":
                                            break;
                                        else:
                                            equipamiento.append(nuevo_equipamiento)
                                    datos = {'equipamiento': equipamiento}
                                    if opcionmodificar == 1:
                                        y = requests.put(BASE + id_habitacion.__str__() + '/equipamiento', data=dumps(datos), headers=HEADER)
                                        if y.status_code == 409:
                                            print(y.json()['error_description'])
                                        else:
                                            print("El equipamiento se cambio correctamente")
                                    if opcionmodificar == 2:
                                        y = requests.put(BASE + id_habitacion.__str__() + '/equipamiento/add', data=dumps(datos), headers=HEADER)
                                        if y.status_code == 409:
                                            print(y.json()['error_description'])
                                        else:
                                            print("El nuevo equipamiento se añadio correctamente")
                                    if opcionmodificar == 3:
                                        y = requests.put(BASE + id_habitacion.__str__() + '/equipamiento/eliminar', data=dumps(datos), headers=HEADER)
                                        if y.status_code == 409:
                                            print(y.json()['error_description'])
                                        else:
                                            print("El equipamiento se elimino correctamente")
                                    break
                                else:
                                    if opcionmodificar == 4:
                                        print("Opción seleccionada: Salir.")
                                        break
                                    else:
                                        print("Opción no valida")
                                    break
                                break
                            except ValueError:
                                print("Debe introducir números.")
                    if opcionseleccionada == 3:
                        print("Introduce el nuevo precio por noche de la habitacion:")
                        while True:
                            try:
                                precio = int(input("> "))
                                if precio >= 0:
                                    break
                                else:
                                    print("El precio no puede ser negativo.")
                            except ValueError:
                                print("Debe introducir números.")
                        y = requests.put(BASE + id_habitacion.__str__() + '/precio', params={'precio': precio}, headers=HEADER)
                        if y.status_code == 409:
                            print(y.json()['error_description'])
                        else:
                            print("El precio se cambio correctamente.")
                    if opcionseleccionada == 4:
                        if r.json()['disponible']:
                            y = requests.put(BASE + id_habitacion.__str__() + '/disponibilidad', params={'disponible': False},headers=HEADER)
                        else:
                            y = requests.put(BASE + id_habitacion.__str__() + '/disponibilidad', params={'disponible': True},headers=HEADER)
                        print("La disponibilidad de la habitación se cambio correctamente.")
                    if opcionseleccionada == 5:
                        print("Opción seleccionada: Salir.")
                        break
                    break
                else:
                    print("Opción no valida")
            except ValueError:
                print("Debe introducir números.")
    iniciar_seleccion()

def consultar_habitaciones():
    r = requests.get(BASE, headers=HEADER)
    if r.status_code == 204:
        print("No existen habitaciones registradas en el sistema.")
    else:
        for i in r.json():
            print("ID de la habitación: ", r.json()[i]['id'])
            print("     Plazas: ", r.json()[i]['plazas'])
            print("     Precio: ", r.json()[i]['precio'])
            print("     Equipamiento: ")
            for j in r.json()[i]['equipamiento']:
                print("         ", j)
            print("     Disponible: ", r.json()[i]['disponible'])
    iniciar_seleccion()

def consultar_habitacion():
    print("Introduce la ID de la habitación que desea consultar:")
    while True:
        try:
            id_habitacion = int(input("> "))
            if id_habitacion >= 1:
                break
            else:
                print("La ID tiene que ser mayor que 0")
        except ValueError:
            print("Debe introducir números.")
    r = requests.get(BASE + id_habitacion.__str__(), headers=HEADER)
    if r.status_code == 404:
        print(r.json()['error_description'])
    else:
        print("ID de la habitación: ", r.json()['id'])
        print("     Plazas: ", r.json()['plazas'])
        print("     Precio: ", r.json()['precio'])
        print("     Equipamiento: ")
        for i in r.json()['equipamiento']:
            print("         ", i)
        print("     Disponible: ", r.json()['disponible'])
    iniciar_seleccion()

def consultar_habitaciones_ocupadas():
    r = requests.get(BASE+'ocupadas', headers=HEADER)
    for i in r.json():
        print("ID de la habitación: ", r.json()[i]['id'])
        print("     Plazas: ", r.json()[i]['plazas'])
        print("     Precio: ", r.json()[i]['precio'])
        print("     Equipamiento: ")
        for j in r.json()[i]['equipamiento']:
            print("         ", j)
        print("     Disponible: ", r.json()[i]['disponible'])
    iniciar_seleccion()

def consultar_habitaciones_desocupadas():
    r = requests.get(BASE+'disponibles', headers=HEADER)
    for i in r.json():
        print("ID de la habitación: ", r.json()[i]['id'])
        print("     Plazas: ", r.json()[i]['plazas'])
        print("     Precio: ", r.json()[i]['precio'])
        print("     Equipamiento: ")
        for j in r.json()[i]['equipamiento']:
            print("         ", j)
        print("     Disponible: ", r.json()[i]['disponible'])
    iniciar_seleccion()

def iniciar_seleccion():
    print("Elige que opción deseas realizar: ")
    print("     1. Dar de alta una habitación.")
    print("     2. Eliminar una habitación.")
    print("     3. Modificar los datos de una habitación.")
    print("     4. Consultar la lista completa de habitaciones.")
    print("     5. Consultar una habitación mediante identificador.")
    print("     6. Consultar la lista de habitaciones ocupadas.")
    print("     7. Consultar la lista de habitaciones desocupadas.")
    print("     8. Salir.")
    while True:
        try:
            opcionseleccionada = int(input("> "))
            if opcionseleccionada >=1 and opcionseleccionada <=8:
                if opcionseleccionada == 1:
                    alta_habitacion()
                if opcionseleccionada == 2:
                    borrar_habitacion()
                if opcionseleccionada == 3:
                    modificar_habitacion()
                if opcionseleccionada == 4:
                    consultar_habitaciones()
                if opcionseleccionada == 5:
                    consultar_habitacion()
                if opcionseleccionada == 6:
                    consultar_habitaciones_ocupadas()
                if opcionseleccionada == 7:
                    consultar_habitaciones_desocupadas()
                if opcionseleccionada == 8:
                    print("Opción seleccionada: Salir.")
                    break
                break
            else:
                print("Opción no valida")
        except ValueError:
            print("Debe introducir números.")

iniciar_seleccion()


from openai import OpenAI
import os
import json
import jsonlines
import time
import csv
from dotenv import load_dotenv
from collections import defaultdict
from pydantic import BaseModel
from io import StringIO

load_dotenv()

# Set your API key
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def valid_data_jsonl(data_path, isTrainingData):
    print("\033[0m" + "Starting valid_data_jsonl...")
    try:
        # Load the dataset
        with open(data_path, 'r', encoding='utf-8') as f:
            dataset = [json.loads(line) for line in f]

        # Initial dataset stats
        print("Num examples:", len(dataset))
        print("First example:")
        for message in dataset[0]["messages"]:
            print(message)

        # Format error checks
        format_errors = defaultdict(int)

        for ex in dataset:
            if not isinstance(ex, dict):
                format_errors["data_type"] += 1
                continue

            messages = ex.get("messages", None)
            if not messages:
                format_errors["missing_messages_list"] += 1
                continue

            for message in messages:
                if "role" not in message or "content" not in message:
                    format_errors["message_missing_key"] += 1

                if any(k not in ("role", "content", "name", "function_call") for k in message):
                    format_errors["message_unrecognized_key"] += 1

                if message.get("role", None) not in ("system", "user", "assistant", "function"):
                    format_errors["unrecognized_role"] += 1

                content = message.get("content", None)
                function_call = message.get("function_call", None)

                if (not content and not function_call) or not isinstance(content, str):
                    format_errors["missing_content"] += 1

            if isTrainingData:
                if not any(message.get("role", None) == "assistant" for message in messages):
                    format_errors["example_missing_assistant_message"] += 1

        if format_errors:
            print("Found errors:")
            for k, v in format_errors.items():
                print(f"{k}: {v}")
            return False

    except FileNotFoundError:
        print("\033[91m\u2718 " + f"The file '{data_path}' was not found.")
        return False

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return False

    print("\033[92m\u2714 " + "No errors found")
    return True

def add_prompt_to_jsonl_file(input_file, output_file, prompt):
    print("\033[0m" + "Starting add_prompt_to_jsonl_file...")
    try:
        with jsonlines.open(input_file, 'r') as reader, jsonlines.open(output_file, 'w') as writer:
            for line in reader:
                messages = line.get('messages', [])
                if messages:
                    messages.insert(0, {'role': 'system', 'content': prompt})
                line['messages'] = messages
                writer.write(line)

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f"Jsonl dataset with prompt saved in {output_file}")
    return output_file

def upload_file(file_path):
    print("\033[0m" + "Starting upload_file...")
    try:
        file_uploaded = client.files.create(file=open(file_path, "rb"), purpose='fine-tune')

        while True:
            print("Waiting for file to process...")
            file_handle = client.files.retrieve(file_uploaded.id)
            if file_handle and file_handle.status == "processed":
                print("\033[92m\u2714 " + "File processed")
                break
            time.sleep(120)

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + "File uploaded")
    return file_uploaded

def create_json_file(path, file_name, content):
    print("\033[0m" + "Starting create_json_file...")
    try:
        directory = os.path.join(path, os.path.dirname(file_name))
        if not os.path.exists(directory):
            os.makedirs(directory)

        existing_files = [item_file for item_file in os.listdir(path) if item_file.startswith(file_name) and item_file.endswith('.json')]
        next_number = 0 if not existing_files else len(existing_files) + 1
        file_name = f'{file_name}{next_number}.json'

        with open(os.path.join(path, file_name), 'w') as result_file:
            json.dump(content, result_file, indent=4)

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f"Results saved in {path}{file_name}")
    return result_file

def create_csv_file(path, file_name, content):
    print("\033[0m" + "Starting create_csv_file...")
    try:
        directory = os.path.join(path, os.path.dirname(file_name))
        if not os.path.exists(directory):
            os.makedirs(directory)

        existing_files = [item_file for item_file in os.listdir(path) if item_file.startswith(file_name) and item_file.endswith('.csv')]
        next_number = 0 if not existing_files else len(existing_files) + 1
        file_name = f'{file_name}{next_number}.csv'

        lines = content.split('\n')
        data = [line.split(',') for line in lines]

        with open(os.path.join(path, file_name), 'w', newline='') as result_file:
            csv_writer = csv.writer(result_file)
            csv_writer.writerows(data)

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f"Results saved in {path}{file_name}")
    return result_file

def create_csv_file_from_array(path, file_name, content):
    print("\033[0m" + "Starting create_csv_file_from_array...")
    try:
        directory = os.path.join(path, os.path.dirname(file_name))
        if not os.path.exists(directory):
            os.makedirs(directory)

        existing_files = [item_file for item_file in os.listdir(path) if item_file.startswith(file_name) and item_file.endswith('.csv')]
        next_number = 0 if not existing_files else len(existing_files) + 1
        file_name = f'{file_name}{next_number}.csv'

        fieldnames = ['User review', 'Emotion for chat completion with temperature 0.2', 'Emotion for chat completion with temperature 0.8']

        with open(os.path.join(path, file_name), 'w', newline='') as result_file:
            writer = csv.writer(result_file)
            writer.writerow(fieldnames)
            writer.writerows(content)

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f"Results saved in {path}{file_name}")
    return result_file

def create_fine_tuning_job(file_uploaded, model):
    print("\033[0m" + "Starting create_fine_tuning_job...")
    try:
        fine_tuning_job = client.fine_tuning.jobs.create(training_file=file_uploaded.id, model=model)

        status = fine_tuning_job.status
        if status not in ["succeeded", "failed"]:
            print("Waiting for fine-tuning to complete...")
            while status not in ["succeeded", "failed"]:
                time.sleep(60)
                fine_tuning_job = client.fine_tuning.jobs.retrieve(fine_tuning_job.id)
                status = fine_tuning_job.status
                print("Status: ", status)

        print("\033[92m\u2714 " + f"Fine-tune job {fine_tuning_job.id} finished with status: {status}")

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    fine_tuning_job_serializable = fine_tuning_job.model_dump()
    create_json_file("results/", "fine_tuning_job_result_", fine_tuning_job_serializable)

    if create_json_file is None:
            print("\033[91m\u2718 " + "Error in create_json_file")
            return None

    return fine_tuning_job

def chat_completion(model, messages, temperature):
    print("\033[0m" + "Starting chat_completion...")
    try:
        completion = client.chat.completions.create(
            model=model,
            messages=messages,
            temperature=temperature
        )

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f'Completion with temperature {temperature}: ', completion.choices[0].message.content)
    return completion

def convert_to_serializable(item):
    try:
        if isinstance(item, set):
            return list(item)
        else:
            return item

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

def generate_chat_completion_results(model, dataset_path):
    print("\033[0m" + "Starting generate_chat_completion_results...")
    try:
        generated_completion = []
        with open(dataset_path, "r") as test_data:
            for line in test_data:
                data = json.loads(line)
                data_message = data.get("messages")
                user_review = data_message[1].get("content")
                print("\033[0m" + 'User review: ', user_review)

                completion_low_temperature = chat_completion(model, data_message, 0.2)
                if chat_completion is None:
                    print("\033[91m\u2718 " + "Error in chat completion with temperature 0.2")
                    return None
                completion_high_temperature = chat_completion(model, data_message, 0.8)
                if chat_completion is None:
                    print("\033[91m\u2718 " + "Error in chat completion with temperature 0.8")
                    return None

                result = [user_review, completion_low_temperature.choices[0].message.content, completion_high_temperature.choices[0].message.content]
                generated_completion.append(result)

        generated_completion = [convert_to_serializable(item) for item in generated_completion]
        if generated_completion is None:
            print("\033[91m\u2718 " + "Error in convert_to_serializable")
            return None

        # NOTE: You can change this to create a json file instead of a csv file
        """create_json_file("results/", "chat_completion_result_", generated_completion)
        if create_json_file is None:
            print("\033[91m\u2718 " + "Error in create_json_file")
            return None
        """

        chat_completion_result = create_csv_file_from_array("results/", "chat_completion_result_", generated_completion)
        if chat_completion_result is None:
            print("\033[91m\u2718 " + "Error in create_csv_file")
            return None

        return chat_completion_result

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

def refactor_id_jsonl(jsonl_file):
    print("\033[0m" + "Starting refactor_id_jsonl...")
    try:
        id_count = {}
        updated_lines = []

        with open(jsonl_file, 'r') as reader:
            lines = reader.readlines()

        for line in lines:
            data = json.loads(line)
            current_id = data.get('id')

            if current_id in id_count:
                id_count[current_id] += 1
                data['id'] = f"{current_id}_{id_count[current_id]}"
            else:
                id_count[current_id] = 0

            updated_lines.append(json.dumps(data))

        with open(jsonl_file, 'w') as writer:
            for updated_line in updated_lines:
                writer.write(f"{updated_line}\n")

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + f'IDs processed in {jsonl_file}')

def add_emotion_and_id_to_csv(jsonl_file, csv_file):
    print("\033[0m" + "Starting add_emotion_and_id_to_csv...")
    try:
        emotions = {}
        ids = []

        # Abre el archivo CSV como objeto
        with open(csv_file.name, 'r+', newline='', encoding='utf-8') as file:
            csv_data = StringIO(file.read())  # Crear un StringIO con el contenido del archivo CSV
            csv_data.seek(0)  # Asegurarse de que el puntero esté al inicio

            csv_reader = csv.reader(csv_data)
            csv_list = list(csv_reader)

            header = csv_list[0]
            header.insert(0, 'ID')
            header.append('Emotion label')

            csv_data.seek(0)  # Mover el puntero al inicio del StringIO

            with jsonlines.open(jsonl_file, 'r') as reader:
                for line in reader:
                    ids.append(line["id"])
                    emotions[line["id"]] = line["emotion"]

            for i, row in enumerate(csv_list[1:], start=1):
                row.insert(0, ids[i - 1])
                emotion = emotions.get(ids[i - 1], '')
                row.append(emotion)

            csv_data.seek(0)  # Mover el puntero al inicio del StringIO

            writer = csv.writer(csv_data)
            writer.writerows(csv_list)

            # Actualizar el contenido del archivo CSV
            file.seek(0)
            file.write(csv_data.getvalue())
            file.truncate()  # Truncar el archivo si es necesario

    except Exception as e:
        print("\033[91m\u2718 " + f"An error occurred: {e}")
        return None

    print("\033[92m\u2714 " + "IDs and emotions added")
    return csv_file

def main():
    print("Starting main...")
    # NOTE: You can change this to any dataset you want to fine-tune on
    training_dataset = "./data/training_dataset.jsonl"
    # NOTE: You can change this to any dataset you want to test
    test_dataset = "./data/test_dataset.jsonl"

    if not valid_data_jsonl(training_dataset, True) or not valid_data_jsonl(test_dataset, False):
        return

    # Add prompt to training file
    system_prompt = "Can you tell me what emotion is expressing the message above? It can be one of the following: happiness, sadness, anger, fear, surprise, disgust or not-relevant (if it doesn't express any relevant emotion)."
    training_dataset_with_prompt = add_prompt_to_jsonl_file(training_dataset, "data/training_dataset_with_prompt.jsonl", system_prompt)
    if training_dataset_with_prompt is None:
        return

    # Upload training file
    file_uploaded = upload_file(training_dataset_with_prompt)
    if file_uploaded is None:
        return

    # Create fine-tuning job
    model = "gpt-3.5-turbo"
    fine_tuned_job = create_fine_tuning_job(file_uploaded, model)
    if fine_tuned_job is None:
        return

    # Get the metrics
    result_files_id = fine_tuned_job.result_files[0]
    content = client.files.retrieve_content(result_files_id)
    csv_file = create_csv_file("results/", "training_metrics_", content)
    if csv_file is None:
        return

    # Add prompt to test file
    test_dataset_with_prompt = add_prompt_to_jsonl_file(test_dataset, "data/test_dataset_with_prompt.jsonl", system_prompt)
    if test_dataset_with_prompt is None:
        return

    # Create chat completion and generate result file
    model = fine_tuned_job.fine_tuned_model
    csv_results_file = generate_chat_completion_results(model, test_dataset_with_prompt)
    if csv_results_file is None:
        return

    # Add ID & emotion to csv file
    emotion_labels_path = "./data/emotion_labels_test_dataset.jsonl"
    refactor_id_jsonl(emotion_labels_path)
    csv_results_file = add_emotion_and_id_to_csv(emotion_labels_path, csv_results_file)
    if csv_results_file is None:
        return

    print("\033[92m\u2714 " + "The program has finished successfully")

if __name__ == '__main__':
    main()


class Solution:
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        '''
        M -> X
        E -> B
        '''
        def calculate_mine(x, y):
            bombs = 0
            for i, j in [x-1,y-1], [x-1,y], [x-1, y+1], [x, y+1], [x+1, y+1], [x+1, y], [x+1, y-1], [x, y-1]:
                if i < 0 or j < 0 or i >= height or j >= width:
                    continue
                if board[i][j] == 'M':
                    bombs += 1
            return bombs

        height = len(board)
        width = len(board[0])

        queue = set()
        queue.add((click[0], click[1]))

        while queue:
            x, y = queue.pop()

            if board[x][y] == 'M':
                board[x][y] = 'X'
                break

            board[x][y] = 'B'

            bombs = calculate_mine(x, y)
            if bombs > 0:
                board[x][y] = str(bombs)
            else:
                for i, j in [x-1,y-1], [x-1,y], [x-1, y+1], [x, y+1], [x+1, y+1], [x+1, y], [x+1, y-1], [x, y-1]:
                    if i < 0 or j < 0 or i >= height or j >= width:
                        continue
                    if board[i][j] == 'E':
                        queue.add((i, j))

        return board


#GOOGLE翻譯:GET請求的交互模式

from urllib import request,parse

googleUrl = "https://translate.google.com.tw/?hl=zh-TW&tab=rT&authuser=0"
headers ={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
          "x-client-data":"CJW2yQEIo7bJAQjEtskBCKmdygEI4qjKAQjLrsoBCM6wygEI6bHKAQjztMoBCPe0ygEYq6TKAQ==",
          "accept":"*/*",
          }

while True:
    key = input("請輸入要翻譯的英文,退出請輸入(CloseMe):")
    if key == "CloseMe":
        break

    formdata = {"client":"webapp",
                "sl":"en",
                "tl":"zh-TW",
                "hl":"zh-TW",
                "dt":"at",
                "dt":"bd",
                "dt":"ex",
                "dt":"ld",
                "dt":"md",
                "dt":"qca",
                "dt":"rw",
                "dt":"rm",
                "dt":"ss",
                "dt":"t",
                "source":"bh",
                "ssel":"0",
                "tsel":"0",
                "kc":"1",
                "tk":"90735.511728",
                "q":key
    }

    #做urlencode
    data = bytes(parse.urlencode(formdata), encoding="utf-8")
    req = request.Request(googleUrl, data, headers, method="POST")
    repsonse = request.urlopen(req)
    info = repsonse.read().decode("utf-8")
    print(info)


import random
import math
import numpy as np
import threading
import time
import os
import sys
import psutil

#sys.argv
#1 = size
#2 = mnum
#3 = iter
#4 =
#5 =
#6 =
state = False
size = int(sys.argv[1])#100
hmax = 1
hmin = 0
mNum = size*1000#int(sys.argv[2])#100000
iVal = 0.001
b    = 1
bVal = iVal*b

def log():
    global state
    try:
        os.system('rm /mnt/f/algTerm1/data/ParticleDataS' + str(size) + '-M' + str(mNum) + '-I' + sys.argv[2] + '.csv')
    except: pass
    f = open('/mnt/f/algTerm1/data/ParticleDataS' + str(size) + '-M' + str(mNum) + '-I' + sys.argv[2] + '.csv','a')
    f.write('time,cpu,mem\n')
    while state:
        f.write(str(time.time()) + ',' + str(psutil.cpu_percent()) + ',' + str(psutil.virtual_memory().used) + '\n')
        time.sleep(0.1)
    f.close()

arr = np.zeros((size,size))

#ul  uc  ur
#ml (pt) mr
#dl  dc  dr
def getNeighbor(x,y):
    global arr
    pos = {'ul':[None,None],'uc':[None,None],'ur':[None,None],'ml':[None,None],'mr':[None,None],'dl':[None,None],'dc':[None,None],'dr':[None,None]}
    if x != 0 and y != 0 :
        pos['ul'][0] = x-1
        pos['ul'][1] = y-1
    if x != 0 :
        pos['ml'][0] = x-1
        pos['ml'][1] = y
    if x != 0 and y < len(arr)-1 :
        pos['dl'][0] = x-1
        pos['dl'][1] = y+1
    if y != 0 :
        pos['uc'][0] = x
        pos['uc'][1] = y-1
    if y < len(arr)-1 :
        pos['dc'][0] = x
        pos['dc'][1] = y+1
    if x < len(arr[0])-1 and y != 0 :
        pos['ur'][0] = x+1
        pos['ur'][1] = y-1
    if x < len(arr[0])-1 :
        pos['mr'][0] = x+1
        pos['mr'][1] = y
    if x < len(arr[0])-1 and y < len(arr)-1 :
        pos['dr'][0] = x+1
        pos['dr'][1] = y+1
    rem = []
    for i in pos:
        if pos[i][0] == None and pos[i][1] == None:
            rem.append(i)
    for i in rem:
        pos.pop(i)
    #print(pos)
    return pos

#returns true if the center is too high
#return false if the center is not too high
def bFail(x,y,pos):
    global arr
    global iVal
    global bVal
    for i in pos:
        if arr[x][y] + iVal > arr[pos[i][0]][pos[i][1]] + bVal:
            return True
    return False

def getLowestNeighbor(x,y, pos):
    global arr
    global hmax
    low = [None,None]
    lowVal = hmax*2
    for i in pos:
        if arr[pos[i][0]][pos[i][1]] < lowVal:
            low[0] = pos[i][0]
            low[1] = pos[i][1]
            lowVal = arr[low[0]][low[1]]
    return low

# arr[1][1] = bVal-iVal
# pos = getNeighbor(1,1)
# print(pos)
# print(bFail(1,1,pos))
# print(getLowestNeighbor(1,1,pos))

def move(x,y):
    global arr
    pos = getNeighbor(x,y)
    if bFail(x,y,pos):
        nxt = getLowestNeighbor(x,y,pos)
        move(nxt[0], nxt[1])
    else:
        arr[x][y] += iVal

def run():
    for i in range(0,mNum):
        x0 = random.randint(0,size-1)
        y0 = random.randint(0,size-1)
        #print(x0)
        #print(y0)
        move(x0,y0)

        if arr[x0][y0] > hmax:
            arr[x0][y0] = hmax

state = True
thread = threading.Thread(target=log)
thread.start()
run()
state = False
thread.join()

dat = open('/mnt/f/algTerm1/files/Particle.csv', 'w')
dat.write(','.join(str(v) for v in list(range(0,size))) + '\n')
for i in arr:
    dat.write(','.join(str(v) for v in i)+ '\n')


import unittest
from tic_tac_toe.TicTacToe import TicTacToe

def board_maker(arr:list=[1,2,3,4,5,6,7,8,9]):
    output = "|{0}|{1}|{2}|\n-------\n"\
        "|{3}|{4}|{5}|\n-------\n"\
        "|{6}|{7}|{8}|\n".format(*arr)
    return output
class test_board_print(unittest.TestCase):
    def test_inital(self):
        game = TicTacToe()
        numbers = [*range(1,11)]
        init_board = "|{0}|{1}|{2}|\n-------\n"\
            "|{3}|{4}|{5}|\n-------\n"\
            "|{6}|{7}|{8}|\n".format(*numbers)
        self.assertEqual(game.get_board(),init_board)

    def test_normal(self):
        game = TicTacToe()
        game.play_turn(1)
        values = ['x',2,3,4,5,6,7,8,9]
        turn_one = board_maker(values)
        self.assertEqual(turn_one, game.get_board())

        game.play_turn(2)
        values = ['x','o',3,4,5,6,7,8,9]
        turn_two = board_maker(values)
        self.assertEqual(turn_two, game.get_board())

        game.play_turn(3)
        values = ['x','o','x',4,5,6,7,8,9]
        turn_three = board_maker(values)
        self.assertEqual(turn_three, game.get_board())

        game.play_turn(4)
        values = ['x','o','x','o',5,6,7,8,9]
        turn_four = board_maker(values)
        self.assertEqual(turn_four, game.get_board())

        game.play_turn(5)
        values = ['x','o','x','o','x',6,7,8,9]
        turn_five = board_maker(values)
        self.assertEqual(turn_five, game.get_board())

        game.play_turn(9)
        values = ['x','o','x','o','x',6,7,8,'o']
        turn_six = board_maker(values)
        self.assertEqual(turn_six, game.get_board())

        game.play_turn(6)
        values = ['x','o','x','o','x','x',7,8,'o']
        turn_seven = board_maker(values)
        self.assertEqual(turn_seven, game.get_board())

        game.play_turn(7)
        values = ['x','o','x','o','x','x','o',8,'o']
        turn_eight = board_maker(values)
        self.assertEqual(turn_eight, game.get_board())

        final_move = game.play_turn(8)
        values = ['x','o','x','o','x','x','o','x','o']
        turn_nine = board_maker(values)
        self.assertEqual(turn_nine, game.get_board())
        self.assertEqual(1,final_move)

if __name__ == "__main__":
    unittest.main(verbosity=True)


# List functions in Python

list1 = [2,"Monday",12,50.5,"Hello"]
list2 = ["Snake", 65]

# How to calculate items in list
print("\nList contains " + str(len(list1)) + " items.")

# Concatenate two lists to one
list3 = list1 + list2
print("List3 is " + str(list3))


import uasyncio as asyncio
from time import sleep

class MHZ19:
    def __init__(self, uart) -> None:
        self.uart = uart

    def set_uart(self, uart):
        self.uart = uart

    def get_co2(self):
        co2_command = [0XFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79]
        self.uart.write(bytes(co2_command))
        sleep(0.5)
        response = self.uart.read(9)
        if not response:
            return None
        a = list(response)
        print(a)
        checksum = 0
        for i in range(1, 7):
            checksum += a[i]
        checksum %= 256
        checksum = ~checksum & 0xFF
        checksum += 1
        print(f"checksum: {checksum}")
        co2 = a[2]*256+a[3]
        return co2


class Solution:
  def maxSumMinProduct(self, nums: List[int]) -> int:
    ans = 0
    stack = []
    prefix = [0] * (len(nums) + 1)

    for i, num in enumerate(nums):
      prefix[i + 1] = prefix[i] + num

    for i in range(len(nums) + 1):
      while stack and (i == len(nums) or nums[stack[-1]] > nums[i]):
        minVal = nums[stack.pop()]
        sum = prefix[i] - prefix[stack[-1] + 1] if stack else prefix[i]
        ans = max(ans, minVal * sum)
      stack.append(i)

    return ans % int(1e9 + 7)

solutions/1856. Maximum Subarray Min-Product/1856.py


from rest_framework import serializers
from .models import (
    Rent,
    RentFeature
)
from cars.serializers import (
    CarListSearializer,
    CarDetailSearializer,
)
from companies.serializers import (
    CompanyDetailSearializer,
)

class RentFeatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = RentFeature
        fields = (
            'id',
            'title',
        )

class RentListSearializer(serializers.ModelSerializer):
    car = CarListSearializer()
    class Meta:
        model = Rent
        fields = (
            'id',
            'car',
            'price',
            'total_cost',
            'deposit',
        )

class RentDetailSearializer(serializers.ModelSerializer):
    car = CarDetailSearializer()
    features = RentFeatureSerializer(many=True)
    company = CompanyDetailSearializer()
    class Meta:
        model = Rent
        fields = (
            'id',
            'car',
            'features',
            'price',
            'deposit',
            'total_cost',
            'total_cost_discount',
            'company',
        )

class RentFilterSerializer(serializers.Serializer):
    start_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required = False)
    end_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required = False)

class RentByLocationSerializer(serializers.Serializer):
    pick_up = serializers.IntegerField()
    drop_off = serializers.IntegerField()


import PySimpleGUI as sg
sg.theme('Dark Blue 3')
#to define a function which is used to create number in tens ,ones
#for e.g. cov(23,4) will give 234
def calculate(d):
    start_num=""
    end_num=""
    result=0
    for i in range (len(d)+1):
        if d[i] in ('+','-','*','/'):
            constant=d[i]
            break
        else:
            continue
    for j in range(len(d)):
        if(j<i):
            start_num=start_num+d[j]
        elif(j>i):
            end_num=end_num+d[j]
        else:
            i=i
    while(constant in ('+','-','*','/')):
        if(constant=='+'):
            result=float(start_num)+float(end_num)
            break
        elif(constant=='-'):
            result=float(start_num)-float(end_num)
            break
        elif(constant=='*'):
            result=float(start_num)*float(end_num)
            break
        elif(constant=='/'):
            result=float(start_num)/ float(end_num)
            break
        else:
            break
    return result

# please make your creations colorful
#layout = [[sg.Text("@"*45)], [sg.Text('LIC Lifeinsurance')], [sg.Input("Enter your name here:-")], [sg.Input()],[sg.FileBrowse()], [sg.OK(), sg.Cancel()]]
layout1 = [[sg.Text("_"*120)], [sg.Text('        Calculator       ')],
           [sg.Text("|         "),sg.Button("1",size=(5,1)),sg.Button("2",size=(5,1)),sg.Button("3",size=(5,1)),sg.Button("+ Add"),sg.Text(" "*100+"|")],
           [sg.Text("|         "),sg.Button("4",size=(5,1)),sg.Button("5",size=(5,1)),sg.Button("6",size=(5,1)),sg.Button("-  Sub"),sg.Text(" "*100+"|")],
           [sg.Text("|         "),sg.Button("7",size=(5,1)),sg.Button("8",size=(5,1)),sg.Button("9",size=(5,1)),sg.Button("*  Mul"),sg.Text(" "*100+"|")],
           [sg.Text("|            "),sg.Text("        "),sg.Button("0",size=(5,1)),sg.Text("           "),sg.Button("/ Div",size=(5,1)),sg.Text(" "*100+"|")],
           [sg.Text('',size=(105,1),key="cal",background_color="Black")],
           [sg.Button("=",size=(5,1)),sg.OK(), sg.Cancel()]]
window = sg.Window('Deepak Calculator', layout1)
d='' #used for stroring the command which user give
s=0  #used to store the starting number
e=0  #used to store the ending number
times=0 #no. of times loop used
flag=0 #used for number or string
while True:
    event, values = window.Read()
    if(event == '0' or event == '1' or event == '2' or event == '3' or event == '4' or event == '5'
       or event == '6' or event == '7' or event == '8' or event == '9'):
        print("Got it",event)
        d=d+event
        window["cal"].Update(d)
    elif(event=='+ Add'):
        print("Got it",event)
        d=d+"+"
        window["cal"].Update(d)
        #e+=d[0]
    elif(event=='- Sub'):
        print("Got it",event)
        d=d+"-"
        window["cal"].Update(d)
        #e-=d[0]
    elif(event=='* Mul'):
        print("Got it",event)
        d=d+"*"
        window["cal"].Update(d)
        #e+=d[0]
    elif(event=='/ Div'):
        print("Got it",event)
        d=d+"/"
        window["cal"].Update(d)
        #e+=d[0]
    elif (event == "="):
        print("Got it",event)
        result=calculate(d)
        d=str(result)
        print(result)
        window["cal"].Update(result)
    elif (event == "OK" or event == "Cancel"):
        print(event)
        window.Close()
    else:
        print("Got it",event)
        window.Close()
        break
#print("Why stopped me you $##@")
'''if(values[0]==''):
    print("Enter your NAME")
if(values[1]==''):
    print("Enter your AGE")
if(event=="OK"):
    print("Give me input $#%%")'''

'''print(event,values)
print(d)'''