from lexeme import Lexeme
from exceptions import UndefinedException

class Environment:

	def __init__(self):
		self._debug = False
		self.env_list = self.create()

	def create(self):
		return self.extend(None, None, None)

	def lookup(self, variable, env_list):
		"""
		Returns the value of a variable if defined, None otherwise.

		Parameters:
			variable -- A VARIABLE type Lexeme object with the variable's
						name as its value.
			env_list -- The Environment list into which to begin the
						the variable.
		"""
		if self._debug: print("Looking up -> " + str(variable))
		head = env_list.left
		while head is not None:
			var = head.left
			val = head.right
			while var is not None:
				if var.value == variable.value:
					return val.value
				var = var.right
				val = val.right
			head = head.right

		raise UndefinedException(variable)

	def update(self, variable, new_val, env_list):
		"""
		Updates the value of an existing variable in
		the specified environment to new_val.

		Parameters:
			variable -- A VARIABLE type Lexeme object with the variable's
						name as its value.

			new_val  -- A NUMBER, BOOLEAN, or STRING type Lexeme object
						with the variable's value as its value.

			env_list -- The Environment list in which to update
						the variable.
		"""
		if self._debug: print(str(variable))
		if self._debug: print(str(new_val))
		head = env_list.left
		var = head.left
		val = head.right
		while var:
			if var.value == variable.value:
				val.value = new_val.value
				return
			var = var.right
			val = val.right

		raise UndefinedException(str(variable) + " is undefined.")
		return None

	def insert(self, variable, value, env_list):
		"""
		Inserts a new variable with the specified value
		into the specified environment.

		Parameters:
			variable -- A VARIABLE type Lexeme object with the variable's
						name as its value.

			value 	 -- A NUMBER, BOOLEAN, or STRING type Lexeme object
						with the variable's value as its value.

			env_list -- The Environment list into which to insert
						the variable.
		"""
		if self._debug: print(
			"Inserting variable [" + str(variable) + "]")
		if self._debug: print(
			"        with value [" + str(value) + "].")
		head = env_list.left
		variable.right = head.left
		value.right = head.right
		head.left = variable
		head.right = value

	def extend(self, variables, values, parent_env):
		"""
		Inserts a new variable with the specified value
		into the specified environment.

		Parameters:
			variables 	-- The first Lexeme in a chain of VARIABLE
						   Lexemes that should be in the new
						   environment.

			values 		-- The first Lexeme in a chain of NUMBER, STRING,
					  	   and BOOLEAN Lexemes that should be in the new
					  	   environment.

			parent_env 	-- The Environment list that the new environment
						   should be attached to.
		"""
		if self._debug: print("In extend().")
		glue = Lexeme(token_type="GLUE", left=variables, right=values)
		env = Lexeme(token_type="ENVIRONMENT", left=glue, right=parent_env)

		return env

if __name__ == '__main__':

	e = Environment()
	env = e.env_list
	# tv = TreeViz("env_pre", env)
	# tv.viz()
	# tv.create_image()
	# tv.open_image()

	print("Inserting variable x with value 5...")
	var = Lexeme(token_type="VARIABLE", value="x")
	val = Lexeme(token_type="NUMBER", value=5)
	e.insert(var, val, env)
	# tv = TreeViz("env_post", env)
	# tv.viz()
	# tv.create_image()
	# tv.open_image()

	print("Attempting to lookup the variable 'x'...")
	print("x = " + str(e.lookup(var, env)))

	print("Updating x to value: 999...")
	e.update(var, 999, env)

	print("Attempting to lookup the variable 'x' after update...")
	print("x = " + str(e.lookup(var, env)))


from functools import reduce

FSM = {'CLOSED': {'APP_PASSIVE_OPEN': 'LISTEN',
                  'APP_ACTIVE_OPEN': 'SYN_SENT'},
       'LISTEN': {'RCV_SYN': 'SYN_RCVD',
                  'APP_SEND': 'SYN_SENT',
                  'APP_CLOSE': 'CLOSED'},
       'SYN_RCVD': {'APP_CLOSE': 'FIN_WAIT_1',
                    'RCV_ACK': 'ESTABLISHED'},
       'SYN_SENT': {'RCV_SYN': 'SYN_RCVD',
                    'RCV_SYN_ACK': 'ESTABLISHED',
                    'APP_CLOSE': 'CLOSED'},
       'ESTABLISHED': {'APP_CLOSE': 'FIN_WAIT_1',
                       'RCV_FIN': 'CLOSE_WAIT'},
       'FIN_WAIT_1': {'RCV_FIN': 'CLOSING',
                      'RCV_FIN_ACK': 'TIME_WAIT',
                      'RCV_ACK': 'FIN_WAIT_2'},
       'CLOSING': {'RCV_ACK': 'TIME_WAIT'},
       'FIN_WAIT_2': {'RCV_FIN': 'TIME_WAIT'},
       'TIME_WAIT': {'APP_TIMEOUT': 'CLOSED'},
       'CLOSE_WAIT': {'APP_CLOSE': 'LAST_ACK'},
       'LAST_ACK': {'RCV_ACK': 'CLOSED'}}

def change_state(current_state, event):
    return FSM[current_state][event]

def traverse_TCP_states(events):
    try:
        return reduce(change_state, events, 'CLOSED')
    except KeyError:
        return 'ERROR'

4. A Simplistic TCP Finite State Machine (FSM)/solution.py


import openai
from time import time, sleep
from halo import Halo
import textwrap
import yaml
import os
from langchain.document_loaders import UnstructuredURLLoader
from langchain.document_loaders import SeleniumURLLoader
from urllib.parse import urlparse

urls = [
    "https://openai.com/policies/usage-policies"
]

loader = SeleniumURLLoader(urls=urls)
data = loader.load()

prompts = [
'Can you give me a very clear explanation of the core assertions, implications, and mechanics elucidated in this paper?',

"Can you explain the value of this in basic terms? Like you're talking to a CEO. So what? What's the bottom line here?",

'Can you give me an analogy or metaphor that will help explain this to a broad audience.',
]

###     file operations

def extract_domain(url):
    parsed_url = urlparse(url)
    domain = parsed_url.netloc
    return domain

# Example usage
website_link = "https://openai.com/policies/usage-policies"
domain_name = extract_domain(website_link)
print(domain_name)

def save_file(filepath, content):
    with open(filepath, 'w', encoding='utf-8') as outfile:
        outfile.write(content)

def open_file(filepath):
    with open(filepath, 'r', encoding='utf-8', errors='ignore') as infile:
        return infile.read()

###     API functions

def chatbot(conversation, model="gpt-3.5-turbo", temperature=0):
    max_retry = 7
    retry = 0
    while True:
        try:
            spinner = Halo(text='Thinking...', spinner='dots')
            spinner.start()

            response = openai.ChatCompletion.create(model=model, messages=conversation, temperature=temperature)
            text = response['choices'][0]['message']['content']

            spinner.stop()

            return text, response['usage']['total_tokens']
        except Exception as oops:
            print(f'\n\nError communicating with OpenAI: "{oops}"')
            if 'maximum context length' in str(oops):
                a = conversation.pop(0)
                print('\n\n DEBUG: Trimming oldest message')
                continue
            retry += 1
            if retry >= max_retry:
                print(f"\n\nExiting due to excessive errors in API: {oops}")
                exit(1)
            print(f'\n\nRetrying in {2 ** (retry - 1) * 5} seconds...')
            sleep(2 ** (retry - 1) * 5)

def chat_print(text):
    formatted_lines = [textwrap.fill(line, width=120, initial_indent='    ', subsequent_indent='    ') for line in text.split('\n')]
    formatted_text = '\n'.join(formatted_lines)
    print('\n\n\nCHATBOT:\n\n%s' % formatted_text)

if __name__ == '__main__':
    # instantiate chatbot, variables
    openai.api_key = open_file('key_openai.txt').strip()

    # Get list of all PDF files in the input folder
    pdf_files = [f for f in os.listdir('input/') if f.endswith('.pdf')]

    for pdf_file in pdf_files:
        # Check if the report already exists in the output folder
        filename = 'output_web/' + pdf_file.replace('.pdf', '.txt')
        if os.path.exists(filename):
            continue

        # Open the PDF file
        with open('input/' + pdf_file, 'rb') as file:
            pdf_reader = PyPDF2.PdfReader(file)
            paper = ''
            for page_num in list(range(0,len(pdf_reader.pages))):
                page = pdf_reader.pages[page_num]
                paper += page.extract_text()

        if len(paper) > 22000:
            paper = paper[0:22000]
        ALL_MESSAGES = [{'role':'system', 'content': paper}]
        report = ''
        for p in prompts:
            ALL_MESSAGES.append({'role':'user', 'content': p})
            response, tokens = chatbot(ALL_MESSAGES)
            chat_print(response)
            ALL_MESSAGES.append({'role':'assistant', 'content': response})
            report += '\n\n\n\nQ: %s\n\nA: %s' % (p, response)

        # Save the report in the output folder with the same name as the PDF file but with .txt extension
        save_file(filename, report.strip())

# Create a new BeautifulSoup object and define the basic structure of the HTML document
soup = BeautifulSoup("<title>Consolidated Policies</title>", "html.parser")

# For each text file
for c in data:
    content = c.page_content

    # Create a new section in the HTML document for this file
    section = soup.new_tag('section')

    # Add a header with the name of the file (without the .txt extension)
    header = soup.new_tag('h1')
    header.string = c.metadata
    section.append(header)

    # Split the content into Q&A pairs and add them to the section
    section.append(content)

    # Add the section to the body of the HTML document
    soup.body.append(section)

# Write the HTML document to a file
with open('web_report.html', 'w') as file:
    file.write(str(soup.prettify()))


# -*- coding: utf-8 -*-
# 使用OpenCV播放视频
import cv2

wnd = 'OpenCV Video'

# 获得视频的格式
videoCapture = cv2.VideoCapture('C:\\Users\\Administrator\\Desktop\\video.mp4')

# 获得码率及尺寸
fps = videoCapture.get(cv2.CAP_PROP_FPS)
size = (int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))

cv2.namedWindow(wnd, flags=0)
cv2.resizeWindow(wnd, size[0] / 2, size[1] / 2)

# 读帧
success, frame = videoCapture.read()

while success:
	cv2.imshow(wnd, frame)  # 显示
	cv2.waitKey(1000 / int(fps))  # 延迟
	success, frame = videoCapture.read()  # 获取下一帧


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

"""
彩色图像的灰度化、二值化
"""
from skimage.color import rgb2gray
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2
import time

def rgb2gray():
    # 灰度化
    img = cv2.imread("../images/lenna.png")
    h,w = img.shape[:2]
    img_gray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    img_gray_1 = np.zeros([h,w],img.dtype)
    t1 = time.time()
    #逐像素处理
    for i in range(h):
        for j in range(w):
            m = img[i,j]
            img_gray_1[i,j] = int(m[0]*0.11 + m[1]*0.59 + m[2]*0.3)
    t2=time.time()

    #numpy运算
    factors = np.array([0.11,0.59,0.3],dtype=np.float32)
    img_gray_2= np.clip(np.sum(img * factors,axis=2).astype(np.uint8),0,255)
    t3 = time.time()

    plt.subplot(221)
    plt.imshow(img[:,:,::-1])
    plt.subplot(222)
    plt.imshow(img_gray,cmap='gray')
    plt.subplot(223)
    plt.imshow(img_gray_1,cmap='gray')
    plt.subplot(224)
    plt.imshow(img_gray_2, cmap='gray')
    info = "逐像素循环计算耗时%.3fs，numpy api运算耗时%.3fs"%(t2-t1,t3-t2)
    print(info)
    plt.show()

if __name__=="__main__":
    rgb2gray()


import os

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.conf import settings
from django.shortcuts import get_object_or_404, render
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.template import loader
from django.views.decorators.csrf import csrf_exempt

from .models import Record
from .speech_to_text import *

# List of language codes and names
LANGUAGES = [
    ("som_Latn", "Somali"),
    ("kik_Latn", "Kikuyu"),
    ("luo_Latn", "Luo"),
    ("kam_Latn", "Kamba"),
    ("zul_Latn", "Zulu"),
    ("swa_Latn", "Swahili"),
    ("fra_Latn", "French"),
    ("eng_Latn", "English"),
    ("deu_Latn", "German"),
]

def record(request):
    if request.method == "POST":
        audio_file = request.FILES.get("recorded_audio")
        language = request.POST.get("language")
        record = Record.objects.create(language=language, voice_record=audio_file)
        record.save()
        messages.success(request, "Audio recording successfully added!")
        return JsonResponse(
            {
                "url": record.get_absolute_url(),
                "success": True,
            }
        )
    context = {"page_title": "Record audio"}
    return render(request, "record.html", context)

def record_detail(request, id):
    record = get_object_or_404(Record, id=id)

    context = {
        "page_title": "Recorded audio detail",
        "record": record,
        "LANGUAGES": LANGUAGES,
    }
    return render(request, "record_detail.html", context)

def translate_audio(request):
    transcription = None
    translation = None

    if request.method == 'POST':
        source_language_code = request.POST.get('source_language_code')
        target_language_code = request.POST.get('target_language_code')

        if not any(lang_tuple[0] == source_language_code for lang_tuple in LANGUAGES) or not any(
                lang_tuple[0] == target_language_code for lang_tuple in LANGUAGES):
            return JsonResponse({'error': 'Invalid source or target language code'}, status=400)

        # Fetch the latest audio file from the 'records' directory in media
        records_directory = os.path.join(settings.MEDIA_ROOT, 'records')
        latest_audio_file = get_latest_audio_file(records_directory)

        if not latest_audio_file:
            return JsonResponse({'error': 'No audio file found in records directory'}, status=400)

        # Transcribe the audio and extract the text
        transcription_response = transcribe_audio(latest_audio_file)

        # Check if the transcription response is in the expected format
        if 'text' in transcription_response:
            transcription = transcription_response['text']
        else:
            return JsonResponse({'error': 'Invalid transcription format'}, status=400)

        # Translate the transcribed text
        translation = translate_text(transcription, source_language_code, target_language_code)

        # Load the 'record_detail.html' template with the appropriate context
        template = loader.get_template('record_detail.html')
        context = {
            'source_language_code': source_language_code,
            'target_language_code': target_language_code,
            'transcription': transcription,
            'translation': translation,
            'LANGUAGES': LANGUAGES,
        }
        rendered_content = template.render(context)

        # Return the rendered content as an HTML response
        return HttpResponse(rendered_content)

    return JsonResponse({'error': 'Invalid request method'}, status=400)

def get_latest_audio_file(directory):
    audio_files = [f for f in os.listdir(directory) if f.endswith('.webm')]
    if not audio_files:
        return None
    audio_files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True)
    return os.path.join(directory, audio_files[0])

@csrf_exempt
def save_audio(request):
    if request.method == 'POST':
        audio_file = request.FILES.get('audio')
        if audio_file:
            # Define the file name
            file_name = 'audio.wav'

            # Construct the full path to the audio file
            audio_path = os.path.join(settings.MEDIA_ROOT, file_name)

            # Delete the existing audio.wav file if it exists
            if default_storage.exists(audio_path):
                default_storage.delete(audio_path)

            # Save the new audio file in Django's MEDIA folder
            file_path = default_storage.save(audio_path, audio_file)

            print("Audio file saved at:", file_path)  # Add this line for debugging

            return JsonResponse({'message': 'Audio saved successfully', 'file_path': file_path})

    return JsonResponse({'error': 'Failed to save audio'},status=400)

@csrf_exempt
def translator(request):
    transcription = None
    translation = None

    if request.method == 'POST':
        source_language_code = request.POST.get('source_language_code')
        target_language_code = request.POST.get('target_language_code')

        if not any(lang_tuple[0] == source_language_code for lang_tuple in LANGUAGES) or not any(
                lang_tuple[0] == target_language_code for lang_tuple in LANGUAGES):
            return JsonResponse({'error': 'Invalid source or target language code'}, status=400)

        # # Save the audio before transcribing
        saved_audio_path = save_audio(request)
        if 'error' in saved_audio_path:
            return JsonResponse(saved_audio_path, status=400)

        audio_path = os.path.join(settings.MEDIA_ROOT, 'audio.wav')
        if not os.path.exists(audio_path):
            return JsonResponse({'error': 'Audio file not found'}, status=404)

        transcription = transcribe_audio(audio_path)

        # Translate the transcribed text
        # translation = translate_text(transcription, source_language_code, target_language_code)

        return JsonResponse({'source_language_code': source_language_code,
                             'target_language_code': target_language_code,
                             'transcription': transcription,
                             'translation': translation})

    return render(request, 'translate.html', {'LANGUAGES': LANGUAGES, 'transcription': transcription, 'translation': translation})

@csrf_exempt
def record_audio(request):
    if request.method == 'POST':
        source_language_code = request.POST.get('source_language_code')
        target_language_code = request.POST.get('target_language_code')

        if not any(lang_tuple[0] == source_language_code for lang_tuple in LANGUAGES) or not any(
                lang_tuple[0] == target_language_code for lang_tuple in LANGUAGES):
            return JsonResponse({'error': 'Invalid source or target language code'}, status=400)

    return render(request, 'translate.html', {'LANGUAGES': LANGUAGES})

class TranslateViewSet(viewsets.ViewSet):
    """
    A ViewSet class that handles the translation of audio files.

    This ViewSet provides functionality for recording audio, transcribing the audio, translating the transcription to the desired language, saving the transcribed and translated text to a file, and converting the translated text to speech.

    Attributes:
        queryset (QuerySet): The queryset of Message objects.
        serializer_class (Serializer): The serializer class for Message objects.
        filterset_class (FilterSet): The filterset class for Message objects.
        permission_classes (list): The list of permission classes.
        http_method_names (list): The list of allowed HTTP methods.
    """

    def create(self, request):
        """
        Translates an audio file.

        This method translates an audio file and returns the translated transcription.

        Args:
            request (HttpRequest): The HTTP request object.

        Returns:
            Response: The HTTP response containing the translated transcription.
        """
        # Get the selected source and target language codes from the request
        source_language_code = request.data.get('source_language_code')
        target_language_code = request.data.get('target_language_code')

        # Check if the selected language codes are in the supported list
        if not any(lang_tuple[0] == source_language_code for lang_tuple in LANGUAGES) or not any(lang_tuple[0] == target_language_code for lang_tuple in LANGUAGES):

            return Response({'error': 'Invalid source or target language code'}, status=status.HTTP_400_BAD_REQUEST)

        audio_path = os.path.join(settings.MEDIA_ROOT, 'audio.wav')

        if not default_storage.exists(audio_path):
            return Response({'error': 'Audio file not found'}, status=status.HTTP_404_NOT_FOUND)

        transcription = transcribe_audio(audio_path)

        # Translate the transcription from source language to target language
        translation = translate_text(transcription, source_language_code, target_language_code)

        return Response({'translation': translation}, status=status.HTTP_200_OK)

# class RecordView(viewsets.ViewSet):
#     """
#     A ViewSet class that handles recording audio files.

#     This ViewSet provides functionality for recording audio files and returning the recorded audio file.

#     Attributes:
#         queryset (QuerySet): The queryset of Message objects.
#         serializer_class (Serializer): The serializer class for Message objects.
#         filterset_class (FilterSet): The filterset class for Message objects.
#         permission_classes (list): The list of permission classes.
#         http_method_names (list): The list of allowed HTTP methods.
#     """

#     def create(self, request):
#         """
#         Records an audio file.

#         This method records an audio file and saves it in the media directory as "audio.wav".
#         It overwrites the existing "audio.wav" file if it exists.
#         It returns the URL of the recorded audio file.

#         Args:
#             request (HttpRequest): The HTTP request object.

#         Returns:
#             Response: The HTTP response containing the URL of the recorded audio file.
#         """
#         filename = "audio.wav"
#         record_audio_manual(filename)

#         # Define the path where the audio file will be saved in the media root
#         audio_path = os.path.join(settings.MEDIA_ROOT, filename)

#         # Delete the existing audio file if it exists
#         if default_storage.exists(audio_path):
#             default_storage.delete(audio_path)

#         # Save the recorded audio to the media directory using default_storage
#         with open(filename, "rb") as audio_file:
#             default_storage.save(audio_path, ContentFile(audio_file.read()))

#         # Generate the URL for the saved audio file
#         audio_url = default_storage.url(audio_path)

#         return Response({'audio_url': audio_url}, status=status.HTTP_201_CREATED)

# class PlayView(viewsets.ViewSet):
#     """
#     A ViewSet class that handles playing audio files.

#     This ViewSet provides functionality for playing audio files.

#     Attributes:
#         queryset (QuerySet): The queryset of Message objects.
#         serializer_class (Serializer): The serializer class for Message objects.
#         filterset_class (FilterSet): The filterset class for Message objects.
#         permission_classes (list): The list of permission classes.
#         http_method_names (list): The list of allowed HTTP methods.
#     """

#     def create(self, request):
#         """
#         Plays an audio file.

#         This method plays an audio file and returns a success message.

#         Args:
#             request (HttpRequest): The HTTP request object.

#         Returns:
#             Response: The HTTP response containing a success message.
#         """
#         # Assuming the 'audio.wav' file is saved in the MEDIA root directory
#         audio_path = os.path.join(settings.MEDIA_ROOT, 'audio.wav')

#         if not default_storage.exists(audio_path):
#             return Response({'error': 'Audio file not found'}, status=status.HTTP_404_NOT_FOUND)

#         # Implement the play_audio function to play the 'audio.wav' file
#         play_audio(audio_path)

#         return Response({'message': 'Audio played successfully'}, status=status.HTTP_200_OK)

class TranscribeView(viewsets.ViewSet):
    """
    A ViewSet class that handles transcribing audio files.

    This ViewSet provides functionality for transcribing audio files.

    Attributes:
        queryset (QuerySet): The queryset of Message objects.
        serializer_class (Serializer): The serializer class for Message objects.
        filterset_class (FilterSet): The filterset class for Message objects.
        permission_classes (list): The list of permission classes.
        http_method_names (list): The list of allowed HTTP methods.
    """

    def create(self, request):
        """
        Transcribes an audio file.

        This method transcribes an audio file and returns the transcription.

        Args:
            request (HttpRequest): The HTTP request object.

        Returns:
            Response: The HTTP response containing the transcription.
        """
        audio_path = os.path.join(settings.MEDIA_ROOT, 'audio.wav')

        if not default_storage.exists(audio_path):
            return Response({'error': 'Audio file not found'}, status=status.HTTP_404_NOT_FOUND)

        transcription = transcribe_audio(audio_path)

        return Response({'transcription': transcription}, status=status.HTTP_200_OK)

class SaveView(viewsets.ViewSet):
    """
    A ViewSet class that handles saving transcribed and translated audio files.

    This ViewSet provides functionality for transcribing an audio file, translating the transcription to English, saving the transcribed and translated text to a file, and converting the translated text to speech.

    Attributes:
        queryset (QuerySet): The queryset of Message objects.
        serializer_class (Serializer): The serializer class for Message objects.
        filterset_class (FilterSet): The filterset class for Message objects.
        permission_classes (list): The list of permission classes.
        http_method_names (list): The list of allowed HTTP methods.
    """

    def create(self, request):
        """
        Saves transcribed and translated audio files.

        This method transcribes an audio file, translates the transcription to English, saves the transcribed and translated text to a file, and converts the translated text to speech.

        Args:
            request (HttpRequest): The HTTP request object.

        Returns:
            Response: The HTTP response containing the transcribed and translated audio files.
        """
        # Assuming the 'audio.wav' file is saved in the MEDIA root directory
        audio_path = os.path.join(settings.MEDIA_ROOT, 'audio.wav')

        if not default_storage.exists(audio_path):
            return Response({'error': 'Audio file not found'}, status=status.HTTP_404_NOT_FOUND)

        transcription = transcribe_audio(audio_path)
        translation = translate_text(transcription, 'en')
        text_filename = "text.txt"
        audio_filename = "audio.mp3"

        # Save the transcribed and translated text to a file
        with open(text_filename, "w") as text_file:
            text_file.write(transcription + "\n" + translation)

        # Convert the translated text to speech and save it as an audio file
        save_text_as_audio(translation, audio_filename)

        return Response({
            'message': 'Transcription and translation saved successfully',
            'text_file': text_filename,
            'audio_file': audio_filename
        }, status=status.HTTP_200_OK)


#PF-Assgn-30

def encode(message):
    string = message
    b= []
    b.append(string[0])
    count =1
    c = []
    for i in range(1,len(string)):
        if string[i]!= string[i-1]:
            b.append(string[i])
            c.append(count)
            count = 1
        elif string[i]==string[i-1]:
            count+=1

    c.append(count)
    s =''
    for x,y in zip(b,c):
        s+= str(y)+x
    del(c)
    del(b)
    return(s)
#Provide different values for message and test your program
encoded_message=encode("ABBBBCCCCCCCCABBB")
print(encoded_message)


import numpy as np
import argparse
import cv2
import pprint
import os

from Face_detect_opencv.face_det import FaceDet
from Person_MobilNet_SSD_opencv.person_det import PersonDet
from MaskClassifier.classifier import MaskClassifier

class MaskDet:
    def __init__(self):
        self.path = os.path.abspath(os.path.dirname(__file__))
        # construct the argument parse
        parser = argparse.ArgumentParser(
            description='Script to do mask detection')
        parser.add_argument("--image", default= self.abspath("images/Trump.jpg"), help="path to image input")
        self.args = parser.parse_args()

        # Person detection
        self.person_obj = PersonDet()
        #Face detection
        self.face_obj = FaceDet()

        #face-mask classifier
        self.mask_classifier = MaskClassifier()

    def abspath(self,filename):
        return os.path.join(self.path, filename)

    def detect(self, frame=None):
        if frame is None:
            frame = cv2.imread(self.args.image)

        #import pdb;pdb.set_trace()

        dets1 = self.person_obj.detect(frame=frame.copy())
        pprint.pprint(dets1)

        detsp={}
        det_countp=0
        for det_countp,boxp in dets1.items():
            crop = boxp['crop']
            H,W,_=crop.shape
            H=min(H,W)
            W=H

            crop = crop[0:H,0:W]
            #cv2.imshow('crop1',crop)
            #cv2.waitKey(100)

            x1p   = boxp['xLeftBottom_']
            y1p   = boxp['yLeftBottom_']
            x2p   = boxp['xRightTop_']
            y2p   = boxp['yRightTop_']

            dets2 = self.face_obj.detect(image=crop)
            pprint.pprint(dets2)

            detsf={}
            det_countf=0
            maskstatus=True
            for det_countf,boxf in dets2.items():
                x1 = boxp['xLeftBottom_']+boxf['startX']
                y1 = boxp['yLeftBottom_']+boxf['startY']
                x2 = boxp['xLeftBottom_']+boxf['endX']
                y2 = boxp['yLeftBottom_']+boxf['endY']

                crop = frame[y1:y2,x1:x2]

                classname,confidence = self.mask_classifier.predict_opencv_image(crop)

                print('classname: ',classname)
                if classname=='nomask':
                    maskstatus = False
                #import pdb;pdb.set_trace()

                detsf[det_countf] = {'class_id':'face', 'x1':x1,'y1':y1,'x2':x2,'y2':y2, 'crop':crop,'status':classname,'confidence':confidence}
                det_countf+=1

                if classname=='yesmask':
                    cv2.rectangle(frame, (x1, y1), (x2, y2),(0, 255, 0),2)
                else:
                    cv2.rectangle(frame, (x1, y1), (x2, y2),(0, 0, 255),2)

                cv2.imshow('frame4',frame)
                cv2.waitKey(100)

            if maskstatus==True:
                cv2.rectangle(frame, (x1p, y1p), (x2p, y2p),(0, 255, 0),2)
            else:
                cv2.rectangle(frame, (x1p, y1p), (x2p, y2p),(0, 0, 255),2)

            detsp[det_countp]={'class':'person','x1p':x1p,'y1p':y1p,'x2p':x2p,'y2p':y2p,'faces':detsf,'maskstatus':maskstatus}

        cv2.imshow('frame4',frame)
        cv2.waitKey(200)
        return detsp

if __name__ == '__main__':
    appobj=MaskDet()
    detsp = appobj.detect()
    pprint.pprint(detsp)


def is_palindromic(a_string):
    return a_string == a_string[::-1]

class Solution:
    def longestPalindrome(self, a_string: str) -> str:
        if len(a_string) in [0, 1]:
            return a_string

        if is_palindromic(a_string):
            return a_string

        string_length = len(a_string)

        for i in range(1, string_length):

            j = string_length - i
            for k in range(i+1):
                sub_string = a_string[k: k+j]
                if is_palindromic(sub_string):
                    return sub_string

## 以下通过的版本

def create_dp_table(table_size):
    """
    根据字元长度建立 dynamic table
    """
    dp_table = [[0] * table_size for _ in range(table_size)]
    for i in range(table_size):
        dp_table[i][i] = True
    return dp_table

def is_palindromic(a_string):
    """
    直接检查这个字串是不是回字
    """
    return a_string == a_string[::-1]

class Solution:
    """
    通过的解法
    参考 https://leetcode.com/problems/longest-palindromic-substring/discuss/900639/Python-Solution-%3A-with-detailed-explanation-%3A-using-DP
    """
    def longestPalindrome(self, a_string: str) -> str:
        if len(a_string) in [0, 1]:
            return a_string

        if is_palindromic(a_string):
            return a_string

        string_length = len(a_string)
        dp_table = create_dp_table(string_length)

        longest_one = a_string[0]
        for k in range(1, string_length):
            # 从 sub_string 字元长度 +1 开始滚到原始字元的长度
            for i in range(string_length - k):
                if k == 1:
                    # 2 个字元的 case 比较特别
                    if a_string[i] == a_string[i+k]:
                        dp_table[i][i+k] = True
                        longest_one = a_string[i:i+k+1]
                else:
                    j = i + k
                    # 开始去滚 dynamic table
                    # 检查 a_string[i:j] 的状况
                    if a_string[i] == a_string[j]:
                        # 第一个条件：第一格字元 = 最后一个字元
                        if dp_table[i+1][j-1]:
                            # 第二个条件：检查前一个状态是不是回字
                            dp_table[i][j] = True
                            if len(a_string[i:j+1]) > len(longest_one):
                                longest_one = a_string[i:j+1]
        return longest_one, dp_table


from abc import ABC, abstractmethod
from dataclasses import dataclass, field
import datetime as dt
from decimal import Decimal
from itertools import groupby
from typing import List, Optional

from dateutil.relativedelta import relativedelta

from domain.common.investments import StockInvestment
from domain.common.investment_position import InvestmentPosition, StockPosition
from domain.common.investment_position_summary import StockPositionSummary
from domain.common.investment_summary import InvestmentSummary, StockSummary
from domain.common.portfolio_item import PortfolioItem

DATE_FORMAT = "%Y%m%d"

@dataclass
class InvestmentConsolidated(PortfolioItem, ABC):
    initial_date: dt.date = dt.datetime.max.date()
    history: List[InvestmentPosition] = field(default_factory=list)

    def __post_init__(self):
        if not isinstance(self.initial_date, dt.date):
            self.initial_date = dt.datetime.strptime(
                str(self.initial_date), DATE_FORMAT
            ).date()

    def to_json(self) -> dict:
        ret = {
            **super().to_json(),
            "initial_date": self.initial_date.strftime(DATE_FORMAT),
            "history": sorted(
                [h.to_dict() for h in self.history], key=lambda h: h["date"]
            ),
        }
        return ret

    @abstractmethod
    def add_investment(self, investment):
        """Adds the investment"""

    def export_investment_summary(self) -> Optional[InvestmentSummary]:
        """Creates an InvestmentSummary objects based on history"""

class StockPositionWrapper:
    def __init__(self, data: StockPosition):
        self.data = data
        self.next: Optional[StockPositionWrapper] = None
        self.prev: Optional[StockPositionWrapper] = None

    @property
    def date(self) -> dt.date:
        return self.data.date

    @property
    def amount(self):
        if self.prev:
            return self.prev.amount + self.data.bought_amount - self.data.sold_amount
        return self.data.bought_amount - self.data.sold_amount

    @property
    def bought_amount(self):
        if self.prev and self.prev.amount > 0:
            return self.prev.bought_amount + self.data.bought_amount
        return self.data.bought_amount

    @property
    def bought_value(self):
        if self.prev and self.prev.amount > 0:
            return self.prev.bought_value + self.data.bought_value
        return self.data.bought_value

    @property
    def average_price(self):
        bought_amount = self.bought_amount
        if bought_amount > 0:
            return (self.bought_value / bought_amount).quantize(Decimal("0.01"))
        return 0

    @property
    def gross_sold_value(self):
        if self.prev:
            return self.prev.position_sold_value + self.data.sold_value
        return self.data.sold_value

    @property
    def invested_sold_value(self):
        if self.prev:
            return (
                    self.prev.current_invested_sold_value
                    + self.data.sold_amount * self.average_price
            )
        return self.data.sold_amount * self.average_price

    @property
    def current_invested_sold_value(self):
        if self.prev and self.prev.amount > 0:
            return (
                    self.prev.current_invested_sold_value
                    + self.data.sold_amount * self.average_price
            )
        return self.data.sold_amount * self.average_price

    @property
    def current_invested_value(self):
        if self.prev:
            return (self.bought_value - self.current_invested_sold_value).quantize(
                Decimal("0.01")
            )
        return (self.data.bought_value - self.current_invested_sold_value).quantize(
            Decimal("0.01")
        )

    @property
    def node_invested_value(self):
        return self.data.bought_value - self.data.sold_amount * self.average_price

    @property
    def node_invested_sold_value(self):
        return self.data.sold_amount * self.average_price

    @property
    def realized_profit(self):
        return (self.gross_sold_value - self.invested_sold_value).quantize(
            Decimal("0.01")
        )

    # @property
    # def gross_value(self):
    #     return self.amount * self.data.close_price
    #
    # @property
    # def prev_adjusted_gross_value(self):
    #     if self.prev and self.prev.amount > 0:
    #         if self.data.sold_amount > 0:
    #             prev_month_amount = self.prev.amount - round(
    #                 self.node_invested_sold_value / self.prev.average_price
    #             )
    #         else:
    #             prev_month_amount = self.prev.amount
    #         return prev_month_amount * self.prev.data.close_price
    #     return 0

    @property
    def month_variation_percent(self):
        if self.prev and self.prev.amount > 0:
            prev_gross_value = self.prev_adjusted_gross_value + self.data.bought_value
        else:
            prev_gross_value = self.current_invested_value
        if prev_gross_value > 0:
            return ((self.gross_value * 100 / prev_gross_value) - 100).quantize(
                Decimal("0.01")
            )
        return 0

class StockPositionWrapperLinkedList:
    def __init__(self):
        self.head: Optional[StockPositionWrapper] = None
        self.tail: Optional[StockPositionWrapper] = None
        self._current: Optional[StockPositionWrapper] = None
        self._first_interaction = False

    def __iter__(self):
        self._first_interaction = True
        self._current = self.head
        return self

    def __next__(self) -> StockPositionWrapper:
        if not self._current:
            raise StopIteration
        if self._first_interaction:
            self._first_interaction = False
            return self._current
        self._current = self._current.next
        if not self._current:
            raise StopIteration
        return self._current

    def push(self, new_val: StockPosition):
        new_node = StockPositionWrapper(new_val)
        new_node.next = self.head
        if self.head is not None:
            self.head.prev = new_node
        self.head = new_node

    def insert(self, prev_node, new_val):
        if prev_node is None:
            return
        new_node = StockPositionWrapper(new_val)
        new_node.next = prev_node.next
        prev_node.next = new_node
        new_node.prev = prev_node
        if new_node.next:
            new_node.next.prev = new_node
        else:
            self.tail = new_node

    def append(self, new_val):
        new_node = StockPositionWrapper(new_val)
        new_node.next = None

        if self.head is None:
            new_node.prev = None
            self.head = new_node
            self.tail = new_node
            return

        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last
        self.tail = new_node

    def find(self, func):
        curr = self.head
        while curr:
            if func(curr):
                return curr
            curr = curr.next
        return None

    @staticmethod
    def list_print(node):
        while node:
            print(node.data),
            node = node.next

@dataclass
class StockConsolidated(InvestmentConsolidated):
    ticker: str = field(default="")
    alias_ticker: str = field(default="")

    def __post_init__(self):
        super().__post_init__()
        self.history = [
            StockPosition(**h) if isinstance(h, dict) else h for h in self.history
        ]

    @property
    def sk(self) -> str:
        sk = f"TICKER#{self.ticker}"
        return sk

    def to_json(self) -> dict:
        _dict = super().to_json()
        _dict["alias_ticker"] = self.alias_ticker
        _dict["ticker"] = self.ticker

        return _dict

    def current_ticker_name(self):
        return self.alias_ticker or self.ticker

    def __add__(self, other):
        initial_date = min(self.initial_date, other.initial_date)
        return StockConsolidated(
            subject=self.subject,
            ticker=self.ticker,
            alias_ticker=self.alias_ticker,
            initial_date=initial_date,
            history=self.history + other.history,
        )

    def find_position_in_history(self, date: dt.date) -> Optional[StockPosition]:
        return next(
            (position for position in self.history if position.date == date),
            None,
        )

    def create_empty_position(self, date: dt.date) -> StockPosition:
        p = StockPosition(date)
        self.history.append(p)
        return p

    def add_investment(self, investment: StockInvestment):
        self.initial_date = min(self.initial_date, investment.date)
        if investment.alias_ticker:
            self.alias_ticker = investment.alias_ticker

        position = self.find_position_in_history(investment.date)
        if not position:
            position = self.create_empty_position(investment.date)

        position.add_investment(investment)
        if position.is_empty():
            self.history.remove(position)

    def add_investments(self, investments: List[StockInvestment]):
        for investment in investments:
            self.add_investment(investment)

    def export_investment_summary(self) -> Optional[StockSummary]:
        wrapper = self.monthly_stock_position_wrapper_linked_list()
        if not wrapper.tail:
            return

        current = wrapper.tail
        previous = current.prev

        previous_position = None
        latest_position = StockPositionSummary(
            date=current.data.date,
            amount=current.amount,
            invested_value=current.current_invested_value,
            bought_value=current.data.bought_value,
            average_price=current.average_price,
        )
        if previous:
            previous_position = StockPositionSummary(
                date=previous.data.date,
                amount=previous.amount,
                bought_value=previous.data.bought_value,
                invested_value=previous.current_invested_value,
            )

        return StockSummary(
            self.ticker,
            alias_ticker=self.alias_ticker,
            latest_position=latest_position,
            previous_position=previous_position,
        )

    def grouped_by_month_stock_position(self) -> List[StockPosition]:
        grouped_positions = []
        for date, positions in groupby(
                sorted(self.history, key=lambda h: h.date),
                key=lambda p: p.date.replace(day=1),
        ):
            grouped = StockPosition(date)
            for position in positions:
                grouped = grouped + position
            grouped_positions.append(grouped)
        return grouped_positions

    def monthly_stock_position_wrapper_linked_list(
            self,
            to_date: dt.date = None,
    ) -> StockPositionWrapperLinkedList:
        doubly = StockPositionWrapperLinkedList()

        prev_date = self.initial_date.replace(day=1)
        for h in self.grouped_by_month_stock_position():
            if h.date > prev_date + relativedelta(months=1):
                while prev_date < h.date:  # filling the gaps
                    doubly.append(StockPosition(prev_date))
                    prev_date += relativedelta(months=1)
            doubly.append(h)
            prev_date = h.date.replace(day=1) + relativedelta(months=1)

        if to_date and doubly.tail:
            while doubly.tail.date < to_date:
                doubly.append(StockPosition(prev_date))
                prev_date += relativedelta(months=1)

        return doubly


import numpy as np
import random

def getnormalProcessingTime(machineNum,jobNum):
    normalProcessingTime = np.random.randint(1,20,(machineNum,jobNum))

    np.save('./example/normalProcessingTime.npy',normalProcessingTime)

def getDeteriorationProcessingTime(machineNum,jobNum):
    deteriorationProcessingTime = np.zeros((machineNum,jobNum,jobNum))

    for m in deteriorationProcessingTime:
        for j in m:
            for ind,lo in enumerate(j):
                if ind == 0:
                    continue
                j[ind] = j[ind-1] + random.randint(1,3) * ind

    np.save('./example/deteriorationProcessingTime.npy', deteriorationProcessingTime)

def maintain_alpha(machineNum):
    alpha = np.random.randint(5,15,(machineNum))
    # alpha = np.random.randint(5, 15, (machineNum)) /10
    np.save('./example/alpha.npy',alpha)

def maintain_beta(machineNum):
    beta = np.random.randint(5,9,(machineNum)) / 10
    # beta = np.random.randint(5, 9, (machineNum)) / 100
    np.save('./example/beta.npy',beta)

def getExample(machineNum,jobNum):
    getnormalProcessingTime(machineNum,jobNum)
    getDeteriorationProcessingTime(machineNum,jobNum)
    maintain_alpha(machineNum)
    maintain_beta(machineNum)

getExample(4,20) #第一个参数为机器数目，第二个参数为工件数目。


from msrest.serialization import Model

class AccessKeys(Model):
    """Namespace/Relay Connection String.

    :param primary_connection_string: Primary connection string of the created
     namespace authorization rule.
    :type primary_connection_string: str
    :param secondary_connection_string: Secondary connection string of the
     created namespace authorization rule.
    :type secondary_connection_string: str
    :param primary_key: A base64-encoded 256-bit primary key for signing and
     validating the SAS token.
    :type primary_key: str
    :param secondary_key: A base64-encoded 256-bit secondary key for signing
     and validating the SAS token.
    :type secondary_key: str
    :param key_name: A string that describes the authorization rule.
    :type key_name: str
    """

    _attribute_map = {
        'primary_connection_string': {'key': 'primaryConnectionString', 'type': 'str'},
        'secondary_connection_string': {'key': 'secondaryConnectionString', 'type': 'str'},
        'primary_key': {'key': 'primaryKey', 'type': 'str'},
        'secondary_key': {'key': 'secondaryKey', 'type': 'str'},
        'key_name': {'key': 'keyName', 'type': 'str'},
    }

    def __init__(self, **kwargs):
        super(AccessKeys, self).__init__(**kwargs)
        self.primary_connection_string = kwargs.get('primary_connection_string', None)
        self.secondary_connection_string = kwargs.get('secondary_connection_string', None)
        self.primary_key = kwargs.get('primary_key', None)
        self.secondary_key = kwargs.get('secondary_key', None)
        self.key_name = kwargs.get('key_name', None)


import unittest
import paramunittest
import readConfig as readConfig
from common import Log as Log
from common import common
from common import configHttp as ConfigHttp

addressList_xls = common.get_xls("userCase.xlsx", "getAddressList")
localReadConfig = readConfig.ReadConfig()
configHttp = ConfigHttp.ConfigHttp()
info = {}

@paramunittest.parametrized(*addressList_xls)
class GetAddressList(unittest.TestCase):
    def setParameters(self, case_name, method, url, code, msg):
        """
        set params
        :param case_name:
        :param method:
        :param url:
        :param code:
        :param msg:
        :return:
        """
        self.case_name = str(case_name)
        self.url = str(url)
        self.method = str(method)
        self.code = str(code)
        self.msg = str(msg)
        self.info = None

    def description(self):
        self.case_name

    def setUp(self):
        self.log = Log.MyLog.get_log()
        self.logger = self.log.get_logger()

    def testGetAddressList(self):
        # set url
        configHttp.set_url(self.url)

        # get visitor token
        token = localReadConfig.get_headers("TOKEN_U")

        # set headers
        header = {"token": str(token)}
        configHttp.set_headers(header)

        # test interface
        if self.method == 'get':
            self.return_json = configHttp.get()
        elif self.method == 'post':
            self.return_json = configHttp.post()
        else:
            self.logger.info("No this interface's method:" + self.method)
        # check result
        self.checkResult()

    def tearDown(self):
        pass

    def checkResult(self):
        self.info = self.return_json.json()
        if self.info['code'] == self.code:
            self.assertEqual(self.info['msg'], self.msg)
            self.log.build_OK_line(self.case_name, self.code, self.msg)
        else:
            self.log.build_NG_line(self.case_name, self.info['code'], self.info['msg'])


import time
from functools import partial
from typing import Callable, List, Optional, Tuple

import pandas as pd

from llama_index import SimpleDirectoryReader
from llama_index.embeddings import OpenAIEmbedding, resolve_embed_model
from llama_index.embeddings.base import DEFAULT_EMBED_BATCH_SIZE, BaseEmbedding

def generate_strings(num_strings: int = 100, string_length: int = 10) -> List[str]:
    """
    Generate random strings sliced from the paul graham essay of the following form:

    offset 0: [0:string_length], [string_length:2*string_length], ...
    offset 1: [1:1+string_length], [1+string_length:1+2*string_length],...
    ...
    """  # noqa: D415
    content = (
        SimpleDirectoryReader("../../examples/paul_graham_essay/data")
        .load_data()[0]
        .get_content()
    )
    content_length = len(content)

    strings_per_loop = content_length / string_length
    num_loops_upper_bound = int(num_strings / strings_per_loop) + 1
    strings = []

    for offset in range(num_loops_upper_bound + 1):
        ptr = offset % string_length
        while ptr + string_length < content_length:
            strings.append(content[ptr : ptr + string_length])
            ptr += string_length
            if len(strings) == num_strings:
                break

    return strings

def create_open_ai_embedding(batch_size: int) -> Tuple[BaseEmbedding, str, int]:
    return (
        OpenAIEmbedding(embed_batch_size=batch_size),
        "OpenAIEmbedding",
        4096,
    )

def create_local_embedding(
    model_name: str, batch_size: int
) -> Tuple[BaseEmbedding, str, int]:
    model = resolve_embed_model(f"local:{model_name}")
    return (
        model,
        "hf/" + model_name,
        model._langchain_embedding.client.max_seq_length,  # type: ignore
    )

def bench_simple_vector_store(
    embed_models: List[Callable[[int], Tuple[BaseEmbedding, str, int]]],
    num_strings: List[int] = [100],
    string_lengths: List[int] = [64, 256],
    embed_batch_sizes: List[int] = [1, DEFAULT_EMBED_BATCH_SIZE],
    torch_num_threads: Optional[int] = None,
) -> None:
    """Benchmark embeddings."""
    print("Benchmarking Embeddings\n---------------------------")

    results = []

    if torch_num_threads is not None:
        import torch

        torch.set_num_threads(torch_num_threads)

    max_num_strings = max(num_strings)
    for string_length in string_lengths:
        generated_strings = generate_strings(
            num_strings=max_num_strings, string_length=string_length
        )

        for string_count in num_strings:
            strings = generated_strings[:string_count]

            for batch_size in embed_batch_sizes:
                models = []
                for create_model in embed_models:
                    models.append(create_model(batch_size=batch_size))  # type: ignore

                for model in models:
                    time1 = time.time()
                    _ = model[0].get_text_embedding_batch(strings, show_progress=True)

                    time2 = time.time()
                    print(
                        f"Embedding with model {model[1]} with "
                        f"batch size {batch_size} and max_seq_length {model[2]} for "
                        f"{string_count} strings of length {string_length} took "
                        f"{time2 - time1} seconds."
                    )
                    results.append((model[1], batch_size, string_length, time2 - time1))
                # TODO: async version

    # print final results
    print("\n\nFinal Results\n---------------------------")
    results_df = pd.DataFrame(
        results, columns=["model", "batch_size", "string_length", "time"]
    )
    print(results_df)

if __name__ == "__main__":
    bench_simple_vector_store(
        embed_models=[
            # create_open_ai_embedding,
            partial(
                create_local_embedding,
                model_name="sentence-transformers/all-MiniLM-L6-v2",
            ),
            partial(
                create_local_embedding,
                model_name="sentence-transformers/all-MiniLM-L12-v2",
            ),
            partial(
                create_local_embedding,
                model_name="BAAI/bge-small-en",
            ),
            partial(
                create_local_embedding,
                model_name="sentence-transformers/all-mpnet-base-v2",
            ),
        ],
        torch_num_threads=None,
    )


import inspect
from src.libs.custom_logger import get_custom_logger
from time import time
import pytest
import allure
from src.libs.common import to_base64, delay
from src.node.waku_message import WakuMessage
from src.env_vars import NODE_1, NODE_2, ADDITIONAL_NODES, NODEKEY, RUNNING_IN_CI
from src.node.waku_node import WakuNode
from tenacity import retry, stop_after_delay, wait_fixed
from src.test_data import VALID_PUBSUB_TOPICS

logger = get_custom_logger(__name__)

class StepsRelay:
    test_pubsub_topic = VALID_PUBSUB_TOPICS[1]
    test_content_topic = "/test/1/waku-relay/proto"
    test_payload = "Relay works!!"

    @pytest.fixture(scope="function")
    def setup_main_relay_nodes(self, request):
        logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
        self.node1 = WakuNode(NODE_1, f"node1_{request.cls.test_id}")
        self.node1.start(relay="true", nodekey=NODEKEY)
        self.enr_uri = self.node1.get_enr_uri()
        self.node2 = WakuNode(NODE_2, f"node2_{request.cls.test_id}")
        self.node2.start(relay="true", discv5_bootstrap_node=self.enr_uri)
        self.main_nodes = [self.node1, self.node2]
        self.optional_nodes = []

    @pytest.fixture(scope="function")
    def setup_optional_relay_nodes(self, request):
        logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
        if ADDITIONAL_NODES:
            nodes = [node.strip() for node in ADDITIONAL_NODES.split(",")]
        else:
            pytest.skip("ADDITIONAL_NODES is empty, cannot run test")
        for index, node in enumerate(nodes):
            node = WakuNode(node, f"node{index}_{request.cls.test_id}")
            node.start(relay="true", discv5_bootstrap_node=self.enr_uri)
            self.optional_nodes.append(node)

    @pytest.fixture(scope="function")
    def subscribe_main_relay_nodes(self):
        logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
        self.ensure_relay_subscriptions_on_nodes(self.main_nodes, [self.test_pubsub_topic])

    @pytest.fixture(scope="function")
    def subscribe_optional_relay_nodes(self):
        logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
        self.ensure_relay_subscriptions_on_nodes(self.optional_nodes, [self.test_pubsub_topic])

    @pytest.fixture(scope="function")
    def relay_warm_up(self):
        try:
            self.wait_for_published_message_to_reach_relay_peer()
            logger.info("WARM UP successful!!")
        except Exception as ex:
            raise TimeoutError(f"WARM UP FAILED WITH: {ex}")

    # this method should be used only for the tests that use the relay_warm_up fixture
    # otherwise use wait_for_published_message_to_reach_relay_peer
    @allure.step
    def check_published_message_reaches_relay_peer(self, message=None, pubsub_topic=None, message_propagation_delay=0.1, sender=None, peer_list=None):
        if message is None:
            message = self.create_message()
        if pubsub_topic is None:
            pubsub_topic = self.test_pubsub_topic
        if not sender:
            sender = self.node1
        if not peer_list:
            peer_list = self.main_nodes + self.optional_nodes

        sender.send_relay_message(message, pubsub_topic)
        delay(message_propagation_delay)
        for index, peer in enumerate(peer_list):
            logger.debug(f"Checking that peer NODE_{index + 1}:{peer.image} can find the published message")
            get_messages_response = peer.get_relay_messages(pubsub_topic)
            assert get_messages_response, f"Peer NODE_{index}:{peer.image} couldn't find any messages"
            assert len(get_messages_response) == 1, f"Expected 1 message but got {len(get_messages_response)}"
            waku_message = WakuMessage(get_messages_response)
            waku_message.assert_received_message(message)

    @allure.step
    def check_publish_without_relay_subscription(self, pubsub_topic):
        try:
            self.node1.send_relay_message(self.create_message(), pubsub_topic)
            raise AssertionError("Publish with no subscription worked!!!")
        except Exception as ex:
            assert "Bad Request" in str(ex) or "Internal Server Error" in str(ex)

    # we need much bigger timeout in CI because we run tests in parallel there and the machine itself is slower
    @allure.step
    def wait_for_published_message_to_reach_relay_peer(
        self, timeout_duration=120 if RUNNING_IN_CI else 20, time_between_retries=1, pubsub_topic=None, sender=None, peer_list=None
    ):
        @retry(stop=stop_after_delay(timeout_duration), wait=wait_fixed(time_between_retries), reraise=True)
        def check_peer_connection():
            message = {"payload": to_base64(self.test_payload), "contentTopic": self.test_content_topic, "timestamp": int(time() * 1e9)}
            self.check_published_message_reaches_relay_peer(message, pubsub_topic=pubsub_topic, sender=sender, peer_list=peer_list)

        check_peer_connection()

    @allure.step
    def ensure_relay_subscriptions_on_nodes(self, node_list, pubsub_topic_list):
        for node in node_list:
            node.set_relay_subscriptions(pubsub_topic_list)

    @allure.step
    def delete_relay_subscriptions_on_nodes(self, node_list, pubsub_topic_list):
        for node in node_list:
            node.delete_relay_subscriptions(pubsub_topic_list)

    @allure.step
    def create_message(self, **kwargs):
        message = {"payload": to_base64(self.test_payload), "contentTopic": self.test_content_topic, "timestamp": int(time() * 1e9)}
        message.update(kwargs)
        return message


#!/usr/bin/env python3
"""
using Layers with TensorFlow
"""

import tensorflow as tf

def create_layer(prev, n, activation):
    """
    prev is the tensor output of the previous layer
    n is the number of nodes in the layer to create
    activation is the activation function that the layer should use
    use tf.contrib.layers.variance_scaling_initializer(mode="FAN_AVG")
      to implement He et. al initialization for the layer weights
    each layer should be given the name layer
    Returns: the tensor output of the layer
    """

    init = tf.contrib.layers.variance_scaling_initializer(mode="FAN_AVG")

    A = tf.layers.Dense(units=n, name='layer', activation=activation,
                        kernel_initializer=init)

    Y_pred = A(prev)

    return (Y_pred)


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

import numpy as np

from data import SOV_SYMBOL

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# Embedding layer that has a lookup table of symbols that is [full_dict_size x input_dim]. Includes dropout.
# Works for both non-batched and batched inputs
class EmbeddingLayer(nn.Module):
    # Parameters: dimension of the word embeddings, number of words, and the dropout rate to apply
    # (0.2 is often a reasonable value)
    def __init__(self, input_dim, full_dict_size, embedding_dropout_rate):
        # print('input_dim', input_dim, 'full_dict_size', full_dict_size, 'embed_dropout', embedding_dropout_rate)
        super(EmbeddingLayer, self).__init__()
        self.dropout = nn.Dropout(embedding_dropout_rate)
        self.word_embedding = nn.Embedding(full_dict_size, input_dim)

    # Takes either a non-batched input [sent len x input_dim] or a batched input
    # [batch size x sent len x input dim]
    def forward(self, input):
        embedded_words = self.word_embedding(input)
        final_embeddings = self.dropout(embedded_words)
        return final_embeddings

# One-layer RNN encoder for batched inputs -- handles multiple sentences at once. You're free to call it with a
# leading dimension of 1 (batch size 1) but it does expect this dimension.
class RNNEncoder(nn.Module):
    # Parameters: input size (should match embedding layer), hidden size for the LSTM, dropout rate for the RNN,
    # and a boolean flag for whether or not we're using a bidirectional encoder
    def __init__(self, input_size, hidden_size, dropout, bidirect):
        super(RNNEncoder, self).__init__()
        self.bidirect = bidirect
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.reduce_h_W = nn.Linear(hidden_size * 2, hidden_size, bias=True)
        self.reduce_c_W = nn.Linear(hidden_size * 2, hidden_size, bias=True)
        self.rnn = nn.GRU(input_size, hidden_size, num_layers=1, batch_first=True,
                               dropout=dropout, bidirectional=self.bidirect)
        self.init_weight()

    # Initializes weight matrices using Xavier initialization
    def init_weight(self):
        nn.init.xavier_uniform_(self.rnn.weight_hh_l0, gain=1)
        nn.init.xavier_uniform_(self.rnn.weight_ih_l0, gain=1)
        if self.bidirect:
            nn.init.xavier_uniform_(self.rnn.weight_hh_l0_reverse, gain=1)
            nn.init.xavier_uniform_(self.rnn.weight_ih_l0_reverse, gain=1)
        nn.init.constant_(self.rnn.bias_hh_l0, 0)
        nn.init.constant_(self.rnn.bias_ih_l0, 0)
        if self.bidirect:
            nn.init.constant_(self.rnn.bias_hh_l0_reverse, 0)
            nn.init.constant_(self.rnn.bias_ih_l0_reverse, 0)

    def get_output_size(self):
        return self.hidden_size * 2 if self.bidirect else self.hidden_size

    def sent_lens_to_mask(self, lens, max_length):
        return torch.from_numpy(np.asarray([[1 if j < lens.data[i].item() else 0 for j in range(0, max_length)] for i in range(0, lens.shape[0])]))

    # embedded_words should be a [batch size x sent len x input dim] tensor
    # input_lens is a tensor containing the length of each input sentence
    # Returns output (each word's representation), context_mask (a mask of 0s and 1s
    # reflecting where the model's output should be considered), and h_t, a *tuple* containing
    # the final states h and c from the encoder for each sentence.
    def forward(self, embedded_words, input_lens):
        # Takes the embedded sentences, "packs" them into an efficient Pytorch-internal representation
        packed_embedding = nn.utils.rnn.pack_padded_sequence(embedded_words, input_lens, batch_first=True)
        # Runs the RNN over each sequence. Returns output at each position as well as the last vectors of the RNN
        # state for each sentence (first/last vectors for bidirectional)
        output, hn = self.rnn(packed_embedding)
        # Unpacks the Pytorch representation into normal tensors
        output, sent_lens = nn.utils.rnn.pad_packed_sequence(output)
        max_length = input_lens.data[0].item()
        context_mask = self.sent_lens_to_mask(sent_lens, max_length)

        # Grabs the encoded representations out of hn, which is a weird tuple thing.
        # Note: if you want multiple LSTM layers, you'll need to change this to consult the penultimate layer
        # or gather representations from all layers.
        if self.bidirect:
            forward, backward = hn[0], hn[1]
#             print(hn[0].shape, hn[1].shape, hn.shape, type(hn))
            # Grab the representations from forward and backward LSTMs
            h_ = torch.cat((forward, backward), dim=1)
            # Reduce them by multiplying by a weight matrix so that the hidden size sent to the decoder is the same
            # as the hidden size in the encoder
            new_h = self.reduce_h_W(h_)
            h_t = new_h
        else:
            h = hn[0][0]
            h_t = (h,)
        return (output, context_mask, h_t)

class RNNDecoder(nn.Module):

    def __init__(self, input_size, encoder_hidden_size, hidden_size, output_size, dropout, attention=True):
        super(RNNDecoder, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.encoder_hidden_size = encoder_hidden_size
        self.attention_hidden_size = encoder_hidden_size + hidden_size
        self.attention = attention
        self.rnn = nn.GRU(input_size, hidden_size, num_layers=1, batch_first=True,
                           dropout=dropout)
        self.hidden2vocab = nn.Linear(self.attention_hidden_size, output_size, bias=True)
        # self.hidden2vocab = nn.Linear(self.hidden_size, output_size, bias=True)

        self.attention_mat = nn.Bilinear(hidden_size, encoder_hidden_size, 1)

        self.init_weight()

    # Initializes weight matrices using Xavier initialization
    def init_weight(self):
        nn.init.xavier_uniform_(self.hidden2vocab.weight)
        nn.init.xavier_uniform_(self.attention_mat.weight)
        nn.init.xavier_uniform_(self.rnn.weight_hh_l0, gain=1)
        nn.init.xavier_uniform_(self.rnn.weight_ih_l0, gain=1)
        nn.init.constant_(self.rnn.bias_hh_l0, 0)
        nn.init.constant_(self.rnn.bias_ih_l0, 0)

    def init_hidden(self):
        return (torch.zeros(1, 1, self.hidden_size),
                torch.zeros(1, 1, self.hidden_size))

    def get_output_size(self):
        return self.hidden_size

    def sent_lens_to_mask(self, lens, max_length):
        return torch.from_numpy(np.asarray([[1 if j < lens.data[i].item() else 0 for j in range(0, max_length)] for i in range(0, lens.shape[0])]))

    def attention_function(self, dec_output, src_hidden):
        return self.attention_mat(dec_output, src_hidden)

    def calculate_weights(self, dec_output, src_sentence_hidden):
        num_src_words = src_sentence_hidden.size()[0]
        dup_dec_output = torch.cat([dec_output] * num_src_words)
        weights = self.attention_function(dup_dec_output, src_sentence_hidden)
        return torch.t(weights)

    def word_embed_weights(self, dec_output, src_sentence_hidden):
        weights = self.calculate_weights(dec_output, src_sentence_hidden)
        normalized_weights = F.softmax(weights, dim=1)
        return normalized_weights

    def get_attention(self, dec_output, src_sentence_hidden):
        word_weights = self.word_embed_weights(dec_output, src_sentence_hidden)
        return torch.mm(word_weights, src_sentence_hidden)

    def forward(self, input_hidden, embedded_word, src_sentence_embed):
        output, self.hidden = self.rnn(embedded_word, input_hidden)
        output = output.squeeze(0)

        if self.attention:
            src_sentence_embed = src_sentence_embed.squeeze(1)
            attention = self.get_attention(output, src_sentence_embed)
            hidden_layer_input = torch.cat((attention, output), dim=1)
        else:
            hidden_layer_input = output

        vocab_output = self.hidden2vocab(hidden_layer_input)
        vocab_prob = F.log_softmax(vocab_output, dim=1).squeeze(0)
        return vocab_prob


class Tree:
    def __init__(self, root_node) -> None:
        self.node_list       = [root_node]
        self.parent_idx_list = [0]
        self.level_list      = [0]

    def add_node(self, node, parent_index:int):
        assert(0<=parent_index<len(self.node_list)),(f'Parent index exceeds limits 0~{len(self.node_list)-1}.')
        self.node_list.append(node)
        self.parent_idx_list.append(parent_index)
        self.level_list.append(len(self.return_node2root(len(self.node_list)-1))-1)

    def return_node2root(self, node_index:int) -> list:
        assert(0<=node_index<len(self.node_list)),(f'Node index exceeds limits 0~{len(self.node_list)-1}.')
        node2root_list = [self.node_list[node_index]]
        parent_idx = self.parent_idx_list[node_index]
        while parent_idx != 0:
            this_node = self.node_list[parent_idx]
            node2root_list.append(this_node)
            parent_idx = self.parent_idx_list[parent_idx]
        node2root_list.append(self.node_list[0])
        return node2root_list

    def print_tree_raw(self) -> None:
        print('Nodes:  ', self.node_list)
        print('Parents:', self.parent_idx_list)
        print('Level:  ', self.level_list)

    def print_tree_inlevel(self) -> None:
        print('#'*8, 'PRTIN TREE', '#'*8)
        print(f'root0: {self.node_list[0]}')
        for level in range(1, max(self.level_list)+1):
            node_index_in_level = [i for i,x in enumerate(self.level_list) if x==level]
            node_index_in_level = [x for x in node_index_in_level if x!=0]
            nodes_in_level = [x for i,x in enumerate(self.node_list) if i in node_index_in_level]
            print(f'node{level}:', nodes_in_level)
        print('#'*28)


import os
from gym import utils
from gym.envs.robotics import pile_env

# Ensure we get the path separator correct on windows
MODEL_XML_PATH = os.path.join('pile', 'table012.xml')

class PileTable0Env(pile_env.PileEnv, utils.EzPickle):
    def __init__(self, reward_type='sparse'):
        initial_qpos = {
                'robot':{
                        'robot0:slide0': 0.405,
                        'robot0:slide1': 0.48,
                        'robot0:slide2': 0.0,
                        },
                'object':{
                        'object:joint:center': [1.3, 0.54, -0.03, 1., 0., 0., 0.],
                        'object:joint:size': [0.025, 0.025, 0.025],
                        'object:joint:range': [0.0, 0.0, 0.0],
                        },
        }
        pile_env.PileEnv.__init__(
            self, MODEL_XML_PATH, object_num=0, block_gripper=False, n_substeps=20,
            gripper_extra_height=0.2, target_in_the_air=False, obs_index=None,
            initial_qpos=initial_qpos, reward_type=reward_type)
        utils.EzPickle.__init__(self)

        self.disc_obs_index = [0,1]
        self.lower_dim = True

    def _is_done(self, obs, rew=False):

        if self.object_num[0] == 1:
            x, y, z = obs[6], obs[7], obs[8]
            xd = x <= 1.06 or x >= 1.54
            yd = y <= 0.34 or y >= 0.74
            zd = z< 0.42

            mx = abs(obs[0] - self.object_range['object:joint:center'][0]) >=0.005
            my = abs(obs[1] - self.object_range['object:joint:center'][1]) >=0.005
            mz = abs(obs[2] - self.object_range['object:joint:center'][2]) >=0.005
            d = xd or yd or zd or mx or my or mz
#            if not rew:
#                d = zd or mx or my or mz
        else:
            x, y, z = obs[0], obs[1], obs[2]
            xd = x <= 1.06 or x >= 1.54
            yd = y <= 0.34 or y >= 0.74
            zd = z< 0.42
            d = xd or yd or zd
#            if not rew:
#                d = zd

        return d

    def compute_reward(self, obs):
        # Compute distance between goal and the achieved goal.
        z = obs[2]

#        print(z)#0.42
        return (0.5 - z)*12.5# + self._is_done(obs, rew=True)
#        if self.reward_type == 'sparse':
#            if z <= 0.45:
#                return 0
#            else:
#                return -1
#        else:
#            return 0.425 - z


x = int(input())
y = {}
for i in range(x):
    starting_point = (int(input()), int(input()))
    ending_point = (int(input()), int(input()))
    y[starting_point] = ending_point
all_the_stairs = []
for point in y:
    stairs = []
    temprature = point
    while 1:
        stairs.append([temprature,y[temprature]])
        if y[temprature] in y:
            temprature = y[temprature]
        else:
            break
    all_the_stairs.append(stairs)
z = len(max(all_the_stairs,key = len))
for stairs in all_the_stairs:
    if len(stairs)==z:
        print(stairs)


"""added additional shoes

Revision ID: 52a9289380b0
Revises: 1137f4cdac18
Create Date: 2018-08-28 20:50:18.573274

"""

# revision identifiers, used by Alembic.
revision = '52a9289380b0'
down_revision = '1137f4cdac18'

from alembic import op
import sqlalchemy as sa

from alembic import op
import sqlalchemy as sa
from datetime import date
from sqlalchemy.sql import table, column
from sqlalchemy import String, Integer, Date

def upgrade():
    # Create an ad-hoc table to use for the insert statement.
    item_table = table('item',
                       column('model', String),
                       column('brand_id', Integer),
                       column('gender_id', Integer),
                       column('small_image_url', String),
                       column('medium_image_url', String),
                       column('type', String)
                       )

    # Asolo
    op.bulk_insert(item_table,
                   [
                       {'model': 'mont blanc gv', 'brand_id': '18',
                           'gender_id': '1', 'type': 'mountain'}
                   ]
                   )

    # Boreal
    op.bulk_insert(item_table,
                   [
                       {'model': 'synergy', 'brand_id': '6',
                        'gender_id': '3', 'type': 'rock'}
                   ]
                   )

    # La Sportiva
    op.bulk_insert(item_table,
                   [
                       {'model': 'G5', 'brand_id': '3',
                        'gender_id': '3', 'type': 'mountain'},
                       {'model': 'G2', 'brand_id': '3',
                        'gender_id': '3', 'type': 'mountain'}
                   ]
                   )

    # Lowa
    op.bulk_insert(item_table,
                   [
                       {'model': 'alpine pro gtx', 'brand_id': '19',
                        'gender_id': '1', 'type': 'mountain'}
                   ]
                   )

    # Zamberlan
    op.bulk_insert(item_table,
                   [
                       {'model': 'mountain pro evo gtx', 'brand_id': '20',
                        'gender_id': '1', 'type': 'mountain'},
                       {'model': 'mountain pro evo gtx', 'brand_id': '20',
                        'gender_id': '2', 'type': 'mountain'},
                       {'model': 'karka evo RR', 'brand_id': '20',
                        'gender_id': '1', 'type': 'mountain'},
                       {'model': 'eiger evo RR', 'brand_id': '20',
                        'gender_id': '1', 'type': 'mountain'},
                       {'model': 'everest evo RR', 'brand_id': '20',
                        'gender_id': '1', 'type': 'mountain'},
                       {'model': 'expert pro gtx RR', 'brand_id': '20',
                        'gender_id': '1', 'type': 'mountain'},
                       {'model': 'sparrow RR', 'brand_id': '20',
                        'gender_id': '2', 'type': 'approach'},
                       {'model': 'intrepid RR', 'brand_id': '20',
                        'gender_id': '1', 'type': 'approach'},
                   ]
                   )

    # Evolv
    op.bulk_insert(item_table,
                   [
                       {'model': 'zender', 'brand_id': '1',
                        'gender_id': '3', 'type': 'approach'}
                   ]
                   )

    # Mad Rock
    op.bulk_insert(item_table,
                   [
                       {'model': 'frenzy ez', 'brand_id': '4',
                        'gender_id': '3', 'type': 'rock'},
                       {'model': 'frenzy lace', 'brand_id': '4',
                                                'gender_id': '3', 'type': 'rock'},
                       {'model': 'banshee', 'brand_id': '4',
                        'gender_id': '2', 'type': 'rock'},
                       {'model': 'mugen tech 2.0', 'brand_id': '4',
                        'gender_id': '3', 'type': 'rock'},
                       {'model': 'maniac', 'brand_id': '4',
                        'gender_id': '3', 'type': 'rock'}
                   ]
                   )

def downgrade():
    pass