import logging
import moment
from exporter import config
from exporter.utils import export_writer
from exporter.sensortower import utils

logger = logging.getLogger(__name__)

REVIEW_ENDPOINT = "/{}/review/get_reviews"

REVIEWS_LIMIT = 200

def export_reviews(exporter, export_from, export_to):
    executor = ReviewExecutor(exporter)
    executor.execute(export_from, export_to)

class ReviewExecutor(utils.Executor):
    kpi = "reviews"
    key_template = "{}_star_{}"

    def get_proccessed_data(self, exported_data):
        logger.info(f"Processing reviews data")
        proccessed_data = {}
        for data in exported_data:
            date = moment.date(data["date"]).format(config.MOMENT_DATE_FORMAT)
            platform = config.SENSORTOWER_APPS[str(data["app_id"])]
            country = data["country"].lower()
            rating = data["rating"]
            record = proccessed_data.setdefault(
                (date, platform), self.get_default_country_values()
            )
            record.update(
                    self.update_rate_counter(country, rating, record),
            )
            record.update(    {
                    f"{country}_average": self.get_average(country, rating, record),
                })

        return proccessed_data

    def get_export_field_list(self, countries):
        return [
            "date",
            *[f"{country}_average" for country in countries],
            *[
                f"{country}_star_{index}"
                for index in range(1, 6)
                for country in countries
            ],
        ]

    def get_average(self, country, rating, record):
        average = 0
        rating_count = sum([record[self.key_template.format(country, index)] for index in range(1,6)])
        for index in range(1, 6):
            average += record[self.key_template.format(country, index)] * index / rating_count
        return round(average, 2)

    def update_rate_counter(self, country, rating, record):
        key = self.key_template.format(country, rating)
        return {key: (record[key] + 1)}

    def get_default_country_values(self):
        return {
            **{f"{country}_average": None for country in config.COUNTRIES},
            **{
                f"{country}_star_{index}": 0
                for index in range(1, 6)
                for country in config.COUNTRIES
            },
        }

    def get_export_data(self, params_list, exporter):
        exported_data = []
        page_count = None
        for platform, params in params_list:
            page = 1
            while page_count is None or page <= page_count:
                params = {**params, "page": page}
                logger.info(
                    f"Getting data from review endpoint for params: {str(params)}"
                )
                data = exporter.request_data(REVIEW_ENDPOINT.format(platform), params)
                page_count = data["page_count"]
                page += 1
                exported_data.extend(data["feedback"])
        return exported_data

    def get_params(self, export_from, export_to, app_id, platform, country):
        return (
            platform,
            {
                "country": country,
                "app_id": app_id,
                "start_date": export_from.strftime(config.DATE_FORMAT),
                "end_date": export_to.strftime(config.DATE_FORMAT),
                "auth_token": config.SENSORTOWER_AUTH_TOKEN,
                "limit": REVIEWS_LIMIT,
            },
        )


import numpy as np
import os

from sklearn.model_selection import cross_validate
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.utils import shuffle as apply_shuffle

from suprb import SupRB
from suprb import rule
from suprb.optimizer.solution import ga
from suprb.optimizer.rule import es
from suprb.utils import check_random_state
from suprb.optimizer.rule.mutation import HalfnormIncrease
import suprb.json as json

def load_higdon_gramacy_lee(n_samples=1000, noise=0., shuffle=True, random_state=None):
    random_state_ = check_random_state(random_state)
    X = np.linspace(0, 20, num=n_samples)
    y = np.zeros(n_samples)
    y[X < 10] = np.sin(np.pi * X[X < 10] / 5) + 0.2 * np.cos(4 * np.pi * X[X < 10] / 5)
    y[X >= 10] = X[X >= 10] / 10 - 1
    y += random_state_.normal(scale=noise, size=n_samples)
    X = X.reshape((-1, 1))
    if shuffle:
        X, y = apply_shuffle(X, y, random_state=random_state)
    return X, y

def setup():
    random_state = 42

    X, y = load_higdon_gramacy_lee(noise=0.1, random_state=random_state)
    X = MinMaxScaler(feature_range=(-1, 1)).fit_transform(X)
    y = StandardScaler().fit_transform(y.reshape((-1, 1))).reshape((-1,))

    model = SupRB(
        rule_generation=es.ES1xLambda(
            n_iter=2,
            operator='&',
            init=rule.initialization.MeanInit(fitness=rule.fitness.VolumeWu(alpha=0.05)),
            mutation=HalfnormIncrease(sigma=0.1)
        ),
        solution_composition=ga.GeneticAlgorithm(
            n_iter=1,
            crossover=ga.crossover.Uniform(),
            selection=ga.selection.Tournament(),
        ),
        n_iter=1,
        n_rules=5,
        verbose=1,
        random_state=random_state,
    )

    return model, X, y

class TestJsonIO:
    def test_save_load_config(self):
        model, X, y = setup()

        scores = cross_validate(model, X, y, cv=4, n_jobs=1, verbose=1, scoring=['r2', 'neg_mean_squared_error'],
                                return_estimator=True)

        model = scores["estimator"][0]
        json_io_params = model.get_params()

        original_config = json._save_config(model)
        model = json._load_config(original_config["config"])
        model_params = model.get_params()

        for key in json_io_params:
            if not key.startswith("logger"):
                assert(type(json_io_params[key]) == type(model_params[key]))

    def test_smoke_test(self):
        model, X, y = setup()

        X_predict = np.linspace(X.min(), X.max(), 500).reshape((-1, 1))

        scores = cross_validate(model, X, y, cv=4, n_jobs=1, verbose=1, scoring=['r2', 'neg_mean_squared_error'],
                                return_estimator=True)

        model = scores["estimator"][0]
        original_prediction = model.predict(X_predict)

        json.dump(model, "save_state.json")
        model = json.load("save_state.json")
        loaded_prediction = model.predict(X_predict)

        assert((original_prediction == loaded_prediction).all())
        os.remove("save_state.json")


from flask import Flask
from flask import render_template
from flask import request

from translator import process_translation

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        msg = request.form['to_translate']
        translation = process_translation(msg=msg)
    else:
        translation = ''
    return render_template('index.html', translation=translation)

if __name__ == '__main__':
    app.run()


class Solution:
    """my sol under hint - first attempt, time k * (m + n) * (m + n)"""
    # def maxNumber(self, nums1: List[int], nums2: List[int], k: int) -> List[int]:
    #
    #     m, n = len(nums1), len(nums2)
    #     ans = None
    #
    #     # iterate k
    #     for i in range(k + 1):
    #         len1, len2 = i, k - i
    #         if len1 <= m and len2 <= n:
    #
    #             # time m + n
    #             l1 = self.largestKdigits(nums1, len1)
    #             l2 = self.largestKdigits(nums2, len2)
    #
    #             # average time m + n, worst case (m + n) ^ 2
    #             cur_ans = self.mergeTwoList(l1, l2)
    #
    #             if not ans:
    #                 ans = cur_ans
    #             else:
    #                 if self.compareTwoEqualLenList(cur_ans, ans):
    #                     ans = cur_ans
    #
    #     return ans
    #
    # @staticmethod
    # def mergeTwoList(l1, l2):
    #
    #     return [max(l1, l2).pop(0) for _ in l1 + l2]
    #
    # @staticmethod
    # def compareTwoEqualLenList(l1, l2):
    #
    #     for i in range(len(l1)):
    #         if l1[i] > l2[i]:
    #             return True
    #         elif l1[i] < l2[i]:
    #             return False
    #
    #     return True
    #
    # @staticmethod
    # def largestKdigits(nums, k):
    #
    #     remove_num = len(nums) - k
    #     mono_q = []
    #
    #     for i in nums:
    #         while remove_num > 0 and mono_q and mono_q[-1] < i:
    #             mono_q.pop()
    #             remove_num -= 1
    #         mono_q.append(i)
    #
    #     mono_q = mono_q[:-remove_num] if remove_num > 0 else mono_q
    #
    #     return mono_q
    pass

class Solution:
    """my modified sol - based on online sol, time k * (m + n) * (m + n)"""
    def maxNumber(self, nums1: List[int], nums2: List[int], k: int) -> List[int]:

        return max(self.mergeTwoList(self.largestKdigits(nums1, i),
                                     self.largestKdigits(nums2, k - i))
                   for i in range(k + 1)
                   if i <= len(nums1) and k - i <= len(nums2))

    @staticmethod
    def mergeTwoList(l1, l2):

        return [max(l1, l2).pop(0) for _ in l1 + l2]

    @staticmethod
    def largestKdigits(nums, k):

        remove_num = len(nums) - k
        mono_q = []

        for i in nums:
            while remove_num > 0 and mono_q and mono_q[-1] < i:
                mono_q.pop()
                remove_num -= 1
            mono_q.append(i)

        mono_q = mono_q[:-remove_num] if remove_num > 0 else mono_q

        return mono_q

Problems/src/321. Create Maximum Number.py


import logging
import re
from dataclasses import dataclass
from typing import List

import unidecode as unidecode

logger = logging.getLogger(__name__)

@dataclass
class Book:
    """
    A Book class that includes a title, author, and ISBN number.

    :cvar id: A unique id for a book.
    :cvar title: A title for a book.
    :cvar author: An author for a book.
    :cvar isbn_no: An ISBN number for a book.
    """

    id: int
    title: str
    author: str
    isbn_no: str
    is_available: bool = True

@dataclass
class Members:
    """
    A Members class that includes a list of books borrowed.

    :cvar id: A unique id for a member.
    :cvar name: A name for a member.
    :cvar member_id: A unique id for a member.
    :cvar books_borrowed: A list of books borrowed.
    """

    id: int
    name: str
    phone: str
    books_borrowed: List[Book]

    def borrow_book(self, book: Book) -> None:
        """
        Borrow a book.
        """
        book.is_available = False
        self.books_borrowed.append(book)

    def return_book(self, book: Book) -> None:
        """
        Return a book.
        """
        book.is_available = True
        self.books_borrowed.remove(book)

def _clean_input(input_str: str) -> str:
    """
    Clean input string.
    """
    return unidecode.unidecode(re.sub("[.,();]:", "", input_str.lower().rstrip()))

class Library:
    """
    A Library class that includes a list of books and a list of members.
    """

    _books: List[Book]
    _members: List[Members]

    def __init__(self) -> None:
        """
        Initialize a library with an empty list of books and an empty list of members.

        :cvar books: A list of books.
        :cvar members: A list of members.
        """
        self._books: List[Book] = []
        self._members: List[Members] = []

    def add_book(self, book: Book) -> None:
        """
        Add a book to the library.
        """
        self._books.append(book)

    def remove_book(self, book: Book) -> None:
        """
        Remove a book from the library.
        """
        self._books.remove(book)

    def add_member(self, member: Members) -> None:
        """
        Add a member to the library.
        """
        self._members.append(member)

    def remove_member(self, member: Members) -> None:
        """
        Remove a member from the library.
        """
        self._members.remove(member)

    def lend_book(self, member: Members, book: Book) -> None:
        """
        Lend a book to a member.
        """
        if not self._is_valid_member(member.id):
            raise Exception("Member not found.")

        if not self._is_book_available(book):
            raise Exception("Book not available.")

        member.borrow_book(book)

    def return_book(self, member: Members, book: Book) -> None:
        """
        Return a book to the library.
        """
        if not self._is_valid_member(member.id):
            raise Exception("Member not found.")

        if self._is_book_available(book):
            raise Exception("Book not borrowed.")

        member.return_book(book)

    def _is_book_available(self, book: Book) -> bool:
        """
        Check if a book is available in the library.
        """
        if book.is_available:
            return True

        return False

    def _find_member_by_id(self, member_id: int) -> Exception:
        """
        Find a member by id.
        """
        for member in self._members:
            if member_id == member.id:
                return member
        return Exception("Member not found.")

    def _is_valid_member(self, member_id: int) -> bool:
        """
        Check if a member is valid.
        """
        for member in self._members:
            if member_id == member.id:
                return True
            continue
        return False

    def search_book(self, book_info: dict) -> Book:
        """
        Search a book by title.

        :param book_info: A dictionary of book information.{id: int, title: str, author: str, isbn_no: str}
        """
        try:
            # TODO: Add more search options. now checking only one field that is available in book_info by priority.
            for book in self._books:
                if book_info["id"] == book.id:
                    return book
                elif book_info["isbn_no"] == book.isbn_no:
                    return book
                # TODO: Add more search options.
                elif _clean_input(book_info["author"]) in _clean_input(book.author):
                    return book
                # TODO: Add more search options.
                elif _clean_input(book_info["title"]) in _clean_input(book.title):
                    return book

        except Exception as e:
            logger.error(e, "Please try again with different input.")

        return logger.error(e, "Book not found. Please try again with different input.")

    def search_member(self, member_info: dict) -> Members:
        """
        Search a member by name or id.

        :param member_info:
        :return:
        """
        try:
            for member in self._members:
                if member_info["id"] == member.id:
                    return member
                elif _clean_input(member_info["name"]) in _clean_input(member.name):
                    return member

        except Exception as e:
            logger.error(e, "Please try again with different input.")

        return logger.error(e, "Member info is not found. Please try again with different input.")

def print_menu() -> None:
    """
    Print the menu.
    """
    print(
        """
Welcome to the Library Management System.

Please select an option:
1. Add a book
2. Remove a book
3. Add a member
4. Remove a member
5. Lend a book
6. Return a book
7. Exit
    """
    )

class LibraryManager:
    """
    A Library Management System that includes Library, Book, and Members.
    """

    def __init__(self) -> None:
        """
        Initialize a library management system.
        """
        self.library = Library()
        self.command_dict = {
            "1": "Add a book",
            "2": "Remove a book",
            "3": "Add a member",
            "4": "Remove a member",
            "5": "Lend a book",
            "6": "Return a book",
            "7": "Search a book",
            "8": "Search a member",
        }

    def add_book(self) -> None:
        book_info = self._get_book_info()
        book = Book(**book_info)
        self.library.add_book(book)
        print("a book has beend added. Thank you.")
        print(book)

    def get_command(self) -> None:
        """
        Get a command from the user.
        """
        try:
            while True:
                print_menu()
                command = input("Enter a command: ")
                if command == "1":
                    self.add_book()
                elif command == "2":
                    book_info = self._get_book_info(command)
                    book = self.library.search_book(book_info)
                    self.library.remove_book(book)
                elif command == "3":
                    member_info = self._get_member_info(command)
                    member_info["books_borrowed"] = []
                    member = Members(**member_info)
                    self.library.add_member(member)
                elif command == "4":
                    member_info = self._get_member_info(command)
                    member = self.library.search_member(member_info)
                    self.library.remove_member(member)
                elif command == "5":
                    member_info = self._get_member_info(command)
                    member = self.library.search_member(member_info)
                    book_info = self._get_book_info(command)
                    book = self.library.search_book(book_info)
                    self.library.lend_book(member, book)
                elif command == "6":
                    member_info = self._get_member_info(command)
                    member = self.library.search_member(member_info)
                    book_info = self._get_book_info(command)
                    book = self.library.search_book(book_info)
                    self.library.return_book(member, book)
                elif command == "7":
                    break
                else:
                    print("Invalid command.")
        except Exception as e:
            logger.error(e)

    def interface(self) -> None:
        """
        An interface for the Library Management System.
        """
        self.get_command()

    def _get_book_info(self) -> dict:
        """
        Get book information from the user.
        """

        print(
            """In order to do so,  the book info is necessary. Please enter book information:"""
        )

        try:
            book_info = {
                "id": int(input("Enter book id: ")),
                "title": input("Enter book title: "),
                "author": input("Enter book author: "),
                "isbn_no": input("Enter book isbn_no: ")
            }
            return book_info

        except Exception as e:
            logger.error(e)
            print("""Book information is invalid. Please try again.""")

    def _get_member_info(self, command_number: int) -> dict:
        """
        Get member information from the user.
        """
        print(
            f"""In order to do {self.command_dict[command_number]},
                the book info is necessary. Please enter book information:"""
        )

        try:
            member_info = {
                "id": int(input("Enter member id: ")),
                "name": input("Enter member name: "),
                "phone": input("Enter member phone: ")
            }

            return member_info

        except Exception as e:
            logger.error(e)
            print("""Member information is invalid. Please try again.""")

def main() -> None:
    """
    A main function of a Library Management System that includes Library, Book, and Members.
    """

    logger.info("Starting library management system...")
    library_manager = LibraryManager()
    library_manager.interface()

if __name__ == "__main__":
    main()


import glob
from dataclasses import dataclass
import random
import os.path
from os import path
import pickle

@dataclass
class PartOfSpeech:
    ordered: dict
    unordered: set

lang = dict()
lang["contractions"] = dict()
lang["adjectives"] = None
lang["adverbs"] = None
lang["nouns"] = None
lang["verbs"] = None
lang["pronouns"] = None

seen = dict()
seen["contractions"] = dict()
seen["adjectives"] = PartOfSpeech({1:list(), 2:list(), 3:list(), 4:list()}, list())
seen["adverbs"] = PartOfSpeech({1:list(), 2:list(), 3:list(), 4:list()}, list())
seen["nouns"] = PartOfSpeech({1:list(), 2:list(), 3:list(), 4:list()}, list())
seen["verbs"] = PartOfSpeech({1:list(), 2:list(), 3:list(), 4:list()}, list())
seen["pronouns"] = PartOfSpeech({1:list(), 2:list(), 3:list(), 4:list()}, list())
seen["unknown"] = list()

def writeDictToFile(filename):
    with open(filename, 'wb') as outfile:
        pickle.dump(seen, outfile)

def readDictFromFile(filename):
    global word_bank
    with open(filename, 'rb') as infile:
        seen = pickle.load(infile)

def loadPartOfSpeech(name):
    ordered_list = {1:list(), 2:list(), 3:list(), 4:list()}
    unordered_list = list()
    files_to_read = glob.glob("partsOfSpeech/" + name + "/*")
    for file_name in files_to_read:
        with open(file_name) as file:
            for line in file:
                if(len(file_name) > 8):
                    if(file_name.split("/")[-1][1:9] == "syllable"):
                        ordered_list[int(file_name.split("/")[-1][0])].append(line.strip())
                    else:
                        unordered_list.append(line.strip())
    word_list = PartOfSpeech(ordered_list, unordered_list)
    return word_list

def getContractions():
    contlist = dict()
    with open("partsOfSpeech/contractions.txt") as file:
        for line in file:
            parts = line.split(" = ")
            contlist[parts[0]] = line[len(parts[0])+2:].strip()
    return contlist

def checkInPartOfSpeech(word, partofspeech):
    for i in range(1,5):
        if word in partofspeech.ordered[i]:
            return i
    if word in partofspeech.unordered:
        return 0
    return -1

def getEnding(word):
    ###THIS COULD BE BETTER
    #THERE ARE ACTUAL RULES FOR THIS
    if(word[-1:] == "'s"):
        return "'s"
    if(word[-3:] == "ing"):
        return "ing"
    if(word[-2:] == "ed"):
        return "ed"
    return "none"

def megaStrip(word):
    return word.replace(",","").replace("!","").replace("?","").replace("\"","").replace("-","")

def getRoot(word):
    ###THIS COULD BE BETTER
    #THERE ARE ACTUAL RULES FOR THIS
    ending = getEnding(word)
    if(ending == "none"):
        return megaStrip(word)
    else:
        return megaStrip(word)[:-len(ending)]

def getWordType(word):
    word = megaStrip(word)
    ending = getEnding(word)
    for part in ["pronouns", "adjectives", "adverbs", "verbs", "nouns"]:
        if(isinstance(lang[part],PartOfSpeech)):
            check = checkInPartOfSpeech(getRoot(word), lang[part])
            if check != -1:
                return part + "." + str(check) + "." + ending
    return "unknown"

def getStrippedSong(song_file):
    strippedLyrics = ""
    with open(song_file) as file:
        for line in file:
            for word in line.split(" "):
                cleaned_word = word.lower().strip()
                if(cleaned_word in lang["contractions"]):
                    cleaned_word = lang["contractions"][cleaned_word]
                #with the contractions sometimes one word becomes two
                for final_word in cleaned_word.split(" "):
                    word_type = getWordType(final_word)
                    if(word_type.split(".")[0] == "unknown"):
                        #print(final_word)
                        seen["unknown"].append(final_word)
                        strippedLyrics += "unknown." + final_word + " "
                    else:
                        type_parts = word_type.split(".")
                        syll_count = int(type_parts[1])
                        if(syll_count > 0):
                            seen[type_parts[0]].ordered[syll_count].append(getRoot(final_word))
                        else:
                            seen[type_parts[0]].unordered.append(getRoot(final_word))
                        strippedLyrics += word_type + " "
            strippedLyrics += "\n"
    return (strippedLyrics)

def getNewSong(strippedSong):
    newLyrics = ""
    written_lines = dict()
    for line in strippedSong.split("\n"):
        newSentance = ""
        if line.strip() in written_lines:
            newSentance = written_lines[line.strip()]
        else:
            for word in line.split(" "):
                cleaned_word = word.strip()
                info = cleaned_word.split(".")
                word_type = info[0]
                if(len(info) >= 2):
                    if(word_type == "unknown"):
                        newSentance += info[1] + " "
                    else:
                        syll_count = int(info[1])
                        ending = ""
                        if(info[2] != "none"):
                            ending = info[2]
                        new_word = ""
                        if(syll_count == 0):
                            new_word = random.choice(tuple(seen[word_type].unordered)) + ending
                        else:
                            new_word = random.choice(tuple(seen[word_type].ordered[syll_count]))
                            if(new_word[-1] == "e"):
                                if(ending == "ing" or ending == "ed"):
                                    new_word = new_word[:-1]
                            new_word += ending
                        newSentance += new_word + " "
        written_lines[line.strip()] = newSentance
        newLyrics += newSentance + "\n"
    return newLyrics

print("Learning to English.")
print("Loading Pronouns")
lang["pronouns"] = loadPartOfSpeech("pronouns")
print("Loading Adverbs")
lang["adverbs"] = loadPartOfSpeech("adverbs")
print("Loading Adjectives")
lang["adjectives"] = loadPartOfSpeech("adjectives")
print("Loading Verbs")
lang["verbs"] = loadPartOfSpeech("verbs")
print("Loading Nouns")
lang["nouns"] = loadPartOfSpeech("nouns")
print("Loading Contractions")
lang["contractions"] = getContractions()
print("done.")
print()
songs_to_learn = glob.glob("lyrics/*")
if(path.exists("word_bank.gar")):
    print("found previous music")
    readDictFromFile("word_bank.gar")
else:
    print("listening to new music.")
    for song in songs_to_learn:
        getStrippedSong(song)
print("done.")
print()
song = random.choice(songs_to_learn)
#song = "lyrics/cap’n-jazz.bluegrassish"
print("Writing new song based on " + song)
print()
print(getNewSong(getStrippedSong(song)))

print(seen["pronouns"])
##todo - verbs and nouns have different es rules


#!/usr/bin/env python
# coding: utf-8
import MeCab
import csv
import sys

def StringCSV2WordCSV( input_filename, output_filename ):

    # -d はシステム辞書を使うという意味

    mcbTagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')

    fo = open(output_filename, 'w')

    for line in csv.reader(open(input_filename, 'r')):
        if len(line) == 0:
            continue
        line = line[0]
        print('Input String:', line)
        fo.write(mcbTagger.parse(line))

    fo.close()

if __name__ == '__main__':
    param = sys.argv

    if len(param) != 3:
        print( 'usage : ', param[0], ' in_strCSVFilename out_strCSVFilename')
    else:
        StringCSV2WordCSV(param[1], param[2])


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp as integrate
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable

#Making a nice movie of beads in a landscape
from moviepy.editor import VideoClip
from moviepy.video.io.bindings import mplfig_to_npimage

pi = np.pi

size=15
params = {'legend.fontsize': 'large',
          'axes.labelsize': size,
          'axes.titlesize': size,
          'xtick.labelsize': size,
          'ytick.labelsize': size,
          'axes.titlepad': 25,
          'lines.linewidth': 3,
          'figure.dpi': 100}
plt.rcParams.update(params)

#General Utilities to present kymos

def plot_kymo(result, title=None, ax=None, colorbar=False, vmin=None, vmax=None, cb_ticks=None, interpolation=None):
    show = False
    if ax is None:
        fig, ax = plt.subplots(1,1, figsize = (5,5))
        show = True
    kymo = ax.imshow(result, origin = 'lower', aspect='auto', vmin=vmin, vmax=vmax, interpolation=interpolation)
    if colorbar:
        ax_divider = make_axes_locatable(ax)
        cax = ax_divider.append_axes("right", size="7%", pad="5%")
        extend='neither'
        if vmin is not None and vmax is not None and cb_ticks is not None:
            if max(cb_ticks) > vmax and min(cb_ticks) < vmin:
                extend='both'
            elif max(cb_ticks) > vmax:
                extend='max'
            elif min(cb_ticks) < vmin:
                extend='min'
        cb = plt.colorbar(kymo, cax=cax, extend=extend, ticks=cb_ticks)
        cb.outline.set_visible(False)
    ax.axes.get_xaxis().set_ticks([])
    ax.axes.get_yaxis().set_ticks([])
    ax.axes.spines['left'].set_visible(False)

    ax.axes.spines['right'].set_visible(False)
    ax.axes.spines['top'].set_visible(False)
    ax.axes.spines['bottom'].set_visible(False)

    ax.set_xlabel('Time')
    ax.set_ylabel('Space')
    ax.set_title(title)

    if show:
        plt.show()

#1 D diffusion operator
def diffusion(vec, h=1., boundary_derivs=(0., 0.)):
    dif = np.zeros(len(vec))
    dif[0] =  vec[1] - 2*vec[0] + (vec[0] - boundary_derivs[0]*h)
    dif[-1] = (vec[-1] + boundary_derivs[1]*h) - 2.*vec[-1] + vec[-2]
    dif[1:-1] = (np.roll(vec, -1) - 2.*vec + np.roll(vec, +1))[1:-1]
    return dif/h**2

#Functions for flow plots and to show excitable dynamics

def phase_plot(L_1,L_2,npoints,some_derivs,*args):
    q = np.linspace(L_1, L_2, npoints)
    xx, yy = np.meshgrid(q,q, indexing = 'xy')
    dZ=some_derivs(1,np.array([xx,yy]), *args)
    vec = np.reshape(dZ, (2,npoints,npoints))
    fig, ax = plt.subplots(1, figsize = (10,10))
    dX=vec[0,:]
    dY=vec[1,:]
    ax.streamplot(xx, yy, dX, dY, density = 3, color = 'gray', linewidth = 0.5)
    ax.contour(xx, yy, dX, (0,), colors=('royalblue',), linewidths=5, alpha=.7) # plots x-nullcline
    ax.contour(xx, yy, dY, (0,), colors=('green',), linewidths=5, alpha=.7) # y-nullcline
    return fig,ax

def plot_excitable(some_derivs,init_vec,L,*args):

    t = np.linspace(0., 200., 5000)
    ap_positions = np.linspace(0.0, 1.0, 1)
    names_plot = ['A', 'S']
    colors_plot = ['tab:red', 'tab:blue']
    results_osc = integrate(some_derivs, (np.min(t), np.max(t)), init_vec, method='RK45', t_eval=t, args=args, rtol=1e-5).y
    plt.figure(figsize = (8,4))
    for i in range(2):
        plt.plot(t/100, results_osc[i], c = colors_plot[i], label = names_plot[i])
    plt.legend()
    plt.xlabel('Time [a.u.]')
    plt.ylabel('Oscillation [a.u.]')
    plt.show()
    npoints=50
    fig,ax=phase_plot(-L,L,npoints,some_derivs,*args)
    ax.plot(results_osc[0],results_osc[1], color='r')
    return fig,ax


"""
This module provides the implementation of a zero-padding function
compatible with the alternative definition of the FFT.
"""

import numpy as np

def pad(x: np.ndarray, new_shape: tuple) -> np.ndarray:
    """Symmetrical zero-padding of the input.

    Parameters
    ----------
    x : np.ndarray
        Input array, n-dimensional.
    new_shape : tuple[int]
        Output shape, n-dimensional int tuple.

    Returns
    -------
    out : np.ndarray
        Zero-padded input.
    """

    res = np.copy(x)
    n_dim = res.ndim

    assert n_dim == len(new_shape)

    pad_width = [(0, 0)] * n_dim

    for i, (n, new_n) in enumerate(zip(x.shape, new_shape)):
        q_n, r_n = divmod(n, 2)
        q_new_n, r_new_n = divmod(new_n, 2)

        if r_n == r_new_n:
            pad_i = (q_new_n - q_n, q_new_n - q_n)
        else:
            pad_i = (q_new_n - q_n, q_new_n - q_n + r_new_n - r_n)

        pad_width[i] = pad_i

    res = np.pad(res, pad_width)

    return res

def adj_pad(x: np.ndarray, original_shape: tuple) -> np.ndarray:
    """Adjoint of `pad`.

    Parameters
    ----------
    x : np.ndarray
        Input array, n-dimensional.
    original_shape : tuple[int]
        Output shape, n-dimensional int tuple.

    Returns
    -------
    out : np.ndarray
        Adjoint of `pad` applied to `x`.
    """
    res = np.copy(x)
    n_dim = res.ndim

    assert n_dim == len(original_shape)

    for i, (n, original_n) in enumerate(zip(x.shape, original_shape)):
        q_n, r_n = divmod(n, 2)
        q_original_n, r_original_n = divmod(original_n, 2)

        if r_n == r_original_n:
            # The padding was: (q_n - q_original_n, q_n - q_original_n)
            indices = np.arange(q_n - q_original_n, n - (q_n - q_original_n))
        else:
            # The padding was: (q_n - q_original_n, q_n - q_original_n + r_n - r_original_n)
            indices = np.arange(
                q_n - q_original_n, n - (q_n - q_original_n + r_n - r_original_n)
            )

        res = np.take(res, indices, axis=i)

    return res


import turtle as tl

"""
Построение изображения пальмы при помощи рекурсии (фракталов)
"""

def trunk_left(size, tilt):
    """
    Построение левого контура ствола
    """
    if size > 40:
        tl.left(95)
        tl.forward(size)
        tl.right(150)
        tl.forward(size / 5)
        tl.left(55 + tilt)
        trunk_left(size - 5, tilt + 2) # Рекурсия

def trunk_right(size, tilt):
    """
    Построение правого контура ствола
    """
    if size > 40:
        tl.left(85)
        tl.forward(size)
        tl.left(150)
        tl.forward(size / 5)
        tl.right(235 - tilt)
        trunk_right(size - 5, tilt + 2) # Рекурсия

def trunk(size):
    """
    Построение всего ствола
    """
    x0, y0 = tl.xcor(), tl.ycor()
    tl.color('black', 'brown')
    tl.begin_fill()
    trunk_left(size, 0)
    x1, y1 = tl.xcor(), tl.ycor()
    tl.penup()
    tl.goto(x0, y0)
    tl.pendown()
    tl.goto(x0 + 50, y0)
    tl.setheading(0)
    trunk_right(size, 0)
    tl.goto(x1, y1)
    tl.end_fill()

def coconuts(size):
    """
    Построение кокосов
    """
    coco_size = size / 3
    if coco_size > 19:
        tl.color('black', 'black')
        tl.begin_fill()
        tl.circle(coco_size)
        tl.penup()
        tl.right(120)
        tl.forward(11)
        tl.pendown()
        tl.end_fill()
        coconuts(size - 10) # Рекурсия

def leaf_up(size, angle, times):
    """
    Построение верхней части листа
    """
    if times > 0:
        tl.left(angle)
        tl.forward(size - 20)
        tl.right(angle + 2.5)
        tl.forward(size - 35)
        tl.right(5)
        leaf_up(size - 1, angle, times - 1) # Рекурсия

def leaf_down(size, angle, times):
    """
    Построение нижней части листа
    """
    if times > 0:
        tl.left(180 - angle)
        tl.forward(size - 20)
        tl.left(angle + 2.5)
        tl.forward(size - 35)
        tl.right(175)
        leaf_down(size - 1, angle, times - 1) # Рекурсия

def leaves(size, angle, n_leaves):
    """
    Построение всех листьев
    """
    if n_leaves > 0:
        tl.color('black', 'green')
        tl.begin_fill()
        heading = tl.heading()
        x0, y0 = tl.xcor(), tl.ycor()
        leaf_up(size, angle, 11)
        x1, y1 = tl.xcor(), tl.ycor()
        tl.penup()
        tl.goto(x0, y0)
        tl.pendown()
        tl.setheading(heading)
        leaf_down(size, angle, 11)
        tl.left(15.849)
        tl.forward(50)
        tl.goto(x1, y1)
        tl.end_fill()
        tl.penup()
        tl.goto(x0, y0)
        tl.pendown()
        tl.setheading(heading)
        tl.right(56)
        leaves(size, angle, n_leaves - 1) # Рекурсия

def palm(size, angle, n_leaves):
    """
    Построение всей пальмы
    """
    trunk(size)
    node = (tl.xcor() + 10, tl.ycor())
    tl.penup()
    tl.left(75)
    tl.backward(75)
    tl.pendown()
    coconuts(size)
    tl.goto(node)
    tl.left(21)
    leaves(size, angle, n_leaves)

"""
Приготовление к выполнению фунций
"""
tl.delay(0)
tl.speed(100)
tl.penup()
tl.goto(40,-320)
tl.pendown()

"""
Эти переменные нельзя изменять, данные значения нужны для корректной работы функций (и упрощения их написания)
"""
size = 80
angle = 162
n_leaves = 5

palm(size, angle, n_leaves)

tl.done()


from copy import deepcopy # copy both reference and object
import pygame
from constants import RED, WHITE

def minimax(position, depth, max_player, game):
    # position is the current board position
    # depth is how far the tree extends
    # max_player is min of player or max of player
    # game is the actual game object
    if depth == 0 or position.winner() != None:
        return position.evaluate(), position

    if max_player:
        # we minimize the score
        maxEval = float('-inf') # from -ve infinity
        best_move = None
        for move in get_all_moves(position, WHITE, game):
            evaluation = minimax(move, depth-1, False, game)[0] # recursion usage
            maxEval = max(maxEval, evaluation)
            if maxEval == evaluation:
                best_move = move

        return maxEval, best_move

    else:
        # we maximize the score
        minEval = float('inf') # from +ve infinity
        best_move = None
        for move in get_all_moves(position, RED, game):
            evaluation = minimax(move, depth-1, True, game)[0] # recursion usage
            minEval = min(minEval, evaluation)
            if minEval == evaluation:
                best_move = move

        return minEval, best_move

def simulate_move(piece, move, board, game, skip):
    board.move(piece, move[0], move[1])
    if skip:
        board.remove(skip)

    return board

def get_all_moves(board, color, game):
    # get all possible moves of the game
    moves = [] # store the new board and piece

    for piece in board.get_all_pieces(color):
        valid_moves = board.get_valid_moves(piece)
        for move, skip in valid_moves.items():
            #draw_moves(game, board, piece)
            temp_board = deepcopy(board)
            temp_piece = temp_board.get_piece(piece.row, piece.col)
            new_board = simulate_move(temp_piece, move, temp_board, game, skip)
            moves.append(new_board)

    return moves

def draw_moves(game, board, piece):
    valid_moves = board.get_valid_moves(piece)
    board.draw(game.win)
    pygame.draw.circle(game.win, (0, 255, 0), (piece.x, piece.y), 50, 5)
    game.draw_valid_moves(valid_moves.keys())
    pygame.display.update()
    #pygame.time.delay(100)


#! /usr/bin/env python3

import sys
import yaml

SUPPORTED_VERSIONS = [.1, .2]

class VersionError(Exception):
    pass

def check_version(version):
    if version not in SUPPORTED_VERSIONS:
        raise VersionError(f"Configuration file version: {version} not in supported list: {SUPPORTED_VERSIONS}")

    return

def open_file(input_filename):
    try:
        # Open the file for read access only
        with open(input_filename, 'r') as input_file:
            # Use the yaml module to convert the file to a usable form
            # The FullLoader parameter handles the conversion from YAML
            # scalar values to Python the dictionary format
            conversion_data = yaml.load(input_file, Loader=yaml.FullLoader)

    except OSError:
        print (f"Could not read file: {input_filename}")
    except KeyError as my_error:
        print (f"Data object missing in file: {my_error}")
        input_file.close()

    input_file.close()
    return conversion_data

def main(input_filename):
    # Make sure we have the right file name here
    print (f"Asking for file name: {input_filename}")

    # Open the file and get the information
    conversion_data = open_file(input_filename)

    # Make sure the configuration file version is accpetable
    check_version(conversion_data["version"])

    print (conversion_data)

if __name__ == "__main__":
    # Check our input to look for 1 argument
    if len(sys.argv) != 2:
        # Raise an error if we don't have the right number
        raise SyntaxError("Insufficient arguments.  Please provide a variables input file name.")
        exit()
    else:
        # Start the conversion by sending the filename to the main function
        main(sys.argv[1])


# -*- coding: utf-8 -*-
import os
import pickle
import warnings

import numpy as np
import torch
import torch.utils.data
import torchvision.transforms as transforms
from torch.utils.tensorboard import SummaryWriter
from tqdm import tqdm

from architectures import DepixelationCNN
from datasets import RandomImagePixelationDataset, ImageDepixelationTestDataset
from submission_serialization import serialize

from utils import plot, stack_with_padding

def evaluate_model(
        model: torch.nn.Module,
        loader: torch.utils.data.DataLoader,
        loss_fn,
        device: torch.device,
):
    model.eval()
    # We will accumulate the mean loss
    loss = 0
    with torch.no_grad():  # We do not need gradients for evaluation
        # Loop over all samples in the specified data loader
        for data in tqdm(loader, desc="Evaluating", position=0, leave=False):
            # Get a sample and move inputs and targets to device
            inputs, known_arrays, targets, _ = data
            inputs = inputs.to(device)
            targets = [target.to(device) for target in targets]

            # Get outputs of the specified model
            outputs = model(inputs)

            # Compute loss based on output and targets
            losses = []
            for i in range(len(outputs)):
                output = outputs[i]
                target = targets[i]
                known_array = known_arrays[i]

                masked_output = output[(~known_array).bool()]
                target_flatten = target.flatten()

                loss = loss_fn(masked_output, target_flatten)
                losses.append(loss)

            loss = sum(losses) / len(losses)

    loss /= len(loader)
    model.train()
    return loss

def main(
        results_path,
        network_config: dict,
        learning_rate: float = 1e-3,
        weight_decay: float = 1e-5,
        epochs: int = 15,
        device: str = "cuda",
):
    """Main function that takes hyperparameters and performs training and
    evaluation of model"""
    device = torch.device(device)
    if "cuda" in device.type and not torch.cuda.is_available():
        warnings.warn("CUDA not available, falling back to CPU")
        device = torch.device("cpu")

    # Set a known random seed for reproducibility
    np.random.seed(0)
    torch.manual_seed(0)

    # Prepare a path to plot to
    plot_path = os.path.join(results_path, "plots")
    os.makedirs(plot_path, exist_ok=True)

    # Load training dataset

    transformations = transforms.Compose(
        [transforms.Resize(size=64), transforms.CenterCrop(size=(64, 64))]
    )
    dataset = RandomImagePixelationDataset(
        image_dir="./data/training",
        width_range=(4, 32),
        height_range=(4, 32),
        size_range=(4, 16),  # transform= transformations
    )

    # Split dataset into training, validation and test set (CIFAR10 dataset
    # is already randomized, so we do not necessarily have to shuffle again)
    training_set = torch.utils.data.Subset(
        dataset, indices=np.arange((int(len(dataset) * (3 / 5))))
    )
    validation_set = torch.utils.data.Subset(
        dataset, indices=np.arange(int(len(dataset) * (3 / 5)), len(dataset))
    )

    train_loader = torch.utils.data.DataLoader(
        training_set,
        batch_size=32,
        shuffle=True,
        num_workers=4,
        collate_fn=stack_with_padding,
        pin_memory=True,
    )
    validation_loader = torch.utils.data.DataLoader(
        validation_set, batch_size=1, shuffle=False, num_workers=4
    )

    # Define a TensorBoard summary writer that writes to directory
    # "results_path/tensorboard"
    writer = SummaryWriter(log_dir=os.path.join(results_path, "tensorboard"))

    # Create Network
    net = DepixelationCNN(**network_config)
    net.to(device)
    net.train()
    # Get mse loss function
    mse = torch.nn.MSELoss()

    # Get adam optimizer
    optimizer = torch.optim.Adam(
        net.parameters(), lr=learning_rate, weight_decay=weight_decay
    )

    write_stats_at = 1000  # Write status to TensorBoard every x updates
    plot_at = 10_000  # Plot every x updates
    validate_at = 5000  # Evaluate model on validation set and check for new best model every x updates
    update = 0  # Current update counter
    best_validation_loss = np.inf  # Best validation loss so far

    # Save initial model as "best" model (will be overwritten later)
    saved_model_file = os.path.join(results_path, "depixelation_cnn.pt")
    torch.save(net, saved_model_file)

    # Training loop
    for epoch in range(epochs):
        train_loader = tqdm(train_loader, desc=f"Epoch: {epoch + 1}", position=0)
        for data in train_loader:
            # Get next samples
            inputs, known_arrays, targets, _ = data

            inputs = inputs.to(torch.device("cuda"))

            known_arrays = known_arrays.to(device)

            # Reset gradients
            optimizer.zero_grad()

            # Get outputs of our network
            outputs = net(inputs)
            targets = [target.to(device) for target in targets]
            losses = []
            for i in range(len(outputs)):
                output = outputs[i]
                target = targets[i]
                known_array = known_arrays[i]

                masked_output = output[(~known_array).bool()]
                target_flatten = target.flatten()

                loss = mse(masked_output, target_flatten)
                losses.append(loss)

            loss = sum(losses) / len(losses)

            loss.backward()
            optimizer.step()

            # Write current training status
            if (update + 1) % write_stats_at == 0:
                writer.add_scalar(
                    tag="Loss/training", scalar_value=loss.cpu(), global_step=update
                )
                for i, (name, param) in enumerate(net.named_parameters()):
                    writer.add_histogram(
                        tag=f"Parameters/[{i}] {name}",
                        values=param.cpu(),
                        global_step=update,
                    )
                    writer.add_histogram(
                        tag=f"Gradients/[{i}] {name}",
                        values=param.grad.cpu(),
                        global_step=update,
                    )

            # Plot output
            if (update + 1) % plot_at == 0:
                plot(
                    inputs.detach().cpu().numpy(),
                    targets.detach().cpu().numpy(),
                    outputs.detach().cpu().numpy(),
                    plot_path,
                    update,
                )

            # Evaluate model on validation set
            if (update + 1) % validate_at == 0:
                val_loss = evaluate_model(
                    net, loader=validation_loader, loss_fn=mse, device=device
                )
                writer.add_scalar(
                    tag="Loss/validation", scalar_value=val_loss, global_step=update
                )
                # Save best model for early stopping
                if val_loss < best_validation_loss:
                    best_validation_loss = val_loss
                    torch.save(net, saved_model_file)

            train_loader.set_description(f"loss: {loss:7.5f}", refresh=True)
            train_loader.update()

            # Increment update counter
            update += 1

    train_loader.close()
    writer.close()
    print("Finished Training!")
    torch.save(net, saved_model_file)
    # Load best model and compute score on test set
    print(f"Computing scores for best model")
    net = torch.load(saved_model_file)
    train_loss = evaluate_model(net, loader=train_loader, loss_fn=mse, device=device)
    val_loss = evaluate_model(net, loader=validation_loader, loss_fn=mse, device=device)
    # test_loss = evaluate_model(net, loader=test_loader, loss_fn=mse, device=device)

    print(f"Scores:")
    print(f"training loss: {train_loss}")
    print(f"validation loss: {val_loss}")
    # print(f"test loss: {test_loss}")

    # Write result to file
    with open(os.path.join(results_path, "results.txt"), "w") as rf:
        print(f"Scores:", file=rf)
        print(f"training loss: {train_loss}", file=rf)
        print(f"validation loss: {val_loss}", file=rf)
        # print(f"test loss: {test_loss}", file=rf)

    test_set = ImageDepixelationTestDataset("./data/test_set.pkl")
    test_loader = torch.utils.data.DataLoader(
        test_set, batch_size=1, shuffle=False, num_workers=0
    )

    # To store predictions
    predictions = []

    # Evaluate the model
    with torch.no_grad():
        for (
                stacked_pixelated_images,
                stacked_known_arrays,
        ) in test_loader:
            stacked_pixelated_images = stacked_pixelated_images.to(device)
            stacked_known_arrays = stacked_known_arrays.to(device)

            outputs = net(stacked_pixelated_images)

            for i in range(len(outputs)):
                output = outputs[i]
                known_array = stacked_known_arrays[i]

                # Get the output where the known array is False, i.e., the pixelated images
                predicted_output = output[~known_array.bool()]

                predicted_output = predicted_output * 255

                predicted_output = (
                    predicted_output.detach().cpu().numpy().astype(np.uint8)
                )

                # Append flattened array to the list
                predictions.append(predicted_output.flatten())

    serialize(predictions, "predictions.bin")

if __name__ == "__main__":
    import argparse
    import json

    parser = argparse.ArgumentParser()
    parser.add_argument("config_file", type=str, help="Path to JSON config file.")
    args = parser.parse_args()
    with open(args.config_file) as cf:
        config = json.load(cf)

    main(**config)


"""Initial Migration

Revision ID: b9b152ecb696
Revises: d6bda99f0d61
Create Date: 2020-05-03 14:12:30.660017

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'b9b152ecb696'
down_revision = 'd6bda99f0d61'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comments', sa.Column('content', sa.String(), nullable=True))
    op.drop_column('comments', 'description')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comments', sa.Column('description', sa.VARCHAR(), autoincrement=False, nullable=True))
    op.drop_column('comments', 'content')
    # ### end Alembic commands ###


numarator=0
dizi=[]
while numarator < 5:
  sayı= int(input('Lütfen sayı giriniz: '))
  dizi.append(sayı)
  numarator = numarator +1
def enbuyuksayı(x):
  enbuyuk = x[0]
  for i in x:
    if i > enbuyuk:
      enbuyuk = i
  return f"Girdiginiz en büyük sayı {i}'dir."
print(enbuyuksayı(dizi))


from unittest.mock import Mock

import pandas as pd
import pytest

from giskard.datasets.base import Dataset
from giskard.llm.client import LLMFunctionCall, LLMOutput
from giskard.llm.evaluators.coherency import CoherencyEvaluator
from giskard.models.base.model_prediction import ModelPredictionResults

def _make_eval_datasets():
    ds1 = Dataset(
        pd.DataFrame({"question": ["What is the capital of France?", "Quo vadis?"], "other": ["test 1", "test 2"]})
    )
    ds2 = Dataset(
        pd.DataFrame(
            {
                "question": ["Why is Madrid the capital of France?", "Eo Romam, quo vadis?"],
                "other": ["test 1", "test 2"],
            }
        )
    )
    return ds1, ds2

def _make_mock_model():
    model = Mock()
    model.predict.return_value = ModelPredictionResults(prediction=["Paris", "Eo Romam"])
    model.meta.feature_names = ["question", "other"]
    model.meta.name = "Mock model for test"
    model.meta.description = "This is a model for testing purposes"
    return model

def test_requirements_evaluator_correctly_flags_examples():
    dataset1, dataset2 = _make_eval_datasets()
    model = _make_mock_model()

    client = Mock()
    client.complete.side_effect = [
        LLMOutput(
            function_call=LLMFunctionCall(
                function="evaluate_model",
                args={"passed_test": False, "reason": "Model output is not coherent"},
            )
        ),
        LLMOutput(
            function_call=LLMFunctionCall(
                function="evaluate_model",
                args={
                    "passed_test": True,
                },
            )
        ),
    ]

    evaluator = CoherencyEvaluator(llm_client=client)

    result = evaluator.evaluate(model, dataset1, dataset2)

    assert len(result.success_examples) == 1
    assert len(result.failure_examples) == 1

    assert result.failure_examples[0]["reason"] == "Model output is not coherent"
    assert result.failure_examples[0]["input_1"] == {"question": "What is the capital of France?", "other": "test 1"}
    assert result.failure_examples[0]["input_2"] == {
        "question": "Why is Madrid the capital of France?",
        "other": "test 1",
    }
    assert result.failure_examples[0]["output_1"] == "Paris"

    # Check LLM client calls arguments
    args = client.complete.call_args_list[0]
    assert "This is a model for testing purposes" in args[0][0][0]["content"]
    assert args[1]["functions"][0]["name"] == "evaluate_model"

def test_requirements_evaluator_handles_generation_errors():
    dataset1, dataset2 = _make_eval_datasets()
    model = _make_mock_model()

    client = Mock()
    client.complete.side_effect = [
        LLMOutput(
            function_call=LLMFunctionCall(
                function="evaluate_model",
                args={"passed_test": True},
            )
        ),
        LLMOutput(
            function_call=LLMFunctionCall(
                function="evaluate_model",
                args={"model_did_pass_the_test": False},
            )
        ),
    ]

    evaluator = CoherencyEvaluator(llm_client=client)

    result = evaluator.evaluate(model, dataset1, dataset2)

    assert len(result.success_examples) == 1
    assert len(result.failure_examples) == 0
    assert len(result.errors) == 1
    assert result.errors[0]["message"] == "Invalid function call arguments received"

def test_raises_error_if_datasets_have_different_length():
    dataset1, dataset2 = _make_eval_datasets()
    dataset2.df.drop(dataset2.df.index[0], inplace=True)
    model = _make_mock_model()

    evaluator = CoherencyEvaluator(llm_client=Mock())
    with pytest.raises(ValueError, match="Datasets must have the same index"):
        evaluator.evaluate(model, dataset1, dataset2)


from django.shortcuts import render
from django.db.models.expressions import RawSQL
from rest_framework.generics import RetrieveUpdateAPIView, UpdateAPIView
from django.db.models import Count, Sum, Q, F, Subquery, FloatField, CharField, Value as V
from django.db.models.functions import Cast, Concat
from rest_framework.response import Response
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.views import APIView
from .serializers.system import (UserInfluencerJSONWebTokenSerializer, UserSerializer,
    UserChangePassSerializer)
from .serializers.product import ProductClassSerializer
from .serializers.order import OrderSerializer
from .mixins import StandardPagination
from apps_base.core.mixins import BaseInfluencerAuthenticated
from apps_base.product.models import Product, ProductClass
from apps_base.order.models import Order
from apps_base.order.constants import PAGADO
from rest_framework_jwt.views import JSONWebTokenAPIView
from datetime import datetime
from .utils import range_month, format_date, range_start_end, month_initial, today_date, daterange
import locale
import json

class ObtainJSONWebToken(JSONWebTokenAPIView):
    """
    API View that receives a POST with a user's username and password.
    Returns a JSON Web Token that can be used for authenticated requests.
    """
    serializer_class = UserInfluencerJSONWebTokenSerializer

obtain_jwt_token = ObtainJSONWebToken.as_view()

class ProductListAPI(BaseInfluencerAuthenticated, ListAPIView):
    serializer_class = ProductClassSerializer
    pagination_class = StandardPagination

    def get_queryset(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        queryset_initial = ProductClass.objects.filter(
            influencer_id=user_influencer.influencer_id).prefetch_related(
            'product_class_products', 'product_class_products__attribute_option')
        search = self.request.query_params.get('search', None)
        field = self.request.query_params.get('field', None)
        orderBy = self.request.query_params.get('orderBy', None)
        filters = self.request.query_params.get('filter', None)
        if search:
            queryset_initial = queryset_initial.filter(name__icontains=search)
        if filters:
            filters = json.loads(filters)
            price_to = filters.get('price_to')
            price_from = filters.get('price_from')
            stock_from = filters.get('stock_from')
            stock_to = filters.get('stock_to')
            is_published = filters.get('is_published', False)
            if is_published == '':
                queryset_initial = queryset_initial.filter(is_published=False)
            else:
                queryset_initial = queryset_initial.filter(is_published=is_published)
            if price_to:
                queryset_initial = queryset_initial.filter(product_class_products__price__lte=float(price_to))
            if price_from:
                queryset_initial = queryset_initial.filter(product_class_products__price__gte=float(price_from))
            if stock_from:
                queryset_initial = queryset_initial.filter(product_class_products__stock__gte=format_date(stock_from))
            if stock_to:
                queryset_initial = queryset_initial.filter(product_class_products__stock__lte=format_date(create_from))
        product_ids = queryset_initial.distinct('id').values_list('id', flat=True)
        queryset = ProductClass.objects.filter(
            id__in=product_ids,
            influencer_id=user_influencer.influencer_id).prefetch_related(
            'product_class_products', 'product_class_products__attribute_option')
        if field:
            if field == 'product_class_products__price':
                ordering = field
                if orderBy == 'desc':
                    ordering = '{0}{1}'.format('-', field)
                queryset = queryset.order_by(ordering)
                # queryset = ProductClass.objects.filter(id__in=queryset.values_list('id', flat=True))
            else:
                if orderBy == 'desc':
                    ordering = '{0}{1}'.format('-', field)
                    queryset = queryset.order_by(ordering)
                else:
                    queryset = queryset.order_by(field)

        return queryset

class ProductDetailAPI(BaseInfluencerAuthenticated, RetrieveAPIView):
    serializer_class = ProductClassSerializer
    lookup_field = 'slug'

    def get_queryset(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        queryset = ProductClass.objects.filter(
            influencer_id=user_influencer.influencer_id).prefetch_related(
            'product_class_products', 'product_class_products__attribute_option')
        return queryset

class OrderListAPI(BaseInfluencerAuthenticated, ListAPIView):
    serializer_class = OrderSerializer
    pagination_class = StandardPagination

    def get_queryset(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        shipping_influencer = str(user_influencer.influencer_id)
        shipping_influencer__price = 'shipping_influencer__' + shipping_influencer + '__total'
        queryset_initial = Order.objects.filter(type_status=PAGADO,
            order_orderdetail__productdetail__product_class__influencer__id=user_influencer.influencer_id
            )
        search = self.request.query_params.get('search', None)
        field = self.request.query_params.get('field', None)
        orderBy = self.request.query_params.get('orderBy', None)
        filters = self.request.query_params.get('filter', None)

        if search:
            queryset_initial = queryset_initial.filter(
                Q(order_order_customer__first_name__icontains=search) |
                Q(order_order_customer__last_name__icontains=search) |
                Q(order_order_customer__email__icontains=search))
        order_ids = queryset_initial.distinct('id').values_list('id', flat=True)
        queryset = Order.objects.filter(
            id__in=order_ids
            ).annotate(full_name=Concat(
                'order_order_customer__first_name', V(' '), 'order_order_customer__last_name',
                output_field=CharField())).prefetch_related(
                'order_order_customer', 'order_ordershipping', 'order_orderdetail').annotate(influencer_json=RawSQL(
                    "(shipping_influencer->%s->%s)::text",
                    (shipping_influencer, 'total'))).annotate(
                    influencer_total=Cast('influencer_json', FloatField()))
        if filters:
            filters = json.loads(filters)
            total_to = filters.get('total_to')
            total_from = filters.get('total_from')
            create_from = filters.get('create_from')
            create_to = filters.get('create_to')
            status = filters.get('status')
            if total_to:
                queryset = queryset.filter(influencer_total__lte=float(total_to))
            if total_from:
                queryset = queryset.filter(influencer_total__gte=float(total_from))
            if create_to:
                queryset = queryset.filter(created__lte=format_date(create_to))
            if create_from:
                queryset = queryset.filter(created__gte=format_date(create_from))
            if status:
                queryset = queryset.filter(type_status_shipping=status)
        if field:
            if field == 'influencer_total':
                ordering = field
                if orderBy == 'desc':
                    ordering = '{0}{1}'.format('-', field)
                queryset = queryset.order_by(ordering)
            else:
                if orderBy == 'desc':
                    ordering = '{0}{1}'.format('-', field)
                    queryset = queryset.order_by(ordering)
                else:
                    queryset = queryset.order_by(field)

        return queryset

    def get_serializer_context(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self,
            'influencer_id': user_influencer.influencer_id
        }

class OrderDetailAPI(BaseInfluencerAuthenticated, RetrieveAPIView):
    serializer_class = OrderSerializer
    lookup_field = 'code'

    def get_queryset(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        shipping_influencer = str(user_influencer.influencer_id)
        queryset = Order.objects.filter(
            type_status=PAGADO,
            order_orderdetail__productdetail__product_class__influencer__id=user_influencer.influencer_id).distinct('id')
            # influencer_json=RawSQL(
            #     "(shipping_influencer->%s->%s)::text",
            #     (shipping_influencer, 'total_influencer'))).annotate(
            #     influencer_total=Cast('influencer_json', FloatField())).prefetch_related(
            #     'order_order_customer', 'order_ordershipping', 'order_orderdetail').distinct('id')
        print(queryset, 'queryset')
        return queryset

    def get_serializer_context(self):
        user = self.request.user
        user_influencer = user.user_user_influencer
        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self,
            'influencer_id': user_influencer.influencer_id
        }

class UserAPI(BaseInfluencerAuthenticated, RetrieveUpdateAPIView):
    serializer_class = UserSerializer

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

class UserChangePassAPI(BaseInfluencerAuthenticated, UpdateAPIView):
    serializer_class = UserChangePassSerializer

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

    def update(self, request, *args, **kwargs):
        self.object = self.get_object()
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            # Check old password
            if not self.object.check_password(serializer.data.get("password")):
                return Response({"password": ["Wrong password."]}, status=403)
            # set_password also hashes the password that the user will get
            self.object.set_password(serializer.data.get("new_password"))
            self.object.save()
            return Response({}, status=200)

        return Response(serializer.errors, status=403)

class DashboardAPI(BaseInfluencerAuthenticated, APIView):
    def get(self, request, format=None):
        locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8')
        user = self.request.user
        user_influencer = user.user_user_influencer
        today = today_date()
        month = month_initial()
        shipping_influencer = str(user_influencer.influencer_id)
        queryset_product = ProductClass.objects.filter(influencer__id=user_influencer.influencer_id)
        queryset_order = Order.objects.filter(
            type_status=PAGADO,
            order_orderdetail__productdetail__product_class__influencer__id=user_influencer.influencer_id)
        queryset = queryset_order.annotate(influencer_json=RawSQL(
                "(shipping_influencer->%s->%s)::text",
                (shipping_influencer, 'total'))).annotate(
                influencer_total=Cast('influencer_json', FloatField()))
        total_sales_month = queryset.filter(created__date__gte=month).aggregate(total_sales_month=Sum('influencer_total'))
        total_sales_month = total_sales_month.get('total_sales_month')
        if not total_sales_month:
            total_sales_month = 0
        total_sales_date = queryset.filter(created__date__gte=today).aggregate(total_sales_date=Sum('influencer_total'))
        total_sales_date = total_sales_date.get('total_sales_date', 0)
        if not total_sales_date:
            total_sales_date = 0
        data = {
            'month': month.strftime("%B %Y").title(),
            'day': month.strftime("%d %B %Y").title(),
            'total_sales_month': total_sales_month,
            'total_sales_date': total_sales_date,
            'total_order_month': queryset_order.filter(created__date__gte=month).count(),
            'total_product': queryset_product.count()
        }
        return Response(data)

class DashboardSalesAPI(BaseInfluencerAuthenticated, APIView):

    def get(self, request, format=None):
        locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8')
        user = self.request.user
        user_influencer = user.user_user_influencer
        shipping_influencer = str(user_influencer.influencer_id)
        list_sum_total = []
        list_mes_anio = []
        create_from = self.request.query_params.get('create_from')
        create_to = self.request.query_params.get('create_to')
        queryset = Order.objects.filter(
            type_status=PAGADO,
            order_orderdetail__productdetail__product_class__influencer__id=user_influencer.influencer_id).annotate(influencer_json=RawSQL(
                "(shipping_influencer->%s->%s)::text",
                (shipping_influencer, 'total'))).annotate(
                influencer_total=Cast('influencer_json', FloatField()))
            # influencer_json=RawSQL(
            #     "(shipping_influencer->%s->%s)::text",
            #     (shipping_influencer, 'total_influencer'))).annotate(
            #     influencer_total=Cast('influencer_json', FloatField())).prefetch_related(
            #     'order_order_customer', 'order_ordershipping', 'order_orderdetail').distinct('id')
        for day in daterange(create_from, create_to):
            order_day = queryset.filter(
                created__date__gte=day.get('mes_start')
            )
            if day.get('mes_end'):
                order_day = order_day.filter(created__date__lt=day.get('mes_end'))
            order_day = order_day.aggregate(total_fecha=Sum('influencer_total'))
            mes_anio = day.get('mes_start').strftime("%d %b %y").title()
            # mes_anio_end = day.get('mes_end').strftime("%d %b %y").title()
            sum_anio = order_day.get('total_fecha')
            if not sum_anio:
                sum_anio = 0
            list_mes_anio.append(mes_anio)
            list_sum_total.append(sum_anio)
        data = {
            'mes_anio': list_mes_anio,
            'sum_total': list_sum_total
        }
        return Response(data)

class DashboardOrderCountAPI(BaseInfluencerAuthenticated, APIView):

    def get(self, request, format=None):
        locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8')
        user = self.request.user
        user_influencer = user.user_user_influencer
        list_reporte_mes = []
        create_from = self.request.query_params.get('create_from')
        create_to = self.request.query_params.get('create_to')
        create_from = format_date(create_from)
        create_to = format_date(create_to)
        status = [
            {
                'value': 'AL',
                'name': 'En Almacén'
            },
            {
                'value': 'DS',
                'name': 'En Despacho'
            },
            {
                'value': 'EG',
                'name': 'Entregado'
            }
        ]
        queryset = Order.objects.filter(
            type_status=PAGADO,
            order_orderdetail__productdetail__product_class__influencer__id=user_influencer.influencer_id)
        queryset = queryset.distinct('id')
        for st in status:
            queryset_status = queryset.filter(
                type_status_shipping=st.get('value'),
                created__date__lte=create_to,
                created__date__gte=create_from
            ).count()
            list_reporte_mes.append({
                'name': st.get('name'),
                'total': queryset_status
            })
        # month_start, month_end = range_start_end()
        data = {
            'mes_anio': create_from.strftime("%d %b %y").title() + " - " + create_to.strftime("%d %b %y").title(),
            'reporte': list_reporte_mes
        }
        return Response(data)


import time
from utils.config import REFRESH_TOKEN, USER_ID
from pixivpy3 import AppPixivAPI

def init_api(self) -> AppPixivAPI:
    """
    Initialize the API.

    Returns:
        AppPixivAPI: The API client.
    """

    self.logger.info("[Start] Initialize the API client.")

    refresh_token = REFRESH_TOKEN

    api = AppPixivAPI()
    api.auth(refresh_token=refresh_token)
    time.sleep(2)

    self.logger.info("[End] Initialize the API client.")

    return api

def get_following_users(self, last_id):
    """
    Get the list of users who the target user is following.
    """
    api = self.api
    logger = self.logger
    logger.info("[Start] Get the list of users who the target user is following.")

    # Define a list of users.
    users = []

    # Get the list of users who the target user is following.
    res = self.api.user_following(USER_ID, restrict=self.restrict)
    time.sleep(5)

    duplicated = False

    while True:
        try:
            user_previews = res.user_previews

            for user_raw in user_previews:
                # Create a user object.
                user = user_raw.user
                latest_date = get_latest_date(user_raw.illusts)

                user_id = user.id

                # If the user ID is already registered in the CSV file, stop the processing.
                if user_id == last_id and self.mode == "diff":
                    self.logger.info(
                        "The user ID is already registered in the CSV file."
                    )
                    duplicated = True
                    break

                user_data = {
                    "id": user_id,
                    "account": user.account,
                    "name": user.name,
                    "latest_date": latest_date,
                }

                users.append(user_data)

            if duplicated:
                break

            next_url = res.next_url
            logger.info(f"Next URL: {next_url}")

            if next_url:
                next_qs = api.parse_qs(res.next_url)
                time.sleep(2)
                res = api.user_following(**next_qs)
                time.sleep(2)
            else:
                break

        except Exception as e:
            logger.error("Failed to get the user.:", str(e))
            break

    logger.info("[End] Get the list of users who the target user is following.")

    return users

def get_latest_date(illusts) -> str:
    """
    Get the latest post date of the user.

    Parameters
    ----------
    illusts: Any[]
          The list of user's illustrations.
    """

    # Check if there are illustrations.
    has_illusts = len(illusts) > 0

    if has_illusts:
        return illusts[0].create_date

    return None


# coding: utf-8
from django.shortcuts import render
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect, HttpRequest, HttpResponseBadRequest
import mutagen
from mpd import MPDClient
from music.models import Artist,Song
from pprint import pprint
import os
from contextlib import contextmanager
import json
import string
import urllib
import html
import pusher
from pprint import pprint

pusher_client = pusher.Pusher(
  app_id=settings.PUSHER_CONFIG['app_id'],
  key=settings.PUSHER_CONFIG['key'],
  secret=settings.PUSHER_CONFIG['secret'],
  cluster=settings.PUSHER_CONFIG['cluster'],
  ssl=settings.PUSHER_CONFIG['ssl']
)

@contextmanager
def mpdConnection():
	client = MPDClient()
	try:
		client.connect("localhost",6600)
		yield client
	finally:
		client.close()
		client.disconnect()

def index(request):
	with mpdConnection() as client:
		cursong = Song()
		cursong.now_playing()
		playlist = client.playlistinfo()
		artistList = client.list('Artist')
	return render(request,'music/index.html',{
			'artist': cursong.artist if hasattr(cursong,'artist') else '',
			'title': cursong.title if hasattr(cursong,'title') else '',
			'album': cursong.album if hasattr(cursong,'album') else '',
			'lUpcoming': playlist[1:11],
			'iTotalTracks': len(playlist) - 1,
			'artistList':artistList
		})

def list(request, queryString,start,end):
	if request.method == 'GET':
		lReturn = []
		with mpdConnection() as client:
			if queryString == 'albums':
				for artist in client.list('albumartist')[int(start):int(end)]:
					for album in client.list('album','artist',artist):
						lReturn.append({'artist':artist,'album':album})
			return HttpResponse(
				json.dumps(lReturn),
				content_type="application/json"
				)

def search(request, queryString):
	if request.method == 'GET':
		with mpdConnection() as client:
			results = client.search('any',queryString)
			if len(results) == 0:
				query = []
				for sString in queryString.split:
					query.append('any')
					query.append(sString)
				results = client.search(*query)
			if len(results) > 10:
				return HttpResponse(
					json.dumps(results[1:11]),
		            content_type="application/json"
		        )
			return HttpResponse(
				json.dumps(results),
	            content_type="application/json"
	        )
	else:
		return HttpResponse(
            json.dumps({"nothing to see": "this isn't happening"}),
            content_type="application/json"
        )

def filter(request, sType, queryString):
	html_parser = html.parser.HTMLParser()
	# print html_parser.unescape(urllib.parse.unquote(queryString))
	dResult = dict()
	with mpdConnection() as client:
		results = client.list('album',sType,html_parser.unescape(urllib.parse.unquote(queryString)))
		for result in results:
			# print client.search('album',result)
			dResult[result] = client.search('album',result)
	return HttpResponse(
		json.dumps(dResult),
		content_type="application/json"
	)

def get_album(request, artistName, albumName):
	html_parser = html.parser.HTMLParser()
	dResult = []
	with mpdConnection() as client:
		results = client.find('albumartist',html_parser.unescape(urllib.parse.unquote(artistName)))
		for result in results:
			if 'album' in result and result['album'] == albumName:
				dResult.append(result)
		pprint(results)
	return HttpResponse(
		json.dumps(dResult),
		content_type="application/json"
	)

def add(request, artistName=None, albumName=None):
	if request.method == "POST":
		with mpdConnection() as client:
			try:
				if json.loads(request.body)['uri']:
					try:
						client.add(json.loads(request.body)['uri'])
						playlist = client.playlistinfo()
						pusher_client.trigger('play-py', 'upcoming-track-list', {
							'tracks': playlist[1:11],
							'iTotalTracks': len(playlist) - 1
							})
						client.play()
						return HttpResponse(
							json.dumps({"result": "success"}),
							content_type="application/json"
						)
					except Exception:
						return HttpResponseBadRequest(
							json.dumps({"result": "failure"}),
							content_type="application/json"
						)
			except json.decoder.JSONDecodeError:
				if artistName:
					client.findadd('artist',artistName,'album',albumName)
					playlist = client.playlistinfo()
					pusher_client.trigger('play-py', 'upcoming-track-list', {
						'tracks': playlist[1:11],
						'iTotalTracks': len(playlist) - 1
						})
					client.play()
					return HttpResponse(
							json.dumps({"result": "success"}),
							content_type="application/json"
					)
	return HttpResponseBadRequest(
		json.dumps({"result": "failure"}),
		content_type="application/json"
	)

'''
NOTE: iTunes doesn't embed album artwork (that's seen in the application) in the files in it's library.
To do this, you can use the following script: http://dougscripts.com/itunes/scripts/ss.php?sp=reembedartwork
'''
def artwork(request):
	client = MPDClient()
	client.connect("localhost",6600)
	current = Song()
	current.now_playing()
	if current.file:
		file = mutagen.File(os.environ['HOME']+"/Music/"+current.file)
		if type(file) is mutagen.mp4.MP4:
			if 'covr' in file.tags:
				return HttpResponse(file.tags['covr'][0],content_type="image/jpeg")

		if type(file) is mutagen.mp3.MP3:
			if 'APIC:' in file.tags:
				return HttpResponse(file.tags['APIC:'].data,content_type=file.tags['APIC:'].mime)

	with open(os.path.join(settings.BASE_DIR, "static/no-artwork.png"), "rb") as f:
		return HttpResponse(f.read(), content_type="image/jpeg")

def artwork_find(request,albumName,artistName=None):
	if request.method == "GET":
		with mpdConnection() as client:
			if artistName:
				result = client.search('album',albumName,'artist',artistName)
			else:
				result = client.search('album',albumName)
			file = mutagen.File(os.environ['HOME']+"/Music/"+result[0]['file'])
			if type(file) is mutagen.mp4.MP4:
				if 'covr' in file.tags:
					return HttpResponse(file.tags['covr'][0],content_type="image/jpeg")

			if type(file) is mutagen.mp3.MP3:
				if 'APIC:' in file.tags:
					return HttpResponse(file.tags['APIC:'].data,content_type=file.tags['APIC:'].mime)

	with open(os.path.join(settings.BASE_DIR, "static/no-artwork.png"), "rb") as f:
		return HttpResponse(f.read(), content_type="image/jpeg")

def bigscreen(request):
	with mpdConnection():
		cursong = Song()
		cursong.now_playing()
	return render(request, 'music/bigscreen.html',{
			'artist': cursong.artist if hasattr(cursong,'artist') else '',
			'title': cursong.title if hasattr(cursong,'title') else '',
			'album': cursong.album if hasattr(cursong,'album') else ''
		})


N = int(input())
ld,rd = {},{}
ld[1] = 0
rd[0] = 1

for i in range(2,N+1):
    num,lr = map(int,input().split())
    if lr==0:
        x = ld[num]
        rd[x] = i
        ld[i] = x
        rd[i] = num
        ld[num] = i
    else:
        x = rd[num]
        rd[num] = i
        ld[i] = num
        rd[i] = x
        ld[x] = i

M = int(input())
for _ in range(M):
    dn = int(input())
    if dn in rd:
        tmp2 = rd[dn]
        tmp1 = ld[dn]
        rd[tmp1] = tmp2
        ld[tmp2] = tmp1
        del rd[dn]

z = 0
while z in rd:
    print(rd[z],end=" ")
    z = rd[z]


import random, copy
from alapanaSupport import *
from htmlTemplatesQuiz import *
from htmlTemplatesZen import *
from flask import Flask, render_template, request
from flask_bootstrap import Bootstrap
from string import Template
from fuzzywuzzy import fuzz

app = Flask(__name__)

alapanasDict = copy.deepcopy(finalAlapanasDict)

def shuffle(alas):
    selections = []
    i = 0
    while i < len(alas):
        selection = random.choice(list(alas.keys()))
        if selection not in selections:
           selections.append(selection)
           i = i+1
    return selections

# GLOBALS ###########################
shuffledAlapanas = shuffle(alapanasDict)
tenAlapanas = shuffledAlapanas[0:5]
times = 0
lnk = ""
numCorrect = 0

@app.route('/')
@app.route('/return', methods=['POST'])
def startPage():
    return render_template("main.html")

# ZEN -------------------------------------
@app.route('/zen', methods=['POST'])
def zenPage():
    return render_template("zen.html")

@app.route('/next', methods=['POST'])
def nextOne():
    global shuffledAlapanas
    a = random.choice(shuffledAlapanas)
    raga = myRagaDict[alapanasDict[a]]
    return(HTML_TEMPLATE_C.substitute(alap=a, rag=raga))

# QUIZ ------------------------------------
@app.route('/quiz', methods=['POST'])
@app.route('/again', methods=['POST'])
def ragaPage():
    global times
    global shuffledAlapanas
    global tenAlapanas
    global lnk
    global numCorrect
    # reset everything
    shuffledAlapanas = shuffle(alapanasDict)
    tenAlapanas = shuffledAlapanas[0:5]
    times = 0
    lnk = ""
    numCorrect = 0
    return render_template('quiz.html')

@app.route('/alapanaQuiz', methods=['POST'])
def alapanaQuiz():
    global times
    global shuffledAlapanas
    global tenAlapanas
    global lnk
    global numCorrect
    if times < 5:
        a = tenAlapanas[times]
        times = times + 1
        lnk = a
        return(HTML_TEMPLATE_Q.substitute(alap=a))
    else:
        return(HTML_TEMPLATE_DONE.substitute(num=numCorrect))

@app.route('/evaluate', methods=['POST'])
def is_correct():
    global lnk
    global numCorrect
    answered = request.form['answerField']
    raga = myRagaDict[alapanasDict[lnk]]
    rat = fuzz.ratio(answered.lower(), raga.lower()) #for approximate match (spelling differences)
    if (rat > 70): #partial match, but shouldn't allow similar ragams (saveri/asavari)
        if (raga == "Asaveri"):
            answered = answered.lower()
            if (answered[0] != "a"):
                return(HTML_TEMPLATE_A.substitute(result="INCORRECT", num=numCorrect, rag=raga))
            else:
                numCorrect = numCorrect + 1
                return(HTML_TEMPLATE_A.substitute(result="CORRECT!", num=numCorrect, rag=raga))
        numCorrect = numCorrect + 1
        return(HTML_TEMPLATE_A.substitute(result="CORRECT!", num=numCorrect, rag=raga))
    else:
        return(HTML_TEMPLATE_A.substitute(result="INCORRECT", num=numCorrect, rag=raga))

if __name__ == '__main__':
    app.run(debug=True)


from bsuite.environments.memory_chain import MemoryChain
import dm_env
import numpy as np
import random
import pandas as pd

class CustomMemoryChain(MemoryChain):
    def __init__(self, memory_length: int, num_bits: int, seed: int = 0):
        super().__init__(memory_length, num_bits, seed)
        assert (
            memory_length >= num_bits
        ), "Memory length must be greater than number of bits for custom Memory Chain."
        assert num_bits % 2 != 0, "Num bits must be an odd number"

        random.seed(seed)

        self._context_timesteps = random.sample(range(memory_length), num_bits)
        self._context_timesteps.sort()
        self._context_index = 0

        # Ignore query
        self._query = 0.0

    def _get_observation(self):
        """Observation of form [time, query, num_bits of context]."""

        obs = np.zeros(shape=(1, self._num_bits + 2), dtype=np.float32)
        # Show the time, on every step.
        obs[0, 0] = 1 - self._timestep / self._memory_length

        # Show the query, on the last step
        if self._timestep == self._memory_length - 1:
            obs[0, 1] = self._query

        # Show part of the context, on varied steps
        if self._timestep in self._context_timesteps:
            obs[0, 2 + self._context_index] = 2 * self._context[self._context_index] - 1
            self._context_index += 1

        return obs

    def _step(self, action: int) -> dm_env.TimeStep:
        observation = self._get_observation()
        self._timestep += 1

        if self._timestep - 1 < self._memory_length:
            # On all but the last step provide a reward of 0.
            return dm_env.transition(reward=0.0, observation=observation)
        if self._timestep - 1 > self._memory_length:
            raise RuntimeError("Invalid state.")  # We shouldn't get here.

        # Convert context from [0, 1] to [-1, 1]
        context = 2 * self._context - 1

        # If sum(context) > 0, action 1
        # If sum(context) < 0, action 0
        if (sum(context) > 0 and action == 1) or (sum(context) < 0 and action == 0):
            reward = 1.0
            self._total_perfect += 1
        else:
            reward = -1.0
            self._total_regret += 2.0
        return dm_env.termination(reward=reward, observation=observation)

    def _reset(self):
        self._context_index = 0

        self._timestep = 0
        self._episode_mistakes = 0
        self._context = self._rng.binomial(1, 0.5, self._num_bits)
        # Ignore query
        self._query = 0.0
        observation = self._get_observation()

        self._timestep += 1

        return dm_env.restart(observation)

    def get_context(self):
        return self._context[self._query]

def memory_preprocess(df_in: pd.DataFrame) -> pd.DataFrame:
    """Preprocess data for memory environments = regret relative to random."""
    df = df_in.copy()
    df["perfection_regret"] = df.episode - df.total_perfect
    # a random agent always has 50% chance on each episode
    # independently from memory length and number of bits.
    df["base_rate"] = 0.5
    df["regret_ratio"] = df.perfection_regret / df.base_rate
    return df

def score(df: pd.DataFrame, group_col: str = "custom_memory") -> float:
    """Output a single score for custom_memory."""
    df = memory_preprocess(df_in=df)
    max_eps = 10000
    ave_perfection = df.loc[df.episode == max_eps, "regret_ratio"].mean() / max_eps
    return ave_perfection

# Length: 3
# Bits: 3
# Length: 10
# Bits: 3, 5, 7, 9
# Length: 30
# Bits: 3, 5, 7, 9, 17, 25
# Length: 100
# Bits: 3, 5, 7, 9, 17, 25, 29, 35, 39

custom_memory_sweep = (
    "memory_custom/0",
    "memory_custom/1",
    "memory_custom/2",
    "memory_custom/3",
    "memory_custom/4",
    "memory_custom/5",
    "memory_custom/6",
    "memory_custom/7",
    "memory_custom/8",
    "memory_custom/9",
    "memory_custom/10",
    "memory_custom/11",
    "memory_custom/12",
)

def load_custom_memory_env(experiment: str):
    memory_length, num_bits = {
        "memory_custom/0": (3, 3),
        "memory_custom/1": (5, 3),
        "memory_custom/2": (5, 5),
        "memory_custom/3": (10, 3),
        "memory_custom/4": (10, 5),
        "memory_custom/5": (10, 7),
        "memory_custom/6": (10, 9),
        "memory_custom/7": (30, 3),
        "memory_custom/8": (30, 5),
        "memory_custom/9": (30, 7),
        "memory_custom/10": (30, 9),
        "memory_custom/11": (30, 17),
        "memory_custom/12": (30, 25),
    }.get(experiment)

    return CustomMemoryChain(memory_length=memory_length, num_bits=num_bits)


from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import PyQGLViewer as pq
from qgllogo import *
import OpenGL.GL as ogl

helpstr = """
D r a w L i g h t

The drawLight() function displays a representation of the OpenGL lights
of your scene. This is convenient for debugging your light setup.

This scene features a directionnal ligth (arrow), a spot light (cone) and a point
light source (sphere). The representation color, position and shape matches the light setup.

Hover over the point light or the spot light to manipulate it using the mouse (right
button translates and left button rotates)."""

class Viewer(pq.QGLViewer):
    def __init__(self):
        pq.QGLViewer.__init__(self)
        self.setStateFileName('.drawLight.xml')
        self.light1 = pq.ManipulatedFrame()
        self.light2 = pq.ManipulatedFrame()
    def draw(self):
        pos = [1.0, 0.5, 1.0, 0.0]
        # Directionnal light
        ogl.glLightfv(ogl.GL_LIGHT0, ogl.GL_POSITION, pos)

        pos[3] = 1.0
        # Spot light
        pos2 = list(self.light1.getPosition()) + [1]
        ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_POSITION, pos2)
        v = self.light1.getInverseTransformOf((0,0,1))
        ogl.glLightfv(ogl.GL_LIGHT1, ogl.GL_SPOT_DIRECTION, v)

        # Point light
        pos3 = list(self.light2.getPosition())
        pos3.append(1.0)
        ogl.glLightfv(ogl.GL_LIGHT2, ogl.GL_POSITION, pos3)
        draw_qgl_logo()
        self.drawLight(ogl.GL_LIGHT0)

        if self.light1.grabsMouse() :
            self.drawLight(ogl.GL_LIGHT1, 1.2)
        else:
            self.drawLight(ogl.GL_LIGHT1)
        if self.light2.grabsMouse():
            self.drawLight(ogl.GL_LIGHT2, 1.2)
        else:
            self.drawLight(ogl.GL_LIGHT2)
    def init(self):
        ogl.glMatrixMode(ogl.GL_MODELVIEW)
        ogl.glLoadIdentity()
        # Light0 is the default ambient light
        ogl.glEnable(ogl.GL_LIGHT0)
        # Light1 is a spot light
        ogl.glEnable(ogl.GL_LIGHT1)
        light_ambient  = [0.8, 0.2, 0.2, 1.0]
        light_diffuse  = [1.0, 0.4, 0.4, 1.0]
        light_specular = [1.0, 0.0, 0.0, 1.0]

        ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_SPOT_EXPONENT,  3.0)
        ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_SPOT_CUTOFF,    20.0)
        ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_CONSTANT_ATTENUATION, 0.5)
        ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_LINEAR_ATTENUATION, 1.0)
        ogl.glLightf( ogl.GL_LIGHT1, ogl.GL_QUADRATIC_ATTENUATION, 1.5)
        ogl.glLightfv( ogl.GL_LIGHT1, ogl.GL_AMBIENT,  light_ambient)
        ogl.glLightfv( ogl.GL_LIGHT1, ogl.GL_SPECULAR, light_specular)
        ogl.glLightfv( ogl.GL_LIGHT1, ogl.GL_DIFFUSE,  light_diffuse)
        # Light2 is a classical directionnal light
        ogl.glEnable(ogl.GL_LIGHT2)

        light_ambient2  = [0.2, 0.2, 2.0, 1.0]
        light_diffuse2  = [0.8, 0.8, 1.0, 1.0]
        light_specular2 = [0.0, 0.0, 1.0, 1.0]

        ogl.glLightfv(ogl.GL_LIGHT2, ogl.GL_AMBIENT,  light_ambient2)
        ogl.glLightfv(ogl.GL_LIGHT2, ogl.GL_SPECULAR, light_specular2)
        ogl.glLightfv(ogl.GL_LIGHT2, ogl.GL_DIFFUSE,  light_diffuse2)

        self.setMouseTracking(True)

        self.light1.setPosition(0.5, 0.5, 0)
        # Align z axis with -position direction : look at scene center
        self.light1.setOrientation(pq.Quaternion(pq.Vec(0,0,1), -self.light1.position()))

        self.light2.setPosition(-0.5, 0.5, 0)
        self.restoreStateFromFile()
        # self.help()
    def helpString(self):
        return helpstr

def main():
    qapp = QApplication([])
    viewer = Viewer()
    viewer.setWindowTitle("drawLight")
    viewer.show()
    qapp.exec_()

if __name__ == '__main__':
    main()


import gym
import numpy as np
import random
from MEC_env import mec_def
from MEC_env import mec_env
import tensorflow as tf
from tensorflow import keras
import tensorboard
import datetime
import MAAC_agent
from matplotlib import pyplot as plt
import json
import os

# tensorflow 中解决显存不足的问题
# os.environ["CUDA_VISIBLE_DEVICES"] = '0'  # 指定第一块GPU可用
config = tf.compat.v1.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.3  # 程序最多只能占用指定gpu50%的显存
# config.gpu_options.allow_growth = True  # 程序按需申请内存1e-13
tf.compat.v1.Session(config=config)

print("TensorFlow version: ", tf.__version__)  # 打印TF版本
# os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))  # 打印可用GPU数量
plt.rcParams['figure.figsize'] = (9, 9)  # 设置图像显示大小为(9, 9)
# logdir="logs/" + datetime.now().strftime("%Y%m%d-%H%M%S")
# tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)

# 设置参数
map_size = 200  # 地图大小 200*10
agent_num = 4  # agent（UAV）数量
sensor_num = 30  # sensor数量
obs_r = 60  # 观察半径 60*10
collect_r = 40  # 收集半径 ** 40*40
speed = 6  # UAV移动速率 6*10
max_size = 10  # UAV缓冲区上限（带计算数据缓冲区，计算完成数据缓冲区）
sensor_lam = 1e3 + 10 * 200  # sensor数据生成速率（到达率）：①poisson分布中，间隔时间的期望；②lam*2是sensor生成数据大小的上限 1e3 + 0 * 200
# i = 0, 2, 4， 6， 8,10

MAX_EPOCH = 5000
MAX_EP_STEPS = 200
LR_A = 0.001  # actor的学习率 learning rate for actor
LR_C = 0.002  # critic的学习率 learning rate for critic
GAMMA = 0.85  # reward折扣（系统惩罚的衰变系数） reward discount
TAU = 0.8  # 软替换（# target网络更新中，保留原始target网络参数的比例系数） soft replacement
BATCH_SIZE = 64
alpha = 0.9  # alpha参数（画图相关参数）
beta = 0.1  # beta参数（没用到）
Epsilon = 0.2  # UAV随机探索概率

# 固定随机种子以重现结果 random seeds are fixed to reproduce the results
map_seed = 1
rand_seed = 17
up_freq = 8  # 联邦更新周期，同时也是target网络更新周期
render_freq = 32  # 画图（MEC环境示意图）间隔
FL = True
FL_omega = 0.5  # 联邦因子
np.random.seed(map_seed)  # 生成指定的随机数
random.seed(map_seed)  # 生成指定的随机数
tf.random.set_seed(rand_seed)  # 生成指定的随机数

# 根据上面参数得到的参数字典
params = {
    'map_size': map_size,
    'agent_num': agent_num,
    'sensor_num': sensor_num,
    'obs_r': obs_r,
    'collect_r': collect_r,
    'speed': speed,
    'max_size': max_size,
    'sensor_lam': sensor_lam,

    'MAX_EPOCH': MAX_EPOCH,
    'MAX_EP_STEPS': MAX_EP_STEPS,
    'LR_A': LR_A,
    'LR_C': LR_C,
    'GAMMA': GAMMA,
    'TAU': TAU,
    'BATCH_SIZE': BATCH_SIZE,
    # 'alpha': alpha,
    # 'beta': beta,
    'Epsilon': Epsilon,
    'learning_seed': rand_seed,
    'env_seed': map_seed,
    'up_freq': up_freq,
    'render_freq': render_freq,
    'FL': FL,
    'FL_omega': FL_omega
}
# 生成MEC world
# 输入：地图大小，agent数量，sensor数量，观察半径，速度，收集半径，缓冲区上限，sensor的lam参数
mec_world = mec_def.MEC_world(map_size, agent_num, sensor_num, obs_r, speed, collect_r, MAX_EP_STEPS, max_size,
                              sensor_lam)
# 生成MEC环境
# 输入：MECworld，alpha参数，beta参数
env = mec_env.MEC_MARL_ENV(mec_world, alpha=alpha, beta=beta)

#
MAAC = MAAC_agent.MAACAgent(env, TAU, GAMMA, LR_A, LR_C, LR_A, LR_C, LR_A, LR_C, BATCH_SIZE, Epsilon)

# 格式化显示当前日期时间的函数 （这行代码的时间显示格式为：年月日-时分秒）
m_time = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
# 将整个程序的参数字典（python对象）转换为适当的json对象，并存储到相应位置
f = open('logs/hyperparam/%s.json' % m_time, 'w')
json.dump(params, f)
f.close()
#
MAAC.train(MAX_EPOCH, MAX_EP_STEPS, up_freq=up_freq, render=True, render_freq=render_freq, FL=FL, FL_omega=FL_omega)