import requests
from bs4 import BeautifulSoup
import norm

def isFloat(s):
    if s == None:
        return False
    for x in s:
        if x not in "0,1,2,3,4,5,6,7,8,9,.".split(","):
            return False
    return True

# SCRAPING
NUM_MOVIES = 250
URL = "https://www.metacritic.com/browse/movies/score/userscore/all/filtered?view=condensed&page="
USER_AGENT = {'User-agent': 'Mozilla/5.0'}
BASE_URL = "https://www.metacritic.com"
movies = []

# SQL
TABLE_NAME = "movies_meta"

# SCRAPING FUNCTIONS

def scrapeAll():
    i = 0
    while len(movies) < NUM_MOVIES:
        page = scrape(URL+str(i), USER_AGENT)
        parseHTML(page)
        i += 1

def scrape(url, userAgent):
    return requests.get(url, headers=userAgent)

# PARSING FUNCTIONS

def parseHTML(page):
    soup = BeautifulSoup(page.content, "html.parser")
    table = soup.find("div", class_="title_bump")
    # Each movie's information is in a <tr> element in the HTML
    trs = table.find_all("tr", class_="expand_collapse")
    for tr in trs:
        movie = parseMovie(tr)
        movies.append(movie)
        if len(movies) >= NUM_MOVIES:
            break

def parseMovie(tr):
    rating = tr.find("td", class_="score").find("div").get_text()

    td = tr.find("td", class_="details")
    title = td.find("h3").get_text()
    href = td.find("a", class_="title").get("href")
    movie_url = BASE_URL + href
    genres = scrapeGenres(movie_url)

    justGotDate = 0
    for child in td.children:
        child = str(child)
        if justGotDate == 1:
            justGotDate = 2
        elif justGotDate == 2:
            pipeIndex = child.find("|")
            if pipeIndex == -1:
                mpaa = "Rating Unlisted"
            else:
                mpaa = child[pipeIndex+2:-7]
            break
        if child[:6] == "<span>":
            year = child[-11:-7]
            justGotDate = 1

    if title == None:
        title = "N/A"
    if genres == None:
        genres = "N/A"
    if year == None:
        year = "N/A"
    if rating == None:
        rating = "N/A"
    if mpaa == None:
        mpaa = "N/A"

    # If title includes year at the end, use this as the year and remove from title
    if len(title) > 7:
        if title[-6] == "(" and title[-1] == ")" and title[-5:-1].isdigit():
            year = title[-5:-1]
            title = title[:-7]

    return (year, rating, title, movie_url)

def scrapeGenres(url):
    page = scrape(url, USER_AGENT)
    soup = BeautifulSoup(page.content, "html.parser")
    return ", ".join([x.get_text() for x in soup.find("div", class_="genres").contents[3].findAll("span")])

def scrapeRatings(titles):
    movies = []
    for title in titles:
        try:
            rating, url = scrapeRating(title[0], title[1])
            print(rating)
            if rating != None:
                movies.append((rating, title[1], title[0], url))
        except:
            print("temporary error")
    return movies

def scrapeRating(title, year):
    urlTitle = norm.normUrl(title)
    baseUrl = BASE_URL + "/movie/"
    if title.lower() == "star wars: episode iv - a new hope":
        thisUrl = "https://www.metacritic.com/movie/star-wars-episode-iv---a-new-hope"
    elif title.lower() == "star wars: episode v - the empire strikes back":
        thisUrl = "https://www.metacritic.com/movie/star-wars-episode-v---the-empire-strikes-back"
    elif title.lower() == "star wars: episode vi - return of the jedi":
        thisUrl = "https://www.metacritic.com/movie/star-wars-episode-vi---return-of-the-jedi"
    elif title.lower() == "moonlight" and year == 2016:
        thisUrl = "https://www.metacritic.com/movie/moonlight-2016"
    elif title.lower() == "hamilton" and year == 2020:
        thisUrl = "https://www.metacritic.com/movie/hamilton-2020"
    else:
        thisUrl = baseUrl + "-".join(urlTitle.split())
    print("metaUrl=", thisUrl)
    page = scrape(thisUrl, USER_AGENT)
    # if error message like 403 or 404, return nothing
    if str(page).split()[1][1] == "4":
        thisUrl += "-" + year
        page = scrape(thisUrl, USER_AGENT)
        if str(page).split()[1][1] == "4":
            return None
    soup = BeautifulSoup(page.content, "html.parser")
    try:
        rating = soup.find("div", class_="us_wrapper").find(
            "a", class_="metascore_anchor").find("span").get_text()
    except AttributeError as e:
        print("Error scraping: {}".format(e))
        return None
    if not isFloat(rating):
        return None
    return (rating, thisUrl)

def run():
    scrapeAll()
    return movies


import sys
line = sys.stdin.readline()[:-1]

stack = []
result = 0
for i in range(len(line)):
    if line[i]=="(":
        stack.append('(')
    elif line[i]==")":
        stack.pop()
        if line[i-1]==")":
            result+=1
        else:
            result+=len(stack)
print(result)


import Tkinter
from Tkinter import Tk, Label, Button

# Create the application window
window = Tk()
window.geometry("500x500")

# Create the user interface

def button_callback():
        print('click')

master=Tk()
my_label = Tkinter.Label(window, text="Hello World!")
my_label.grid(row=10, column=10)
my_button=Tkinter.Button(window,text="button", command=button_callback)

# Start the GUI event loop
window.mainloop()


import datetime

from django.contrib.auth.models import User
from django.db import connection
from elasticsearch import Elasticsearch
from knox.models import AuthToken
from rest_framework import permissions, generics
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import BlogPost as BlogPostModel
from .models import BlogPostTag
from .models import KnowledgeBaseItem
from .models import KnowledgeBaseTag
from .models import Tool
from .models import BlogPostComment
from django.contrib.auth.models import User
from .serializers import CreateUserSerializer, UserSerializer, LoginUserSerializer, CommentSerializer

es = Elasticsearch(["http://elastic:9200"])

def article_index_payload_builder(blogpost_db_id, blogpost_data, author_first_name, created_date, type):
    data = {
        "id": blogpost_db_id,
        "title": blogpost_data["title"],
        "content": blogpost_data["content"],
        "type": type,
        "author": author_first_name,
        "createdDate": created_date,
        "tags": blogpost_data["tags"]
    }
    return data

class Blogs(APIView):
    def get(self, request, pk):
        try:
            blogs = BlogPostModel.objects.get(id=pk)
        except:
            return Response(status=404, data={"message": "Could't find your post."})

        values = blogs.__dict__
        values["tags"] = []
        values["createdByDisplayName"] = blogs.createdBy.first_name + ' ' + blogs.createdBy.last_name
        values["type"] = "blog_post"
        values["createdById"] = blogs.createdBy.id
        del values["createdBy_id"]

        for tag in blogs.tags.all():
            values["tags"].append(tag.tag)

        del values['_state']

        return Response(status=200, data=values)

    def delete(self, request, pk):
        try:
            blog = BlogPostModel.objects.get(id=pk)
        except:
            return Response(status=404, data={"message": "The post you're trying to delete "
                                                         "may have already been deleted. "
                                                         "Can't find it here."})
        blog.delete()

        es.delete_by_query(index='knowledge_base', body=
        {
            "query": {
                "match": {
                    "id": pk,
                }
            }
        })
        return Response(status=200, data={"message": "Post deleted"})

    def put(self, request, pk):

        """
         {
            "title": "Pavan first blogpost",
            "content": "Content for the blogpost blah blah blah blach",
            "authorId": "1",
            "tags": ["happiness", "joy"],
            "type": "blog_post"
        }
        """

        request_data = request.data
        if not BlogPostModel.objects.filter(id=pk).exists():

            data = {'message': "This blogpost does not exist"}
            return Response(data=data, status=404)
        else:
            user = User.objects.get(id=request_data["authorId"])
            blogpost_db = BlogPostModel.objects.get(id=pk)
            blogpost_db.title = request_data["title"]
            blogpost_db.content = request_data["content"]

            add_tags_blogpost(blogpost_db, request_data["tags"])

            blogpost_db.save()

            # Delete the old index in elasticsearch and reindex
            es.delete_by_query(index='knowledge_base', body=
            {
                "query": {
                    "match": {
                        "id": pk,
                    }
                }
            })

            # Re-index in elasticsearch
            blogpost_es = article_index_payload_builder(blogpost_db.id, request_data, user.first_name,
                                                        str(datetime.datetime), "blog_post")
            es.index(index='knowledge_base', body=blogpost_es)

        return Response(status=200, data={"message": "Successfully edited blogpost",
                                          "id": blogpost_db.id,
                                          "type": "blog_post"})

def blogmodelToDict(blogs):
    values = list(blogs.values())

    for idx, blog in enumerate(blogs):
        values[idx]["tags"] = []
        values[idx]["createdByDisplayName"] = blog.createdBy.first_name + ' ' + blog.createdBy.last_name
        values[idx]["type"] = "blog_post"
        values[idx]["commentCount"] = BlogPostComment.objects.filter(blog_post_id=blog.id).count()
        for tagId in blog.tags.all():
            values[idx]["tags"].append(tagId.tag)

    return values

def kbmodelToDict(kb_items):
    values = list(kb_items.values())

    for idx, blog in enumerate(kb_items):
        values[idx]["tags"] = []
        values[idx]["type"] = "knowledge_base"
        for tagId in blog.tags.all():
            values[idx]["tags"].append(tagId.tag)

    return values

"""
 Blogpost Item
 {
     "title": "Pavan first blogpost",
     "content": "Content for the blogpost blah blah blah blach",
     "authorId": "1",
     "tags": ["happiness", "joy"],
     "type": "blog_post"
 }

 Knowledge Base
  {
     "title": "Pavan first knowledge base item",
     "content": "Content for the blogpost blah blah blah blach",
     "authorId": "2",
     "tags": ["happiness", "first", "knowledge"],
     "type": "knowledge_base",
     "toolId": "7"
 }
"""

class BlogsList(APIView):
    def get(self, request):
        blogs = BlogPostModel.objects.all()

        values = list(blogs.values())

        for idx, blog in enumerate(blogs):
            values[idx]["tags"] = []
            values[idx]["createdByDisplayName"] = blog.createdBy.first_name + ' ' + blog.createdBy.last_name
            values[idx]["type"] = "blog_post"
            values[idx]["createdById"] = blog.createdBy.id
            del values[idx]["createdBy_id"]

            for tagId in blog.tags.all():
                values[idx]["tags"].append(tagId.tag)

        return Response(status=200, data=values)

    def post(self, request):
        request_data = request.data

        print(request_data)

        if "type" in request_data and request_data["type"] == 'knowledge_base':
            if KnowledgeBaseItem.objects.filter(title__iexact=request_data["title"]):
                return Response(status=200, data={
                    "message": "You already have a knowledge base item with the same title. Please choose another title."})

            user = User.objects.get(id=request_data["authorId"])

            # if not user.is_staff:
            #     return Response(status=403, data={'message':'You are not authorized to create a knowledge base item'})

            if "likeCount" in request_data:
                likeCount = request_data["likeCount"]
            else:
                likeCount = 0

            tool = Tool.objects.get(id=request_data["toolId"])
            knowledge_base_item = KnowledgeBaseItem(title=request_data["title"],
                                                    content=request_data["content"],
                                                    tool_id=tool,
                                                    likeCount=likeCount)
            knowledge_base_item.save()
            add_tags_knowledge_base(knowledge_base_item, request_data["tags"])

            knowledge_base_es = article_index_payload_builder(knowledge_base_item.id, request_data, user.first_name,
                                                              str(datetime.datetime), "knowledge_base")

            es.index(index='knowledge_base', body=knowledge_base_es)
            return Response(status=200, data={"message": "Successfully add a new knowledge base item",
                                            "id": knowledge_base_item.id,
                                            "type": "knowledge_base"})

        if does_blog_post_exist(request_data["authorId"], request_data["title"]):

            data = {'message': "You already have a blogpost with the same title. Please choose another title."}
            return Response(data=data, status=403)
        else:
            user = User.objects.get(id=request_data["authorId"])

            blogpost_db = BlogPostModel(title=request_data["title"],
                                        content=request_data["content"],
                                        createdBy=user,
                                        likeCount=0,
                                        visibility="visible")

            blogpost_db.save()

            # Save tags
            add_tags_blogpost(blogpost_db, request_data["tags"])

            # Index in elasticsearch
            blogpost_es = article_index_payload_builder(blogpost_db.id, request_data, user.first_name,
                                                        str(datetime.datetime), "blog_post")
            es.index(index='knowledge_base', body=blogpost_es)
        return Response(status=200, data={"message": "Successfully add a new blog post",
                                          "id": blogpost_db.id,
                                          "type": "blog_post"})

def add_tags_knowledge_base(knowledge_base_model, tags):
    for i in tags:
        if knowledge_base_model.tags.filter(id=knowledge_base_model.id).exists():
            continue
        tag = KnowledgeBaseTag(tag=i)
        tag.save()
        knowledge_base_model.tags.add(tag)

def add_tags_blogpost(blogpostModel, tags):
    for i in tags:
        if blogpostModel.tags.filter(id=blogpostModel.id).exists():
            continue
        tag = BlogPostTag(tag=i)
        tag.save()
        blogpostModel.tags.add(tag)

class PopularBlogList(APIView):
    def get(self, request):
        top = request.GET.get('top')
        if not top:
            top = 10

        blogs = BlogPostModel.objects.all().order_by('-likeCount')[:int(top)]

        values = list(blogs.values())

        for idx, blog in enumerate(blogs):
            values[idx]["tags"] = []
            values[idx]["createdByDisplayName"] = blog.createdBy.first_name + ' ' + blog.createdBy.last_name
            values[idx]["type"] = "blog_post"
            values[idx]["createdById"] = blog.createdBy.id
            values[idx]["commentCount"] = BlogPostComment.objects.filter(blog_post_id=blog.id).count()
            del values[idx]["createdBy_id"]

            for tagId in blog.tags.all():
                values[idx]["tags"].append(tagId.tag)
        return Response(status=200, data=values)

def dictfetchall(cursor):
    "Return all rows from a cursor as a dict"
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
        ]

class AllCategories(APIView):
    def get(self, request):
        with connection.cursor() as cursor:
            cursor.execute('SELECT distinct category from API_TOOL')
            data = dictfetchall(cursor)

        return Response(data, status=200)

class ExploreCategories(APIView):
    def get(self, request):
        with connection.cursor() as cursor:
            cursor.execute('SELECT category, '
                           'COUNT(1) as "publishedCount" '
                           'from API_TOOL GROUP BY '
                           'CATEGORY ORDER BY "publishedCount" DESC '
                           'LIMIT 6')
            data = dictfetchall(cursor)

        return Response(data, status=200)

class PopularBlogTags(APIView):
    def get(self, request):
        with connection.cursor() as cursor:
            cursor.execute('select tag, count(1) "tagCount" from '
                           '(select ab.tag as tag from  '
                           'api_blogpost_tags abt join api_blogposttag ab '
                           'on ab.id = abt.blogposttag_id) t '
                           'group by tag '
                           'order by "tagCount" desc limit 10')
            data = dictfetchall(cursor)

        return Response(data, status=200)

def does_blog_post_exist(author, title):
    with connection.cursor() as cursor:
        cursor.execute("SELECT COUNT(*) FROM api_blogpost WHERE api_blogpost.\"createdBy_id\" = %s AND title = %s",
                       [author, title])
        data = dictfetchall(cursor)
        print(data)
        if int(data[0]["count"]) > 0:
            return True
        else:
            return False

class Search(APIView):
    def get(self, request):
        query = request.GET.get('query')
        top = request.GET.get('top')

        if not top:
            top = 15

        if not query:
            return Response(status=400, data={"message": "No search query provided"})

        resp = es.search(body=
        {
            "query": {
                "multi_match": {
                    "query": query,
                    "fields": ["content", "title", "tags", "createdByDisplayName", "visibility"],
                    # "auto_generate_synonyms_phrase_query": True
                }
            }
        })

        if len(resp["hits"]["hits"]) <= 0:
            return Response(status=404, data={})

        blog_result_id = []
        kb_result_id = []

        for res in resp["hits"]["hits"]:
            print(res["_source"]["type"])
            if "blog" in res["_source"]["type"]:
                id = res["_source"]["id"]
                blog_result_id.append(id)

            else:
                id = res["_source"]["id"]
                kb_result_id.append(id)

        print(blog_result_id)

        blog_results = BlogPostModel.objects.filter(id__in=blog_result_id)
        kb_results = KnowledgeBaseItem.objects.filter(id__in=kb_result_id)

        blog_results = blogmodelToDict(blog_results)
        kb_results = kbmodelToDict(kb_results)

        final = blog_results + kb_results

        return Response(data=final[:int(top)], status=200)

class FilterCategories(APIView):
    def get(self, request, category):
        tools = Tool.objects.filter(category__iexact=category)
        values = []
        for idx, t in enumerate(tools):
            value = {"name": t.name, "category": t.category}
            values.append(value)
        return Response(status=200, data=values)

class Tools(APIView):
    def get(self, request):
        tools = Tool.objects.all()

        values = []
        for idx, t in enumerate(tools):
            value = {"id": t.id, "name": t.name, "category": t.category}
            values.append(value)
        return Response(status=200, data=values)

class RegistrationAPI(generics.GenericAPIView):
    serializer_class = CreateUserSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginUserSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data

        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })

class UserAPI(generics.RetrieveAPIView):
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

class CommentListAPI(APIView):
    def get(self, request, pk):
        '''GET method of comments (returns all comments for given BlogPost ID)'''

        # Grab list of comments for this BlogPost
        try:
            comments = BlogPostComment.objects.all().filter(blog_post_id__exact=pk)
            values = list(comments.values())
        except:
           return Response(status=404, data={"message": "Error: BlogPost not found."})

        # Double check that blogpost was found
        if len(values) == 0:
            return Response(status=404, data={"message": "Error: BlogPost not found."})

        for idx, comment in enumerate(comments):
            # Build response object
            values[idx]["id"] = comment.id
            values[idx]["author"] = comment.created_by.first_name + ' ' + comment.created_by.last_name
            values[idx]["createdOn"] = comment.created_on
            values[idx]["body"] = comment.content
            values[idx]["authorId"] = comment.created_by.id

            # Delete un-needed values
            del values[idx]["created_by_id"]
            del values[idx]["blog_post_id_id"]
            del values[idx]["content"]
            del values[idx]["created_on"]

        return Response(status=200, data=values)

class CommentAPI(APIView):
    def post(self, request):
        '''POST method for BlogPost comments'''

        comment_data = request.data

        # Get user instance
        try:
            user = User.objects.get(id=comment_data["authorId"])
        except:
           return Response(status=400, data={"message": "Author not found."})

        # Get blogpost instance
        try:
            blog_post = BlogPostModel.objects.get(id=comment_data["postId"])
        except:
            return Response(status=400, data={"message": "The blog post was not found."})

        # Finally, create the actual comment
        comment_db_item = BlogPostComment(content=comment_data["body"],
                                        blog_post_id=blog_post,
                                        created_by=user
                                        )
        comment_db_item.save()

        return Response(status=200, data={"message": "Successfully created a comment"})

    def delete(self, request, pk):
        '''DELETE method for comment'''

        try:
            comment = BlogPostComment.objects.get(id=pk)
        except:
            return Response(status=404, data={"message": "The comment you're trying to delete "
                                                         "may have already been deleted. "
                                                         "It cannot be found."})
        # Perform delete
        comment.delete()

        return Response(status=200, data={"message": "Comment deleted."})

class PopularKnowledgeList(APIView):
    def get(self, request):
        top = request.GET.get('top')
        if not top:
            top = 10

        kb_items = KnowledgeBaseItem.objects.all().order_by('-likeCount')[:int(top)]
        values = list(kb_items.values())

        for idx, item in enumerate(kb_items):
            values[idx]["tags"] = []
            values[idx]["type"] = "knowledge_base"
            tool = Tool.objects.filter(id=values[idx]["tool_id_id"])[0]
            tool_name = tool.name
            tool_category = tool.category

            values[idx]["toolName"] = tool_name
            values[idx]["toolId"] = values[idx]["tool_id_id"]
            values[idx]["toolCategory"] = tool_category

            del values[idx]["content_type"]
            del values[idx]["tool_id_id"]

            for tagId in item.tags.all():
                values[idx]["tags"].append(tagId.tag)

        return Response(status=200, data=values)

class KnowledgeBaseList(APIView):
    def get(self, request, pk):
        try:
            kb_items = KnowledgeBaseItem.objects.get(id=pk)
        except:
            return Response(status=404, data={"message": "Could't find your post."})

        values = kb_items.__dict__
        values["tags"] = []
        values["type"] = "knowledge_base"
        tool = Tool.objects.get(id=values["tool_id_id"])
        values["toolCategory"] = tool.category
        values["toolName"] = tool.name
        values["toolId"] = values["tool_id_id"]
        del values["tool_id_id"]
        del values["content_type"]

        for tag in kb_items.tags.all():
            values["tags"].append(tag.tag)

        del values['_state']

        return Response(status=200, data=values)

class LikeCounter(APIView):
    def get(self, request, pk):
        try:
            blog = BlogPostModel.objects.get(id=pk)
        except:
            return Response(status=404, data={"message": "Could't find your post."})

        return Response(status=200, data={"id": blog.id, "title": blog.title, "likeCount": blog.likeCount})

    def post(self, request, pk):
        try:
            blog = BlogPostModel.objects.get(id=pk)
            blog.likeCount += 1
            blog.save()
        except:
            return Response(status=404, data={"message": "Could't find your post."})

        return Response(status=200, data={"id": blog.id, "title": blog.title, "likeCount": blog.likeCount})

class UserDetails(APIView):
    def get(self, request, pk):
        '''GET method for retrieving user data'''

        try:
            with connection.cursor() as cursor:
                cursor.execute("SELECT * FROM auth_user WHERE id = %s", [pk])
                data = dictfetchall(cursor)[0]
        except:
            return Response(status=404, data={"message": "User not found!"})

        display_name = data["first_name"] + " " + data["last_name"]
        return Response(status=200, data={"id": data["id"],
                                         "display_name": display_name,
                                         "email": data["email"],
                                        "username": data["username"]})

class UserBlogs(APIView):
    def get(self, request, pk):
        blogs = BlogPostModel.objects.filter(id=pk)

        values = list(blogs.values())

        for idx, blog in enumerate(blogs):
            values[idx]["tags"] = []
            values[idx]["createdByDisplayName"] = blog.createdBy.first_name + ' ' + blog.createdBy.last_name
            values[idx]["type"] = "blog_post"
            values[idx]["createdById"] = blog.createdBy.id
            del values[idx]["createdBy_id"]

            for tagId in blog.tags.all():
                values[idx]["tags"].append(tagId.tag)

        return Response(status=200, data=values)


# if the string is "19:55 Switzerland 2 - 1 Spain", it returns ['2', '1']
def get_scores_from_string(string):
    infos = string.split(" ")
    scores = []
    for data in infos:
        if data.isnumeric():
            scores.append(int(data))

    return scores

# if the string is "19:55 Switzerland 2 - 1 Spain", it returns ['Switzerland', 'Spain']
def get_teams_from_string(string):
    infos = string.split(" - ")

    team_1 = infos[0].split(" ")
    team_1.pop(0)
    del team_1[-1]
    team_1 = " ".join(team_1)

    team_2 = infos[1].split(" ")
    team_2.pop(0)
    team_2 = " ".join(team_2)

    return [team_1, team_2]

# if the string is "19:55 Switzerland 2 - 1 Spain", it returns "19:55"
def get_hour_from_string(string):
    infos = string.split(" ")
    return infos[0]

def is_same_scoreboard(score, scores_2_verify):
    return score == scores_2_verify or score[::-1] == scores_2_verify


import rclpy
import logging
from rclpy.node import Node
from geometry_msgs.msg import Pose
from intelligible.publisher import Publisher

class Oracle(Node):
    def __init__(self):
        super().__init__("oracle")
        self.oracle = Publisher(self, "enqueue", "/enqueue", Pose)
        self.oracle.create_timer(1.0, self.timer_callback)

    def timer_callback(self):
        print("Know thyself; tell me a position, and I will show you where you will go.")

        msg = Pose()

        msg.position.x = float(input('Enter x position: '))
        msg.position.y = float(input('Enter y position: '))
        msg.position.z = 0.0 # Zero because we don't want to rotate the robot

        self.oracle.publish(msg)

        self.get_logger().info(f"Pose {msg.position.x, msg.position.y} published.")

    def destroy(self):
        self.oracle.destroy_pub()
        self.destroy_node()

def main(args=None):
    rclpy.init(args=args)
    oracle_node = Oracle()
    rclpy.spin(oracle_node)
    oracle_node.destroy()
    rclpy.shutdown()

if __name__ == '__main__':
    main()


from kafka import KafkaProducer
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
from pyspark import SparkConf, SparkContext
import json
import sys
import nltk
from nltk import sent_tokenize, word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from stop_words import get_stop_words

#nltk.download('punkt')

def createSparkContext():
    spark_conf = SparkConf().setAppName("KafkaWordCount")
    sc = SparkContext(conf=spark_conf)
    sc.setLogLevel("ERROR")

    return sc

def createStreamingContext(sc):
    ssc = StreamingContext(sc, 5)
    #ssc.checkpoint("file:///usr/local/spark/checkpoint")
    # 这里表示把检查点文件写入分布式文件系统HDFS，所以要启动Hadoop
    ssc.checkpoint("_checkpoint")

    return ssc

def createKafkaStream(ssc, zkQuorum, group, topics, numThreads):
    topicAry = topics.split(",")
    # 将topic转换为hashmap形式，而python中字典就是一种hashmap
    topicMap = {}
    for topic in topicAry:
        topicMap[topic] = numThreads
    lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap).map(lambda x: x[1])

    return lines

def updateFunc(new_values, last_sum):
    return sum(new_values) + (last_sum or 0)

def preprocessing(text):
    # tokenize into words
    tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]

    # remove stopwords
    stop = stopwords.words('english')
    tokens = [token for token in tokens if token not in stop]

    # remove words less than three letters
    tokens = [word for word in tokens if len(word) >= 3]

    # lower capitalization
    tokens = [word.lower() for word in tokens]

    # lemmatize
    lmtzr = WordNetLemmatizer()
    tokens = [lmtzr.lemmatize(word) for word in tokens]
    preprocessed_text= ' '.join(tokens)

    return preprocessed_text

def getStatDSFromKafkaStream(sc, lines):
    # RDD with initial state (key, value) pairs
    initialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)])

    words = lines.\
            flatMap(word_tokenize)

    statDS = words.\
                map(lambda x: (x, 1)).\
                updateStateByKey(updateFunc, initialRDD=initialStateRDD)

    return statDS

def setStopWordFilterOnStatDS(statDS):
    stop_words = get_stop_words('en')
    print("--------- stop word ---------")
    print(stop_words)

    statDS = statDS.\
                filter(lambda x: x[1]>=5).\
                filter(lambda x: x[0] not in stop_words)

    return statDS

def createStatDSOnKafkaStream(sc, lines):
    statDS = getStatDSFromKafkaStream(sc, lines)

    statDS = setStopWordFilterOnStatDS(statDS)

    return statDS

# 格式转化，将[["1", 3], ["0", 4], ["2", 3]]变为[{'1': 3}, {'0': 4}, {'2': 3}]，这样就不用修改第四个教程的代码了
def Get_dic(rdd_list):
    res = []
    for elm in rdd_list:
        tmp = {elm[0]: elm[1]}
        res.append(tmp)
    return json.dumps(res)

def sendmsg(rdd):
    if rdd.count != 0:
        msg = Get_dic(rdd.collect())
        producer = KafkaProducer(bootstrap_servers='localhost:9092')
        # 实例化一个KafkaProducer示例，用于向Kafka投递消息
        producer.send("wordStats", msg.encode('utf8'))
        # 很重要，不然不会更新
        producer.flush()

def setSenderOnStatDS(statDS):
    statDS.foreachRDD(lambda x: sendmsg(x))

    statDS.pprint()

def KafkaWordCount(zkQuorum, group, topics, numThreads):
    sc = createSparkContext()
    ssc = createStreamingContext(sc)

    lines = createKafkaStream(ssc, zkQuorum, group, topics, numThreads)

    statDS = createStatDSOnKafkaStream(sc, lines)

    setSenderOnStatDS(statDS)

    ssc.start()
    ssc.awaitTermination()

if __name__ == '__main__':
    # 输入的四个参数分别代表着
    # 1.zkQuorum为zookeeper地址
    # 2.group为消费者所在的组
    # 3.topics该消费者所消费的topics
    # 4.numThreads开启消费topic线程的个数
    if (len(sys.argv) < 5):
        print("Usage: KafkaWordCount <zkQuorum> <group> <topics> <numThreads>")
        exit(1)

    zkQuorum = sys.argv[1]
    group = sys.argv[2]
    topics = sys.argv[3]
    numThreads = int(sys.argv[4])
    print(group, topics)
    KafkaWordCount(zkQuorum, group, topics, numThreads)


from matplotlib import pyplot as plt
from matplotlib import animation
from matplotlib import style
import serial

fig,ax1=plt.subplots(figsize=(12,6))
ax1.set_xlabel("X")
ax1.set_ylabel("Y")
ax1.set_title("CAR'S PATH")
ser = serial.Serial('COM3', 115200)
ax1.plot(50, 50, "bo-")
def plotea (i):
    xx=[]
    yy=[]
    for i in range(50):
        data=ser.readline()
        data=data.splitlines()[0]
        data=data.decode().split(",")
        xx.append(float(data[0]))
        yy.append(float(data[1]))
        print(data[0],data[1])
    ax1.set_ylim([-30, 60])
    ax1.set_xlim([-30,60])

    try:  # Nos permite comprobar si hay un error al ejecutar la siguiente instrucción.
        ax1.plot(xx,yy, "r--")
    except:
        pass

ani = animation.FuncAnimation(fig, plotea, interval = 1) #Creamos animación para que se ejecute la función plotea con un intervalo de 1ms.

plt.show() #Muestra la gráfica.


from dataclasses import dataclass, field
from typing import Tuple, Union, Dict, Callable, Optional

import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
from sklearn.base import BaseEstimator, RegressorMixin

from fit_psyche.models.logit import logit
from fit_psyche.models.wh2001 import wh2001

@dataclass
class PsychometricCurve(BaseEstimator, RegressorMixin):
    model: str = "logit"
    mean_lims: Tuple[float, float] = (0, 20)
    var_lims: Tuple[float, float] = (0.001, 20)
    guess_rate_lims: Tuple[float, float] = (0.01, 0.05)
    lapse_rate_lims: Tuple[float, float] = (0.01, 0.05)

    _fit_func: Optional[Callable] = field(default=None, init=False)
    coefs_: Optional[Union[None, Dict[str, float]]] = field(default=None, init=False)

    """
   Fit a Logit or Wichmann and Hill 2001 psychometric curve.

   Model parameters:
     - Both:
       - mean (bias): The mean point of the experimental variable where the decision flips (on average).
                      Describes decision bias.
       - var / discrimination threshold: The distribution variance. Lower means the decision flips quicker, so is
                                         "better". Both models are cumulative normal distributions. Greater
                                         variance = wider distribution = more change in x before decision flips.
     - wh only
       - Guess and lapse rates: Model subject fallibility. Essentially allow either end of the fit cumulative
                                distribution to anchor to points other than 0 and 1 at each end of the curve
                                (respectively). See Wichmann and Hill, 2001.

   For all parameters, starting points are set as a mean of the specified limits.

   :param model: Which model to use, 'logit' or 'wh'. Logit model has two parameters, mean and variance. WH
                 adds guess and lapse rate. Default 'logit'.
   :param mean_lims: Limit for the mean parameter. Should be set according to range of independent (x) variable.
                     For example, if the x variable is set between 10 and 20 units in the experiment, limits within
                     that range are reasonable. If it's outside something weird is going on!. Specified as
                     tuple(min, max). Default (0, 20).
   :param var_lims: Limit for the var parameter. Lower limit should be >0 and upper limit should be set according
                    to task difficulty. Specified as tuple(min, max). Default (0.001, 100).
   :param guess_rate_lims: Limit for the guess parameter. Sets anchor point for start of curve and represents
                           proportion of trails where subject acts randomly. Limits should be set according the
                           expectations about subject.
                           For example, it should be higher for humans than a machine learning model... Unless,
                           it's a machine learning model with stochastic elements like a NN with dropout or
                           reinforcement learning model that uses Epsilon greedy.
                           Suggestions:
                             - Human (0.01, 0.05) ie. 1-5%
                             - Deterministic ML model (0, 1e-6) - the 'logit' model may be more appropriate.
                             - Stochastic ML model: Around known epsilon greedy value, or some low value in other
                               cases.
                           Specified as tuple(min, max). Default (0.01, 0.05).
   :param lapse_rate_lims: Sets the anchor point for the upper end of the curve. See guess_rate_lims.
   """

    def __post_init__(self):
        if self.model not in ['logit', 'wh']:
            raise ValueError(f"Unknown model: {self.model}. Available models: 'logit', 'wh'")

    def fit(self, x: np.ndarray, y: np.ndarray) -> "PsychometricCurve":
        if self.model.lower() == "wh":
            self._fit_func = wh2001
            lims = [
                self.mean_lims,
                self.var_lims,
                self.guess_rate_lims,
                self.lapse_rate_lims,
            ]

            bounds = (
                [
                    self.mean_lims[0],
                    self.var_lims[0],
                    self.guess_rate_lims[0],
                    self.lapse_rate_lims[0],
                ],
                [
                    self.mean_lims[1],
                    self.var_lims[1],
                    self.guess_rate_lims[1],
                    self.lapse_rate_lims[1],
                ],
            )
        else:
            self._fit_func = logit
            lims = [self.mean_lims, self.var_lims]
            bounds = (
                [self.mean_lims[0], self.var_lims[0]],
                [self.mean_lims[1], self.var_lims[1]],
            )

        popt, pcov = optimize.curve_fit(
            f=self._fit_func,
            xdata=x,
            ydata=y,
            p0=[np.mean(lim) for lim in lims],
            bounds=bounds,
        )

        self.coefs_ = {"mean": popt[0], "var": popt[1]}
        if self.model.lower() == "wh":
            self.coefs_.update({"guess_rate": popt[2], "lapse_rate": popt[3]})

        return self

    def predict(self, x: np.array) -> np.ndarray:
        return self._fit_func(x, **self.coefs_)

    def plot(
            self,
            x: np.ndarray,
            y: np.ndarray = None,
            show: bool = True,
            y_label: str = "Prop.",
            x_label: str = "Independent variable",
    ) -> None:
        fig, ax = plt.subplots()

        ax.plot(x, self.predict(x), label="y_pred")

        if y is not None:
            ax.scatter(x, y, label="y")

        ax.legend()
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
        ax.set_title(f"Model: {self.model}")
        fig.tight_layout()

        if show:
            fig.show()

        return fig

if __name__ == "__main__":
    x_ = np.linspace(start=8, stop=16, num=16)
    y_ = (x_ > x_.mean()).astype(float)

    pc = PsychometricCurve(model="wh", guess_rate_lims=(0, 0.2)).fit(x_, y_)
    pc.plot(x_, y_)


from __future__ import division

import pytest
p = pytest.mark.parametrize

import operator, types, random, math
from itertools import combinations_with_replacement, combinations
from functools import reduce
from collections import OrderedDict

# Audiolazy internal imports
from ..lazy_poly import Poly, lagrange, resample, x
from ..lazy_misc import almost_eq, blocks
from ..lazy_compat import orange, xrange, iteritems, xzip, xzip_longest as xzl
from ..lazy_math import inf, e, pi
from ..lazy_filters import z
from ..lazy_itertools import count
from ..lazy_core import OpMethod
from ..lazy_stream import Stream, thub
from ..lazy_synth import white_noise

from . import skipper
operator.div = getattr(operator, "div", skipper("There's no operator.div"))

def poly_str_match(poly, string):
  return string.replace(" ", "") == str(poly).replace(" ", "")

class TestPoly(object):
  example_data = [[1, 2, 3], [-7, 0, 3, 0, 5], [1], orange(2, -6, -1)]

  instances = [
    Poly([1.7, 2, 3.3]),
    Poly({-2: 1, -1: 5.1, 3: 2}),
    Poly({-1.1: 1, 1.1: .5}),
  ]

  polynomials = [ # Simple polynomials, always from higher to lower powers
    12 * x ** 2 + .5 * x + 18,
    .45 * x ** 17 + 2 * x ** 5 - x + 8,
    8 * x ** 5 + .2 * x ** 3 + .1 * x ** 2,
    42.7 * x ** 4,
    8 * x ** 3 + 3 * x ** 2 + 22.2 * x + .17,
  ]

  diff_table = [ # Pairs (polynomial, its derivative)
    (x + 2, 1),
    (Poly({0: 22}), 0),
    (Poly({}), 0),
    (x ** 2 + 2 * x + x ** -7 + x ** -.2 - 4,
     2 * x + 2 - 7 * x ** -8 - .2 * x ** -1.2),
  ]

  to_zero_inputs = [0, 0.0, False, {}, []]

  @p("data", example_data)
  def test_len_iter_from_list(self, data):
    assert len(Poly(data)) == len([k for k in data if k != 0])
    assert len(list(Poly(data).values())) == len(data)
    assert list(Poly(data).values()) == data

  def test_empty(self):
    assert len(Poly()) == 0
    assert not Poly()
    assert len(Poly([])) == 0
    assert not Poly([])

  @p(("key", "value"), [(3, 2), (7, 12), (500, 8), (0, 12), (1, 8)])
  def test_input_dict_one_item(self, key, value):
    data = {key: value}
    assert list(Poly(dict(data)).values()) == [0] * key + [value]

  def test_input_dict_three_items_and_fake_zero(self):
    data = {8: 5, 7: -1, 6: 80, 9: 0}
    polynomial = Poly(dict(data))
    assert len(polynomial) == 3
    assert list(polynomial.values()) == [0] * 6 + [80, -1, 5]

  @p("data", example_data)
  def test_output_dict(self, data):
    assert dict(Poly(data).terms()) == {k: v for k, v in enumerate(data)
                                             if v != 0}

  def test_sum(self):
    assert Poly([2, 3, 4]) + Poly([0, 5, -4, -1]) == Poly([2, 8, 0, -1])

  def test_float_sub(self):
    poly_obj = Poly([.3, 4]) - Poly() - Poly([0, 4, -4]) + Poly([.7, 0, -4])
    assert len(poly_obj) == 1
    assert almost_eq(poly_obj[0], 1)

  @p("val", instances)
  @p("div", [operator.div, operator.truediv])
  @p("den", [.1, -4e-3, 2])
  def test_int_float_div(self, val, div, den):
    assert almost_eq(div(den * val, den).terms(), val.terms())
    assert almost_eq(div(den * val, -den).terms(), (-val).terms())
    assert almost_eq(div(den * -val, den).terms(), (-val).terms())
    assert almost_eq(div(-den * val, den).terms(), (-val).terms())
    expected = Poly({k: operator.truediv(v, den) for k, v in val.terms()})
    assert almost_eq(div(val, den).terms(), expected.terms())
    assert almost_eq(div(val, -den).terms(), (-expected).terms())
    assert almost_eq(div(-val, den).terms(), (-expected).terms())
    assert almost_eq(div(-val, -den).terms(), expected.terms())

  @p("poly", instances + polynomials)
  def test_value_zero(self, poly):
    expected = ([v for k, v in poly.terms() if k == 0] + [0])[0]
    assert expected == poly(0)
    assert expected == poly(0.0)
    assert expected == poly[0]
    assert expected == poly[0.0]

  @p("poly", [Poly(v) for v in [{}, {0: 1}, {0: 0}, {0: -12.3}]])
  def test_constant_and_empty_polynomial_and_laurent(self, poly):
    assert poly.is_polynomial()
    assert poly.is_laurent()

  @p("poly", polynomials)
  def test_is_polynomial(self, poly):
    assert poly.is_polynomial()
    assert (poly + x ** 22.).is_polynomial()
    assert (poly + 8).is_polynomial()
    assert (poly * x).is_polynomial()
    assert (poly(-x) * .5).is_polynomial()
    assert (poly * .5 * x ** 2).is_polynomial()
    assert not (poly * .5 * x ** .2).is_polynomial()
    assert not (poly * x ** .5).is_polynomial()
    assert not (poly * x ** -(max(poly.terms())[0] + 1)).is_polynomial()

  @p("poly", polynomials)
  def test_is_laurent(self, poly):
    plaur = poly(x ** -1)
    assert poly.is_laurent()
    assert plaur.is_laurent()
    assert (plaur + x ** 2.).is_laurent()
    assert (plaur + 22).is_laurent()
    assert (plaur * x ** 2).is_laurent()
    assert (poly * x ** -(max(poly.terms())[0] + 1)).is_laurent()
    assert (plaur * x ** -(max(poly.terms())[0] + 1)).is_laurent()
    assert (plaur * x ** -(max(poly.terms())[0] // 2 + 1)).is_laurent()
    assert not (poly * x ** .5).is_laurent()
    assert not (poly + x ** -.2).is_laurent()

  def test_values_order_empty(self):
    poly = Poly({})
    val = poly.values()
    assert isinstance(val, types.GeneratorType)
    assert list(val) == []
    assert poly.order == 0
    assert poly.is_polynomial()
    assert poly.is_laurent()

  def test_values_order_invalid(self):
    poly = Poly({-1: 3, 1: 2})
    val = poly.values()
    with pytest.raises(AttributeError):
      next(val)
    with pytest.raises(AttributeError):
      poly.order
    assert not poly.is_polynomial()
    assert poly.is_laurent()

  @p("poly", polynomials)
  def test_values_order_valid(self, poly):
    order = max(poly.terms())[0]
    assert poly.order == order
    values = list(poly.values())
    for key, value in poly.terms():
      assert values[key] == value
      values[key] = 0
    assert values == [0] * (order + 1)

  @p("poly", polynomials)
  @p("zero", to_zero_inputs)
  def test_values_order_valid_with_zero(self, poly, zero):
    new_poly = Poly(list(poly.values()), zero=zero)
    order = max(new_poly.terms())[0]
    assert new_poly.order == order == poly.order

    if zero != poly.zero:
      assert len(new_poly) == order + 1
      for power, coeff in enumerate(poly.values()):
        if coeff is poly.zero:
          assert new_poly[power] == coeff
          new_poly[power] = zero # Should be the same to "del new_poly[power]"

    assert len(new_poly) == len(poly)
    values = list(new_poly.values())
    for key, value in poly.terms():
      assert values[key] == value
      values[key] = zero
    assert values == [zero] * (order + 1)

  @p(("poly", "diff_poly"), diff_table)
  def test_diff(self, poly, diff_poly):
    assert poly.diff() == diff_poly

  @p(("poly", "diff_poly"), diff_table)
  def test_integrate(self, poly, diff_poly):
    if not isinstance(diff_poly, Poly):
      diff_poly = Poly(diff_poly)
    integ = diff_poly.integrate()
    poly = poly - poly[0] # Removes the constant
    assert almost_eq(integ.terms(), poly.terms())

  @p("poly", polynomials + [0])
  def test_integrate_error(self, poly):
    if not isinstance(poly, Poly):
      poly = Poly(poly)
    if poly[-1] == 0: # Ensure polynomial has the problematic term
      poly = poly + x ** -1
    with pytest.raises(ValueError):
      print(poly)
      poly.integrate()
      print(poly.integrate())

  def test_empty_comparison_to_zero(self):
    inputs = [[], {}, [0, 0], [0], {25: 0}, {0: 0}, {-.2: 0}]
    values = [0, 0.] + [Poly(k) for k in inputs]
    for a, b in combinations_with_replacement(values, 2):
      assert a == b

  @p("input_data", [[], {}, [0, 0], [0], {25: 0}, {0: 0}, {-.2: 0}])
  def test_empty_polynomial_evaluation(self, input_data):
    poly = Poly(input_data)
    assert poly(5) == poly(0) == poly(-3) == poly(.2) == poly(None) == 0
    for zero in self.to_zero_inputs:
      polyz = Poly(poly, zero=zero)
      assert polyz(5) is zero
      assert polyz(0) is zero
      assert polyz(-3) is zero
      assert polyz(.2) is zero
      assert polyz(None) is zero

  def test_not_equal(self):
    for a, b in combinations(self.polynomials, 2):
      assert a != b

  @p("op", OpMethod.get("+ - *"))
  @p("zero", to_zero_inputs)
  def test_operators_with_poly_input_keeping_zero(self, op, zero):
    if op.rev: # Testing binary reversed
      for p0, p1 in combinations_with_replacement(self.polynomials, 2):
        p0 = Poly(p0)
        p1 = Poly(p1, zero)
        result = getattr(p0, op.dname)(p1)
        assert isinstance(result, Poly)
        assert result.zero == 0
        result = getattr(p1, op.dname)(p0)
        assert isinstance(result, Poly)
        assert result.zero is zero
    elif op.arity == 2: # Testing binary
      for p0, p1 in combinations_with_replacement(self.polynomials, 2):
        p0 = Poly(p0)
        p1 = Poly(p1, zero)
        result = op.func(p0, p1)
        assert isinstance(result, Poly)
        assert result.zero == 0
        result = op.func(Poly(p1), p0) # Should keep
        assert isinstance(result, Poly)
        assert result.zero is zero
    else: # Testing unary
      for poly in self.polynomials:
        poly = Poly(poly, zero)
        result = op.func(poly)
        assert isinstance(result, Poly)
        assert result.zero is zero

  @p("op", OpMethod.get("pow truediv"))
  @p("zero", to_zero_inputs)
  def test_pow_truediv_keeping_zero(self, op, zero):
    values = [Poly(2), Poly(1, zero=[]), 3]
    values += [0, Poly()] if op.name == "pow" else [.3, -1.4]
    for value in values:
      for poly in self.polynomials:
        poly = Poly(poly, zero)
        result = op.func(poly, value)
        assert isinstance(result, Poly)
        assert result.zero is zero

  def test_pow_raise(self):
    with pytest.raises(NotImplementedError):
      (x + 2) ** (.5 + x ** -1)
    with pytest.raises(NotImplementedError):
      (x ** -1 + 2) ** (2 * x)
    with pytest.raises(TypeError):
      2 ** (2 * x)

  def test_truediv_raise(self): # In Python 2 div == truediv due to OpMethod
    with pytest.raises(NotImplementedError):
      (x + 2) / (.5 + x ** -1)
    with pytest.raises(NotImplementedError):
      (x ** -1 + 2) / (7 + 2 * x)
    with pytest.raises(TypeError):
      2 / (2 * x) # Would be "__rdiv__" in Python 2, anyway it should raise

  def test_truediv_zero_division_error(self):
    with pytest.raises(ZeroDivisionError):
      x ** 5 / (0 * x)
    with pytest.raises(ZeroDivisionError):
      (2 + x ** 1.1) / (0 * x)
    with pytest.raises(ZeroDivisionError):
      (x ** -31 + 7) / 0.

  @p("zero", to_zero_inputs)
  @p("method", ["diff", "integrate"])
  def test_eq_ne_diff_integrate_keep_zero(self, zero, method):
    if method == "diff":
      expected = Poly([3, 4])
    else:
      expected = Poly([0., 4, 1.5, 2./3])
    result = getattr(Poly([4, 3, 2], zero=zero), method)()
    if zero == 0:
      assert result == expected
    else:
      assert result != expected
    assert almost_eq(result.terms(), expected.terms())
    assert result == Poly(expected, zero=zero)
    assert result.zero is zero

  @p("op", OpMethod.get("pow truediv"))
  @p("zero", to_zero_inputs)
  def test_pow_truediv_from_empty_poly_instance(self, op, zero):
    empty = Poly(zero=zero)
    result = op.func(empty, 2)
    assert result == empty
    assert result != Poly(zero=op)
    assert len(result) == 0
    assert result.zero is zero

  @p("data", example_data)
  @p("poly", polynomials + [x + 5 * x ** 2 + 2])
  def test_stream_evaluation(self, data, poly):
    result = poly(Stream(data))
    assert isinstance(result, Stream)
    result = list(result)
    assert len(result) == len(data)
    assert result == [poly(k) for k in data]

  def test_stream_coeffs_with_integer(self): # Poly before to avoid casting
    poly = x * Stream(0, 2, 3) + x ** 2 * Stream(4, 1) + 8 # Order matters!
    assert str(poly) == "8 + a1 * x + a2 * x^2"
    result = poly(5)
    assert isinstance(result, Stream)
    expected = 5 * Stream(0, 2, 3) + 25 * Stream(4, 1) + 8
    assert all(expected.limit(50) == result.limit(50))

  def test_stream_coeffs_purely_stream(self): # Poly before to avoid casting
    poly = x * Stream(0, 2, 3) + x ** 2 * Stream(4, 1) + Stream(2, 2, 2, 2, 5)
    assert str(poly) == "a0 + a1 * x + a2 * x^2"
    result = poly(count())
    assert isinstance(result, Stream)
    expected = (count() * Stream(0, 2, 3) + count() ** 2 * Stream(4, 1) +
                Stream(2, 2, 2, 2, 5))
    assert all(expected.limit(50) == result.limit(50))

  def test_stream_coeffs_mul(self):
    poly1 = x * Stream(0, 1, 2) + 5 # Order matters
    poly2 = x ** 2 * count() - 2
    poly = poly1 * poly2
    result = poly(Stream(4, 3, 7, 5, 8))
    assert isinstance(result, Stream)
    expected = (Stream(4, 3, 7, 5, 8) ** 3 * Stream(0, 1, 2) * count()
                + Stream(4, 3, 7, 5, 8) ** 2 * 5 * count()
                - Stream(4, 3, 7, 5, 8) * Stream(0, 1, 2) * 2
                - 10
               )
    assert all(expected.limit(50) == result.limit(50))

  @p("zero", to_zero_inputs)
  def test_stream_coeffs_add_copy_with_zero(self, zero):
    poly = x * Stream(0, 4, 2, 3, 1)
    new_poly = 3 * poly.copy(zero=zero)
    new_poly += poly
    assert isinstance(new_poly, Poly)
    assert new_poly.zero is zero
    result = new_poly(Stream(1, 2, 3, 0, 4, 7, -2))
    assert isinstance(result, Stream)
    expected = 4 * Stream(1, 2, 3, 0, 4, 7, -2) * Stream(0, 4, 2, 3, 1)
    assert all(expected.limit(50) == result.limit(50))

  @p("zero", to_zero_inputs)
  @p("horner", [True, False])
  def test_stream_coeffs_mul_copy_with_zero(self, zero, horner):
    poly = x ** 2 * Stream(3, 2, 1) + 2 * count() + x ** -3
    new_poly = poly.copy(zero=zero)
    new_poly *= poly + 1
    assert isinstance(new_poly, Poly)
    assert new_poly.zero is zero
    result = new_poly(count(18) ** .5, horner=horner)
    assert isinstance(result, Stream)
    expected = (count(18) * Stream(3, 2, 1)
                + 2 * count() + count(18) ** -1.5
               ) * (count(18) * Stream(3, 2, 1)
                + 2 * count() + count(18) ** -1.5 + 1
               )
    assert almost_eq(expected.limit(50), result.limit(50))

  def test_eq_ne_of_a_stream_copy(self):
    poly = x * Stream(0, 1)
    new_poly = poly.copy()
    assert poly == poly
    assert poly != new_poly
    assert new_poly == new_poly
    other_poly = poly.copy(zero=[])
    assert new_poly != other_poly
    assert new_poly.zero != other_poly.zero

  @p("poly", polynomials)
  def test_pow_basics(self, poly):
    assert poly ** 0 == 1
    assert poly ** Poly() == 1
    assert poly ** 1 == poly
    assert poly ** 2 == poly * poly
    assert poly ** Poly(2) == poly * poly
    assert almost_eq((poly ** 3).terms(), (poly * poly * poly).terms())

  def test_power_one_keep_integer(self):
    for value in [0, -1, .5, 18]:
      poly = Poly(1) ** value
      assert poly.order == 0
      assert poly[0] == 1
      assert isinstance(poly[0], int)

  @p("zero", to_zero_inputs)
  @p("horner", [True, False])
  def test_pow_with_stream_coeff(self, zero, horner):
    poly = Poly(x ** -2 * Stream(1, 0) + 2, zero=zero)
    new_poly = poly ** 2
    assert isinstance(new_poly, Poly)
    assert new_poly.zero is zero
    result = new_poly(count(1), horner=horner)
    assert isinstance(result, Stream)
    expected = (count(1) ** -4 * Stream(1, 0)
                + 4 * count(1) ** -2 * Stream(1, 0)
                + 4
               )
    assert almost_eq(expected.limit(50), result.limit(50))

  @p("zero", to_zero_inputs)
  @p("horner", [True, False])
  def test_truediv_by_stream(self, zero, horner):
    poly = Poly(x ** .5 * Stream(.2, .4) + 7, zero=zero)
    new_poly = poly / count(2, 4)
    assert isinstance(new_poly, Poly)
    assert new_poly.zero is zero
    result = new_poly(Stream(17, .2, .1, 0, .2, .5, 99), horner=horner)
    assert isinstance(result, Stream)
    expected = (Stream(17, .2, .1, 0, .2, .5, 99) ** .5 * Stream(.2, .4) + 7
               ) / count(2, 4)
    assert almost_eq(expected.limit(50), result.limit(50))

  def test_setitem(self):
    poly = x + 2
    poly[3] = 5
    assert poly == 5 * x ** 3 + x + 2
    poly[.2] = 1
    assert poly == 5 * x ** 3 + x + 2 + x ** .2
    var_coeff = Stream(1, 2, 3)
    poly[0] = var_coeff
    term_iter = poly.terms(sort=True)
    power, item = next(term_iter)
    assert item is var_coeff
    assert power == 0
    assert Poly(dict(term_iter)) == 5 * x ** 3 + x + x ** .2

  def test_hash_makes_poly_immutable(self):
    poly = x + 1
    poly[3] = 1
    poly.zero = 0
    my_set = {poly, 27, x}
    with pytest.raises(TypeError):
      poly[3] = 0
    with pytest.raises(TypeError):
      poly.zero = 0.
    assert poly == x ** 3 + x + 1
    assert poly in my_set

  def test_hash_equalness_on_different_sorting(self):
    assert hash(x + 1) == hash(1 + x)
    assert hash(x ** 2 + x + 1) == hash(1 + (1 + x) * x)
    assert hash(x + x ** .34 + 1) == hash((1 - x + x ** .34) + 2 * x)
    assert hash(x ** (2j + 1) + x ** 3) == hash(x ** 3 + x ** (2j + 1))

  @p("poly", polynomials + [5 - x ** -2, x + 2 * x ** .3, x ** 4.3j + x - 1])
  def test_hash_non_equal_for_different_zeros(self, poly):
    class Zero(): pass
    poly_other_zero = Poly(poly, zero=Zero)
    assert hash(poly) == hash(x + poly - x)
    assert hash(poly) != hash(poly_other_zero)

  @p("poly", [x ** 2 - 2 * x + 1, .3 * x ** 7 - 4 * x ** 2 + .1])
  def test_roots(self, poly):
    prod = lambda iterable: reduce(operator.mul, iterable, Poly(1))
    rebuilt_poly = poly[poly.order] * prod(x - r for r in poly.roots)
    assert almost_eq.diff(poly.values(), rebuilt_poly.values())

  @p("poly", [5 - x ** -2, x + 2 * x ** .3])
  def test_roots_invalid(self, poly):
    with pytest.raises(AttributeError):
      poly.roots

  def test_constants_have_no_roots(self):
    assert all(Poly(c).roots == [] for c in [2, -3, 4j, .2 + 3.4j])

  @p("list_data", [[1, 2, 3], [-7, 0, 3, 0, 5], orange(-5, 3)])
  def test_list_constructor_unsorted_terms_order(self, list_data):
    random.shuffle(list_data)
    poly = Poly(list_data)
    dict_data = ((idx, el) for idx, el in enumerate(list_data) if el)
    for (idx, el), (power, coeff) in xzl(dict_data, poly.terms(sort=False)):
      assert idx == power
      assert el == coeff

  @p("dict_data", [
    [(3, 4), (7, 3), (5, 2.5)],
    [(4, 3), (19, .2), (-4, 1e-18), (7, .25)],
    [(3, 2j), (3j, 4), (.5, 0.23)],
  ])
  def test_dict_constructor_unsorted_terms_order(self, dict_data):
    random.shuffle(dict_data)
    poly = Poly(OrderedDict(dict_data))
    for (idx, el), (power, coeff) in xzl(dict_data, poly.terms(sort=False)):
      assert idx == power
      assert el == coeff

  @p("poly", instances + polynomials)
  def test_copy_keep_unsorted_terms_order(self, poly):
    poly_copy = poly.copy()
    assert hash(poly) == hash(poly_copy)
    for a, b in xzl(poly.terms(sort=False), poly_copy.terms(sort=False)):
      assert a == b

  def test_diff_keep_unsorted_terms_order(self):
    data = [3, 2, 5, -1, 8, 0, 4]
    diff1 = [2, 10, -3, 32, 0, 24]
    diff2 = [10, -6, 96, 0, 120]

    order = orange(len(data))
    random.shuffle(order)

    dict_data = OrderedDict((k, data[k]) for k in order)
    dict_diff1 = OrderedDict((k - 1, diff1[k - 1]) for k in order if k >= 1)
    dict_diff2 = OrderedDict((k - 2, diff2[k - 2]) for k in order if k >= 2)

    poly = Poly(dict_data)
    pdiff1 = poly.diff()
    pdiff2 = poly.diff(2)

    expected1 = Poly(dict_diff1)
    for a, b in xzl(pdiff1.terms(sort=False), expected1.terms(sort=False)):
      assert a == b

    expected2 = Poly(dict_diff2)
    for a, b in xzl(pdiff2.terms(sort=False), expected2.terms(sort=False)):
      assert a == b

  def test_integrate_keep_unsorted_terms_order(self):
    data = [18, 2, 12, 0, 60, -54]
    integ = [18, 1, 4, 0, 12, -9]

    order = orange(len(data))
    random.shuffle(order)

    dict_data = OrderedDict((k, data[k]) for k in order)
    dict_integ = OrderedDict((k + 1, integ[k]) for k in order)

    pinteg = Poly(dict_data).integrate()
    expected = Poly(dict_integ)
    assert almost_eq(pinteg.terms(sort=False), expected.terms(sort=False))

  def test_add_sub_keep_unsorted_terms_order(self):
    poly1 = Poly(OrderedDict([(1, 4), (3, 8)]))
    poly2 = Poly(OrderedDict([(2, 5), (1, -2)]))
    padd = poly1 + poly2
    psub = poly1 - poly2
    expected_add = Poly(OrderedDict([(1, 2), (3, 8), (2, 5)]))
    expected_sub = Poly(OrderedDict([(1, 6), (3, 8), (2, -5)]))

    for a, b in xzl(padd.terms(sort=False), expected_add.terms(sort=False)):
      assert a == b
    for a, b in xzl(psub.terms(sort=False), expected_sub.terms(sort=False)):
      assert a == b

  def test_add_mul_pow_keep_unsorted_terms_order(self):
    poly1 = x ** 2 + 6 * x + 9
    poly2 = x * (x + 6) + 9 # Horner scheme
    poly3 = (x + 3) ** 2

    revp1 = 9 + 6 * x + x ** 2
    revp2 = 9 + (6 + x) * x
    revp3 = (3 + x) ** 2

    for a, b, c, d in xzl(poly1.terms(sort=False), poly2.terms(sort=False),
                          poly3.terms(sort=False), [(2, 1), (1, 6), (0, 9)]):
      assert a == b == c == d
    for a, b, c, d in xzl(revp1.terms(sort=False), revp2.terms(sort=False),
                          revp3.terms(sort=False), [(0, 9), (1, 6), (2, 1)]):
      assert a == b == c == d

  @p("div", [operator.div, operator.truediv])
  def test_div_keep_unsorted_terms_order(self, div):
    data = [18, 2, 12, 0, 60, -54]
    denominator = 12.5
    divided = [el / denominator for el in data]

    order = orange(len(data))
    random.shuffle(order)

    dict_data = OrderedDict((k, data[k]) for k in order)
    dict_div = OrderedDict((k, divided[k]) for k in order)

    pdiv = Poly(dict_data) / denominator
    expected = Poly(dict_div)
    assert almost_eq(pdiv.terms(sort=False), expected.terms(sort=False))

  @p("op", OpMethod.get("1", without="~"))
  def test_unary_operators_keep_unsorted_terms_order(self, op):
    data = thub(white_noise(low=-20, high=20), 2)
    powers = thub(white_noise(low=-20, high=20).limit(20), 2)

    dict_data = OrderedDict(xzip(powers, data))
    dict_op = OrderedDict(xzip(powers, op.func(data)))

    poly = op.func(Poly(dict_data))
    expected = Poly(dict_op)
    assert almost_eq(poly.terms(sort=False), expected.terms(sort=False))

  @p("poly", [poly for poly in polynomials if len(poly) >= 2])
  def test_terms_sort_simple_polynomials(self, poly):
    values = [(idx, v) for idx, v in enumerate(poly.values()) if v != 0]
    terms_auto = list(poly.terms())
    terms_sorted = list(poly.terms(sort=True))
    terms_not_sorted = list(poly.terms(sort=False))

    assert terms_not_sorted != terms_sorted
    assert terms_auto == values == terms_sorted == terms_not_sorted[::-1]

  def test_terms_sort_reverse_laurent_polynomials(self):
    data = white_noise(low=-1000, high=500)
    powers = white_noise(low=-230, high=20).map(int).limit(50)
    dict_original = OrderedDict(xzip(powers, data))
    poly = Poly(dict_original)

    terms_auto = list(poly.terms())
    terms_sorted = list(poly.terms(sort=True))
    terms_not_sorted = list(poly.terms(sort=False))
    terms_auto_rev = list(poly.terms(reverse=True))
    terms_sorted_rev = list(poly.terms(sort=True, reverse=True))
    terms_not_sorted_rev = list(poly.terms(sort=False, reverse=True))

    assert terms_not_sorted != terms_sorted
    assert (terms_auto == # Default is sorted
            terms_sorted == terms_auto_rev[::-1] == terms_sorted_rev[::-1])
    assert terms_not_sorted == terms_not_sorted_rev[::-1]
    assert terms_sorted == sorted(terms_not_sorted)
    assert terms_not_sorted == list(iteritems(dict_original))

  def test_terms_sort_reverse_float_powers(self):
    data = white_noise(low=-10, high=30)
    powers = white_noise(low=-30, high=40).limit(40)
    dict_original = OrderedDict(xzip(powers, data))
    poly = Poly(dict_original)

    terms_auto = list(poly.terms())
    terms_sorted = list(poly.terms(sort=True))
    terms_not_sorted = list(poly.terms(sort=False))
    terms_auto_rev = list(poly.terms(reverse=True))
    terms_sorted_rev = list(poly.terms(sort=True, reverse=True))
    terms_not_sorted_rev = list(poly.terms(sort=False, reverse=True))

    assert terms_not_sorted != terms_sorted
    assert (terms_auto == terms_not_sorted == # Default is not sorted
            terms_auto_rev[::-1] == terms_not_sorted_rev[::-1])
    assert terms_sorted == terms_sorted_rev[::-1]
    assert terms_sorted == sorted(terms_not_sorted)
    assert terms_not_sorted == list(iteritems(dict_original))

  def test_complex_power(self):
    poly = x ** 2j + 2 * x + 1
    assert set(poly.terms()) == {(0, 1), (1, 2), (2j, 1)}
    assert poly(0) == 1
    assert poly(1) == 4
    k = e ** pi
    assert almost_eq.diff(poly(k), 2 * (1 + k))
    ln4 = math.log(4)
    assert almost_eq.diff(poly(2), math.cos(ln4) + 5 + math.sin(ln4) * 1j)

  def test_call_horner_on_complex_invalid(self):
    poly = x ** 2j + 2 * x + 1
    assert poly(0, horner=True) == 1 # For zero the scheme isn't evaluated
    with pytest.raises(ValueError):
      poly(1, horner=True) # Here it need to be evaluated

  def test_set_to_and_the_zero_with_setitem_internal_data_and_property(self):
    poly = x ** 2 - 1
    poly[3.] = 0 # Using __setitem__
    poly[-1] = 8.
    assert len(poly) == 3
    assert poly_str_match(poly, # Laurent polynomial (sorted)
                          "8 * x^-1 - 1 + x^2")

    poly._data[.18] = 0 # Without using __setitem__
    assert len(poly) == 4 # Due to an undesired extra [hacked] zero
    assert poly_str_match(poly, # Sum of powers w/ a float power (not sorted)
                          "x^2 - 1 + 8 * x^-1 + 0 * x^0.18")

    assert list(poly.terms()) == [(2, 1), (0, -1), (-1, 8), (.18, 0)]
    poly.zero = 0 # This should clean that undesired zero
    assert len(poly) == 3
    assert list(poly.terms()) == [(-1, 8), (0, -1), (2, 1)] # Laurent (sorted)

  def test_string_representation(self):
    assert str(x) == "x"
    assert all(str(Poly(k)) == str(k) for k in [2, -3, 4j, 0])
    print(2 * x ** 5 + 1.8 * x - 7)
    assert poly_str_match(2 * x ** 5 + 1.8 * x - 7,
                          "-7 + 1.8 * x + 2 * x^5") # Polynomial (sorted)
    assert poly_str_match(8. * x ** -5 + 0 * x - 1. * x ** .2 + x ** .5j,
                          "8 * x^-5 - x^0.2 + x^0.5j") # Complex power

class TestLagrange(object):

  values = [-5, 0, 14, .17]

  @p("v0", values)
  @p("v1", values)
  def test_linear_func(self, v0, v1):
    for k in [0, v0, v1]:
      pairs = [(1 + k, v0), (-1 + k, v1)]
      for interpolator in [lagrange(pairs), lagrange(reversed(pairs))]:
        assert isinstance(interpolator, types.LambdaType)
        assert almost_eq(interpolator(k), v0 * .5 + v1 * .5)
        assert almost_eq(interpolator(3 + k), v0 * 2 - v1)
        assert almost_eq(interpolator(.5 + k), v0 * .75 + v1 * .25)
        assert almost_eq(interpolator(k - .5), v0 * .25 + v1 * .75)

  @p("v0", values)
  @p("v1", values)
  def test_linear_poly(self, v0, v1):
    for k in [0, v0, v1]:
      pairs = [(1 + k, v0), (-1 + k, v1)]
      for interpolator in [lagrange.poly(pairs),
                           lagrange.poly(reversed(pairs))]:
        expected = Poly([v0 - (1 + k) * (v0 - v1) * .5, (v0 - v1) * .5])
        assert almost_eq(interpolator.values(), expected.values())

  @p("v0", values)
  @p("v1", values)
  def test_parabola_poly(self, v0, v1):
    pairs = [(0, v0), (1, v1), (v1 + .2, 0)]
    r = v1 + .2
    a = (v0 + r *(v1 - v0)) / (r * (1 - r))
    b = v1 - v0 - a
    c = v0
    expected = a * x ** 2 + b * x + c
    for interpolator in [lagrange.poly(pairs),
                         lagrange.poly(pairs[1:] + pairs[:1]),
                         lagrange.poly(reversed(pairs))]:
      assert almost_eq(interpolator.values(), expected.values())

  data = [.12, .22, -15, .7, 18, 227, .1, 4, 0, -9e3, 1, 18, 1e-4,
          44, 3, 8.00000004, 27]

  @p("poly", TestPoly.polynomials)
  def test_recover_poly_from_samples(self, poly):
    expected = list(poly.values())
    size = len(expected)
    for seq in blocks(self.data, size=size, hop=1):
      pairs = [(k, poly(k)) for k in seq]
      interpolator = lagrange.poly(pairs)
      assert almost_eq.diff(expected, interpolator.values())

class TestResample(object):

  def test_simple_downsample(self):
    data = [1, 2, 3, 4, 5]
    resampled = resample(data, old=1, new=.5, order=1)
    assert resampled.take(20) == [1, 3, 5]

  def test_simple_upsample_linear(self):
    data = [1, 2, 3, 4, 5]
    resampled = resample(data, old=1, new=2, order=1)
    expected = [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]
    assert almost_eq(resampled.take(20), expected)

  def test_simple_upsample_linear_time_varying(self):
    acc = 1 / (1 - z ** -1)
    data = resample(xrange(50), old=1, new=1 + count() / 10, order=1)
    assert data.take() == 0.
    result = data.take(inf)
    expected = acc(1 / (1 + count() / 10))
    assert almost_eq(result, expected.limit(len(result)))


from numpy import log
from hyperopt import fmin, tpe, hp, STATUS_OK, Trials
import train_dist
import dist_util
import os, sys

MEASURE_TIME = False
DIST = False

class EarlyStopper:
    def __init__(self,patient):
        self.patient = patient
        self.best = None
        self.count = 0
    def __call__(self,score):
        if self.best is None:
            self.best = score
        elif score > self.best:
            self.best = score
            self.count = 0
        else:
            self.count += 1
        return self.count >= self.patient

def objective(config):

    if not MEASURE_TIME:
        config['kernel_size']+=1 # must be odd
        config['dropout'] = float(config['dropout'])
        config['pos_weight'] = float(config['pos_weight'])
        config['num_blocks'] = int(config['num_blocks'])
        config['initial_filter'] = int(config['initial_filter'])
        config['kernel_size'] = int(config['kernel_size'])
        config['scale_filter'] = float(config['scale_filter'])
        if DIST:
            dist_util.broadcast(config)
            print(f'Rank {dist_util.get_rank()} (master) got config {config}')
        config['exp_name'] = f'hyperopt_{config}'

    if MEASURE_TIME:
        config = {'dropout': 0.1535039249785174, 'initial_filter': 30, 'kernel_size': 5, 'num_blocks': 5, 'pos_weight': 1.0125812944977837, 'scale_filter': 1.1299710421481397} # Best

    earlyStopper = EarlyStopper(10)
    for pr_auc in train_dist.main(config,yeild_prauc = True):
        if earlyStopper(pr_auc):
            if DIST:
                dist_util.broadcast("stop")
                print(f'early stop')
            break
        else:
            if DIST:
                dist_util.broadcast("continue")

    return {
        'loss': - earlyStopper.best,
        'status': STATUS_OK,
    }

def main():
    if DIST:
        dist_util.setup_dist()
    if dist_util.is_master():
        trials = Trials()
        best = fmin(objective,
            space={
                'dropout':hp.uniform('dropout', 0, 0.5),
                'pos_weight':hp.loguniform('pos_weight', 0, 3),
                'num_blocks':hp.quniform('num_blocks', 3, 7, 1),
                'initial_filter':hp.quniform('initial_filter', 10, 30, 1),
                'kernel_size':hp.quniform('kernel_size', 4, 12, 2),
                'scale_filter':hp.loguniform('scale_filter',log(1),log(2)),
                },
            algo=tpe.suggest,
            max_evals=1000,
            trials=trials,
            show_progressbar=False,
            )
    else:
        while True:
            config = dist_util.broadcast()
            #print(f'Rank {dist_util.get_rank()} got config {config}')
            for _ in train_dist.main(config,yeild_prauc = True):
                if dist_util.broadcast() == "stop":
                    break

if __name__ == '__main__':
    main()

Stage 1. Hyperparameter tuning/optim_hyp.py


################################################################################
#
# This file provides a datamodule which joins the voxceleb and librispeech
# dataset in a multi-task learning setting.
#
# Author(s): Anonymous
################################################################################

from dataclasses import dataclass
from typing import List, Optional

from pytorch_lightning.utilities.types import EVAL_DATALOADERS, TRAIN_DATALOADERS

from src.data.loading_config import SpeechDataLoaderConfig, SpeakerDataLoaderConfig
from src.data.modules import (
    LibriSpeechDataModuleConfig,
    VoxCelebDataModuleConfig,
    LibriSpeechDataModule,
    VoxCelebDataModule,
)
from src.data.modules.abstract import (
    SpeakerLightningDataModule,
    SpeechLightningDataModule,
)
from src.data.pipeline.base import Preprocessor
from src.evaluation.speaker.speaker_recognition_evaluator import EvaluationPair
from src.evaluation.speech.tokenizer import BaseTokenizer

################################################################################
# implement the data module

@dataclass
class JointLibrispeechVoxcelebDataModuleConfig:
    ls_cfg: LibriSpeechDataModuleConfig
    vc_cfg: VoxCelebDataModuleConfig

    test_voxceleb: bool
    test_librispeech: bool

class JointLibrispeechVoxcelebDataModule(
    SpeakerLightningDataModule, SpeechLightningDataModule
):
    def __init__(
        self,
        cfg: JointLibrispeechVoxcelebDataModuleConfig,
        speaker_dl_cfg: SpeakerDataLoaderConfig,
        speaker_train_pipeline: List[Preprocessor],
        speaker_val_pipeline: List[Preprocessor],
        speaker_test_pipeline: List[Preprocessor],
        speech_dl_cfg: SpeechDataLoaderConfig,
        tokenizer: BaseTokenizer,
        speech_train_pipeline: List[Preprocessor],
        speech_val_pipeline: List[Preprocessor],
        speech_test_pipeline: List[Preprocessor],
    ):
        super().__init__()

        self.cfg = cfg

        self.ls_dm = LibriSpeechDataModule(
            cfg=self.cfg.ls_cfg,
            dl_cfg=speech_dl_cfg,
            tokenizer=tokenizer,
            train_pipeline=speech_train_pipeline,
            val_pipeline=speech_val_pipeline,
            test_pipeline=speech_test_pipeline,
        )
        self.vox_dm = VoxCelebDataModule(
            cfg=self.cfg.vc_cfg,
            dl_cfg=speaker_dl_cfg,
            train_pipeline=speaker_train_pipeline,
            val_pipeline=speaker_val_pipeline,
            test_pipeline=speaker_test_pipeline,
        )

    @property
    def num_speakers(self) -> int:
        return self.vox_dm.num_speakers

    @property
    def val_pairs(self) -> List[EvaluationPair]:
        return self.vox_dm.val_pairs

    @property
    def test_pairs(self) -> List[List[EvaluationPair]]:
        return self.vox_dm.test_pairs

    @property
    def test_names(self) -> List[str]:
        names = []

        if self.cfg.test_librispeech:
            names += ["clean", "other"]

        if self.cfg.test_voxceleb:
            names += self.vox_dm.test_names

        return names

    @property
    def vocabulary(self) -> List[str]:
        return self.ls_dm.vocabulary

    @property
    def tokenizer(self) -> BaseTokenizer:
        return self.ls_dm.tokenizer

    def prepare_data(self) -> None:
        self.ls_dm.prepare_data()
        self.vox_dm.prepare_data()

    def setup(self, stage: Optional[str] = None) -> None:
        self.ls_dm.setup()
        self.vox_dm.setup()

    def summary(self):
        self.ls_dm.summary()
        self.vox_dm.summary()

    def train_dataloader(self) -> TRAIN_DATALOADERS:
        vox_dm_loader = self.vox_dm.train_dataloader().repeat().__iter__()
        ls_dm_loader = self.ls_dm.train_dataloader().repeat().__iter__()

        while True:
            speaker_batch = next(vox_dm_loader)
            speech_batch = next(ls_dm_loader)

            yield {"speech": speech_batch, "speaker": speaker_batch}

    def val_dataloader(self) -> EVAL_DATALOADERS:
        return [] + self.ls_dm.val_dataloader() + [self.vox_dm.val_dataloader()]

    def test_dataloader(self) -> EVAL_DATALOADERS:
        loaders = []

        if self.cfg.test_librispeech:
            loaders += self.ls_dm.test_dataloader()

        if self.cfg.test_voxceleb:
            loaders += (
                [self.vox_dm.test_dataloader()]
                if len(self.vox_dm.additional_test_sets) == 0
                else self.vox_dm.test_dataloader()
            )

        return loaders

    def predict_dataloader(self) -> EVAL_DATALOADERS:
        raise NotImplemented()


# asf -> answer so far
def floodfill(maze, sr, sc, asf,n,m,visited):
    if(sr<0 or sr >= n or sc<0 or sc >= m or maze[sr][sc]==1 or visited[sr][sc]==True):
    #invalid case
        return

    if (sr == n-1 and sc == m-1):
        print(asf);
        return

    visited[sr][sc]=True

    #top
    floodfill(maze, sr-1, sc, asf+'t',n,m,visited)
    #left
    floodfill(maze, sr, sc-1, asf+'l',n,m,visited)
    #down
    floodfill(maze, sr+1, sc, asf+'d',n,m,visited)
    #right
    floodfill(maze, sr, sc+1, asf+'r',n,m,visited)

    visited[sr][sc]=False

def main():
    n, m = input().split()
    n = int(n)
    m = int(m)
    arr = []
    for i in range(n):
      row = list(map(int, input().split()))
      arr.append(row)

    visited = []

    for i in range(n):
      row = [False]*m
      visited.append(row)
    floodfill(arr, 0, 0, "",n,m,visited);

main()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This script rebases a file in Annovar format to a new reference genome using
UCSC liftOver.

@author: Christian Brueffer (ORCID: 0000-0002-3826-0989)

Home:    https://github.com/cbrueffer/misc_bioinf/
License: https://github.com/cbrueffer/misc_bioinf/LICENSE.md
"""

from __future__ import print_function

import pandas as pd

COL_CHROM = 0
COL_START = 1
COL_END = 2
COL_REF_ALLELE = 3
COL_VAR_ALLELE = 4

def exec_cmd(command, log=True):
    """Executes a given commandline and prints the command output to stdout."""
    import subprocess

    try:
        s = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             universal_newlines=True)
        while True:
            line = s.stdout.readline()
            if not line:
                break
            if log:
                print(line, end='')
    except:
        raise

def liftover_annovar(annovarfile, chainfile, workdir=None, liftover='liftOver',
                     sep='\t'):
    """Convert the genomic coordinates in an Annovar-compatible file to
    a new reference genome using UCSC liftOver.
    """
    if workdir is None:
        workdir = os.path.abspath(os.path.dirname(annovarfile))

    print("Using workdir:", workdir)

    liftover_infile = os.path.join(workdir, 'liftover_input.txt')
    liftover_lifted_file = os.path.join(workdir, 'liftover_lift_ok.txt')
    liftover_failed_file = os.path.join(workdir, 'liftover_lift_failed.txt')
    outfile_lifted = annovarfile + ".liftok"
    outfile_failed = annovarfile + ".liftfail"

    df_in = pd.read_csv(annovarfile, header=None, sep=sep)

    col_position = len(df_in.columns)

    # add a new column with genome positions
    df_in[col_position] = df_in.apply(lambda row: "chr%s:%i-%i" %
        (row[COL_CHROM], row[COL_START], row[COL_END]), axis=1)

    # write the liftOver input file containing only genome positions
    df_in[col_position].to_csv(liftover_infile, index=False, header=False)

    # build liftOver command line and execute
    liftover_cmd = [liftover, "-positions", liftover_infile, chainfile,
                    liftover_lifted_file, liftover_failed_file]

    try:
        exec_cmd(liftover_cmd)

        # read the successfully lifted locations
        with open(liftover_lifted_file) as infile:
            liftover_ok = infile.read().splitlines()
        # read the locations failed to lift over
        with open(liftover_failed_file) as infile:
            liftover_failed = infile.read().splitlines()
            # remove comments
            liftover_failed = [s for s in liftover_failed if not s.startswith("#")]
    except:
        raise

    # Throw out input locations that failed to lift.  For the rest we update
    # coordinates to the lifted ones.
    df_out_lifted = df_in[~df_in[col_position].isin(liftover_failed)]

    # Drop the position column, as the filtering it was needed for is done.
    df_out_lifted = df_out_lifted.drop(df_out_lifted.columns[[col_position]],
                                       axis=1)

    # remove chr prefix
    liftover_ok = [s.replace("chr", "") for s in liftover_ok]
    # split into a data frame with three columns (chr, start, end)
    liftover_ok_df = pd.DataFrame([s.replace("-", ":").split(":") for s in liftover_ok])

    # make sure we have the same number of rows
    assert(len(liftover_ok_df.index) == len(df_out_lifted.index))

    # update genomic location in the output frame and write it
    df_out_lifted.update(liftover_ok_df)

    df_out_lifted.to_csv(outfile_lifted, sep=sep, index=False, header=False)

    # write the input lines that failed to lift over
    df_out_failed = df_in[df_in[col_position].isin(liftover_failed)]
    df_out_failed.to_csv(outfile_failed, sep=sep, index=False, header=False)

    print()
    print('Locations in input file:  ', len(df_in.index))
    print('Locations lifted:         ', len(liftover_ok))
    print('Locations failed to lift: ', len(liftover_failed))
    print()
    print("Lifted annovar file (new coordinates):             ", outfile_lifted)
    print("File with failed to lift entries (old coordinates):", outfile_failed)

if __name__ == "__main__":
    import argparse
    import os
    import sys

    parser = argparse.ArgumentParser(description='Lift over a file in Annovar'
                                     ' format to a new reference genome.  Extra columns are preserved.')
    parser.add_argument("-d", "--debug", action='store_true',
                        help="enable debug mode")
    parser.add_argument("-v", "--version", action="version", version="%(prog)s 0.1")
    parser.add_argument("-c", "--chainfile", required=True,
                        help="liftOver chain file (available from UCSC)")
    parser.add_argument("-i", "--infile", required=True,
                        help="file in Annovar input format (chromosome, start,"
                        " end, ref_allele, var_allele, ...)")
    parser.add_argument("-l", "--liftover", default="liftOver",
                        help="path to the liftOver binary (default: system PATH)")
    parser.add_argument("-w", "--workdir", default=None,
                        help="work directory (default: directory containing INFILE)")
    args = parser.parse_args()

    for f in [args.infile, args.chainfile]:
        if not os.path.exists(f) or not os.path.isfile(f):
            print("Input file cannot be read: %s" % f, file=sys.stderr)
            sys.exit(1)

    # check whether the liftOver binary is available
    try:
        exec_cmd([args.liftover], log=False)
    except OSError as e:
        print("liftOver binary cannot be executed:", str(e), file=sys.stderr)
        sys.exit(1)

    try:
        liftover_annovar(args.infile, args.chainfile, workdir=args.workdir,
                         liftover=args.liftover)
    except KeyboardInterrupt:
        print("Program interrupted by user, exiting.")
    except Exception as e:
        if args.debug:
            import traceback
            print(traceback.format_exc())

        print('Error: %s' % str(e), file=sys.stderr)


import os
import pickle
import numpy as np
import pandas as pd
from tqdm import tqdm

from pymantra.namemapping import NameMapper

def get_metabolite_cluster(name, meta):
    matches = meta['Exact Match to Standard (* = isomer family)'] == name
    return meta.index[matches].tolist()

def generate_map(file: str, ids):
    if not os.path.exists(file):
        name_mapper = NameMapper()
        mapping = {
            str(idx): name_mapper.map_id(idx, "hmdb", "internal")
            if str(idx).startswith("HMDB") else None
            for idx in ids
        }
        pickle.dump(mapping, open(file, "wb"))
        return mapping
    return pickle.load(open(file, "rb"))

def apply_mapping(data: pd.DataFrame, mapping_tups: set):
    index = []
    mapped_data = np.zeros((len(mapping_tups), data.shape[1]))
    for i, (idx, int_idx) in enumerate(tqdm(mapping_tups)):
        rep_data = data.loc[idx, :]
        if rep_data.values.ndim > 1:
            mapped_data[i, :] = rep_data.sum()
        else:
            mapped_data[i, :] = rep_data
        index.append(int_idx)
    mapped_df = pd.DataFrame(
        mapped_data, index=index,
        columns=data.columns
    )
    return mapped_df.groupby(mapped_df.index).sum()


#coding:utf-8

# html元素定位方式
G_LOCAL = {
    "id":"By.ID",
    "name":"By.NAME",
    "xpath":"By.XPATH",
    "tag":"By.TAG",
    "link":"By.LINK_TEXT",
    "class":"By.CLASS",
    "css":"By.ID",
    "partiallink":"find_element_by_partial_link_text"
}

# assertion
G_LOCAL_ASSERT = {
    "assert_text":"By.ID",
    "name":"By.NAME",
    "xpath":"By.XPATH",
    "tag":"By.TAG",
    "link":"By.LINK_TEXT",
    "class":"By.CLASS",
    "css":"By.ID",
    "partiallink":"find_element_by_partial_link_text"
}

# 关键字定义
G_LOCAL_KEY = {
    'input':'send', # 键盘输入
    'input_Text':'send', # 键盘输入
    'get_text':'getText', # 获取文本
    'get_attr':'getAttr', # 获取熟悉
    'click':'click', # 鼠标单击
    'startbrowser':'startBrowser',# 启动浏览器
    'openurl':'get', # 打开网页
    'get':'get',     # 打开网页
    'set_page_timeout':'setPageTimeout', # 设置网页加载timeout
    'snapshot':'snapshot', # 截图
    'switch_to_frame':'switchToFrame', # 切换至特定frame
    'select_by_value':'selectByValue', # 通过选择框value选择下拉选项
    'select_by_text':'selectByText', # 通过选择框可视文本选择下拉选项
    'contain':'contain', # 包含验证
    'equal':'equal', # 相等验证
    'sleep':'waiting', # 延时，以秒为单位，参数可以传入整数、浮点数
    'close':'close', # 关闭窗口
    'quit':'quit',   # 退出浏览器
    'max':'maxWindow', # 最大化浏览器
    'switch_to_active_element':'switchToActiveEle', # 切换至活动的html 元素
    'alert_dismiss':'alertDismiss', # 取消alert窗口
    'alert_confirm':'alertConfirm', # 确定alert窗口
    'switch_to_alert':'switchToAlert',# 切换至alert窗口
    'max_window':'maxWindow', # 最大化浏览器
    'switch_to_default_frame':'switchToDefaultFrame', # 切换至默认的frame
    'clear':'clearCookies' # 清除所有cookies
}


# Напишите программу для преобразования списка в кортеж

import random
LIST_QTY = 10

l = [random.randint(0,9) for _ in range(0,LIST_QTY)]
print(f"\n{type(l)} : ", l)

t = tuple(l)
print(f"{type(t)}: \33[34m", t)


import numpy as np
import copy
from scipy.interpolate import interp1d

def interpol_and_norm(mvc_normed):
    mvc_normed_ = {}

    for key, sensors in mvc_normed.items():
        mvc_normed_[key] = [list(sensor) for sensor in sensors]  # Shallow copy of nested arrays
        for sensor, data in enumerate(mvc_normed_[key]):
            for num, sensor_data in enumerate(data):
                x = np.linspace(0, len(sensor_data)-1, len(sensor_data))
                cubic_fx = interp1d(x, sensor_data, kind='cubic')
                resampled_x = np.linspace(0, len(sensor_data)-1, 101)
                mvc_normed_[key][sensor][num] = cubic_fx(resampled_x)

    return mvc_normed_


import pandas as pd
import numpy as np
import time
inicio= time.time()

archivo=pd.ExcelFile("datos.xlsx")          # Archivo donde se leen los datos obtenidos
Prec_Simple=archivo.parse("Normalizado_S")  # Debe existir una hoja con datos normalizados de
Prec_Total=archivo.parse("Normalizado_T")   # precisión simple y otra con precisión total
Radio_S=archivo.parse("radio_S")            # Relaciones de proporcionalidad de la longitud relativa
Radio_T=archivo.parse("radio_T")            # entre ambas varillas, con precisión simple y total

##############################################################################################
# Funciones para poder comparar las filas de los datos del video vs los datos de la simulación

def xro(fila,caso,archi1,archi2):     # Caso 1 precisión simple, Caso 2 precisión total
        if caso==1:
            return archi1.loc[fila][1]
        elif caso==2:
            return archi2.loc[fila][1]

def yro(fila,caso,archi1,archi2):
        if caso==1:
            return archi1.loc[fila][2]
        elif caso==2:
            return archi2.loc[fila][2]

def xaz(fila,caso,archi1,archi2):
        if caso==1:
            return archi1.loc[fila][3]
        elif caso==2:
            return archi2.loc[fila][3]

def yaz(fila,caso,archi1,archi2):
        if caso==1:
            return archi1.loc[fila][4]
        elif caso==2:
            return archi2.loc[fila][4]

# Función para comparar arreglos de datos
# Archivo1=Simple, Archivo2=Total, Archivo3=Runge-Kutta
def comparar(archivo1,archivo2,archivo3,a,delta,porcentaje,caso):
    total=1
    acierto=1
    for i in np.arange(0,a,2):
        total+=1
        if abs((xaz(i,caso,archivo1,archivo2)-xaz(i,caso,archivo3,archivo3)))<delta:
            if abs((xro(i,caso,archivo1,archivo2)-xro(i,caso,archivo3,archivo3)))<delta:
                acierto+=1
    return (100*acierto)/total

# cálculo de la constante de proporcionalidad entre ambas varillas
def relativo(caso,archi1,archi2):
    return yro(0,caso,archi1,archi2)/xro(0,caso,archi1,archi2)

##############################################################################################
# Encontrar theta1 y theta2 iniciales en un rango determinado

theta_0=[]
theta1_0=[]
theta2_0=[]

for theta1 in np.arange(200,210,0.2):
    x1=54*np.sin(np.radians(theta1))
    xvaluar=xro(0,1,Prec_Simple,Prec_Total)*100
    porcent=xvaluar*0.01
    if  x1>xvaluar+porcent and x1<xvaluar-porcent:
        theta_0.append(theta1)
for theta11 in(theta_0):
    for theta2 in np.arange(15,25,0.2):
        x2=54*np.sin(np.radians(theta11))+45*np.sin(np.radians(theta2))
        x2valuar=xaz(0,1,Prec_Simple,Prec_Total)*100
        porcent2=xvaluar*0.01
        if  x2>x2valuar+porcent2 and x2<x2valuar-porcent2:
            theta2_0.append(theta2)
            theta1_0.append(theta11)

##############################################################################################
# Inicia código modificado de Ahmed Alkharusi, estas modificaciones fueron para
# adecuar el código según las necesidades del problema
"""
# =============================================================================
# Simulating the double pendulum using Runge–Kutta method (RK4)
# =============================================================================
Created on Fri Jul 17 2020
@author: Ahmed Alkharusi
"""
# =============================================================================
# Functions defn.
# =============================================================================

def angular_acc1(a1_arr,a2_arr):
    """Calculate the angular acceleration for the 1st pendulum
    Inputs-> a1_arr: np.array([Initial angle, Initial angular velocity]);
    a2_arr: np.array([Initial angle, Initial angular velocity]);"""
    num = -g *(2*m1+m2)*np.sin(a1_arr[0]) - m2*g*np.sin(a1_arr[0]-2*a2_arr[0])- 2* m2*np.sin(a1_arr[0]-a2_arr[0]) * (r2*pow(a2_arr[1],2)+r1*pow(a1_arr[1],2)*np.cos(a1_arr[0]-a2_arr[0]))
    den = r1*(2*m1+m2-m2 * np.cos(2*a1_arr[0]-2*a2_arr[0]))
    return num/den

def angular_acc2(a1_arr,a2_arr):
    """Calculate the angular acceleration for the 2nd pendulum
    Inputs-> a1_arr: np.array([Initial angle, Initial angular velocity]);
    a2_arr: np.array([Initial angle, Initial angular velocity]);"""
    temp = (2*np.sin(a1_arr[0]-a2_arr[0]))
    num = temp * (r1*pow(a1_arr[1],2)*(m1+m2)+g*(m1+m2)*np.cos(a1_arr[0])+r2*pow(a2_arr[1],2)*m2*np.cos(a1_arr[0]-a2_arr[0]))
    den = r2*(2*m1+m2-m2 * np.cos(2*a1_arr[0]-2*a2_arr[0]))
    return num/den

def deriv_a1(a1_arr,a2_arr,t):
    """
    Returns an array np.array([first derivative, 2nd derivative])
    Inputs-> a1_arr: np.array([Initial angle, Initial angular velocity]);
    a2_arr: np.array([Initial angle, Initial angular velocity]);
    t: the dependent variable;
    """
    return np.array([a1_arr[1],angular_acc1(a1_arr,a2_arr)])

def deriv_a2(a2_arr,a1_arr,t):
    return np.array([a2_arr[1],angular_acc2(a1_arr,a2_arr)])

def rk4(deriv,func_i,func_i2, x_i,h):
    """
    Implements the RK4 method
    Inputs-> deriv: a function that takes two arguments;
    func_i: the function to be calculated;
    func_i2: this is just passed as an argument for func_i (see above deriv_a1 and deriv_a2);
    x_i: the dependent variable of func_i;
    h: the step size;

    """
    k1 = deriv(func_i,func_i2,x_i)
    k2 = deriv(func_i+h/2,func_i2,h*k1/2)
    k3 = deriv(func_i+h/2,func_i2,h*k2/2)
    k4 = deriv(func_i+h,func_i2,h*k3)
    func = func_i + (1/6) * h * (k1 +2*k2+2*k3+k4)
    x = x_i + h
    return (x,func)

##############################################################################################

ite=0                       # Variable de conteo sobre las iteraciones realizadas
theta1_salida=[]            # Arreglos para almacenar variables necesarias
theta2_salida=[]
m1_salida=[]
r1_salida=[]
porcentaje_salida=[]

cant_p = 300                            # Cantidad de pasos a realizar
g = 981                                 # cm/s^2 gravedad
h = 0.008333333333                      # Tamaño de la iteración para el método RK4
relacion=relativo(1,Radio_S,Radio_T)    # Constante de proporcinalidad
for aa in range(0,len(theta1_0)):       # Variar para cada pareja de candidatos de los de ángulos iniciales
    for a in np.arange(5,15,0.5):       # Se varía el valor de ambas barillas
        for b in np.arange(0.1,6,0.2):  # y también la longitud de las masas

            # Condiciones iniciales
            m1 = b                      # masa del péndulo rojo
            m2 = m1                     # asumimos que es la misma masa
            r1 = a                      # longitud péndulo rojo
            r2 = r1*relacion            # longitud péndulo azul
            runit = np.sqrt(r1**2+r2**2)  # Se normaliza para poder trabajar independiente de la distancia
            x = y = []

            # Condiciones iniciales de los ángulos [ángulo, velocidad angular]
            a1_arr = np.array([np.radians(theta1_0[aa]),0])
            a2_arr = np.array([np.radians(theta2_0[aa]),0])
            t = 0                           # Tiempo inicial
            steps_no = cant_p
            time_arr = np.array([t])
            func_array1 = np.array([a1_arr])
            func_array2 = np.array([a2_arr])

            tiempo=[]                   # Arreglo para añadir tiempo al data frame
            tiempo.clear()
            tiempo.append(0)
            for i in range(steps_no):
                temp =a1_arr
                (t,a1_arr) = rk4(deriv_a1,a1_arr,a2_arr,t,h)
                t -=h
                (t,a2_arr) = rk4(deriv_a2,a2_arr,temp,t,h)
                time_arr2 = np.append(time_arr, t)
                func_array1 = np.vstack((func_array1,np.array([a1_arr])))
                func_array2 = np.vstack((func_array2,np.array([a2_arr])))
                tiempo.append(t)
                ite+=1                  # Aumenta la cantidad de iteraciones

            # You can plot the pendulum's position or angular speed/acceleration as a function of time
            [pendulum1_theta, pendulum1_angular_speed] = func_array1.transpose()
            [pendulum2_theta, pendulum2_angular_speed] = func_array2.transpose()

            pendulum1_x = np.divide(r1*np.sin(pendulum1_theta),runit)
            pendulum1_y = np.divide(- r1*np.cos(pendulum1_theta),runit)

            pendulum2_x = np.divide(r2*np.sin(pendulum2_theta),runit) + pendulum1_x
            pendulum2_y = pendulum1_y - np.divide(r2*np.cos(pendulum2_theta),runit)

            np.true_divide(pendulum1_x,runit)

            # Se crea un dataframe con los datos obtenidos en este caso
            dataf = pd.DataFrame({"t":tiempo,
                                  "xr":pendulum1_x,
                                  "yr":pendulum1_y,
                                  "xa":pendulum2_x,
                                  "ya":pendulum2_y,})

            # Se compara el resultado de la simulación contra los datos obtenidos
            porcentaje = comparar(Prec_Simple,Prec_Total,dataf,cant_p,0.05,10,1)
            if porcentaje > 50:         # Si se desea solamente resultados sobre cierto porcentaje
                theta1_salida.append(theta1_0[aa])  # Se almacenan las cond. iniciales que cumplan
                theta2_salida.append(theta2_0[aa])
                m1_salida.append(m1)
                r1_salida.append(r1)
                porcentaje_salida.append(porcentaje)

##############################################################################################
# Se crea un dataframe con los casos que superaron el límite anterior
cond_inic_salida=pd.DataFrame({"porcentaje":porcentaje_salida,
                               "theta1": theta1_salida,
                               "theta2": theta2_salida,
                               "m1": m1_salida,
                               "r1": r1_salida})

# Para evitar realizar operaciones en excel, se ordenan los resultados de mayor a menor
cond_inic_salida=cond_inic_salida.sort_values(by=['porcentaje'])
cond_inic_salida=cond_inic_salida[::-1]
k2="condiciones.xlsx"   # El archivo de excel con los resultados se llama "condiciones"
writer2=pd.ExcelWriter(k2)
cond_inic_salida.to_excel(writer2,index=False)
writer2.save()
##############################################################################################
# Se muestran el tiempo de ejecución y la cantidad de iteraciones
print("iteraciones=",ite)
fin = time.time()
print("tiempo=",fin-inicio,"s")